【发布时间】:2023-12-29 10:00:01
【问题描述】:
我有一个问题困扰了我好几个星期。当我更新到新的 Facebook SDK 时,我有一段时间忘记了它,但现在它又回到了我的梦想中。
我基本上是在制作一个 Facebook 订阅阅读器。它从 API 调用中获取 JSON 数据并使用它来填充 ListView。每次自定义适配器调用 getView() 方法时,它都会检查它是什么类型的“状态”。如果是“照片”状态,则视图将有两个图像(个人资料图片和状态更新的图片)。我正在使用 nostra13 的 Universal Image Loader 在使用 holder 类对 ImageView 进行充气后加载两个图像,以帮助回收视图。这就是我认为我的问题所在。
当我滚动浏览列表时,所有个人资料图片都可以正常加载并且效果很好。但当我滚动时,状态照片会做几件事:
1.) 全部加载相同的图像(我以前没有这个问题,但我给自己尝试修复其他问题)。
2.) 图像跳来跳去,要么消失,要么出现在与预期不同的视图中。
3.) 如果图像加载正确并且并非全部显示相同的图像,则图像会随着我向上和向下滚动而改变,最终都变成相同的图像。
我将发布我的 getView() 代码(抱歉有点长)。
@Override
public View getView(final int position, View convertView, ViewGroup parent) {
final ViewHolder holder;
try {
jsonObject = getItem(position);
jsonFrom = jsonObject.getJSONObject("from");
postType = jsonObject.getString("type");
posterName = jsonFrom.getString("name");
posterID = jsonFrom.getString("id");
posterPhoto = "http://graph.facebook.com/" + posterID
+ "/picture?type=square";
if (jsonObject.has("message")) {
posterMessage = jsonObject.getString("message");
} else {
posterMessage = jsonObject.getString("story");
}
} catch (JSONException e) {
e.printStackTrace();
}
if (postType.equals("status")) {
if (convertView == null) {
LayoutInflater inflater = (LayoutInflater) activity.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
convertView = inflater.inflate(R.layout.status_post_holder,null);
holder = new ViewHolder();
convertView.setTag(holder);
} else {
holder = (ViewHolder) convertView.getTag();
}
holder.posterName = (TextView) convertView.findViewById(R.id.posterName);
holder.posterMessage = (TextView) convertView.findViewById(R.id.posterMessage);
holder.posterProfilePhoto = (ImageView) convertView.findViewById(R.id.posterProfilePic);
if (jsonObject != null) {
holder.posterName.setText(posterName);
if (posterMessage != null) {
holder.posterMessage.setText(posterMessage);
} else {
holder.posterMessage.setText("No message for this post.");
}
profileImageLoader.displayImage(posterPhoto,
holder.posterProfilePhoto);
}
}
else if (postType.equals("photo")) {
if (convertView == null) {
try {
posterImageURL = jsonObject.getString("picture");
} catch (JSONException e) {
e.printStackTrace();
}
LayoutInflater inflater = (LayoutInflater) activity.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
convertView = inflater.inflate(R.layout.photo_post_holder, null);
holder = new ViewHolder();
convertView.setTag(holder);
} else {
holder = (ViewHolder) convertView.getTag();
}
holder.posterName = (TextView) convertView.findViewById(R.id.posterName);
holder.posterMessage = (TextView) convertView.findViewById(R.id.posterMessage);
holder.posterProfilePhoto = (ImageView) convertView.findViewById(R.id.posterProfilePic);
holder.posterImage = (ImageView) convertView.findViewById(R.id.posterImage);
if (jsonObject != null) {
holder.posterName.setText(posterName);
if (posterPhoto != null) {
profileImageLoader.displayImage(posterPhoto,holder.posterProfilePhoto);
}
if (posterImageURL != null) {
pictureImageLoader.displayImage(posterImageURL,holder.posterImage);
}
if (posterMessage != null) {
holder.posterMessage.setText(posterMessage);
} else {
holder.posterMessage.setText("No message for this post.");
}
}
}
else if (postType.equals("link")) {
if (convertView == null) {
LayoutInflater inflater = (LayoutInflater) activity.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
convertView = inflater.inflate(R.layout.status_post_holder,null);
holder = new ViewHolder();
convertView.setTag(holder);
} else {
holder = (ViewHolder) convertView.getTag();
}
holder.posterName = (TextView) convertView.findViewById(R.id.posterName);
holder.posterMessage = (TextView) convertView.findViewById(R.id.posterMessage);
holder.posterProfilePhoto = (ImageView) convertView.findViewById(R.id.posterProfilePic);
if (jsonObject != null) {
holder.posterName.setText(posterName);
if (posterMessage != null) {
holder.posterMessage.setText(posterMessage);
} else {
holder.posterMessage.setText("No message for this post.");
}
profileImageLoader.displayImage(posterPhoto,holder.posterProfilePhoto);
}
}
else {
if (convertView == null) {
LayoutInflater inflater = (LayoutInflater) activity.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
convertView = inflater.inflate(R.layout.status_post_holder,null);
holder = new ViewHolder();
convertView.setTag(holder);
} else {
holder = (ViewHolder) convertView.getTag();
}
holder.posterName = (TextView) convertView.findViewById(R.id.posterName);
holder.posterMessage = (TextView) convertView.findViewById(R.id.posterMessage);
holder.posterProfilePhoto = (ImageView) convertView.findViewById(R.id.posterProfilePic);
if (jsonObject != null) {
holder.posterName.setText(posterName);
if (posterMessage != null) {
holder.posterMessage.setText(postType);
} else {
holder.posterMessage.setText("No message for this post.");
}
profileImageLoader.displayImage(posterPhoto,holder.posterProfilePhoto);
}
}
return convertView;
}
我确信这与 Android 回收视图和效率有关,但我无法弄清楚我在哪里犯了错误。问题只存在于一个图像视图也很奇怪。任何帮助都会很热。谢谢。
更新:我们发现这是我的 JSON 解析错误。您必须使用 setTag() 来保留特定于该行项目的图像。适配器试图为视图设置一个 null 标记,这导致了 NPE。
再次更新:在深入挖掘之后,看起来是 ImageView 本身给出了一个空值,就好像它没有找到正确的布局一样。我为不同类型的帖子使用了两种不同的 xml 布局。所以现在看起来最好的解决方案是使用相同的布局,并根据状态类型有条件地在每个视图中膨胀不同的元素。
【问题讨论】:
-
为我解决了这个问题:*.com/questions/22726847/…
标签: android android-listview universal-image-loader