为RecyclerView打造通用Adapter.docx
《为RecyclerView打造通用Adapter.docx》由会员分享,可在线阅读,更多相关《为RecyclerView打造通用Adapter.docx(38页珍藏版)》请在冰豆网上搜索。
为RecyclerView打造通用Adapter
为RecyclerView打造通用Adapter
##RecycleView简介
RecyclerView控件和ListView的原理有很多相似的地方,都是维护少量的View来进行显示大量的数据,不过RecyclerView控件比ListView更加高级并且更加灵活。
当我们的数据因为用户事件或者网络事件发生改变的时候也能很好的进行显示。
和ListView不同的是,RecyclerView不用在负责Item显示相关的功能,所有有关布局、绘制、数据绑定等都被分拆成不同的类进行管理。
同时RecyclerView控件提供了以下两种方法来进行简化和处理大数量集合:
1.基本使用
RecycleView的基本使用
RecycleView导包(可有可无)dependencies中添加
compile'com.android.support:
recyclerview-v7:
23.1.1'
在布局文件中定义
android:
id="@+id/rcv_history"
android:
layout_width="match_parent"
android:
layout_height="match_parent">
3.对其进行初始化
rcv_history=(RecyclerView)findViewById(R.id.rcv_history);
4.LinearLayoutManager和GrideLayouManager两种显示风格
//LinearLayoutManager(ListView)
rcv_history.setLayoutManager(new(HistoryActivity.this));
//GridLayoutManager(GrideView)
//第二个参数就是GridView一样一行显示个个数
rcv_history.setLayoutManager(newGridLayoutManager(HistoryActivity.this,2));
rcv_history.setAdapter(Adapter);
创建一个类继承RecycleView.Adapter
5.RecycleView.Adapter==>classHistoryAdapterextendsRecyclerView.Adapter//指定泛型
创建一个类集成RecycleView.ViewHolder()
//返回的是一个Holder
@Override
//i不是下标而是类型如何实现了getItemViewType()//
//onCreateViewHolder加载对应布局,初始化对应的holder,每种布局对应自己的holder
publicHistoryAdapter.MediaHolderonCreateViewHolder(ViewGroupviewGroup,intviewType){
MediaHolderholder=newMediaHolder(LayoutInflater.from(HistoryActivity.this).inflate(R.layout.item_history,null));
Viewview=null;
ViewHolderholder=null;
switch(viewType){case...break}//根据类型的不同加载对应的布局
returnholder;
}
classMediaHolderextendsRecycleView.ViewHolder{
Viewview;
publicMediaHolder(ViewitemView){//构造器itemView列表中的item,类似convertView
super(itemView);
this.view=itemView;//对item布局进行初始化
//textView=itemView.findViewById(R.id.textView);
iv_item_history_icon=(ImageView)itemView.findViewById(R.id.iv_item_history_icon);
tv_item_history_title=(TextView)itemView.findViewById(R.id.tv_item_history_title);
tv_item_history_duration=(TextView)itemView.findViewById(R.id.tv_item_history_duration);
iv_item_history_del=(ImageView)itemView.findViewById(R.id.iv_item_history_del);
}
}
6.//onBindViewHolder绑定对应的holder,加载对应的布局
设置Item的显示//第一个参数onCreateViewHolder中返回的Holder类型第二个参数指定的下标
publicvoidonBindViewHolder(HistoryAdapter.MediaHolderholder,finalintposition){holder.ivitemhistory_icon.setImageResource();}//返回Item的总大小
@OverridepublicintgetItemCount(){if(mediaInfos!
=null){returnmediaInfos.size();
}else{
return0;
}
}
7.自定义RecycleView的监听1.自定义RecycleView2.Adapter里设置监听
1.创建一个接口
publicinterfaceRecycleItemClickListener{
voidonItemClickListener(Viewview,intposition);
}
2.声明变量
RecycleItemClickListenerlistener;
3.set方法
publicvoidsetRecycleItemClickListener(RecycleItemClickListenerrecycleItemClickListener){
this.recycleItemClickListener=recycleItemClickListener;
}
4.实现的地方
//在Hodler中得到itemVidew对象
//this.view=itemView;在ViewHolder个构造器里获得其View
在onBindViewHolder下//在此才有position
publicvoidonBindViewHolder(HistoryAdapter.MediaHolderholder,finalintposition){
holder.view.setOnClickListener(newOnClickListener(){
publicvoidonClick(Viewv){
if(listener!
=null){
listener.onItemClickListener(holder.view,position)
}
}
});
}
5.实现监听
adapter.setRecycleItemClickListener(newRecycleItemClickListener(
publicvoidonItemClickListener(holder.view,position){
//对其进行一系列的操作
}
))
----------------------------------------------------------------------------------------------------------------------------------------------
详细使用
采用LayoutManager来处理Item的布局
提供Item操作的默认动画,例如在增加或者删除item的时候
为了使用RecyclerView控件,我们需要创建一个Adapter和一个LayoutManager:
Adapter:
继承自RecyclerView.Adapetr类,主要用来将数据和布局item进行绑定。
LayoutManager:
布局管理器,设置每一项view在RecyclerView中的位置布局以及控件itemview的显
示或者隐藏。
当View重用或者回收的时候,LayoutManger都会向Adapter来请求新的数据来进行替换原来数据的内容。
这种回收重用的机制可以提供性能,避免创建很多的view或者是频繁的调用findViewById方法。
这种机制和ListView还是很相似的。
RecyclerView提供了三种内置的LayoutManager:
LinearLayoutManager:
线性布局,横向或者纵向滑动列表
GridLayoutManager:
表格布局
StaggeredGridLayoutManager:
流式布局,例如瀑布流效果
优点:
插拔式,高度的解耦,异常灵活
#主要API
LayoutManager:
布局管理器(LinearLayoutManager、GridLayoutManager、StaggeredGridLayoutManager)
ItemDecoration:
绘制Item间的间隔
ItemAnimator:
Item增删的动画
#使用步骤
1.build.gradle中添加
dependencies{
……
compile'com.android.support:
recyclerview-v7:
23.1.1'
}
2.布局内添加
android:
id="@+id/recyclerView"
android:
layout_width="match_parent"
android:
layout_height="match_parent"
>
3.代码中初始化并设置
RecyclerViewrecycleView=findView(R.id.recyclerview);
设置布局管理器
LinearLayoutManagerlinearLayoutManager=newLinearLayoutManager(this);//线性
GridLayoutManagergridLayoutManager=newGridLayoutManager(this,4);//网格
StaggeredGridLayoutManagerstaggeredGridLayoutManager=newStaggeredGridLayoutManager(4,StaggeredGridLayoutManager.VERTICAL);//流式
设置布局管理器的方向
linearLayoutManager.setOrientation(LinearLayoutManager.VERTICAL);
linearLayoutManager.setOrientation(LinearLayoutManager.HORIZONTAL);
设置
recyclerView.setLayoutManager(layout);
recyclerView.setAdapter(adapter);
recyclerView.addItemDecoration(newDividerGridItemDecoration(this));//添加分割线,继承RecyclerView.ItemDecoration
recyclerView.setItemAnimator(newDefaultItemAnimator());//设置默认Item增删动画
#Adapter的实现
1.自定义类继承RecycleView的Adapter同时绑定ViewHolder
classMyAdapterextendsRecyclerView.Adapter
2.实现方法
@Override
publicMyViewHolderonCreateViewHolder(ViewGroupparent,intviewType){
LayoutInflatermInflater=LayoutInflater.from(context);
MyViewHolderholder=newMyViewHolder(mInflater.inflate(
R.layout.item_home,parent,false));
returnholder;
}
@Override
publicvoidonBindViewHolder(MyViewHolderholder,intposition){
holder.tv.setText(mDatas.get(position));
}
@Override
publicintgetItemCount(){
returnmDatas.size();
}
3.MyViewHolder
classMyViewHolderextendsRecyclerView.ViewHolder{
TextViewtv;
publicMyViewHolder(Viewview){
super(view);
tv=(TextView)view.findViewById(R.id.id_num);
}
}
#增删Item的动画
mDatas.add(position,"InsertOne");
notifyItemInserted(position);//增加
mDatas.remove(position);
notifyItemRemoved(position);//删除
#设置点击监听
1.在Adapter中自定义监听
publicinterfaceOnItemClickLitener{
voidonItemClick(Viewview,intposition);
voidonItemLongClick(Viewview,intposition);
}
privateOnItemClickLitenermOnItemClickLitener;
publicvoidsetOnItemClickLitener(OnItemClickLitenermOnItemClickLitener){
this.mOnItemClickLitener=mOnItemClickLitener;
}
2.在onBindViewHolder方法中绑定
if(mOnItemClickLitener!
=null){
holder.itemView.setOnClickListener(newOnClickListener(){
@Override
publicvoidonClick(Viewv){
intpos=holder.getLayoutPosition();
mOnItemClickLitener.onItemClick(holder.itemView,pos);
}
});
holder.itemView.setOnLongClickListener(newOnLongClickListener(){
@Override
publicbooleanonLongClick(Viewv){
intpos=holder.getLayoutPosition();
mOnItemClickLitener.onItemLongClick(holder.itemView,pos);
removeData(pos);
returnfalse;
}
});
}
3.在Activity中设置监听
mAdapter.setOnItemClickLitener(newHomeAdapter.OnItemClickLitener(){
@Override
publicvoidonItemClick(Viewview,intposition){
Toast.makeText(HomeActivity.this,position+"click",
Toast.LENGTH_SHORT).show();
}
@Override
publicvoidonItemLongClick(Viewview,intposition){
Toast.makeText(HomeActivity.this,position+"longclick",
Toast.LENGTH_SHORT).show();
}
});
#分类型的RecycleView
1.MyAdapter继承RecyclerView.Adapter
classMyAdapterextendsRecyclerView.Adapter
2.通过枚举定义不同的Item
//枚举Item
publicenumITEM_TYPE{
ITEM1,
ITEM2,
ITEM3,
ITEM4
}
3.根据不同的Item加载不同的ViewHolder
@Override
publicRecyclerView.ViewHolderonCreateViewHolder(ViewGroupparent,intviewType){
//加载的时候,根据不同的Item加载不同的布局
//Enum类提供了一个ordinal()方法,返回枚举类型的序数,这里ITEM_TYPE.ITEM1.ordinal()代表0,ITEM_TYPE.ITEM2.ordinal()代表1
if(viewType==ITEM_TYPE.ITEM1.ordinal()){
returnnewItem1ViewHolder(layoutInflater.inflate(R.layout.item1,parent,false));
}elseif(viewType==ITEM_TYPE.ITEM2.ordinal()){
returnnewItem2ViewHolder(layoutInflater.inflate(R.layout.item2,parent,false));
}elseif(viewType==ITEM_TYPE.ITEM3.ordinal()){
returnnewItem3ViewHolder(layoutInflater.inflate(R.layout.item3,parent,false));
}else{
returnnewItem4ViewHolder(layoutInflater.inflate(R.layout.item4,parent,false));
}
}
4.根据position返回不同类型的Item
@Override
publicintgetItemViewType(intposition){
if(positionreturnITEM_TYPE.ITEM1.ordinal();
}elseif(positionreturnITEM_TYPE.ITEM2.ordinal();
}elseif(positionreturnITEM_TYPE.ITEM3.ordinal();
}elseif(positionreturnITEM_TYPE.ITEM4.ordinal();
}
returnsuper.getItemViewType(position);
}
5.根据Item的类型设置数据
@Override
publicvoidonBindViewHolder(RecyclerView.ViewHolderholder,intposition){
//根据holder的类型设置数据
if(holderinstanceofItem1ViewHolder){
if(position((Item1ViewHolder)holder).tv1.setText(item1.get(position));
}
}elseif(holderinstanceofItem1ViewHolder){
if(position>item1.size()&&position((Item2ViewHolder)holder).tv2.setText(item2.get(position));
}
}else{
......
}
}
6.返回总数量
@Override
publicintgetItemCount(){
returnitem1.size()+item2.size()+item3.size()+item4.size();
}
7.创建ViewHolder
publicstaticclassItem1ViewHolderextendsRecyclerView.ViewHolder{
TextViewtv;
publicItem1ViewHolder(ViewitemView){
super(item