Android ListView与RecyclerView
来源:互联网 发布:部落冲突防御设施数据 编辑:程序博客网 时间:2024/05/18 18:17
Android中,最复杂的原生控件就是ListView,在support-v7中,Google提供了一种功能更加丰富的控件来代替ListView,那就是RecyclerView,本篇文章,就来解析一下ListView与RecyclerView。
使用ListView控件需要为设置一个Adapter:
public class listadapter extends BaseAdapter { private Context context; private List<listitem> list; class ViewHolder { ImageView imageView; TextView textView; } public listadapter(Context context, List<listitem> list) { this.context = context; this.list = list; } public listitem getItem(int position) { return list.get(position); } public long getItemId(int postion) { return postion; } public int getCount() { return list.size(); } public View getView(int position, View convertview, ViewGroup parent) { listitem listitem = getItem(position); View view; ViewHolder viewHolder; if(convertview == null) { int id = getItemViewType(position); viewHolder = new ViewHolder(); if(id == 0) { view = LayoutInflater.from(context).inflate(R.layout.listitem_layout0, parent, false); viewHolder.imageView = (ImageView) view.findViewById(R.id.image0); viewHolder.textView = (TextView) view.findViewById(R.id.name0); view.setTag(viewHolder); } else { view = LayoutInflater.from(context).inflate(R.layout.listitem_layout1, parent, false); viewHolder.imageView = (ImageView) view.findViewById(R.id.image1); viewHolder.textView = (TextView) view.findViewById(R.id.name1); view.setTag(viewHolder); } } else { view = convertview; viewHolder = (ViewHolder) view.getTag(); } viewHolder.imageView.setImageResource(listitem.getImageId()); viewHolder.textView.setText(listitem.getName()); return view; } @Override public int getItemViewType(int position) { if(position < 6) return 0; else return 1; } @Override public int getViewTypeCount() { return 2; }}
上面的代码中,Adapter继承自BaseAdapter, 复写了六种方法。其中
public listitem getItem(int position) { return list.get(position);}public long getItemId(int postion) { return postion;}public int getCount() { return list.size();}public View getView(int position, View convertview, ViewGroup parent) {
}
四种方法最为基本(注意getItemId方法的返回值类型为long),getView在每次获取View时都会被调用,里面复写的逻辑尽可能简单。
此外,使用convertview与ViewHolder来对ListView进行优化。
@Overridepublic int getItemViewType(int position) { if(position < 6) return 0; else return 1;}@Overridepublic int getViewTypeCount() { return 2;}复写以上两种方法,可以实现ListView的多种布局。getViewTypeCount方法返回布局类型的数目,getItemViewType方法返回布局类型的序号,范围为0~n-1(n为布局类型的数目)。
ListView还可以直接与Android自带的轻量级数据库sqlite相关联。
相比于ListView,RecyclerView除了需要设置Adapter,还需要设置LayoutManager。
class RecyclerViewAdapter extends RecyclerView.Adapter<RecyclerViewAdapter.MyViewHolder>{ private Set<BitmapWorkerTask> taskCollection; //private List<square> squareList = new ArrayList<>(); private LruCache<String, Bitmap> bitmapLruCache; private RecyclerView recyclerView; private StaggeredGridLayoutManager layoutManager; private int firstVisibleItem, lastVisibleItem; private boolean isFirstEnter = true; @Override public MyViewHolder onCreateViewHolder(ViewGroup parent, int viewType) { MyViewHolder holder = new MyViewHolder(LayoutInflater.from( parent.getContext()).inflate(R.layout.squareitem, parent, false)); return holder; } @Override public void onBindViewHolder(MyViewHolder holder, int position) { final String url = image.imageThumbUrls[position]; ImageView bg = holder.bg; bg.setTag(url); Bitmap bitmap = getBitmapFromMemoryCache(url); if (bitmap != null) { bg.setImageBitmap(bitmap); } else { bg.setImageResource(R.color.black_overlay); } } @Override public int getItemCount() { return image.imageThumbUrls.length; } class MyViewHolder extends RecyclerView.ViewHolder { ImageView bg; public MyViewHolder(View view) { super(view); bg = (ImageView) view.findViewById(R.id.bgimage); } } public RecyclerViewAdapter(RecyclerView recyclerView) { //this.squareList = squareList; this.recyclerView = recyclerView; layoutManager = (StaggeredGridLayoutManager)recyclerView.getLayoutManager(); taskCollection = new HashSet<>(); int maxMemory = (int) Runtime.getRuntime().maxMemory(); int cacheSize = maxMemory / 8; bitmapLruCache = new LruCache<String, Bitmap>(cacheSize) { @Override protected int sizeOf(String key, Bitmap bitmap) { return bitmap.getByteCount(); } }; System.out.println("CacheSize : " + cacheSize); recyclerView.addOnScrollListener(new RecyclerView.OnScrollListener() { @Override public void onScrollStateChanged(RecyclerView recyclerView, int newState) { super.onScrollStateChanged(recyclerView, newState); if (newState == SCROLL_STATE_IDLE) { loadBitmaps(firstVisibleItem, lastVisibleItem); } else { cancelAllTasks(); } } @Override public void onScrolled(RecyclerView recyclerView, int dx, int dy) { super.onScrolled(recyclerView, dx, dy); firstVisibleItem = layoutManager.findFirstVisibleItemPositions(null)[0]; lastVisibleItem = layoutManager.findLastVisibleItemPositions(null)[1]; System.out.println("firstvisibleitem : " + firstVisibleItem); System.out.println("lastvisibleitem : " + lastVisibleItem); if (isFirstEnter && lastVisibleItem - firstVisibleItem > 0) { loadBitmaps(firstVisibleItem, lastVisibleItem); isFirstEnter = false; } } }); } private void loadBitmaps(int firstVisibleItem, int lastVisibleItem) { try { for (int i = firstVisibleItem; i <= lastVisibleItem; i ++) { String imageUrl = image.imageThumbUrls[i]; Bitmap bitmap = getBitmapFromMemoryCache(imageUrl); if (bitmap == null) { BitmapWorkerTask task = new BitmapWorkerTask(); taskCollection.add(task); task.execute(imageUrl); System.out.println("task is executing"); } else { ImageView imageView = (ImageView) recyclerView.findViewWithTag(imageUrl); if (imageView != null && bitmap != null) { imageView.setImageBitmap(bitmap); } } } } catch (Exception e) { e.printStackTrace(); System.out.println("task failed"); } } public void addBitmapToMemoryCache(String key, Bitmap bitmap) { if (getBitmapFromMemoryCache(key) == null) { bitmapLruCache.put(key, bitmap); } } public Bitmap getBitmapFromMemoryCache(String key) { return bitmapLruCache.get(key); } public void cancelAllTasks() { if (taskCollection != null) { for (BitmapWorkerTask task : taskCollection) { task.cancel(false); } } } class BitmapWorkerTask extends AsyncTask<String, Void, Bitmap> { private String imageUrl; @Override protected Bitmap doInBackground(String... params) { imageUrl = params[0]; Bitmap bitmap = downloadBitmap(params[0]); if (bitmap != null) { addBitmapToMemoryCache(params[0], bitmap); } return bitmap; } @Override protected void onPostExecute(Bitmap bitmap) { super.onPostExecute(bitmap); ImageView imageView = (ImageView) recyclerView.findViewWithTag(imageUrl); if(imageView != null && bitmap != null) { imageView.setImageBitmap(bitmap); } taskCollection.remove(this); } private Bitmap downloadBitmap(String imageUrl) { Bitmap bitmap = null; HttpURLConnection con = null; try { URL url = new URL(imageUrl); con = (HttpURLConnection) url.openConnection(); con.setConnectTimeout(5000); con.setReadTimeout(10000); bitmap = BitmapFactory.decodeStream(con.getInputStream()); } catch (Exception e) { e.printStackTrace();; } finally { if (con != null) { con.disconnect(); } } return bitmap; } }}上面的代码中使用了LRUCache对图片进行缓存,同时对RecyclerView进行了滑动监听,仅在静止时加载图片。
RecyclerView使用的Adapter继承了RecyclerView.Adapter<T>,泛型T为RecyclerView.ViewHolder类型,需要在Adapter中自己设置,继承RecyclerView.ViewHolder,重写构造函数。其他需要重写的三个函数:
@Overridepublic MyViewHolder onCreateViewHolder(ViewGroup parent, int viewType)@Overridepublic void onBindViewHolder(MyViewHolder holder, int position)@Overridepublic int getItemCount()onCreateViewHolder方法返回ViewHolder。在onBindViewHolder方法中设置Item的View,相当于ListView中的getView方法,不过onBinderViewHolder无需返回View。getItemCount方法返回Item的数量,相当于ListView中的getCount方法。LayoutManager表示RecyclerView的布局格式。不同于ListView的线性的颇显单调的布局,RecyclerView提供了LinearLayourManager(线性布局),GridLayoutManager(方格布局)和StaggeredGridLayoutManager(瀑布流布局)三种布局格式。一次性解决了ListView和GridView,还提供了瀑布流的布局格式。此外,还可以同过setItemAnimator
和addItemDecoration
方法来设置RecyclerView的增删Item的动画以及分割线的格式。这两个属性,我们下回再说。
0 0
- Android ListView与RecyclerView
- Android RecyclerView之代替ListView与GridView
- Android RecyclerView与ListView局部刷新
- Android(4)—ListView与RecyclerView
- Android Filter ListView, RecyclerView
- android databinding RecyclerView / ListView
- Android学习笔记(三)--ListView与RecyclerView
- Android ListView 与 RecyclerView 对比浅析--缓存机制
- Android ListView 与 RecyclerView 对比浅析--缓存机制
- Android开发之RecyclerView与ListView对比详解
- Android ListView 与 RecyclerView 对比浅析--缓存机制
- Android ListView与RecyclerView对比浅析--缓存机制
- Android ListView与RecyclerView对比浅析--缓存机制
- Android ListView 与 RecyclerView 对比浅析--缓存机制
- Android控件RecyclerView及与ListView的异同
- Android ListView与RecyclerView对比浅析--缓存机制
- RecyclerView与ListView的异同
- ListView与RecyclerView的区别
- 动态规划练习一—9移动路线
- OpenCV安装,入门(基于Python)
- 美团秋招补招(2016-12-14更新)
- Python入门学习1.2
- Unity资源打包策略及建议
- Android ListView与RecyclerView
- Mybatis与Spring整合
- JAVA——构建字符串StringBuilder(二)
- Iterator
- sap 物料MIGO入库时[有关业务/事件类型WA在年2017的号码范围不存在]的解决方法
- 时间日期格式转换
- 【51NOD 1048】【51NOD 1383】整数分解为2的幂 V2
- 踩坑之为数组原型扩展方法
- numpy常用函数及实例