本菜开源的一个自己写的Demo,希望能给Androider们有所帮助,水平有限,见谅见谅…
https://github.com/zhiaixinyang/PersonalCollect (拆解GitHub上的优秀框架于一体,全部拆离不含任何额外的库导入)
https://github.com/zhiaixinyang/MyFirstApp(Retrofit+RxJava+MVP)
感兴趣的看官,可以看看我的其他文章:
1、常用集合的源码分析:HashMap
2、Java反射实践:从反射中理解class
3、从公司项目配置看Gradle
写在前面
最近抽到了音乐组去给音乐组大佬们干些杂活,端茶送水捏捏肩啥的...
给我安排的活是重构音乐的锁屏页,所以本来是想记一记锁屏的相关内容,但是后来想了想还是等锁屏重构review过后再记录吧,免得review如果有什么更好的建议也不用再回过来改动了。所以这次记录一个我觉得很有趣的点:
因为现阶段的音乐项目需要大量的列表去展示歌曲,所以势必要用到RecyclerView或是ListView,大量的复用势必要引起封装,在我没有看到代码的时候,我以为是常规的对Adapter之类的进行封装,减少重复的Adapter的操作过程。后来看了代码才发现并没有这样而是提供了一个全新的角度和思路。
直接去封装界面的基类,在基类中进行List的展示,如果其他界面需要List的效果,直接继承,如果需要特殊的展示效果,提供全新的Adapter;总的来说就是需要什么就重写什么,如果不需要,那就直接继承走封装的界面逻辑...
还是让我们直接上代码。
开始:
1、常规的Adapter封装(BaseAdapter)
在看公司的BaseAdapter(继承自RecyclerView.Adapter)的时候,发现并没有进行比较常见的Adapter,个人猜测主要是为了更好的去拓展业务。因为Item样式的多变并没有进行对Adapter中的onBindViewHolder方法的封装。
而是仅做了一些notifyItemRemoved
,notifyDataSetChanged
, notifyItemInserted(position)
这类方法的封装。所以BaseAdapter并没有什么操作。
2、常规的Adapter封装(BaseListAdapter)
下一层Adapter是BaseListAdapter,毫无疑问继承至BaseAdapter。而这里边封装了一些界面风格一致的Item,也就是说在设计师给出的Item样式相同是可以直接使用BaseListAdapter。事实上通过后续的封装,如果设计师的Item样式没有变化,Adapter这个步骤变得异常的方便...让我们往下看。
3、Fragment封装(BaseListFragment)
关于Adapter的封装并未涉及什么巧妙的设计在里边,唯一需要注意的地方就是在BaseListAdapter之中封装了常用设计风格的Item。
BaseListFragment之中,考虑了一些情况:
1、对外暴露方法,动态改变LayoutManager
2、对外暴露方法,动态改变Item的样式
3、对外暴露方法,可以监听到滑动状态
这三个方法都比较好处理,直接把这些方法abstract出去。
1、比如:因为Adapter是必需要提供的,所以进行了abstract必须要实现
protected abstract BaseAdapter newContentAdapter();
2、比如:这里如果需要新的LayoutManager,重写这个方法return一个自己的LayoutManager即可。
protected RecyclerView.LayoutManager newLayoutManager() {
return new LinearLayoutManager(getActivity(), LinearLayoutManager.VERTICAL, false);
}
3、比如:这里是对应RecyclerView的滑动回调的重写方法。这里封装的时候用的是Rx,因此这个RecyclerViewScrollEvent是Rxbinding里边的类。
protected void onRecyclerViewScrolled(RecyclerView recyclerView, RecyclerViewScrollEvent event) {}
protected void onRecyclerViewScrollStateChanged(RecyclerView recyclerView, int newState) {}
Rxbinding的方法:
Subscription scrollEventSubscribe = RxRecyclerView.scrollEvents(mRecyclerView)
.subscribe(new SafeAction1<RecyclerViewScrollEvent>() {
@Override
public void call(RecyclerViewScrollEvent recyclerViewScrollEvent) {
onRecyclerViewScrolled(mRecyclerView, recyclerViewScrollEvent);
//省略部分代码
}
}
在这里回调了我们的onRecyclerViewScrolled()
,不用Rxbinding也没啥不一样,无非是换成了addOnScrollListener
对应处理一下即可:
.addOnScrollListener(new RecyclerView.OnScrollListener() {
@Override
public void onScrollStateChanged(RecyclerView recyclerView, int newState) {
super.onScrollStateChanged(recyclerView, newState);
}
@Override
public void onScrolled(RecyclerView recyclerView, int dx, int dy) {
super.onScrolled(recyclerView, dx, dy);
}
});
其实这里边还涉及到了对Header的封装,不过设计的内容比较多:ItemDecoration,Buidler等,所以暂时本篇就不展开了。
BaseListFragment整体的封装思路:说白了就是处理大多数的通用情况,然后把拓展性高的业务暴露出去。
而我们如果想要使用的话:只需要继承BaseListFragment,BaseListAdapter...接下来让我们看一下对封装的使用。
使用:
如果当我想要写的界面,所展示的List的Item效果已经被封装到BaeListAdapter之中的时候,我所需要做的就是:
- 1、继承BaseListFragment:
public class PlaylistFragment extends BaseListFragment
- 2、继承BaseListAdapter:
//因为这里我们的Item效果已经封装好了,所以就不需要重写onBindItemViewHolder等方法
public class PlayListAdapter extends BaseListAdapter
- 3、重写newContentAdapter,return自己实现的Adapter
完成上诉3步,一个正常的列表就可以显示了。省掉我们写自己的布局的时间。
这里还有一个好用的封装就是添加Header,我们只需要初始化我们想要展示的Header布局,然后调用封装在BaseListFragment中的mHeaderAdapter.addHeader()
方法即可。当然这里边涉及到的疯转本次文章是没办法展开了,下次下次....
此外,如果我们想要处理滑动事件啊,LayoutManager,只需要复写上边提到的对外暴露的三个方法即可。
总结
其实这套思路适用在列表展示比较规格化的情况,如果嵌套十分严重,并不好进行套用。但是反过来,如果嵌套比较严重其实对应封装反而有些画蛇添足。因为复杂的业务本身就是特别且独立,个人认为这种业务并不适合封装,反而是那些重复、规模化的东西才适合进行封装。
这里记录这套业务的封装并不是为了以后的套用,而是记录一种思想。
就像我的实习导师问过我:“公司做过的大大小小的项目不知道你看过没有,你对构架上有什么看法...”
“导师写的就是吊,其他写的都是渣...”
“我们做的很多项目设计都是滞后的,很多代码都是为了业务而去写,大多数的封装还是架构都是基于业务层面的。所以一切的是基础认真写业务,业务写多了,架构自然会出来。”
2016/10/12这是项目的开始时间,也就是说这种业务封装思想是在于1年之前,时间上可能比较老,但是带来的思路确是新的。
尾声
第一次在简书上写文章,之前都是在CSDN上,这边文章算是我实习以来第一次对公司项目的梳理。以后会有更多的关于公司项目的学习和思考记录,因为公司的大佬太多...能学习总结记录的也太多...
最后希望各位看官可以star我的GitHub,三叩九拜,满地打滚求star:
https://github.com/zhiaixinyang/PersonalCollect
https://github.com/zhiaixinyang/MyFirstApp
2018年7月2号,我正式开始了自己的Android工作,为了能够让自己能够好好完成工作,并且能够快速得到技术提升。所以打算以公众号的方式去敦促自己学习,我会把自己日常的学习笔记发布到公众号上,如果可以,共同进步!~
个人公众号