我有一个问题困扰了我几周。当我更新到新的Facebook SDK时,我暂时忘记了它,但现在它又回来了。
我正在制作一个Facebook信息流阅读器。它从API调用中获取JSON数据,并使用该数据填充ListView。每次自定义适配器调用getView()方法时,它都会检查它是什么类型的“状态”。如果它是“照片”状态,则视图将具有两个图像(个人资料图片和状态更新的图片)。我使用nostra13的通用图像加载器,在充气ImageViews之后使用持有人类来帮助循环利用视图。这就是我认为问题存在的地方。
当我浏览列表时,所有个人资料图片都能正常加载并运行良好。但随着我滚动,状态照片会出现以下几种情况:
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本身提供了null值,就好像它没有找到正确的布局一样。我正在为不同类型的帖子使用两个不同的XML布局。因此,现在最好的解决方案似乎是使用相同的布局,并根据状态类型有条件地充气每个视图中的不同元素。