美文网首页
RecyclerView 使用及真实案例

RecyclerView 使用及真实案例

作者: 压抑的内心 | 来源:发表于2018-08-06 18:55 被阅读142次

    前言

    在前面两篇文章(Android RecyclerView的使用解析(一)Android RecyclerView的使用解析(二))中,我们主要对RecyclerView作了简单的介绍并实现了它不同的布局效果,在本文中,我将对RecyclerView的动画机制和点击事件进行讲解。

    ItemAnimator

    说到RecyclerView的动画机制,那我们就不得不提ItemAnimator这个类了,我们就

    是依靠它来实现item的动画效果的。这个类仍然是个抽象类,不过Google给我们提供了一些实现类,我们也可以自定义它的实现类以显示更加炫酷的效果。网上有很多讲解该类的文章,这里我就不多作分析了。

    给item设置添加、删除动画

    首先我们需要在菜单栏添加两个实现增加和删除item的按钮,打开menu文件夹下的布局文件,添加两个item项:

    接着在TestAdapter中添加两个增加和删除item的方法:

    publicvoidaddData(intpos){        mDataset.add (pos,"Insert one");        notifyItemInserted (pos);    }publicvoidremoveData(intpos){        mDataset.remove (pos);        notifyItemRemoved (pos);    }

    然后在MainActivity的Oncreate方法中给RecyclerView设置一个默认的动画效果:

    mRecyclerView.setItemAnimator (newDefaultItemAnimator ());

    最后在onOptionsItemSelected方法中增加两个按钮的id:

    caseR.id.action_add:                mAdapter.addData (1);break;caseR.id.action_remove:                mAdapter.removeData (1);break;

    由于我们给瀑布流的布局设置了不同的activity,所以还需将以上代码添加到StaggeredGridActivity和StagggeredAdapter。

    运行效果如下:

    ItemAnimator

    额。。。虽然我们实现了添加和删除动画,但是每次都通过点击菜单选项来操作好像很繁琐耶,我们来优化一下呗。

    我们可以给我们的demo增加一个ActionBar或ToolBar并把ADD和REMOVE按钮放在其上,为了方便,我这里使用的是ActionBar。修改代码,让MainActivty和StaggeredGridActivity继承自ActionBarActivity,接着修改values/styles.xml,将Theme指定为Theme.AppCompat.Light.DarkActionBar,代码如下:

    @drawable/my_divider-->

    重新运行程序,试试效果吧:

    ChagedItemAnimator

    嘿嘿,是不是方便多啦!

    添加OnClick监听

    熟悉ListView的人应该知道,ListView给我们提供了onItemClickListener之类的监听器,当我们点击item的时候,它会回调相关的方法,以便我们可以方便的处理item的点击事件。然而RecyclerView它丫的竟然没有对item提供任何相关的回调方法,太不负责任了!还能肿么办,只能我们自己去添加咯,谁叫人家是当大爷的命呢。

    简单起见,我们可以在Adapter中为其添加,修改TestAdapter,代码如下:

    packagecom.wuminmiao.recycleviewtest;importandroid.content.Context;importandroid.support.v7.widget.RecyclerView;importandroid.view.LayoutInflater;importandroid.view.View;importandroid.view.ViewGroup;importandroid.widget.TextView;importjava.util.List;/**

    * Created by wmm on 2016/10/13.

    */publicclassTestAdapterextendsRecyclerView.Adapter{privateContext mContext;protectedList mDataset;privateLayoutInflater mInflater;//    提供接口publicinterfaceOnItemClickListener{voidonItemClick(View view,intposition);voidonItemLongClick(View view,intposition);    }//    声明类型privateOnItemClickListener mOnItemClickListener;//    提供它的set方法,供activity设置回调publicvoidsetOnItemClickListener(OnItemClickListener listener){this.mOnItemClickListener = listener;    }//提供一个合适的构造方法publicTestAdapter(Context context, List dataset){this.mContext = context;this.mDataset = dataset;        mInflater = LayoutInflater.from (context);    }/**    *将布局转换为View并传递给自定义的MyViewHolder    *@paramviewGroup    *@paramviewType    *@return*/@OverridepublicMyViewHolderonCreateViewHolder(ViewGroup viewGroup,intviewType){        View view = mInflater.inflate (R.layout.item, viewGroup,false);        MyViewHolder viewHolder =newMyViewHolder (view);returnviewHolder;    }/**    * 建立起MyViewHolder中视图与数据的关联    *@paramviewHolder    *@paramposition    */@OverridepublicvoidonBindViewHolder(finalMyViewHolder viewHolder,finalintposition){        viewHolder.mTextView.setText (mDataset.get (position));        setUpItemEvent (viewHolder);    }//    设置item的回调protectedvoidsetUpItemEvent(finalMyViewHolder viewHolder){if(mOnItemClickListener !=null) {            viewHolder.itemView.setOnClickListener (newView.OnClickListener () {@OverridepublicvoidonClick(View v){intlayoutPosition = viewHolder.getLayoutPosition ();                    mOnItemClickListener.onItemClick (viewHolder.itemView, layoutPosition);                }            });            viewHolder.itemView.setOnLongClickListener (newView.OnLongClickListener () {@OverridepublicbooleanonLongClick(View v){intlayoutPosition = viewHolder.getLayoutPosition ();                    mOnItemClickListener.onItemLongClick (viewHolder.itemView, layoutPosition);returnfalse;                }            });        }    }/**    * 获取item的数目    *@return*/@OverridepublicintgetItemCount(){returnmDataset.size ();    }publicvoidaddData(intposition){        mDataset.add (position,"Insert one");        notifyItemInserted (position);    }publicvoidremoveData(intposition){        mDataset.remove (position);        notifyItemRemoved (position);    }//自定义的ViewHoder,持有item的所有控件publicstaticclassMyViewHolderextendsRecyclerView.ViewHolder{        TextView mTextView;publicMyViewHolder(View view){super(view);            mTextView = (TextView) view.findViewById(R.id.text);        }    }}

    可以看到,我们给适配器提供了一个OnItemClickListener的接口,里面封装了两个回调方法分别是onItemClick(点击)和onItemLongClick(长按)。接着提供setOnItemClickListener方法让activity可以去监听它的回调方法。最后在onBindViewHolder中设置这两个回调方法。

    这样就可以在activity中去监听这两个回调方法啦,我们在onCreate方法中添加如下代码:

    mAdapter.setOnItemClickListener (newTestAdapter.OnItemClickListener () {@OverridepublicvoidonItemClick(View view,intposition){                Toast.makeText (MainActivity.this,"你点击了第"+ position +"个item",                        Toast.LENGTH_SHORT).show ();            }@OverridepublicvoidonItemLongClick(View view,intposition){                mAdapter.removeData (position);            }        });

    代码很简单,当我们点击一个item时,会弹出一个Toast,而当我们长按一个item则会删除该item。

    别忘了,我们的瀑布流布局与其他布局是不同的activity和adapter,我们还需要修改它们的代码。

    StaggeredGridActivity中和MainActivity需要添加的代码是一样的,而StagggeredAdapter也可以继承我们的TestAdapter,保留其特有的属性和方法就行了,StagggeredAdapter修改后的代码如下:

    packagecom.wuminmiao.recycleviewtest;importandroid.content.Context;importandroid.view.ViewGroup;importjava.util.ArrayList;importjava.util.List;/**

    * Created by wmm on 2016/10/13.

    */publicclassStagggeredAdapterextendsTestAdapter{privateList mHeight;//提供一个合适的构造方法publicStagggeredAdapter(Context context, List dataset){super(context, dataset);        mHeight =newArrayList ();for(inti =0; i < mDataset.size (); i++) {            mHeight.add ((int) (100+ Math.random ()*300));        }    }/**    * 建立起MyViewHolder中视图与数据的关联    *@paramviewHolder    *@paramposition    */@OverridepublicvoidonBindViewHolder(MyViewHolder viewHolder,intposition){        viewHolder.mTextView.setText(mDataset.get (position));        ViewGroup.LayoutParams lp  = viewHolder.itemView.getLayoutParams ();        lp.height = mHeight.get (position);        viewHolder.itemView.setLayoutParams (lp);        setUpItemEvent (viewHolder);    }}

    还有一点要注意的是,如果现在运行程序的话,当我们点击item时它的颜色是不会变化的,这样的用户体验肯定很差,我们需要给它优化一下。

    首先,在drawable中新建一个xml文件,就叫做bg_item吧:

    接着在values/colors.xml中指定其颜色:

    #3F51B5#303F9F#FF4081#728cd4#add8e6

    我们给默认的item和点击后的item设置了不同的颜色,这样体验效果应该会好一点。

    现在,就可以运行我们的程序啦,效果如下:

    相关文章

      网友评论

          本文标题:RecyclerView 使用及真实案例

          本文链接:https://www.haomeiwen.com/subject/irdlgxtx.html