Android RecyclerView 基础知识详解
作者:lum 时间:2022-10-04 13:40:20
本周的谷歌I/O大会带来了很多关于Android的振奋人心的消息。可能我们需要较长的时间来消化Android L引入的新东西。
这些天我一直在研究RecyclerView,并想在此给各位分享一下到目前为止我的成果。
RecyclerView是什么?
RecyclerView是一种新的视图组,目标是为任何基于适配器的视图提供相似的渲染方式。它被作为ListView和GridView控件的继承者,在最新的support-V7版本中提供支持。
在开发RecyclerView时充分考虑了扩展性,因此用它可以创建想到的任何种类的的布局。但在使用上也稍微有些不便。这就是Android——要完成一件事情总不是那么容易。
如果使用RecyclerView,你需要了解以下三个元素:
RecyclerView.Adapter
LayoutManager
ItemAnimator
RecyclerView.Adapter
RecyclerView包含了一种新型适配器。它与现在使用的适配器类似,但也稍有不同,例如它需要使用ViewHolder。使用时需要重写两个主要方法:一个用来展现视图和它的持有者,而另一个用来把数据绑定到视图上。这么做的好处是,第一种方法只有当我们真正需要创建一个新视图时才被调用,不需要检查它是否已经被回收。
; html-script: false ]
public class MyRecyclerAdapter extends RecyclerView.Adapter<MyRecyclerAdapter.ViewHolder> {
private List<ViewModel> items;
private int itemLayout;
public MyRecyclerAdapter(List<ViewModel> items, int itemLayout) {
this.items = items;
this.itemLayout = itemLayout;
}
@Override public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View v = LayoutInflater.from(parent.getContext()).inflate(itemLayout, parent, false);
return new ViewHolder(v);
}
@Override public void onBindViewHolder(ViewHolder holder, int position) {
ViewModel item = items.get(position);
holder.text.setText(item.getText());
holder.image.setImageBitmap(null);
Picasso.with(holder.image.getContext()).cancelRequest(holder.image);
Picasso.with(holder.image.getContext()).load(item.getImage()).into(holder.image);
holder.itemView.setTag(item);
}
@Override public int getItemCount() {
return items.size();
}
public static class ViewHolder extends RecyclerView.ViewHolder {
public ImageView image;
public TextView text;
public ViewHolder(View itemView) {
super(itemView);
image = (ImageView) itemView.findViewById(R.id.image);
text = (TextView) itemView.findViewById(R.id.text);
}
}
}
这是一个简单的适配器,但是事情逐渐开始变得有点复杂。在RecyclerView中,没有一个onItemClickListener方法(至少我没有发现)。所以适配器是一个处理事件的良好的候选人。
如果想要从适配器上添加或移除条目,需要明确通知适配器。这与先前的notifyDataSetChanged()方法稍微有些不同。
; html-script: false ]
public void add(ViewModel item, int position) {
items.add(position, item);
notifyItemInserted(position);
}
public void remove(ViewModel item) {
int position = items.indexOf(item);
items.remove(position);
notifyItemRemoved(position);
}
LayoutManager
这个类决定视图被放在画面中哪个位置,但这只是它的众多职责之一。它可以管理滚动和循环利用。
LayoutManager只有一个叫做LinearLayoutManager的实现类,它有1500多行代码。但从这一点就可以看出它有多复杂。管理器可以模拟列表视图(包括横向和纵向),但没有页眉和页尾。
为LayoutManager编写子类不太适合新手,我们需要依靠社区来发掘RecyclerView的全部潜力。与这个例子一起,在短时间内我会上传一个GridView控件的实现。
我认为这背后的关键是要仿照LinearLayoutManager的代码创建一个BaseLayoutManager,并且基于此进行扩展。或许support-v7的最终版本会提供更多、更好的实现。
ItemAnimator
ItemAnimator会根据适配器上收到的通知动画显示视图组的修改。基本上,它会自动显示添加和移除条目动画。这也不是一个简单的类,但我们发现DefaultItemAnimator已经可以运行得很好了。
RecyclerView设置
所以最后,如果想要初始化一个运行的RecyclerView,你需要做这样的事情:
; html-script: false ]
RecyclerView recyclerView = (RecyclerView) findViewById(R.id.list);
recyclerView.setHasFixedSize(true);
recyclerView.setAdapter(new MyRecyclerAdapter(createMockList(), R.layout.item));
recyclerView.setLayoutManager(new LinearLayoutManager(this));
recyclerView.setItemAnimator(new DefaultItemAnimator());
setHasFixedSize()方法用来使RecyclerView保持固定的大小,该信息被用于自身的优化。
总结
RecyclerView确实是一个强大的视图,它为开发者提供了无限的扩展能力。学习曲线可能会非常陡峭。但我相信,不久Android社区就会发布LayoutManager超棒的实现。
我在创建一个github仓库,在那里可以找到这个例子。它是我计划创建的一个扩展库的基础。你可以测试GridView的实现。欢迎各种形式的反馈。
![](/images/zang.png)
![](/images/jiucuo.png)
猜你喜欢
Mybatis-plus全局id生成策略详解
Java基础将Bean属性值放入Map中的实例
SpringCloud使用Feign实现远程调用流程详细介绍
![](https://img.aspxhome.com/file/2023/5/79875_0s.png)
Android ListView 实现上拉加载的示例代码
![](https://img.aspxhome.com/file/2023/2/126782_0s.gif)
java 实现迷宫回溯算法示例详解
![](https://img.aspxhome.com/file/2023/2/62982_0s.png)
Android通知栏微技巧一些需要注意的小细节
![](https://img.aspxhome.com/file/2023/4/125524_0s.jpg)
Android之在linux终端执行shell脚本直接打印当前运行app的日志的实现方法
unity实现摄像头跟随
C#实现的文件上传下载工具类完整实例【上传文件自动命名】
通过Java连接SQL Server数据库的超详细操作流程
![](https://img.aspxhome.com/file/2023/8/63098_0s.png)
Java实战个人博客系统的实现流程
![](https://img.aspxhome.com/file/2023/4/103834_0s.png)
关于C# TabPage如何隐藏的问题
详解Java volatile 内存屏障底层原理语义
![](https://img.aspxhome.com/file/2023/5/116225_0s.png)
Android Studio设置或修改Android SDK路径方法
![](https://img.aspxhome.com/file/2023/0/122240_0s.png)
Android中实现下载URL地址的网络资源的实例分享
C++版本基于ros将文件夹中的图像转换为bag包
![](https://img.aspxhome.com/file/2023/0/127230_0s.jpg)
Java double转BigDecimal的注意事项说明
使用Springboot自定义转换器实现参数去空格功能
Java编程思想里的泛型实现一个堆栈类 分享
Android中WebView无法后退和js注入漏洞的解决方案
![](https://img.aspxhome.com/file/2023/9/90149_0s.jpg)