RecyclerView Part 1:为ListView专家写的基础
2015-01-13 20:09
381 查看
是时候讲清楚了:我了解RecylerView有些晚。太迟了。
这只能怪我自己。你可以从文档中得知RecylerView应该会取代ListView,并且在工具包里没有几个视图比ListView更重要。所以,RecyclerView十分重要。
但是它们还是会有很多不同,对吗?嗯。所以我一直推迟对它的讲解,直到几周之前我为HackNight准备一个讲座的时候。我最终做了大量的研究,我承认这些研究很有乐趣。
最终的结果是RecyclerView非常酷,值的去替换listView。它把以前非常棘手的东西变的非常非常简单。最重要的是,它可以让一个item轻松的从一个可行的列表中动画流入和流出,而不像之前那样慢。
通过指出所有的这些要点,我决定把ListView从我们的Androidprogrammingguide中删除,并用RecyclerView代替。我发现使用RecyclerView会使大多数的工作变的非常容易,并且最终的代码非常简洁。
除了一点:选择模式(choicemodes)。setChoiceMode()被去掉了,并且让一个RecyclerView转换多项选择,会导致了一些有趣的问题。在以后的几篇博客中我将会按照步骤来跟你分享我的解决方案。在这里我先从RecyclerView的基本用法开始。
RecyclerView做的更少
如果你打算替换ListView,那么现在让我们讨论下RecyclerView中的一些重大变化。
第1步,当然这是非常重要的,你需要在build.gradle里写入下面这一行:
compile‘com.android.support:recyclerview-v7:+’
第二步:有一个很好的的去掉setChoiceMode(int)的原因。RecyclerView能做的比ListView更多,但是比起ListView它有更少的责任。创造性的,RecyclerView并不需要处理:
1.在屏幕上item的位置
2.动画视图
3.除了滚动可以捕获任何触控事件
但是,所有的这些都被放到了ListView中,而RecyclerView是通过使用合作者类去(collaboratorclass)做这些工作的。
前两个,RecyclerView通过使用LayoutManager和ItemAnimator来实现。RecyclerView拥有一个默认的ItemAdapter,所以你不必要担心这些。你要做的是给item一个LayoutManager。这是我们的CriminalIntent应用中listfragment的OnCreateView():
LinearLayoutManager在RecyclerViewsupportlibrary中。它会让RecyclerView中的item像ListView中显示的那样。还有其它的布局管理者,比如网格,或者交错网格。至于CrimeAdapter,我将立即讨论它。
当在ListView中点击一个item时,你可能会这样做:
通过监听事件你可以处理adapter返回的单个item的点击事件。这并不常见,也不推荐使用。虽然ListView给了你一些不错的功能,诸如,允许在点击处理之上建立可选择的item的ListView.setChoiceMode(int)。(setChoiceMode(int)可以让你选择单独的item或者是多个item)
然而,RecyclerView并不需要处理这些,所以它不需要模式选择。你不能使用OnItemClickListener来捕获item被点击。RecyclerView提供了一个OnItemTouchListener,但这不同于OnItemClickListener:这个事件并不告诉你哪个item被触发了。你需要通过MotionEvent去寻找哪个item被触发,但大多数情况这并不需要。
ViewHolder
另一个大的不同是viewholder变的更重要。如果你从我们这里学习怎样使用ListView,你可以不知道什么是viewholder,因为我们并没有教那样做。Viewholder是附加在ListView中每一行的对象。一般的viewholder会如下图所展示的这样:
当view获得视图时,你也需要创建一个ViewHolder对象,并且添入相应的数据。然后通过setTag()把ViewHolder关联到view上。
你每创建一个view,相应的要创建一个ViewHolder。之前使用ViewHolder是为了实现滚动性能更好:它通过调用findViewById()保存了solvedCheckBox所以在每次寻找组件时更方便。如果你有其它的操作需要调用组件,你同样会选择使用ViewHolder,而不是使用getView()。
下面是我们为RecyclerView写的包含ViewHolder的代码:
注意这里没有ArrayAdapter,所以你需要为Adapter关联一个List。幸运的是这并不难。
就像ListViewAdapter中的那样,你需要要建立两个类:一个Adapter和一个ViewHolder。在RecyclerView的adapter中,更像是系统的一块基石。你的RecyclerView.Adapter去创造和绑定ViewHolder,而不是之前的View。
同样你创建的ViewHolder更加健壮。RecyclerView.ViewHolder子类拥有一大堆RecyclerView使用的方法。ViewHolder知道刚刚绑定的是哪个位置和item的id。
这样ViewHolder就被建立了。以前控制整个item视图是ListView的工作,ViewHolder只是控制其中的一小部分。现在,ViewHolder在ViewHolder.itemView中控制所有视图,并在构造函数中给itemView赋值。
自从ViewHolder有了这个新的责任,它同样可以被赋予更多其它的责任。所以在新的实现中我们加入了一个新的方法——bindCrime(),以前我们常常在getView()里做很多的工作。ViewHolder同样成为捕获特定item点击事件的场所。
在ListView中关于怎样控制点击事件有一些地方比较模糊:是每个单独的视力控制这些事件,还是ListView通过OnItemClickListener控制?在RecyclerView中ViewHolder是确定做为行级(row-level)控制对象来处理这些细节。
我们之前看到LayoutManager处理视图位置,ItemAnimator处理动画。ViewHolder是最后的部分:它的职责是处理发生在RecyclerView中特定item的事件。
选择模式及下一个是什么
那么选择模式(choicemode)怎么办?怎么在RecyclerView中使用它们?我们在这里会很自然的在ViewHolder中展示出来,因为它处理item的点击事件。
在这里我有一些坏消息:ViewHolder并没有提供任何工具来实现选择。去实现单个或多个选择,我将在下一篇博客中讲遇到的两个问题:
1.跟踪选择。我们需要一些代码来获取哪个item被选择了,或者选择有没有被激活。
2.展示哪些item被选择了。ListView通过调用每个item视图中的setActivated()实现。你可以在Lollipop中实现,但是在实现过程中几个陷阱。
转载自并发编程网–ifeve.com本文链接地址:RecyclerView
Part1:为ListView专家写的基础
这只能怪我自己。你可以从文档中得知RecylerView应该会取代ListView,并且在工具包里没有几个视图比ListView更重要。所以,RecyclerView十分重要。
但是它们还是会有很多不同,对吗?嗯。所以我一直推迟对它的讲解,直到几周之前我为HackNight准备一个讲座的时候。我最终做了大量的研究,我承认这些研究很有乐趣。
最终的结果是RecyclerView非常酷,值的去替换listView。它把以前非常棘手的东西变的非常非常简单。最重要的是,它可以让一个item轻松的从一个可行的列表中动画流入和流出,而不像之前那样慢。
通过指出所有的这些要点,我决定把ListView从我们的Androidprogrammingguide中删除,并用RecyclerView代替。我发现使用RecyclerView会使大多数的工作变的非常容易,并且最终的代码非常简洁。
除了一点:选择模式(choicemodes)。setChoiceMode()被去掉了,并且让一个RecyclerView转换多项选择,会导致了一些有趣的问题。在以后的几篇博客中我将会按照步骤来跟你分享我的解决方案。在这里我先从RecyclerView的基本用法开始。
RecyclerView做的更少
如果你打算替换ListView,那么现在让我们讨论下RecyclerView中的一些重大变化。
第1步,当然这是非常重要的,你需要在build.gradle里写入下面这一行:
compile‘com.android.support:recyclerview-v7:+’
第二步:有一个很好的的去掉setChoiceMode(int)的原因。RecyclerView能做的比ListView更多,但是比起ListView它有更少的责任。创造性的,RecyclerView并不需要处理:
1.在屏幕上item的位置
2.动画视图
3.除了滚动可以捕获任何触控事件
但是,所有的这些都被放到了ListView中,而RecyclerView是通过使用合作者类去(collaboratorclass)做这些工作的。
前两个,RecyclerView通过使用LayoutManager和ItemAnimator来实现。RecyclerView拥有一个默认的ItemAdapter,所以你不必要担心这些。你要做的是给item一个LayoutManager。这是我们的CriminalIntent应用中listfragment的OnCreateView():
01 | @Override |
02 | public View |
03 |
04 | { |
05 | View false ); |
06 |
07 | mRecyclerView |
08 | mRecyclerView.setLayoutManager( new LinearLayoutManager(getActivity())); |
09 | mCrimes |
10 | mRecyclerView.setAdapter( new CrimeAdapter()); |
11 |
12 | return v; |
13 | } |
当在ListView中点击一个item时,你可能会这样做:
01 | public View |
02 |
03 | { |
04 | ... |
05 |
06 | mListView.setOnItemClickListener( this ); |
07 |
08 | ... |
09 | } |
10 |
11 | public void onItemClick(AdapterView<?> int position, |
12 | long id) { |
13 | // |
14 | } |
然而,RecyclerView并不需要处理这些,所以它不需要模式选择。你不能使用OnItemClickListener来捕获item被点击。RecyclerView提供了一个OnItemTouchListener,但这不同于OnItemClickListener:这个事件并不告诉你哪个item被触发了。你需要通过MotionEvent去寻找哪个item被触发,但大多数情况这并不需要。
ViewHolder
另一个大的不同是viewholder变的更重要。如果你从我们这里学习怎样使用ListView,你可以不知道什么是viewholder,因为我们并没有教那样做。Viewholder是附加在ListView中每一行的对象。一般的viewholder会如下图所展示的这样:
01 | private static class ViewHolder { |
02 | private CheckBox mSolvedCheckBox; |
03 | } |
04 |
05 | private class CrimeAdapter extends ArrayAdapter<Crime> { |
06 | public CrimeAdapter(ArrayList<Crime> |
07 | super (getActivity(), 0 , crimes); |
08 | } |
09 |
10 | @Override |
11 | public View getView( int position, |
12 | ViewHolder holder; |
13 | if ( null == |
14 | convertView |
15 | .inflate(R.layout.list_item_crime, false ); |
16 | holder new ViewHolder(); |
17 | holder.mSolvedCheckBox |
18 | .findViewById(R.id.solvedCheckBox); |
19 |
20 | convertView.setTag(holder); |
21 | } |
22 |
23 | ViewHolder |
24 | Crime |
25 | holder.mSolvedCheckBox.setChecked(crime.isSolved()); |
26 |
27 | return convertView; |
28 | } |
29 | } |
你每创建一个view,相应的要创建一个ViewHolder。之前使用ViewHolder是为了实现滚动性能更好:它通过调用findViewById()保存了solvedCheckBox所以在每次寻找组件时更方便。如果你有其它的操作需要调用组件,你同样会选择使用ViewHolder,而不是使用getView()。
下面是我们为RecyclerView写的包含ViewHolder的代码:
01 | private class CrimeHolder extends ViewHolder { |
02 | private final CheckBox mSolvedCheckBox; |
03 | private Crime mCrime; |
04 |
05 | public CrimeHolder(View |
06 | super (itemView); |
07 |
08 | mSolvedCheckBox |
09 | .findViewById(R.id.crime_list_item_solvedCheckBox); |
10 | } |
11 |
12 | public void bindCrime(Crime |
13 | mCrime |
14 | mSolvedCheckBox.setChecked(crime.isSolved()); |
15 | } |
16 | } |
17 |
18 | private class CrimeAdapter |
19 | extends RecyclerView.Adapter<CrimeHolder> { |
20 | @Override |
21 | public CrimeHolder int pos) { |
22 | View |
23 | .inflate(R.layout.list_item_crime, false ); |
24 | return new CrimeHolder(view); |
25 | } |
26 |
27 | @Override |
28 | public void onBindViewHolder(CrimeHolder int pos) { |
29 | Crime |
30 | holder.bindCrime(crime); |
31 | } |
32 |
33 | @Override |
34 | public int getItemCount() { |
35 | return mCrimes.size(); |
36 | } |
37 | } |
就像ListViewAdapter中的那样,你需要要建立两个类:一个Adapter和一个ViewHolder。在RecyclerView的adapter中,更像是系统的一块基石。你的RecyclerView.Adapter去创造和绑定ViewHolder,而不是之前的View。
同样你创建的ViewHolder更加健壮。RecyclerView.ViewHolder子类拥有一大堆RecyclerView使用的方法。ViewHolder知道刚刚绑定的是哪个位置和item的id。
这样ViewHolder就被建立了。以前控制整个item视图是ListView的工作,ViewHolder只是控制其中的一小部分。现在,ViewHolder在ViewHolder.itemView中控制所有视图,并在构造函数中给itemView赋值。
自从ViewHolder有了这个新的责任,它同样可以被赋予更多其它的责任。所以在新的实现中我们加入了一个新的方法——bindCrime(),以前我们常常在getView()里做很多的工作。ViewHolder同样成为捕获特定item点击事件的场所。
01 | private class CrimeHolder extends ViewHolder |
02 | implements View.OnClickListener { |
03 | ... |
04 |
05 | public CrimeHolder(View |
06 | super (itemView); |
07 |
08 | itemView.setOnClickListener( this ); |
09 |
10 | ... |
11 | } |
12 |
13 | @Override |
14 | public void onClick(View |
15 | if (mCrime null ) { |
16 | Intent |
17 | startActivity(i); |
18 | } |
19 | } |
20 | } |
我们之前看到LayoutManager处理视图位置,ItemAnimator处理动画。ViewHolder是最后的部分:它的职责是处理发生在RecyclerView中特定item的事件。
选择模式及下一个是什么
那么选择模式(choicemode)怎么办?怎么在RecyclerView中使用它们?我们在这里会很自然的在ViewHolder中展示出来,因为它处理item的点击事件。
在这里我有一些坏消息:ViewHolder并没有提供任何工具来实现选择。去实现单个或多个选择,我将在下一篇博客中讲遇到的两个问题:
1.跟踪选择。我们需要一些代码来获取哪个item被选择了,或者选择有没有被激活。
2.展示哪些item被选择了。ListView通过调用每个item视图中的setActivated()实现。你可以在Lollipop中实现,但是在实现过程中几个陷阱。
转载自
Part1:为ListView专家写的基础
相关文章推荐
- RecyclerView Part 1:为ListView专家写的基础
- Android基础——5:ListView及RecyclerView
- 【Android】の基础——ListView和RecyclerView缓存机制
- Android的v7包中的新控件——(二)RecyclerView(超级 listview,传说会代替listview)
- ListView或者RecyclerView滚动时隐藏Toolbar (1)
- RecyclerView--实现 ListView,GridView,瀑布流 效果
- [Android]使用RecyclerView替代ListView(一)
- Android 自定义RecyclerView (替代ListView的最新组件)实现真正的Gallery效果
- RecyclerView(替代ListView)用法介绍
- UltimateRecyclerView发布,Android下新Listview的大杀器
- Android 5.0学习之ListView升级版RecyclerView
- RecyclerView 横向的listview 直接解决你的自定义问题
- android基础_imageview的scaleType,listview的cacheColorHint和android:listSelector
- 如何使用Android最新的RecyclerView取代ListView?
- Android控件RecyclerView与ListView的异同
- Android使用RecyclerView替代ListView(一)
- Android最新组件RecyclerView,替代ListView
- android基础笔记——使用viewholder模式优化ListView
- ListView的新朋友-------RecyclerView初识
- ListView hide the part of headerView