列表视图在滚动时显示错误位置的图像

时间:2014-10-18 16:55:03

标签: android image listview android-asynctask

我有一个ListView,我从服务器填充。一切正常但单个问题是滚动时下载的图像显示在错误的项目位置。只有几秒钟后,它才能在正确的位置显示正确的图像。

这是我的ArrayAdapter类,其中包含AsynchTask:

public class ApplicationAdapter extends ArrayAdapter<Application> {
    private List<Application> items;

    public ApplicationAdapter(Context context, List<Application> items) {
        super(context, R.layout.app_custom_list, items);
        this.items = items;
    }

    @Override
    public int getCount() {
        return items.size();
    }

    @Override
    public View getView(int position, View convertView, ViewGroup parent) {

        View v = convertView;

        if (v == null) {
            LayoutInflater li = LayoutInflater.from(getContext());
            v = li.inflate(R.layout.app_custom_list, null);
        }

        Application app = items.get(position);

        if (app != null) {
            ImageView imageView = (ImageView) v.findViewById(R.id.appIcon);
            TextView titleText  = (TextView) v.findViewById(R.id.titleTxt);

            if (imageView != null) {

                String path_image = app.getImagePath();

                // Call AsynchTask to load image into ImageView from path
                DownloadImageTask1 d = new DownloadImageTask(imageView);
                d.execute(path_image);
            }


            if (titleText != null) {

                titleText.setText(app.getTitle());

            }

        }

        return v;
    }

private class DownloadImageTask1 extends AsyncTask<String, Void, Bitmap> {
    ImageView bmImage;

    public DownloadImageTask1(ImageView bmImage) {
        this.bmImage = bmImage;
    }

    protected Bitmap doInBackground(String... urls) {
        String urldisplay = urls[0];
        Bitmap mIcon11 = null;
        try {
            InputStream in = new java.net.URL(urldisplay).openStream();
            mIcon11 = BitmapFactory.decodeStream(in);
        } catch (Exception e) {
            Log.e("Error", e.getMessage());
            e.printStackTrace();
        }
        return mIcon11;
    }

    protected void onPostExecute(Bitmap result) {
        bmImage.setImageBitmap(getRoundedCornerBitmap(result));

    }
}

有人可以指导我走向正确的方向吗?我已经工作了几天来解决这个问题。感谢!!!

4 个答案:

答案 0 :(得分:6)

这是因为滚动ImageView时会重复使用listview。在listview onPreExecute中显示加载图片。如果你使用像picasso这样的库,那么wolul会更好。因为它可以为您完成所有工作,包括将图像保存在捕获中

答案 1 :(得分:1)

您应该使用另一个类来保存您的对象,它可以帮助您在设置后保持良好的引用。

最好稍微更换适配器。

您最好获得一次layoutInflater的引用,因为为列表视图中的每个项都调用了getView。

因此,为整个类声明layoutInflater并仅获取一次引用

例如:

 private LayoutInflater inflater;


 @Override
    public View getView(int position, View convertView, ViewGroup parent) {
        ImageHolder holder = new ImageHolder();

        if (inflater == null)
            inflater = (LayoutInflater) activity
                    .getSystemService(Context.LAYOUT_INFLATER_SERVICE);

        if(convertView == null){
            convertView = inflater.inflate(R.layout.fragment_list_item_transition, null);
            ImageView imageView = (ImageView) convertView.findViewById(R.id.appIcon);
            TextView titleText  = (TextView) convertView.findViewById(R.id.titleTxt);
            holder.image = imageView;
            holder.title = titleText;
            convertView.setTag(holder); 

        }else{
            holder = (ImageHolder) convertView.getTag(position);
        }

        Application app = items.get(position);

        if (app != null) {


            holder.title.seText(app.getTitle());
            String path_image = app.getImagePath();

            // Call AsynchTask to load image into ImageView from path
            DownloadImageTask1 d = new DownloadImageTask1(holder.imageView);

            d.execute(path_image);
        }

        return convertView;
    }


    private static class ImageHolder{
        ImageView image;
        TextView title;

    }

答案 2 :(得分:1)

您还可以尝试使用UniversalImageLoader库来加载图片。试试这个

ImageLoader.getInstance().displayImage(url, holder.imgView, options);

在适配器中加载图片..

在适配器

的构造函数中使用DisplayImageOptions,如下所示
 options = new DisplayImageOptions.Builder()
                .showImageOnLoading(android.R.color.transparent)
                .showImageForEmptyUri(android.R.color.transparent)
                .showImageOnFail(android.R.color.transparent)
                .cacheInMemory(true)
                .cacheOnDisk(true)
                .considerExifParams(true)
                .bitmapConfig(Bitmap.Config.RGB_565)
                .build();

并添加

StrictMode.ThreadPolicy policy = new StrictMode.ThreadPolicy.Builder().permitAll().build();
        StrictMode.setThreadPolicy(policy);

在片段/活动的onCreateView / onCreate中包含列表

答案 3 :(得分:0)

尝试这样的事情......

replace

 if (v == null) {
            LayoutInflater li = LayoutInflater.from(getContext());
            v = li.inflate(R.layout.app_custom_list, null);
        }

with

if (v == null) {
            LayoutInflater li = LayoutInflater.from(getContext());
            v = li.inflate(R.layout.app_custom_list, null);
            convertView.setTag(v);
        } else {
            v = (View) convertView.getTag();
        }