转自:JonesYang
ListView 是什么?(上古神器)不,是不是该问 RecyclerView 是什么?(也是上古神器?在它的替代品出来之前最好别这样称呼)趁着这段时间,我想我也应该把这些乱七八糟的东西整理一下。
OK,不演了,ListView 和 RecyclerView 都是用来展示列表数据了。相比与 ListView ,RecyclerView 更加强大,下面先说 ListView。
关于 ListView 先简单看一下它的适配器代码:
public class ListViewAdapter extends BaseAdapter {//用于加载 itemprivate LayoutInflater mInflater;//通过构造函数 把 Context 传递进来public ListViewAdapter(Context context) {mInflater = LayoutInflater.from(context);}/*** 获取的数据存储在这个集合中,一般来说这个集合中存储了子项的 item*/private List mList = new ArrayList();/*** @return 返回集合的大小*/public int getCount() {return mList.size();}/*** @param position* @return 返回具体的 item*/public Object getItem(int position) {return mList.get(position);}public long getItemId(int position) {return position;}/*** 作用:加载 子项 item 的布局** @param position item 的位置* @param convertView item 进行复用,避免一个 item 发生多次加载的情况* @param parent 父容器,根据具体的情况而定* @return item*/public View getView(int position, View convertView, ViewGroup parent) {if (convertView == null){convertView = mInflater.inflate(R.layout.activity_detail,parent,false);}//对 item 进行复用,返回 convertViewreturn convertView;}}
可以看到,基本上每一个 item 都需要在 getView() 中加载,如果 item 的数量过多,就会产生性能问题,影响用户体验。这个时候我们就需要使用 ViewHolder(开发者自定义类),这是 ListViewAdapter 的内部类,它的代码如下:
/*** 作用:加载 子项 item 的布局** @param position item 的位置* @param convertView item 进行复用,避免一个 item 发生多次加载的情况* @param parent 父容器,根据具体的情况而定* @return item*/public View getView(int position, View convertView, ViewGroup parent) {ViewHolder holder = null;if (convertView == null){holder = new ViewHolder();convertView = mInflater.inflate(R.layout.activity_detail,parent,false);convertView.setTag(holder);} else {如果 convertView 不为空,直接进行复用holder = (ViewHolder) convertView.getTag();}//对 item 进行复用,返回 convertViewreturn convertView;}//这是一个内部类private class ViewHolder{//获取 item 的控件都定义在这里}
好了,关于 ListView 就到这里了,下面总结两个关键点:
下面开始写 RecyclerView ,先把 RecyclerView 的关键点总结在这里。其实和 ListView 是差不多的,主要有两条:
先看下面 RecyclerView 适配器的代码:
public class RecyclerViewAdapter extends RecyclerView.Adapter<RecyclerViewAdapter.ViewHolder> {/*** 这个方法主要生成为每个Item inflater出一个View,但是该方法返回的是一个ViewHolder。* 该方法把View直接封装在ViewHolder中,然后我们面向的是ViewHolder这个实例,* 当然这个ViewHolder需要我们自己去编写。** @param parent* @param viewType* @return viewHolder*/public RecyclerViewAdapter.ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {return null;}/*** 这个方法主要用于适配渲染数据到View中,* 方法提供给你了一viewHolder而不是原来的convertView** @param holder* @param position*/public void onBindViewHolder(@NonNull RecyclerViewAdapter.ViewHolder holder, int position) {//在这里更新 UI}/*** @return 返回 item 的数量*/public int getItemCount() {return 0;}public class ViewHolder extends RecyclerView.ViewHolder {public ViewHolder(@NonNull View itemView) {super(itemView);}}}
从基础使用上看,我们明显可以看出,RecyclerView 相比 ListView 在基础使用上的区别主要有如下几点:
接下来看一下如何在 Activity 中使用 RecyclerView :(ListView 大致相同)
//1、设置布局管理器LinearLayoutManager manager = new LinearLayoutManager(this);RecyclerView recyclerView = findViewById(R.id.detail_rv);recyclerView.setLayoutManager(manager);//2、设置适配器RecyclerViewAdapter adapter = new RecyclerViewAdapter();recyclerView.setAdapter(adapter);
关于 RecyclerView ,还得再说一下它的布局管理器,RecyclerView 提供了三种布局管理器可供选择:
之所以说 RecyclerView 更加强大,也正是因为 RecyclerView 提供了多种布局管理器,只需在 Activity 中进行设置即可。另外,关于布局管理器的一些API如下:
canScrollHorizontally();//能否横向滚动canScrollVertically();//能否纵向滚动scrollToPosition(int position);//滚动到指定位置setOrientation(int orientation);//设置滚动的方向getOrientation();//获取滚动方向findViewByPosition(int position);//获取指定位置的Item ViewfindFirstCompletelyVisibleItemPosition();//获取第一个完全可见的Item位置findFirstVisibleItemPosition();//获取第一个可见Item的位置findLastCompletelyVisibleItemPosition();//获取最后一个完全可见的Item位置findLastVisibleItemPosition();//获取最后一个可见Item的位置
我们可以为 REcyclerview 的 item 绘制分割线,用系统已经定义好的分割线:
//添加分割线myRecyclerView.addItemDecoration(new DividerItemDecoration(this, DividerItemDecoration.VERTICAL));
同样,我们也可以定义自己的分割线,实现不同的效果:
自定义间隔样式需要继承RecyclerView.ItemDecoration类,该类是个抽象类,官方目前并没有提供默认的实现类,主要有三个方法。
– EOF –