volley+NetworkImageView实现列表界面的列表项中的左侧图标展现之【实现已经加载的列表项的图标上翻的时候不重新加载】

参考资料:http://blog.csdn.net/guolin_blog/article/details/17482165

我使用的列表的适配器是继承ArrayAdapter的,所以关于使用volley+NetworkImageView获取图标资源,是在getView中执行的。

/**列表的适配器:继承ArrayAdapter*/
public class NewsListArrayAdapter extends ArrayAdapter<CnBlogsNews>{
    
    private static final String TAG = "NewsListArrayAdapter";
    
    private int listItemResourceId;
    
    private Context thisContext;
    
    private LruCache<String, Bitmap> mMemoryCache;//必须设置为全局变量,而不是写在BitmapCache类中,同样,实例化也必须写在构造函数中
    
    public NewsListArrayAdapter(Context context, int resource,
            List<CnBlogsNews> objects) {
        super(context, resource, objects);
        
        listItemResourceId = resource;
        
        thisContext = context;
        
        initLruCache();//改进后的BitmapCache构造函数
    }
    
    /*改进后的BitmapCache构造函数*/
    private void initLruCache(){
        
        // 获取到可用内存的最大值,使用内存超出这个值会引起OutOfMemory异常
        int maxMemory = (int) (Runtime.getRuntime().maxMemory() / 1024);//以字节为单位,除以1024就是KB为单位
        Log.v(TAG, "maxMemory="+maxMemory+"KB");//196608KB == 192M
        
        int maxSize = 1 * 1024 * 1024;
        
        // LruCache通过构造函数传入缓存值,以KB为单位
        
        mMemoryCache = new LruCache<String, Bitmap>(maxSize) {
            @Override
            protected int sizeOf(String key, Bitmap bitmap) {
                // 重写此方法来衡量每张图片的大小,默认返回图片数量。
                Log.v(TAG, "bitmap.getRowBytes() * bitmap.getHeight()="+bitmap.getRowBytes() * bitmap.getHeight());
                return bitmap.getRowBytes() * bitmap.getHeight();
            }
        };
    }
    
    
    @Override
    public View getView(int position, View convertView, ViewGroup parent) {
        
        final CnBlogsNews cnblogsNews = getItem(position);
        
        View view = null;
        ViewHolder holder;
        
        if(convertView == null){
            
            view = LayoutInflater.from(thisContext).inflate(listItemResourceId, parent, false);
            
            holder = new ViewHolder();
            holder.newslist_topicIcon = (NetworkImageView) view.findViewById(R.id.newslist_topicIcon);
            holder.newslist_title = (TextView) view.findViewById(R.id.newslist_title);
            holder.newslist_Published = (TextView) view.findViewById(R.id.newslist_Published);
            
            view.setTag(holder);
            
        }else{
            view = convertView;
            holder = (ViewHolder) view.getTag();
        }
        
        //加载图标资源
        loadImageViewWithUrl(holder.newslist_topicIcon,cnblogsNews.getNewsTopicIconUrl());
        
        holder.newslist_title.setText(cnblogsNews.getNewsTitle());
        holder.newslist_Published.setText(cnblogsNews.getNewsPublished()+":序号="+position);
        
        //添加链接地址,通过webView方式打开
        view.setOnClickListener(new OnClickListener() {
            
            @Override
            public void onClick(View v) {
                WebViewActivity.openWebViewActivity(thisContext, cnblogsNews.getNewsLink());
                
            }
        });
        
        return view;
    }
    
    
    class ViewHolder{
        NetworkImageView newslist_topicIcon;//新闻主题图片
        TextView newslist_title;//新闻标题
        TextView newslist_Published;//新闻发布时间
    }
    
    
    //根据URL地址加载图片
    
    /*
     * 1. 创建一个RequestQueue对象。
     * 2. 创建一个ImageLoader对象。
     * 3. 获取一个ImageListener对象。
     * 4. 调用ImageLoader的get()方法加载网络上的图片。
     * */
    private void loadImageViewWithUrl(NetworkImageView imgView , String urlStr){
        
        RequestQueue requestQueue = Volley.newRequestQueue(thisContext);
        //实现缓存功能
        ImageLoader imgLoader = new ImageLoader(requestQueue,new BitmapCache());
        
        //ImageListener imgListener = ImageLoader.getImageListener(imgView, R.drawable.ic_empty, R.drawable.ic_error);
        //imgLoader.get(urlStr, imgListener);
        
        imgView.setDefaultImageResId(R.drawable.ic_empty);
        imgView.setErrorImageResId(R.drawable.ic_error);
        
        imgView.setImageUrl(urlStr, imgLoader);
        
    }
    
    //将缓存图片的大小设置为10M==改进后的
    private class BitmapCache implements ImageCache {

        @Override
        public Bitmap getBitmap(String url) {
            Log.v(TAG, "getBitmap==url=="+url);
            return mMemoryCache.get(url);
        }

        @Override
        public void putBitmap(String url, Bitmap bitmap) {
            Log.v(TAG, "putBitmap==url=="+url);
            
            if (mMemoryCache.get(url) == null) {
                mMemoryCache.put(url, bitmap);
            }
            
        }

    }

}
NewsListArrayAdapter

关键在于:不在BitmapCache类中实例化LruCache类,而是将LruCache类赋值为全局变量,这样就保证了整个列表的所有项的图标使用的是同一个LruCache。

如果在BitmapCache类中实例化LruCache的话(代码如下),下翻页后再重新回到上一页的时候,会发现图标重新在加载。

public class BitmapCache implements ImageCache {

    private LruCache<String, Bitmap> mCache;

    public BitmapCache() {
        int maxSize = 10 * 1024 * 1024;
        mCache = new LruCache<String, Bitmap>(maxSize) {
            @Override
            protected int sizeOf(String key, Bitmap bitmap) {
                return bitmap.getRowBytes() * bitmap.getHeight();
            }
        };
    }

    @Override
    public Bitmap getBitmap(String url) {
        return mCache.get(url);
    }

    @Override
    public void putBitmap(String url, Bitmap bitmap) {
        mCache.put(url, bitmap);
    }

}
BitmapCache
原文地址:https://www.cnblogs.com/whycxb/p/4826534.html