ListView控件 - 图片洗牌,而滚动 [英] ListView - Images shuffle while scrolling

查看:131
本文介绍了ListView控件 - 图片洗牌,而滚动的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有两个TextViews和一个ImageView的一个ListView。这些图像都是从网上下载并LruCache被缓存。滚动时通过在ListView图像被得到混洗为几秒钟。疗法只是不应该有任何图像,直到右图像满载。我发现了一些问题,同样的问题,但没有人帮助我:/。这是我的code:

 公共类NewsAdapter扩展了BaseAdapter {
    私有静态LayoutInflater充气;
    私人列表<项目>项目=新的LinkedList<项目>();
    私人LruCache<字符串,位图> mMemoryCache;

    公共NewsAdapter(上下文的背景下){
        充气=(LayoutInflater)context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);

        //位图缓存
        最终诠释maxMemory =(INT)(调用Runtime.getRuntime()maxMemory()/ 1024);
        最终诠释CACHESIZE = maxMemory / 8;
        mMemoryCache =新LruCache<字符串,位图>(CACHESIZE){
            @覆盖
            保护INT整型尺寸(字符串键,位图位图){
                返回getSizeInBytes(位)/ 1024;
            }
        };
    }

    公共无效添加(逐项){
        items.add(项目);
    }

    @覆盖
    公共查看getView(INT位置,查看convertView,ViewGroup中父){
        ViewHolder viewHolder =新ViewHolder();
        如果(convertView == NULL){
            convertView = inflater.inflate(R.layout.list_item_item,NULL);
            viewHolder.ivPic =(ImageView的)convertView.findViewById(R.id.ivPic);
            viewHolder.tvTitle =(TextView中)convertView.findViewById(R.id.tvTitle);
            viewHolder.tvShortDesc =(TextView中)convertView.findViewById(R.id.tvShortDesc);
            convertView.setTag(viewHolder);
        } 其他 {
            viewHolder =(ViewHolder)convertView.getTag();
        }

        最后一个项目的项目= items.get(位置);
        viewHolder.tvTitle.setText(item.getTitle());
        viewHolder.tvShortDesc.setText(Html.fromHtml(item.getShortDesc()));

        点阵位图= mMemoryCache.get(item.getPicUrl());
        如果(位图!= NULL){
            viewHolder.ivPic.setImageBitmap(位);
        } 其他 {
            GetBitmap GB =新GetBitmap(item.getPicUrl(),viewHolder.ivPic);
            gb.execute();
        }

        返回convertView;
    }

    静态类ViewHolder {
        ImageView的ivPic;
        TextView的tvTitle;
        TextView的tvShortDesc;
    }

    @覆盖
    公众诠释getCount将(){
        返回items.size();
    }

    @覆盖
    公共项目的getItem(INT位置){
        返回items.get(位置);
    }

    @覆盖
    众长getItemId(INT位置){
        返回0;
    }

    @燮pressLint(NewApi)
    公共静态INT getSizeInBytes(位图位图){
        如果(Build.VERSION.SDK_INT> = Build.VERSION_ codeS.HONEYCOMB){
            返回bitmap.getByteCount();
        } 其他 {
            返回bitmap.getRowBytes()* bitmap.getHeight();
        }
    }

    私有类GetBitmap扩展的AsyncTask<太虚,位图,位图> {
        私人字符串URL;
        私人ImageView的ivPic;

        公共GetBitmap(字符串URL,ImageView的ivPic){
            this.url =网址;
            this.ivPic = ivPic;
        }

        @覆盖
        受保护的位图doInBackground(空... PARAMS){
            点阵位图= NULL;
            尝试 {
                网址URL =新的URL(this.url);
                位= BitmapFactory.de codeStream(url.openConnection()的getInputStream());
            }赶上(例外五){
                e.printStackTrace();
            }

            返回的位图;
        }

        @覆盖
        保护无效onPostExecute(位图位图){
            super.onPostExecute(位);
            如果(位图!= NULL)ivPic.setImageBitmap(位);
        }

    }

}
 

这将是很好,如果任何人有一个想法......在此先感谢!

PS:我忘了什么事,请不要提出任何库,我想这样做没有任何外部库

解决方案

 公共GetBitmap(字符串URL,ImageView的ivPic,INT位置){
    this.url =网址;
    this.ivPic = ivPic;
    this.position =位置;
    ivPic.setTag(位置);
    ivPic.setImageBitmap(空);
}

@覆盖
保护无效onPostExecute(位图位图){
     super.onPostExecute(位);
     如果(位图=空&安培;!及((整数)getTag)== this.position)
         ivPic.setImageBitmap(位);
}
 

问题是你不检查,如果该图像是在相同的位置或没有。尝试上述code希望这将有助于。

I have a ListView with two TextViews and one ImageView. The images are loaded from the Internet and are cached by LruCache. While scrolling through the ListView the images are getting shuffled for a few seconds. Ther just shouldn't be any image until the right image is fully loaded. I found a few questions with the same problem but no one helped me :/. Here's my code:

public class NewsAdapter extends BaseAdapter {
    private static LayoutInflater inflater;
    private List<Item> items = new LinkedList<Item>();
    private LruCache<String, Bitmap> mMemoryCache;

    public NewsAdapter(Context context) {
        inflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);

        // Bitmap Cache
        final int maxMemory = (int) (Runtime.getRuntime().maxMemory() / 1024);
        final int cacheSize = maxMemory / 8;
        mMemoryCache = new LruCache<String, Bitmap>(cacheSize) {
            @Override
            protected int sizeOf(String key, Bitmap bitmap) {
                return getSizeInBytes(bitmap) / 1024;
            }
        };
    }

    public void add(Item item) {
        items.add(item);
    }

    @Override
    public View getView(int position, View convertView, ViewGroup parent) {
        ViewHolder viewHolder = new ViewHolder();
        if(convertView == null) {
            convertView = inflater.inflate(R.layout.list_item_item, null);
            viewHolder.ivPic = (ImageView) convertView.findViewById(R.id.ivPic);
            viewHolder.tvTitle = (TextView) convertView.findViewById(R.id.tvTitle);
            viewHolder.tvShortDesc = (TextView) convertView.findViewById(R.id.tvShortDesc);
            convertView.setTag(viewHolder);
        } else {
            viewHolder = (ViewHolder) convertView.getTag();
        }

        final Item item = items.get(position);
        viewHolder.tvTitle.setText(item.getTitle());
        viewHolder.tvShortDesc.setText(Html.fromHtml(item.getShortDesc()));

        Bitmap bitmap = mMemoryCache.get(item.getPicUrl());
        if (bitmap != null) {
            viewHolder.ivPic.setImageBitmap(bitmap);
        } else {
            GetBitmap gb = new GetBitmap(item.getPicUrl(), viewHolder.ivPic);
            gb.execute();
        }

        return convertView;
    }

    static class ViewHolder {
        ImageView ivPic;
        TextView tvTitle;
        TextView tvShortDesc;
    }

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

    @Override
    public Item getItem(int position) {
        return items.get(position);
    }

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

    @SuppressLint("NewApi")
    public static int getSizeInBytes(Bitmap bitmap) {
        if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB) {
            return bitmap.getByteCount();
        } else {
            return bitmap.getRowBytes() * bitmap.getHeight();
        }
    }

    private class GetBitmap extends AsyncTask<Void, Bitmap, Bitmap> {
        private String url;
        private ImageView ivPic;

        public GetBitmap(String url, ImageView ivPic) {
            this.url = url;
            this.ivPic = ivPic;
        }

        @Override
        protected Bitmap doInBackground(Void... params) {
            Bitmap bitmap = null;
            try {
                URL url = new URL(this.url);
                bitmap = BitmapFactory.decodeStream(url.openConnection().getInputStream());
            } catch (Exception e) {
                e.printStackTrace();
            }

            return bitmap;
        }

        @Override
        protected void onPostExecute(Bitmap bitmap) {
            super.onPostExecute(bitmap);
            if (bitmap != null) ivPic.setImageBitmap(bitmap); 
        }

    }

}

It would be nice if anyone has an idea... Thanks in advance!

P.S.: I forgot something, please do not suggest any libraries, I want to do it without any external library.

解决方案

public GetBitmap(String url, ImageView ivPic, int position) {
    this.url = url;
    this.ivPic = ivPic;
    this.position = position;
    ivPic.setTag(position);
    ivPic.setImageBitmap(null);
}

@Override
protected void onPostExecute(Bitmap bitmap) {
     super.onPostExecute(bitmap);
     if(bitmap != null && ((Integer)getTag) == this.position)
         ivPic.setImageBitmap(bitmap); 
}

Issue is you are not checking if the image is in the same position or not. Try the above code hope it will help.

这篇关于ListView控件 - 图片洗牌,而滚动的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆