繁体   English   中英

ListView中来自URL的图像随机图像错误

[英]Image from url in ListView random image error

我的问题是在AsyncTask中为列表视图加载图像。 应用程序输出是带有textview的listview,效果很好,但是ImageView会加载几乎随机的图像,在某些项目中该图像会更改为其他图像(有时像循环一样)。

logcat -s“测试”->没有发现任何问题

活页夹数据:

package cz.www3.tech_apps.cinetube.cinetube;

import java.io.InputStream;
import java.net.HttpURLConnection;
import java.net.URL;
import java.net.URLConnection;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;

import android.app.Activity;
import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Canvas;
import android.graphics.Paint;
import android.graphics.Path;
import android.graphics.PorterDuff;
import android.graphics.PorterDuffXfermode;
import android.graphics.Rect;
import android.graphics.drawable.Drawable;
import android.os.AsyncTask;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.BaseAdapter;
import android.widget.ImageView;
import android.widget.ListView;
import android.widget.RelativeLayout;
import android.widget.TextView;

public class Binderdatakomunita extends BaseAdapter {

    LayoutInflater inflater;
    List<HashMap<String,String>> komunitaarray;
    ViewHolder holder;


    public Binderdatakomunita() {

    }

    public Binderdatakomunita(Activity act, List<HashMap<String,String>> map) {

        this.komunitaarray = map;

        inflater = (LayoutInflater) act
                .getSystemService(Context.LAYOUT_INFLATER_SERVICE);
    }


    public int getCount() {
        return komunitaarray.size();
    }

    public Object getItem(int arg0) {
        return null;
    }

    public long getItemId(int position) {
        return 0;
    }
    public int position;

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

        View vi=convertView;
        if(convertView==null){

            vi = inflater.inflate(R.layout.lide, parent, false);
            holder = new ViewHolder();

            holder.jmeno = (TextView)vi.findViewById(R.id.jmeno);
            holder.akce = (TextView)vi.findViewById(R.id.akce);
            holder.id = (TextView)vi.findViewById(R.id.id);
            holder.profilovkaimg = (ImageView)vi.findViewById(R.id.profilovka);

            vi.setTag(holder);
        }
        else{

            holder = (ViewHolder)vi.getTag();
        }
        holder.jmeno.setText(komunitaarray.get(position).get("jmeno"));
        if (komunitaarray.get(position).get("akce") != null){
            holder.akce.setText(komunitaarray.get(position).get("akce"));
        } else {
            holder.akce.setText("Neznámá akce");
        }
        try {
            new DownLoadImageTask(holder.profilovkaimg).execute(komunitaarray.get(position).get("obrazek"));
        } catch (Exception e) {
            Log.e("test", "exception", e);
        }
        holder.id.setText(Integer.toString(position));

        return vi;
    }

    static class ViewHolder{

        TextView jmeno;
        TextView akce;
        TextView id;
        ImageView profilovkaimg;
    }

    private class DownLoadImageTask extends AsyncTask<String,Void,Bitmap>{
        ImageView imageView;

        public DownLoadImageTask(ImageView imageView){
            this.imageView = imageView;
        }

        public Bitmap scaleDown(Bitmap realImage, float maxImageSize,
                                       boolean filter) {
            float ratio = Math.min(
                    (float) maxImageSize / realImage.getWidth(),
                    (float) maxImageSize / realImage.getHeight());
            int width = Math.round((float) ratio * realImage.getWidth());
            int height = Math.round((float) ratio * realImage.getHeight());

            Bitmap newBitmap = Bitmap.createScaledBitmap(realImage, width,
                    height, filter);
            return newBitmap;
        }

        public Bitmap getCroppedBitmap(Bitmap bitmap) {
            Bitmap output = Bitmap.createBitmap(bitmap.getWidth(),
                    bitmap.getHeight(), Bitmap.Config.ARGB_8888);
            Canvas canvas = new Canvas(output);

            final int color = 0xff424242;
            final Paint paint = new Paint();
            final Rect rect = new Rect(0, 0, bitmap.getWidth(), bitmap.getHeight());

            paint.setAntiAlias(true);
            canvas.drawARGB(0, 0, 0, 0);
            paint.setColor(color);
            // canvas.drawRoundRect(rectF, roundPx, roundPx, paint);
            canvas.drawCircle(bitmap.getWidth() / 2, bitmap.getHeight() / 2,
                    bitmap.getWidth() / 2, paint);
            paint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.SRC_IN));
            canvas.drawBitmap(bitmap, rect, rect, paint);
            //Bitmap _bmp = Bitmap.createScaledBitmap(output, 60, 60, false);
            //return _bmp;
            return output;
        }

        protected Bitmap doInBackground(String...urls){
            String urlOfImage = urls[0];
            Bitmap logo = null;
            try{
                URLConnection con = new URL( urlOfImage ).openConnection();
                con.connect();
                InputStream is = con.getInputStream();
                logo = BitmapFactory.decodeStream(is);
                is.close();
            }catch(Exception e){
                e.printStackTrace();
            }
            try{
                return getCroppedBitmap(scaleDown(logo, 100, true));
            }catch(Exception e){
                return null;
            }
        }

        protected void onPostExecute(Bitmap result){
            imageView.setImageBitmap(result);
        }
    }
}

滚动屏幕时,ListView / RecyclerView会根据需要创建和销毁视图。 考虑一下触发AsyncTask来获取图像但图像离开屏幕的情况。 现在,适配器可以尝试回收该视图,但是AsyncTask仍然保留对该视图的引用,这可能导致内存泄漏,从而导致此类问题。 可以在文档中找到更多信息

考虑使用像Picasso这样的图像库来轻松加载图像,而不是使用自定义AsyncTask。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM