定制适配器重复

时间:2014-07-21 21:17:18

标签: android android-asynctask imageview adapter

我有这个CustomAdapter,用我的数据填充列表。问题是Imageview被下载并绘制了很多次。例如:

我在服务器上搜索视频列表:

(Video1) Title 1 Description 1

(Video2) Title 2 Description 2

(Video3) Title 3 Description 3

..

加载时,Video1中的图像加载,然后加载到同一Imageview,Video2Image加载,并再次加载列表中的每个视频,同样加载列表中的视频。当我滚动适配器时,再次下载所有图像。有一些方法可以解决这个问题,我不明白这种行为。

CustomAdapter.java

public class CustomAdapter extends ArrayAdapter<Video> {
    // declaring our ArrayList of items
    private ArrayList<Video> objects;

    public CustomAdapter(Context context, int textViewResourceId, ArrayList<Video> objects) {
        super(context, textViewResourceId, objects);
        this.objects = objects;
    }

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

        View v = convertView;

        if (v == null) {
            LayoutInflater inflater = (LayoutInflater) getContext().getSystemService(Context.LAYOUT_INFLATER_SERVICE);
            v = inflater.inflate(R.layout.list_row, null);
        }

        Video i = objects.get(position);

        if (i != null) {

            TextView title = (TextView) v.findViewById(R.id.title);
            TextView description = (TextView) v.findViewById(R.id.description);
            ImageView imagen = (ImageView) v.findViewById(R.id.list_image);

            title.setText(i.getTitulo());
            description.setText(i.getDescripcion());

            //Creamos imagen descargada y la seteamos
            new DownloadImageTask(imagen).execute(i.getUrlimagen());
            BitmapDrawable drawable = (BitmapDrawable) imagen.getDrawable();
            Bitmap bitmap = drawable.getBitmap();
            imagen.setImageBitmap(bitmap);

            Log.i("Debug", "Creando una imagen para: " + i.getTitulo());

            v.setTag(R.id.id_url, i.getUrl().trim());//1.Url
            v.setTag(R.id.id_titulo,i.getTitulo().trim());//2.Título
            v.setTag(R.id.id_video,i.getId().trim());//3.ID

        }

        return v;

    }

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

        public DownloadImageTask(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();
                BitmapFactory BitmapFactory = null;
                mIcon11 = BitmapFactory.decodeStream(in);
            } catch (Exception e) {
                e.printStackTrace();
            }
            return mIcon11;
        }

        protected void onPostExecute(Bitmap result) {
            if(result!=null)
                bmImage.setImageBitmap(result);
        }
    }

    public ArrayList getValues(){
        return objects;
    }

}

对不起我的英语。

3 个答案:

答案 0 :(得分:1)

我有一段时间没遇到这个问题。如果您在getView()中放入一个日志,只要您滚动到屏幕的末尾,就会看到它被调用。这意味着滚动时图像会被多次下载。

要解决此问题,您需要缓存位图。一旦有了缓存,每次调用getView时,都要先查询缓存FIRST以查看图像是否已经下载然后如果它不可用,请下载并将其添加到缓存中。

此方法在Android开发者处解释(带代码)。 http://developer.android.com/training/displaying-bitmaps/cache-bitmap.html

答案 1 :(得分:1)

我之前回答这个问题,然后我再次为你回答:不要重新发明轮子!

由于您现在看到的原因(以及其他内容管理,缓存管理等),图像下载/缓存非常复杂,所以只需使用一个有效的库。

以下是使用Picasso(我最喜欢的Android图像下载库)

的代码
public View getView(int position, View convertView, ViewGroup parent){

    View v = convertView;

    if (v == null) {
        LayoutInflater inflater = (LayoutInflater) getContext().getSystemService(Context.LAYOUT_INFLATER_SERVICE);
        v = inflater.inflate(R.layout.list_row, null);
    }

    Video i = objects.get(position);

    if (i != null) {

        TextView title = (TextView) v.findViewById(R.id.title);
        TextView description = (TextView) v.findViewById(R.id.description);
        ImageView imagen = (ImageView) v.findViewById(R.id.list_image);

        title.setText(i.getTitulo());
        description.setText(i.getDescripcion());

        //Creamos imagen descargada y la seteamos
        Picasso
            .with(imagen.getContext())
            .load(i.getUrlimagen())
            .into(imagen);

        Log.i("Debug", "Creando una imagen para: " + i.getTitulo());

        v.setTag(R.id.id_url, i.getUrl().trim());//1.Url
        v.setTag(R.id.id_titulo,i.getTitulo().trim());//2.Título
        v.setTag(R.id.id_video,i.getId().trim());//3.ID

    }

    return v;

}

完成!该代码负责线程,缓存,取消。

ps:你应该阅读更多的regaring适配器和ViewHolder模式,你没有正确地做到这一点。

答案 2 :(得分:0)

您的getview始终在创建DownloadImageTask。你不想这样做 - 你想检查一下你是否已经拥有它,并且只有在你没有的情况下才下载一个新的。