Android 单击列表项时,图像在listview中交换其行
我在ListView中使用AsyncTask加载图像时遇到了一个奇怪的问题。在我的ListView中,每一行都包含一个ImageView和一个TextView。我跟随了这个链接: 正在从URL成功下载图像,并将其填充到受尊重的行中。但是当我滚动ListView或单击任何列表项时,图像只是交换它们的行。尽管文本视图中的文本保持在同一行上。我不明白为什么会这样。我在谷歌上搜索了很多,但找不到一个完美的理由。请帮忙 以下是我的适配器类:Android 单击列表项时,图像在listview中交换其行,android,listview,android-asynctask,imageview,Android,Listview,Android Asynctask,Imageview,我在ListView中使用AsyncTask加载图像时遇到了一个奇怪的问题。在我的ListView中,每一行都包含一个ImageView和一个TextView。我跟随了这个链接: 正在从URL成功下载图像,并将其填充到受尊重的行中。但是当我滚动ListView或单击任何列表项时,图像只是交换它们的行。尽管文本视图中的文本保持在同一行上。我不明白为什么会这样。我在谷歌上搜索了很多,但找不到一个完美的理由。请帮忙 以下是我的适配器类: private class ListAdapter
private class ListAdapter extends BaseAdapter{
private ArrayList<HashMap<String, Object>> allFriends;
private LayoutInflater mInflater;
public ListAdapter(ArrayList<HashMap<String, Object>> allFriends, Context context){
this.allFriends = allFriends;
mInflater = LayoutInflater.from(context);
}
@Override
public int getCount() {
return allFriends.size();
}
@Override
public Object getItem(int position) {
return allFriends.get(position);
}
@Override
public long getItemId(int position) {
return position;
}
@Override
public View getView(final int position, View convertView, ViewGroup parent) {
FriendsViewHolder holder;
if (convertView == null||!(convertView instanceof TextView)||!(convertView instanceof ImageView)) {
convertView = mInflater.inflate(R.layout.friend_list_view, null);
holder = new FriendsViewHolder();
holder.friendName = (TextView) convertView.findViewById(R.id.friendName);
holder.friendImage = (ImageView) convertView.findViewById(R.id.friendImage);
convertView.setTag(holder);
}else {
holder = (FriendsViewHolder) convertView.getTag();
}
holder.friendName.setText((String) allFriends.get(position).get(FriendsActivity.FRIENDS_NAME_KEY));
String otherId=(String) allFriends.get(position).get(FriendsActivity.IDKEY);
String isImage=(String) allFriends.get(position).get(FriendsActivity.IS_IMAGE_KEY);
if(isImage.equalsIgnoreCase("true")){
download(otherId, holder.friendImage);
}
return convertView;
}
}//End of list adapter
此处BitmapDownloaderTask是用于下载图像的异步任务:
class BitmapDownloaderTask extends AsyncTask<String, Void, Bitmap> {
private String otherId;
private final WeakReference<ImageView> imageViewReference;
public BitmapDownloaderTask(ImageView imageView) {
imageViewReference = new WeakReference<ImageView>(imageView);
}
@Override
// Actual download method, run in the task thread
protected Bitmap doInBackground(String... params) {
// params comes from the execute() call: params[0] is the url.
return getOtherUserImage(params[0]);
}
@Override
// Once the image is downloaded, associates it to the imageView
protected void onPostExecute(Bitmap bitmap) {
if (isCancelled()) {
bitmap = null;
}
if(bitmap!=null){
if (imageViewReference != null) {
ImageView imageView = imageViewReference.get();
if(imageView != null ){
imageView.setImageBitmap(bitmap);
}
}
}
}
}
这描述了如何正确地将图像异步加载到ListView中,并提供了一个很好的示例应用程序,您应该能够快速轻松地修改(我做过)以满足您的需要
实际上,出于内存效率的原因,ListView
会回收视图
当用户滚动时显示的。如果一个人抛出这个名单,一个
给定的ImageView
对象将被多次使用。每次都是
显示的ImageView
正确触发图像下载任务,
这最终会改变它的形象。那么问题出在哪里呢?作为
对于大多数并行应用程序,关键问题在于排序。在里面
在我们的情况下,无法保证下载任务将在
开始的顺序。结果是图像
最后显示在列表中的项目可能来自上一个项目
只是碰巧下载时间更长。这不是问题
如果您下载的图像被一次性绑定到给定的
图像视图
这描述了如何正确地将图像异步加载到ListView中,并提供了一个很好的示例应用程序,您应该能够快速轻松地修改(我做过)以满足您的需要
实际上,出于内存效率的原因,ListView
会回收视图
当用户滚动时显示的。如果一个人抛出这个名单,一个
给定的ImageView
对象将被多次使用。每次都是
显示的ImageView
正确触发图像下载任务,
这最终会改变它的形象。那么问题出在哪里呢?作为
对于大多数并行应用程序,关键问题在于排序。在里面
在我们的情况下,无法保证下载任务将在
开始的顺序。结果是图像
最后显示在列表中的项目可能来自上一个项目
只是碰巧下载时间更长。这不是问题
如果您下载的图像被一次性绑定到给定的
图像视图
我认为你应该让下载图片的方法“同步”。很多线程同时运行,因此图像可能会出现错误位置。我认为应该将下载图像的方法设置为“同步”。许多线程同时运行,因此图像可能会出现错误位置。您是否遵循视图持有者方法?发布您的自定义适配器以查看发生了什么。是的,我遵循ViewHolder方法。请查看编辑。您是否遵循视图持有者方法?发布您的自定义适配器以查看发生了什么。是的,我遵循ViewHolder方法。请查看编辑。我也在上面的链接中尝试过这种方法,但仍然不起作用:(还有其他想法……嗨,杰夫。我已经下载了上面链接中给出的代码,并在代码中实现了与之完全相同的功能。我也可以缓存图像。但是图像显示在错误行的问题仍然存在。现在滚动时不会发生这种情况,因为我正在使用缓存。但有时在打开屏幕时会出现错误或者第一次,它们已经出现在错误的地方。在我的情况下,我没有使用“url”因为我只有一个URL,我必须在上面发送用户Id并获取他的图像。所以我使用Id而不是URL来区分图像的位置。但是没有成功。有什么想法吗?好的,我终于做到了。但是我这里有一个小问题。我想在加载图像时显示默认图像。就像在这个链接中:@Yogessomani Can u请告诉我你是如何解决这个问题的?我在上面的链接中也尝试过这种方法,但仍然不起作用(还有其他想法……嗨,杰夫。我已经下载了上面链接中给出的代码,并在代码中实现了与之完全相同的功能。我也可以缓存图像。但是图像显示在错误行的问题仍然存在。现在滚动时不会发生这种情况,因为我正在使用缓存。但有时在打开屏幕时会出现错误或者第一次,它们已经出现在错误的地方。在我的情况下,我没有使用“url”因为我只有一个URL,我必须在上面发送用户Id并获取他的图像。所以我使用Id而不是URL来区分图像的位置。但是没有成功。有什么想法吗?好的,我终于做到了。但是我这里有一个小问题。我想在加载图像时显示默认图像。就像在这个链接中:@Yogessomani Can u请告诉我你是如何解决这个问题的?
class BitmapDownloaderTask extends AsyncTask<String, Void, Bitmap> {
private String otherId;
private final WeakReference<ImageView> imageViewReference;
public BitmapDownloaderTask(ImageView imageView) {
imageViewReference = new WeakReference<ImageView>(imageView);
}
@Override
// Actual download method, run in the task thread
protected Bitmap doInBackground(String... params) {
// params comes from the execute() call: params[0] is the url.
return getOtherUserImage(params[0]);
}
@Override
// Once the image is downloaded, associates it to the imageView
protected void onPostExecute(Bitmap bitmap) {
if (isCancelled()) {
bitmap = null;
}
if(bitmap!=null){
if (imageViewReference != null) {
ImageView imageView = imageViewReference.get();
if(imageView != null ){
imageView.setImageBitmap(bitmap);
}
}
}
}
}
public Bitmap getOtherUserImage(String otherUserId){
// code to download the image goes here. It returns bitmap "bmImg".
if(bmImg==null){
return null;
}else {
bmImg = Bitmap.createScaledBitmap(bmImg,imageWidth, imageHeight, true);
/*availableFriends.get(position).put(BITMAP_KEY, bmImg);
runOnUiThread(new Runnable() {
public void run() {
adapter.notifyDataSetChanged();
}
});*/
return bmImg;
}
}