Custom Adapter repeating

為{幸葍}努か 提交于 2019-12-25 04:24:38

问题


I have this CustomAdapter, to fill a list with my data. The problem is that the Imageview is downloaded and drawed a lot of times. Example:

I search to my server a list of videos:

(Video1) Title 1 Description 1

(Video2) Title 2 Description 2

(Video3) Title 3 Description 3

..

When this loads, the image from the Video1 loads, then on the same Imageview, the Video2Image load, and again for each video on the list, same times how videos are on the list. When I scroll the adapter, this download all the images again. There are some option to fix this, I dont understand this behaivour.

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;
    }

}

Sorry my english.


回答1:


I answer that before and I answer it again for you: do not re-invent the wheel!

Image download/caching is q pretty complex thing for reasons you're seeing now (and others such as memory management, cache management, etc), so just use a library that works.

Below is your code using Picasso (my favorite image download library for 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;

}

Done! That code takes care of threading, caching, cancellation.

ps.: You should read a bit more regaring adapter and the ViewHolder pattern, you're not doing it correctly.




回答2:


I had this problem a while back. If you put a log in getView() you will see that it is called whenever you scroll past the end of the screen. This means the images are being downloaded many many times as you scroll.

To get around this you need to cache your bitmaps. Once you have a cache, every time you call getView, do a query to the cache FIRST to see if the image has already been downloaded THEN if it is not available, download it and add it to the cache.

This method is explained (with code) here on Android Developers. http://developer.android.com/training/displaying-bitmaps/cache-bitmap.html




回答3:


Your getview is always creating a DownloadImageTask. You don't want to do that- you want to check to see if you already have it, and download a new one only if you don't.



来源:https://stackoverflow.com/questions/24874952/custom-adapter-repeating

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!