Android ListView异步加载网络图片出现位置错乱闪烁及优化ListView的加载

每次联网会从服务器端返回50条数据,每条数据包含一张jpg图片,一个String字符串,一个double类型数据。使用之前优化的listview加载图片会闪烁、错乱。后来查找资料发现需要给图片设置tag,然后加载的时候进行对比,tag相等再加载显示。同时需要给图片设置缓存,从网络加载的图片存入缓存中,第二次使用时就不再从网络端获取,而是从缓存中读取。代码如下:

解析从服务器端获取的50条数据:

JSONArray peopleArray;
    List<String> scoreList = new ArrayList<>();
    List<String> chineseNameList = new ArrayList<>();
    List<String> englishNameList = new ArrayList<>();
    List<String> peopleFaceList = new ArrayList<>();
    private void parseCelebrityJsonResult(String response) {
        JSONObject jsonObject = JSON.parseObject(response);
        peopleArray = jsonObject.getJSONArray("people");
        Log.e("peopleArray",peopleArray.toJSONString());
        Double score;
        String peopleId;
        String chineseName;
        String englishName;
        JSONObject peopleJsonObj;
        String peopleImgUrl;
        String scoreStr;
        if(peopleArray != null && peopleArray.size() > 0) {
            for (int i = 0;i < peopleArray.size();i++){
                peopleJsonObj = peopleArray.getJSONObject(i);

                score = peopleJsonObj.getDouble("score");
                scoreStr = doubleToPercent(score);
                Log.e("相似度:",scoreStr);
                scoreList.add(scoreStr);

                chineseName = peopleJsonObj.getString("chinese_name");
                Log.e("相似名字:",chineseName + i);
                chineseNameList.add(chineseName);

                englishName = peopleJsonObj.getString("english_name");
                englishNameList.add(englishName);

                peopleId = peopleJsonObj.getString("id");
                peopleImgUrl = "http://facde.cn/static/img/celebrity/"+peopleId+".jpg";
                Log.e("相似图片:",peopleImgUrl);
                peopleFaceList.add(peopleImgUrl);
            }
        }

        initAdapter();
    }

private void initAdapter() {
        if(celebAdapter == null) {
            celebAdapter = new CelebrityAdapter(CelebrityDetectActivity.this);
        }
        celebAdapter.notifyDataSetChanged();
        lvResult.setAdapter(celebAdapter);
    }
public class CelebrityAdapter extends BaseAdapter{
        Context mContext;
        LayoutInflater mInflater;
        ViewHolder viewHolder;
        String name;
        LruCache<String,Bitmap> lruCache;

        public CelebrityAdapter(Context context){
            mContext = context;
            mInflater = (LayoutInflater) mContext.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
            //获取应用程序最大可用内存
            int maxMemory = (int) Runtime.getRuntime().maxMemory();
            //初始化LruCache并为其分配最大的缓存值
            lruCache = new LruCache<String, Bitmap>(maxMemory/4){
                @Override
                protected int sizeOf(String key, Bitmap value) {
                    //返回存进缓存的bitmap的大小
                    return value.getByteCount();
                }
            };
        }

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

        @Override
        public Object getItem(int position) {
            return null;
        }

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

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

            if(convertView == null) {
                viewHolder = new ViewHolder();
                convertView = mInflater.inflate(R.layout.item_listview_celebrity_detect,null);
                viewHolder.ivCelebrityFace = (ImageView) convertView.findViewById(R.id.iv_celebrity_face);

                viewHolder.tvCelebrityName = (TextView) convertView.findViewById(R.id.tv_celebrity_name);
                viewHolder.tvCelebrityScore = (TextView) convertView.findViewById(R.id.tv_celebrity_score);
                convertView.setTag(viewHolder);
            } else {
                viewHolder = (ViewHolder) convertView.getTag();
            }

            progressDialog.dismiss();

            viewHolder.ivCelebrityFace.setTag(peopleFaceList.get(position));
            if(chineseNameList.get(position).equals("") || chineseNameList.get(position) == null) {
                name = englishNameList.get(position);
            } else {
                name = chineseNameList.get(position);
            }

            viewHolder.tvCelebrityName.setText("相似人:" + name);
            viewHolder.tvCelebrityScore.setText("相似度:" + scoreList.get(position));
            new ImageLoaderByLrucache(position,peopleFaceList,peopleFaceList.get(position),viewHolder.ivCelebrityFace,lruCache).imageloadAsyncTask();

            return convertView;
        }

    }
    public class ViewHolder{
        ImageView ivCelebrityFace;
        TextView tvCelebrityName,tvCelebrityScore;
    }
/**
 * 从缓存中加载图片
 * Created by D.bj on 2017/9/6.
 */

public class ImageLoaderByLrucache{
    int position;
    ImageView imageView;
    LruCache<String,Bitmap> lruCache;
    String url;
    List<String> urlList;

    public ImageLoaderByLrucache(){}

    public ImageLoaderByLrucache(int position,List<String> urlList,String url,ImageView imageView,LruCache<String,Bitmap> lruCache){
        this.position = position;
        this.urlList = urlList;
        this.url = url;
        this.imageView = imageView;
        this.lruCache = lruCache;
    }

    //通过URL从缓存中获取对应的bitmap
    private Bitmap getBitmapFromLruCache(String url){
        return lruCache.get(url);
    }

    //将bitmap设置进缓存中
    private void setBitmapIntoLruCache(String url,Bitmap bitmap){
        Bitmap bitmap1 = getBitmapFromLruCache(url);
        if(bitmap1 == null) {
            lruCache.put(url,bitmap);
        }
    }

    public void imageloadAsyncTask(){
        //加载图片之前先判断缓存中是否有该图片,如果有直接使用缓存中的,如果没有通过网络加载
        Bitmap bitmap = getBitmapFromLruCache(url);
        if(bitmap != null) {
            if(imageView.getTag().equals(url)) {
                imageView.setImageBitmap(bitmap);
            }
        } else {
            new LoadBitmapFromUrl(position,imageView).execute(urlList.get(position));
        }
    }

    public class LoadBitmapFromUrl extends AsyncTask<String,Void,Bitmap> {
        int position;
        ImageView imageView;

        public LoadBitmapFromUrl(){}

        public LoadBitmapFromUrl(int position,ImageView imageView){
            this.position = position;
            this.imageView = imageView;
        }

        @Override
        protected Bitmap doInBackground(String... params) {
            Log.e("params-0:",params[0]);
            return loadImageFromNetwork(params[0]);
        }

        @Override
        protected void onPostExecute(Bitmap bitmap) {
            super.onPostExecute(bitmap);
            if(imageView.getTag().equals(urlList.get(position))) {
                imageView.setImageBitmap(bitmap);
            } else {
                imageView.setImageBitmap(null);
            }
        }
    }

    private Bitmap loadImageFromNetwork(String url) {
        Bitmap bitmap = simpleNetworkImage(url);
        if(bitmap == null) {
            Log.i("","");
        }
        return bitmap;
    }

    private Bitmap simpleNetworkImage(String url) {
        Bitmap imgBitmap = null;
        try {
            URL picUrl = new URL(url);
            imgBitmap = BitmapFactory.decodeStream(picUrl.openStream());
            //判断缓存中是否存在该数据
            if(getBitmapFromLruCache(url) == null) {
                //将通过网络加载的图片放入缓存中
                setBitmapIntoLruCache(url,imgBitmap);
            }
        } catch (MalformedURLException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
        return imgBitmap;
    }
}












评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值