大家好,郭老司机又来了。以前看文章的小喵同志,现在终于体会到码字的不易了。作为一个沉默寡言的程序员,深深的佩服那些写过无数码字的前辈们((/--)/。RecylerView相信大家都听过但是(你一定要说没听过==),在ListView时代风靡一时,RecyclerView背负着褒贬不一的评价开始进入我们的视线。当时刚开始一个新项目,刚好拿来练习。不错。下面进入介绍过程。建议从demo开始。(??-??)通常情况下,对于每一个不同的列表,我们往往需要实现不同的Adapter来处理相应的逻辑,这导致我们有很多重复的代码。在代码优化的驱动下(惰性),我个人实现了一个通用的Adapter,后面说的Holder可以理解为列表中的一个Item,属于它的逻辑处理类,一种Item有一种Holder,你只需要一个Adapter,你就可以实现各种类型的列表,comp兼容不同类型的列表Item,只需要维护你的Holder(类似ListinOneItem)和Model,无需关心其他,高复用和多样式逻辑,外部支持自定义动画,多种上拉下拉实现方式,无需编写任何Adapter代码(^o^)/。1.CommonRecyclerManager:绑定layoutId和你的Holder类名。该管理类用于绑定Holder和R.layout.xxx,以便后面的CommonRecyclerAdapter通过数据Model的layoutId来找到对应的Holder并创建。//将布局的ID与容器类型相关联commonRecyclerManager.addType(TextHolder.ID,TextHolder.class.getName());2.RecyclerBaseHolder:继承这个Holder,满足你的需求。RecyclerBaseHolder的所有Holders的基类,它继承了RecyclerView.ViewHolder,定义并写了两个方法,所以你继承就对了,creatView的时候找控件,onBind的时候读取数据填屏。这里就是你实现梦想的地方!//实现的hodler继承RecyclerBaseHolder,重载如下方法满足你的需求publicclassTextHolderextendsRecyclerBaseHolder{//Layoutid,一般我习惯这个Holder需要处理的id都写在这里易于管理,v);}/iew被创建,更多的数据处理逻辑@OverridepublicvoidonBind(RecyclerBaseModelmodel,intposition){//转换为你的modelTextModeltextModel=(TextModel)(model);itemText.setText(textModel.getText());}//你不需要写@OverridepublicAnimatorSetgetAnimator(Viewview){//实现你的动画returnnull;}}3.CommonRecyclerAdapter:一般的adapter只需要传入数据List和CommonRecyclerManager,它会传数据acco的layoutId根据Model的顺序,RecyclerView中会自动生成对应的Holder,其他功能只需要简单配置即可。//创建带数据的adapter和manageradapter=newCommonRecyclerAdapter(getActivity(),commonRecyclerManager,datas);//支持需要加载更多的adapter.setNeedLoadMore(true);//支持空数据显示空页adapter.setShowNoData(true);//设置项目显示动画支持以启用adapter.setNeedAnimation(true);4.RecyclerBaseModel:数据模型的积累,一定要继承它,永远不要抛弃它。继承它的作用是因为整个Adapter都是基于它的,所以需要继承它。最后还需要Model对应的layoutId,让它找到自己的Holder。//继承RecyclerBaseModel实现你需要的数据类型继承RecyclerBaseHolder,这里就是你实现你的需求的地方,相当于Item的逻辑。2.让你的数据模型继承RecyclerBaseModel,设置Model的LayoutId(很重要),这样模型会通过CommonRecyclerManager找到与LayoutId关联的Holder,并生成。3.你需要一个CommonRecyclerManager来绑定你的LayoutId和处理这个布局的Holder类名。4.通过CommonRecyclerManager和Model的数据列表生成CommonRecyclerAdapter。5.将适配器交给回收商。逻辑似乎有点复杂?其实就是model的LayoutId,CommonRecyclerManager关联到它的Holder。这样我们只需要根据数据列表中的数据设置不同的LayoutId模型,Adapter就会自动匹配对应的Holder。这样<( ̄︶ ̄)>只需要实现Holder,组装好Model,不用写Adapter逻辑就可以使用任意列表。Adapter会根据model的顺序自动生成对应的Holder,同一个Holder可以绑定不同的LayoutId。以后你只需要维护和兼容你的Holder。您的持有人逻辑在每个列表中都很常见。是即时代码吗?干净多了?下拉刷新上拉加载更多常用列表,直接使用系统的SwipeRefreshLayout即可,简单易用。下拉加载更多直接添加下面的方法,轻松实现上下拉刷新<( ̄︶ ̄),简单粗暴,记得加个锁,避免重复进入。//开启支持需要加载更多adapter.setNeedLoadMore(true);recycler.addOnScrollListener(newLoadMoreScrollListener(){@OverridepublicvoidonLoadMore(){//注意加锁}},2000);}}//哪个项目是当前最后可见的项目@OverridepublicvoidonScrolled(intfirstPosition){}});还可以配置其他配置配置是否显示动画效果,配置上拉加载的颜色,点击和长按等,见下文。//支持空数据显示空页adapter.setShowNoData(true);//显示空数据模型,不设置显示默认空页adapter.setNoDataModel(noDataModel);//显示空数据页面布局,不设置显示默认,layoutid需要通过CommonRecyclerManager关联hodleadapter.setNoDataLayoutId(noDataLayoutId);//设置动画支持开启adapter.setNeedAnimation(true);//添加点击adapter.setOnItemClickListener();XRecyclerView兼容性支持XRecyclerView在这里添加和修改。XRecyclerView内置了一个内部Adapter,支持添加header和带有上拉下拉效果的控件。经过一些调整,完全支持CommonRecyclerAdapter。无需监听滑动,无需SwipeRefreshLayout,轻松添加刷新加载更多。而且,它支持动态配置和各种风格的上下。具体来说,ProgressStyle下有多种支持配置,解决了Adapter对瀑布上拉的支持不够兼容的问题。这里的用法和普通的RecyclerView一样,支持与CommonRecyclerAdapter的配合,也支持空页显示,也支持添加各种header。唯一需要注意的是,在添加分界线类addItemDecoration和点击的时候,需要将头部添加上去,将刷新后的绝对位置转换成相对位置。在这里我曾经自己哭过╥﹏╥...下面看代码。//是否屏蔽下拉//xRecycler.setPullRefreshEnabled(false);//上拉加载更多样式,也可以设置下拉xRecycler.setLoadingMoreProgressStyle(ProgressStyle.SysProgress);//设置管理器,关联布局和holder类名不同id可以管理一个holderCommonRecyclerManagercommonRecyclerManager=newCommonRecyclerManager();commonRecyclerManager.addType(ImageHolder.ID,ImageHolder.class.getName());commonRecyclerManager.addType(TextHolder.ID,TextHolder.class.getName());commonRecyclerManager.addType(ClickHolder.ID,ClickHolder.class.getName());//初始化总管commonRecyclerAdapter=newCommonRecyclerAdapter(getActivity(),commonRecyclerManager,dataList);xRecycler.setAdapter(commonRecyclerAdapter);ImageViewimageView=newImageView(getActivity());imageView.setImageResource(R.drawable.xxx1);imageView.setScaleType(ImageView.ScaleType.CENTER_CROP);imageView.setMinimumHeight(dip2px(getActivity(),100));//添加headerxRecycler.addHeaderView(imageView);//也支持设置Emptylocal//xRecycler.setEmptyView();xRecycler.setLoadingListener(newXRecyclerView.LoadingListener(){@覆盖publicvoidonRefresh(){xRecycler.postDelayed(newRunnable(){@Overridepublicvoidrun(){xRecycler.refreshComplete();}},2000);}@OverridepublicvoidonLoadMore(){xRecycler.postDelayed(newRunnable(){@Overridepublicvoidrun(){loadMore();}},2000);}});commonRecyclerAdapter.setOnItemClickListener(newOnItemClickListener(){@OverridepublicvoidonItemClick(Contextcontext,intposition){//你需要减去你的header和刷新view的个数Toast.makeText(getActivity(),"点击!! "+(position-2),Toast.LENGTH_SHORT).show();}});***你已经知道这里的一般用法。详细的内部实现可以通过ViewDEMO。一般逻辑是CommonRecyclerManager与layoutId和Holder类名相关联。CommonRecyclerAdapter通过Model的layoutId找到Holder,然后用layoutId创建view,将View、position、model传入Holder,实现数据填充。layoutId也是*typeid**,注意:使用的时候记得给你的model设置setResLayoutId(),这个最容易忘记。
