Android UI控件之ListView&RecyclerView
来源:互联网 发布:高中地理优化设计 编辑:程序博客网 时间:2024/06/05 02:53
Android UI控件之ListView&RecyclerView
前言
ListView&RecyclerView 这次我们来说说这两个控件的区别,我们知道ListView在有限的屏幕上显示更多的内容,若不使用优化的方案会导致性能很差,现在出现了RecyclerView滚动控件,同样可以实现listView的功能还可以解决listView存在的问题。
两者虽然功能很强大但是创建起来比起普通的控件多少有些麻烦,而创建之中要属适配器的定制是最麻烦的。适配器:是一个连接数据和AdapterView(ListView就是一个典型的AdapterView)的桥梁,通过它能有效实现数据与AdapterView的分离设置,使AdapterView和数据的绑定简便,修改更加方便。搞定适配器基本就了解这两个控件是怎么玩的了。
ListView
我们先来看ListView的创建过程,ListView的子项中显示什么需要定义一个实体类,作为ListView适配器的适配类型,
如:
public class Fruit { private String name; private int imageId; public Fruit(String name, int imageId) { this.name = name; this.imageId = imageId; } // Getter() …… }
再创建ListView子项的自定义布局文件。在展示ListView的布局中使用的标签
public class FruitAdapter extends ArrayAdapter<Fruit> { private int resourceId; //这个构造函数传入的参数分别是:上下文、ListView子项布局的id、数据 public FruitAdapter(Context context, int textViewResourceId,List<Fruit> objects) { super(context, textViewResourceId, objects); resourceId = textViewResourceId; } @Override public View getView(int position, View convertView, ViewGroup parent) { Fruit fruit = getItem(position); // 获取当前项的Fruit实例 View view = LayoutInflater.from(getContext()).inflate(resourceId, parent, false); ImageView fruitImage = (ImageView) view.findViewById (R.id.fruit_image); TextView fruitName = (TextView) view.findViewById (R.id.fruit_name); fruitImage.setImageResource(fruit.getImageId()); fruitName.setText(fruit.getName()); return view; } }
下面将数据借助适配器加载到ListView控件中显示
FruitAdapter adapter = new FruitAdapter(MainActivity.this, R.layout.fruit_item, fruitList);ListView listView = (ListView) findViewById(R.id.list_view);listView.setAdapter(adapter);
可是这样的适配器是比较难用的,每次快速滚动ListView的时候,getView()中每次都要将布局重新加载一遍,影响性能。每次都要重新加载布局,想想都觉得会拖慢速度,怎么办?所以把getView()中的代码进行一次小的修改。如下:
@Overridepublic View getView(int position, View convertView, ViewGroup parent) { Fruit fruit = getItem(position); // 获取当前项的Fruit实例 View view; if (convertView == null) { view = LayoutInflater.from(getContext()).inflate(resourceId, parent, false); } else { view = convertView; } ImageView fruitImage = (ImageView) view.findViewById (R.id.fruit_image); TextView fruitName = (TextView) view.findViewById (R.id.fruit_name); fruitImage.setImageResource(fruit.getImageId()); fruitName.setText(fruit.getName()); return view; }
没错就是加了一个条件判断的语句,判断convertView是否为null,为null就用LayoutInflater重新加载布局,否则直接重用。这样是解决了布局的重复加载的问题,可是控件还是要重新调用,所以还要进一步优化,这时候就要用到ViewHolder。代码如下:
@Overridepublic View getView(int position, View convertView, ViewGroup parent) { Fruit fruit = getItem(position); // 获取当前项的Fruit实例 View view; ViewHolder viewHolder; if (convertView == null) { view = LayoutInflater.from(getContext()).inflate(resourceId, parent, false); viewHolder = new ViewHolder(); viewHolder.fruitImage = (ImageView) view.findViewById (R.id.fruit_image); viewHolder.fruitName = (TextView) view.findViewById (R.id.fruit_name); view.setTag(viewHolder); // 将ViewHolder存储在View中 } else { view = convertView; viewHolder = (ViewHolder) view.getTag(); // 重新获取ViewHolder } viewHolder.fruitImage.setImageResource(fruit.getImageId()); viewHolder.fruitName.setText(fruit.getName()); return view; } class ViewHolder { ImageView fruitImage; TextView fruitName; }
上一次的优化是加入了convertView且进行判断,是对子项布局缓存并重用,这个是在自定义适配器类中定义了ViewHolder类并声明了子项中得控件。在填充了子项布局后实例化控件,view.setTag(viewHolder)将ViewHolder缓存在View中。 view.getTag()将ViewHolder重新取出,经过这两次优化会很好的提高性能,其中我们也叫能看清ListView实现的过程。
RecyclerView
接下来我们继续来介绍RecyclerView滚动控件,RecyclerView定义在support库中所以需要在build.gradle中添加依赖库
dependencies{ ..... compile 'com.android.support:recyclerview-v7:24.2.1' }
布局中添加RecyclerView控件
<android.support.v7.widget.RecyclerView android:id="@+id/recycler_view" android:layout_width="match_parent" android:layout_height="match_parent" />
RecyclerView控件很强大,不但能实现listView的功能,在滚动方向上可以横向滑动。
下面来介绍RecyclerView控件适配器类的创建,以便和ListView做个对比,这个仍然要定义一个实体类作为适配器的适配类型。
代码如下:
public class FruitAdapter extends RecyclerView.Adapter<FruitAdapter.ViewHolder>{ private List<Fruit> mFruitList; static class ViewHolder extends RecyclerView.ViewHolder { ImageView fruitImage; TextView fruitName; public ViewHolder(View view) { super(view); fruitImage = (ImageView) view.findViewById(R.id.fruit_image); fruitName = (TextView) view.findViewById(R.id.fruit_name); } } public FruitAdapter(List<Fruit> fruitList) { mFruitList = fruitList; } @Override public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) { View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.fruit_item, parent, false);//recyclerView这里就添加子项布局,而listView在真正适配的时候用到子项布局 ViewHolder holder = new ViewHolder(view); return holder; } @Override public void onBindViewHolder(ViewHolder holder, int position) { Fruit fruit = mFruitList.get(position); holder.fruitImage.setImageResource(fruit.getImageId()); holder.fruitName.setText(fruit.getName()); } @Override public int getItemCount() { return mFruitList.size(); } }
我们看到这个适配器继承了RecyclerView.Adapter,并指定FruitAdapter.ViewHolder泛型类型,这里也写一个内部类ViewHolder,和ListView适配器中很像,但这个除了声明了控件,还获得了控件的实例,这样控件直接封装到这个ViewHolder里。
这个内部类往下,有一个构造函数用来传入数据。剩下的是重写的三个方法:onCreateViewHolder()、onBindViewHolder()和getItemCount()。
- onCreateViewHolder():中用来创建ViewHolder实例和加载子项布局
- onBindViewHolder():通过获得子项的位置position,对RecyclerView每个子项进行赋值添加数据。
- getItemCount():返回子项的长度
看一下如何使用这个适配器:
RecyclerView recyclerView = (RecyclerView) findViewById(R.id.recycler_view); LinearLayoutManager layoutManager = new LinearLayoutManger(this); //对线性布局设置排列的方向,默认是纵向,这个是设置成了横向排列 //layoutManager.setOrientation(LinearLayoutManager.HORIZONTAL); recyclerView.setLayoutManager(layoutManager); FruitAdapter adapter = new FruitAdapter(fruitList); recyclerView.setAdapter(adapter);
这里我们可以看到RecyclerView除了绑定控件获得实例,通过适配器添加数据,还加入了对RecyclerView滚动控件布局形式的排列,不得不说这要比ListView在展现形式要灵活很多。
此外在事件触发的设计上两者也存在着差异,结果还是RecyclerView要好一些。
- Android UI控件之ListView&RecyclerView
- Android UI控件之RecyclerView的简单应用
- 【Android 开发】:UI控件之 ListView 列表控件的使用
- Android UI设计之RecyclerView
- Android UI高级之RecyclerView
- Android UI设计之RecyclerView
- Android UI 之 ListView
- Android之UI学习篇十一:ListView控件学习(一)
- Android之UI学习篇十二:ListView控件学习(二)
- Android UI控件之ListView实现圆角效果
- Android UI控件之ListView实现圆角效果
- Android控件RecyclerView和ListView的异同
- Android控件RecyclerView和ListView的异同
- Android控件RecyclerView和ListView的异同
- Android控件RecyclerView和ListView的异同
- Android控件RecyclerView和ListView的异同
- Android之UI控件
- Android 控件之ListView
- Plugin is too old, please update to a more recent version问题根本解决办法
- 主键生成策略优劣比较以及应用
- Android杂谈(22)GreenDAO的使用
- 【b604】2K进制数
- bzoj【1552/3506】[Cerc2007]robotic sort
- Android UI控件之ListView&RecyclerView
- [树形DP 暴力] BZOJ 3696 化合物
- LeetCode 108. Convert Sorted Array to Binary Search Tree 题解
- 数据结构实验之链表七:单链表中重复元素的删除
- [Unity3D课堂作业] 改进版:Priests and Devils 牧师与恶魔
- Java Hello World
- 面试笔记。
- win10_64安装Cplex12.5
- 多线程_继承Thread类的方式卖电影票案例