关闭

总结一下这两天所学RecyclerView

245人阅读 评论(0) 收藏 举报
分类:
转载自:http://blog.csdn.net/wxj1018/article/details/51531838

RecycleView学习总结复习篇

                 recyclerView是android5.0之后推出的一款新的View布局,功能相较于ListView有过之而无不及,相信在以后的学习和工作中都将可能会用上,这两天自己在边看边学其中功能与各种效果,现来博客与诸君分享,也为日后自己复习设下渠道。奋斗

       首先,我们了解一下为什么要叫做RecyclerView?
它不关心Item是否显示在正确位置,如何显示;不关心Item间如何分割;不关注Item增加和删除的动画效果;仅仅关注如何回收和服用View(即英文Recycle的译义)。
那可能有人要问了,这些都是View里比较重要的且频繁使用的属性和效果,都不关心的话,如何做到控制和实现呢?其实,不必担心,我们可以通过LayoutManager来实现Item的显示,ItemDecoration来自定义Item之间的分割线,以及ItemAnimator来完成Item增加和删除时所需要的各种动画(下面的文章会详细介绍)。所以它的功能还是很强大的,值得我们深入研究!

        知道了RecyclerView的概念,我们来大体了解一下它具备的功能:
1.ListView
2.GridView
3.横向ListView
4.横向GridView
5.瀑布流
6.定制Item增加和删除动画
大致为以上功能,是不是挺强大的。生气

工欲善其事必先利其器,下面给出2个需要使用到的链接:
github上recyclerviewItemDecoration原地址


github/上recyclerview动画效果集合原地址


下面进入今天的主题:
由于我们的工程依赖android.support.v7包里的recyclerViewjar包,建立工程时要找到你的sdk存放路径的extras/android/support/v7/recyclerview/libs文件目录下的jar包拷贝到工程目录libs下,才能实现全部功能!

首先我们要首先ListView,写两个方法:initViews();initDatas();
[java] view plain copy
 print?
  1. private void initDatas() {  
  2.         mDatas = new ArrayList<String>();  
  3.         for (int i = 'A'; i <= 'z'; i++) {  
  4.             mDatas.add("" + (char) i);  
  5.         }  
  6.   
  7.     }  
  8.   
  9.     private void initViews() {  
  10.         mRecyclerView = (RecyclerView) findViewById(R.id.id_recyclerview);  
  11.   
  12.     }  
[html] view plain copy
 print?
  1. <android.support.v7.widget.RecyclerView  
  2.         android:id="@+id/id_recyclerview"  
  3.         android:layout_width="wrap_content"  
  4.         android:layout_height="wrap_content">  
  5.           
  6.     </android.support.v7.widget.RecyclerView>  
这两个方法用来创建View和存放数据。这里我放的是A-z。
然后创一个SimpleAdapter来适配主界面。这里需要注意的是要继承RecyclerView.Adapter<MyViewHolder> ,以自己写的MyViewHolder类作为泛型,才能对recycleView里的Item进行配置。
[java] view plain copy
 print?
  1. class MyViewHolder extends ViewHolder {  
  2.   
  3.     TextView tv;  
  4.   
  5.     public MyViewHolder(View arg0) {  
  6.         super(arg0);  
  7.         tv = (TextView) arg0.findViewById(R.id.id_tv);  
  8.     }  
这里我就给每个Item一个TextView,然后通过我们自己的ViewHolder来初始化它。
另外还要重写父类的方法:
[java] view plain copy
 print?
  1.     @Override  
  2.     public int getItemCount() {  
  3.         return mDatas.size();  
  4.     }  
  5.   
  6.     @Override  
  7.     public void onBindViewHolder(final MyViewHolder holder, final int pos) {  
  8.         holder.tv.setText(mDatas.get(pos));  
  9.   
  10.         // click  
  11.         setUpItemEvent(holder);  
  12.     }  
  13. @Override  
  14.     public MyViewHolder onCreateViewHolder(ViewGroup arg0, int arg1) {  
  15.         View view = mInflater.inflate(R.layout.item_simple_textview, arg0, false);  
  16.         MyViewHolder viewHolder = new MyViewHolder(view);  
  17.         return viewHolder;  
  18.     }  
这里主要关注第二个和第三个方法,顾名思义就是绑定ViewHolder和创建Viewholder,
绑定里用位置来设置Item内Text显示的文字,setUpItemEvent(holder);这个方法后面会讲到大家先忽略。然后Create方法里就是初始化View工作,要创建一个item_simple_textview布局文件,里面只放了一个TextView这里我就不做过多赘述,最后返回我们的viewHolder。别忘了做绑定,
mAdapter = new SimpleAdapter(this, mDatas);
mRecyclerView.setAdapter(mAdapter);
还要给布局设置一个管理器:
[java] view plain copy
 print?
  1. // 设置recyclerview的布局管理  
  2.         LinearLayoutManager layoutManager = new LinearLayoutManager(this, LinearLayoutManager.VERTICAL, false);  
  3.         mRecyclerView.setLayoutManager(layoutManager);  

然而此时我们运行程序会发现虽然ListView正常展示了,可是Item直接并没有分割。

看起来很不舒服,接下来,我们就完成自定义分割线的工作。
由于RecyclerView自身并不能为Item添加分割线,所以我们采用外部开源文件的方法叫做DividerItemDecoration,该方法可以在正文开篇的地址里找到并下载。
[java] view plain copy
 print?
  1. // 设置recyclerview的Item分割线,通过抽象类来控制  
  2. mRecyclerView.addItemDecoration(new DividerItemDecoration(this, DividerItemDecoration.VERTICAL_LIST));  
这里给Item加一个垂直方向的默认的分割线。(稍后说下自定义)可以得到如下效果

但是,如果默认的分割线不合你的胃口,你完全可以自定义你想要的分割线样式。这就需要我们对开源代码进行简单的分析!
[java] view plain copy
 print?
  1. public DividerItemDecoration(Context context, int orientation)  
  2.     {  
  3.         final TypedArray a = context.obtainStyledAttributes(ATTRS);  
  4.         mDivider = a.getDrawable(0);  
  5.         a.recycle();  
  6.         setOrientation(orientation);  
  7.     }  
这是DividerItemDecoration类的构造方法,从中我们不难看出a对象是从context.obtainStyledAttributes(ATTRS);中获取到的,也就是说从theme中可以得到,这样我们就可以自己定义一个shape放入theme里,就可以给方法查找和调用了。
[html] view plain copy
 print?
  1. <?xml version="1.0" encoding="utf-8"?>  
  2. <shape xmlns:android="http://schemas.android.com/apk/res/android"  
  3.     android:shape="rectangle" >  
  4.   
  5.     <size android:height="4dp" />  
  6.   
  7.     <gradient  
  8.         android:centerColor="#ff00ff00"  
  9.         android:endColor="#ff0000ff"  
  10.         android:startColor="#ffff0000" />  
  11.   
  12. </shape>  
这里我们写了一个4dp高度的矩形,中间有三种颜色的渐变来作为我们的分割线。
然后由于我使用的SDK是6.0版本,所以讲它放入values-v14包里。
[html] view plain copy
 print?
  1. <resources>  
  2.   
  3.     <!--  
  4.         Base application theme for API 14+. This theme completely replaces  
  5.         AppBaseTheme from BOTH res/values/styles.xml and  
  6.         res/values-v11/styles.xml on API 14+ devices.  
  7.     -->  
  8.     <style name="AppBaseTheme" parent="android:Theme.Holo.Light.DarkActionBar">  
  9.         <!-- API 14 theme customizations can go here. -->  
  10.         <span style="background-color: rgb(255, 0, 0);"><!--  <item name="android:listDiveder">@drawable/divider</item>--></span>  
  11.     </style>  
  12.   
  13. </resources>  
然后再次运行程序,就可以得到我们想要的效果。


到这里我们的ListView差不多就实现了。接下来说明一下各自布局的切换使用。
-------------------------------------------------------------------------------------------------------------------


我们用menu里的item来实现不同布局的切换!
进入main.xml添加三个Item
[html] view plain copy
 print?
  1. <item  
  2.     android:id="@+id/action_listView"  
  3.     android:orderInCategory="100"  
  4.     android:showAsAction="never"  
  5.     android:title="ListView"/>  
  6. <item  
  7.     android:id="@+id/action_gridView"  
  8.     android:orderInCategory="100"  
  9.     android:showAsAction="never"  
  10.     android:title="gridView"/>  
  11. <item  
  12.     android:id="@+id/action_staggered"  
  13.     android:orderInCategory="100"  
  14.     android:showAsAction="never"  
  15.     android:title="Staggered"/>  
分别代表ListView、GridView、瀑布流布局。然后根据id来设置点击到不同Item时显示的布局样式。
[java] view plain copy
 print?
  1. @Override  
  2.     public boolean onOptionsItemSelected(MenuItem item) {  
  3.         // Handle action bar item clicks here. The action bar will  
  4.         // automatically handle clicks on the Home/Up button, so long  
  5.         // as you specify a parent activity in AndroidManifest.xml.  
  6.         int id = item.getItemId();  
  7.         switch (id) {  
  8.         case R.id.action_add:  
  9.             mAdapter.addData(1);  
  10.             break;  
  11.         case R.id.action_delete:  
  12.             mAdapter.deleteData(1);  
  13.             break;  
  14.         case R.id.action_listView:  
  15.             mRecyclerView.setLayoutManager(new LinearLayoutManager(this));  
  16.             break;  
  17.         case R.id.action_gridView:  
  18.             mRecyclerView.setLayoutManager(new GridLayoutManager(this3));  
  19.             break;  
  20.         case R.id.action_staggered:  
  21.             Intent intent = new Intent(this, StaggeredActivity.class);  
  22.             startActivity(intent);  
  23.             break;  
  24.         default:  
  25.             break;  
  26.         }  
  27.         return false;  
  28.     }  

同样,上面两个后面再做解释,先看后面三个选项。每当不同id被选中时,我们给予recyclerView不同的LayoutManager,这样它就显示不同的布局了!由于GridView和ListView是继承自同一父类,所以他们之间转化不要开启新的Activity而瀑布流布局就需要开启新Acitivity来显示,我们采用显式Intent切换。


GridView就这样了,比较简单,下面我们主要研究一下瀑布流的代码。

我们把MainActivity和SimpleAdapter都拷贝一份,改名为StaggeredActivity和StaggeredAdapter。
为了防止代码复写的麻烦,直接在SimpleAdapter里提供一个回调方法,供StaggeredAdapter使用,实现点击和长按事件。
[java] view plain copy
 print?
  1. // 设置一个接口回调,给Item绑定一个点击事件  
  2.     public interface OnItemClickListener {  
  3.         void onItemClick(View view, int position);  
  4.   
  5.         void onItemLongClick(View view, int position);  
  6.     }  
  7.   
  8.     private OnItemClickListener onItemClickListener;  
  9.   
  10.     public void setOnItemClickListener(OnItemClickListener listener) {  
  11.         this.onItemClickListener = listener;  
  12.     }  
[java] view plain copy
 print?
  1. protected void setUpItemEvent(final MyViewHolder holder) {  
  2.         if (onItemClickListener != null) {  
  3.             holder.itemView.setOnClickListener(new OnClickListener() {  
  4.   
  5.                 @Override  
  6.                 public void onClick(View v) {  
  7.   
  8.                     int layoutPosition = holder.getLayoutPosition();  
  9.                     onItemClickListener.onItemClick(holder.itemView, layoutPosition);  
  10.   
  11.                 }  
  12.             });  
  13.         }  
  14.         // longclick  
  15.         holder.itemView.setOnLongClickListener(new OnLongClickListener() {  
  16.   
  17.             @Override  
  18.             public boolean onLongClick(View v) {  
  19.                 int layoutPosition = holder.getLayoutPosition();  
  20.                 onItemClickListener.onItemLongClick(holder.itemView, layoutPosition);  
  21.                 return false;  
  22.             }  
  23.         });  
  24.     }  
这样处理的话,就可以让StaggeredAdapter的代码更加简洁:
[java] view plain copy
 print?
  1. public class StaggeredAdapter extends SimpleAdapter {  
  2.   
  3.     private LayoutInflater mInflater;  
  4.     private Context mContext;  
  5.     private List<String> mDatas;  
  6.     private List<Integer> mHeight;  
  7.   
  8.     public StaggeredAdapter(Context context, List<String> datas) {  
  9.         super(context, datas);  
  10.   
  11.         mHeight = new ArrayList<Integer>();  
  12.         for (int i = 0; i < mDatas.size(); i++) {  
  13.             mHeight.add((int) (100 + Math.random() * 300));  
  14.         }  
  15.     }  
  16.   
  17.     @Override  
  18.     public void onBindViewHolder(MyViewHolder holder, int pos) {  
  19.   
  20.         LayoutParams lp = (LayoutParams) holder.itemView.getLayoutParams();  
  21.         lp.height = mHeight.get(pos);  
  22.         holder.itemView.setLayoutParams(lp);  
  23.   
  24.         holder.tv.setText(mDatas.get(pos));  
  25.         setUpItemEvent(holder);  
  26.   
  27.     }  
  28.   
  29. }  

把height做一个随机数处理,就可以得到瀑布流那样不规则的分布布局。然后通过LayoutParams和height进行绑定,就可以动态的设置item的高度了。setUpItemEvent就是响应点击和长按事件。效果如下:


关于Item增加和删除的动画:
在menu里加入两个图标,增加和删除,对应前面代码所示的switch方法内add和delete方法。代码如下:
[java] view plain copy
 print?
  1. public void addData(int pos) {  
  2.         mDatas.add(pos, "Insert one");  
  3.         notifyItemInserted(pos);  
  4.     }  
  5.   
  6.     public void deleteData(int pos) {  
  7.         mDatas.remove(pos);  
  8.         notifyItemRemoved(pos);  
  9.     }  
注意:这里使用了notifyItemInserted和notifyItemRemoved两个方法,它会导致点击加入或者删除Item后,新增的Item和删除的Item后面那个Item的postion不变,因为他只notify了增加和移除,并没有重绘View,所以后面代码里用getParamPosition()方法来得到View所显示的Item的动态位置,就不会造成多个position相同的情况。

[java] view plain copy
 print?
  1. mRecyclerView.setItemAnimator(new DefaultItemAnimator());  
这里我使用的默认的动画效果,大家可以去开篇给出的链接下载动画效果源码,实现各种炫酷的动画!

-------------------------------------------------------------------------------------------------------------------


好了,基本的功能已经介绍的差不多了,更多的炫酷动画和花式布局,需要靠我们更多的去研究和学习!本人也只是小白阶段,跟着视频学习完写个博客记录一下学习成果,方便以后的复习同时也能给需要的人带来一点参考和建议吧。共勉!
1
0
查看评论

总结一下这两天所学RecyclerView

RecycleView学习总结复习篇                  recyclerView是android5.0之后推出的一款新的View布局,功能相较于ListView有过之而无不及,相信在以后的学习和...
  • wxj1018
  • wxj1018
  • 2016-05-29 13:57
  • 2899

总结一下近来所学

1、简单说一下ssh。structs主要的是一个action跳转,这个跳转在spring mvc中可以用mindandview的方式实现,hibernate主要就是model类和映射关系的一个设定,具体去看网上资料。在这里要理解一点,它们都是mvc的实现,mvc才是真实的最主要的东西,了解...
  • llbbxx_0703
  • llbbxx_0703
  • 2015-09-16 15:47
  • 414

总结一下这两天

<br />这两天,我要宣布一下 我被分配到了公司的电子渠道部门的移动公司的自助终端的一组,我还真不知道这是干什么的,主要是用C和java方面的,本来是要做短信的,用c++的,可是我C++不是很会啊呵呵 ,所以先把这方面做好,以后多自己学习c++还有linux这些东西,为以后自己的发展方...
  • wallwind
  • wallwind
  • 2011-03-09 23:26
  • 622

要对过去所学所得进行总结

可能总结是很少做的事情,将所有学到的东西进行总结    ,其结果可能就是一个新的东西现在是太不善于总结了2005年2月2日
  • lstart
  • lstart
  • 2005-02-02 15:21
  • 523

在此总结一下最近所学

在此总结一下最近所学   最近主要学习js语言中的循环语句数组,随机函数以及函数的使用。 Js语言和其他的语言并没有太大的区别,就像是数学中的知识块一样,知识都差不多一样多一样丰富多彩,让人眼花缭乱。好了,废话不多说,开始正题: Js中的循环语句主要是while,do while,...
  • zi__kang
  • zi__kang
  • 2016-08-13 20:02
  • 155

解决RecyclerView局部刷新时闪烁

RecyclerView局部刷新是由于其自带的item动画造成的,相信都看过RecyclerView在移除某个item时的删除动画吧,这个闪烁也是默认动画中的效果,所以只要去掉默认动画里的闪烁效果问题就解决了。代码如下:((DefaultItemAnimator) mRecyclerView.get...
  • CSDN_LQR
  • CSDN_LQR
  • 2017-01-04 19:42
  • 3497

RecyclerView 拖动才刷新内容

RecyclerView 拖动才刷新内容遇到问题是在ViewPager中的某个RecyclerView明明在UI线程调用了它的adapter.notifydatasetchanged()方法,但是UI就是没有刷新,且用手指拖动界面之后其才会刷新。 这个问题常见于内存消耗比较大,貌似Fragmen...
  • h3c4lenovo
  • h3c4lenovo
  • 2015-07-22 11:33
  • 1198

【Java】Java基础知识总结

Java基础知识总结 写代码: 1,明确需求。我要做什么? 2,分析思路。我要怎么做?1,2,3。 3,确定步骤。每一个思路部分用到哪些语句,方法,和对象。 4,代码实现。用具体的java语言代码把思路体现出来。   学习新技术的四点: 1,该技术是什么? 2,该技术有什么特点(使用注意)...
  • Taily_Duan
  • Taily_Duan
  • 2016-08-18 19:30
  • 2248

RecyclerView 更新单个item时,闪烁问题的处理

情景描述1、调用mAdapter.notifyItemChanged(position);时,会重复加载图片,出现占位图等。 2、根据tag标记判断是否加载,不起作用。原因重复加载的原因就是onBindViewHolder的重复调用。而tag不起作用的原因则是每次更新都会使用一个新的holder。...
  • wove55678
  • wove55678
  • 2016-12-22 10:48
  • 1424

解决recyclerview notifyItemChanged 闪烁问题

闪烁主要由于RecyclerView使用的默认的动画导致的,所以解决的方法就是修改默认的动画。首先把默认的动画(DefaultItemAnimator)代码复制到自定义的MyItemAnimator类里面。 接着找到animateChangeImpl方法修改其中的两行代码。 // 去掉alpha(0...
  • java_goodstudy
  • java_goodstudy
  • 2017-02-18 17:27
  • 1463
    个人资料
    • 访问:118591次
    • 积分:1425
    • 等级:
    • 排名:千里之外
    • 原创:2篇
    • 转载:175篇
    • 译文:0篇
    • 评论:10条
    最新评论