Collection聚合了项目搭建的一些基本模块,节约开发者时间,协助项目的快速搭建,RecyclerView+Adapter+网络请求+MVP+基本Base,能够满足一个项目的基本实现,框架中暂时还没有把数据库和SharePrefence添加进去,后续会把两者跟网络请求封装在一起的 。
github地址:https://github.com/usernameyangyan/Collection-Android掘金地址:文章目录
1.框架的引入
2.PullToRefreshRecyclerView的使用
框架默认下拉刷新、上拉加载更多样式
自定义下拉刷新、上拉加载更多样式
上拉加载更多结合SwipeRefreshLayout使用
RecyclerView添加头部、空布局
上拉加载更多实现NoMoreData、自动刷新
3.BaseRecyclerViewAdapter的使用
BaseRecyclerViewAdapter比原始Adapter代码量减少
添加Item的点击事件
添加Item的长按事件
多布局的使用
添加拖拽、滑动删除
4.MVP+RxJava+Retrofit的封装使用
框架中的Retrofit+RxJava封装的了解
使用框架在项目需要做的操作
MVP+RxJava+Retrofit+OkHttp的缓存机制
MVP+RxJava+Retrofit+自定义磁盘缓存机制
5.Base的使用
Base封装了MVP和项目的基类
UI状态控制StateView的使用
三步实现Permission(权限)设置
一、框架整体模块
二、框架的引入
implementation 'com.youngman:collectionlibrary:1.1.5'
compile 'com.youngman:collectionlibrary:1.1.5'
Error:Could not find com.android.support:appcompat-v7:27.0.2.
因为library的Support Repository是27.0.2,可能跟项目有所冲突,如果sdk已经装了27还是会出现同样的错误。
解决办法:在项目根build.gradle中加入 maven { url "https://maven.google.com" }
三 、PullToRefreshRecyclerView的使用
1.框架默认下拉刷新、上拉加载更多样式
(1)布局文件
(2)代码设置
2、自定义下拉刷新、上拉加载更多样式
(1)代码设置
(2)自定义刷新和加载更多样式在进行自定义View之前先来了解刷新和加载更多的几种状态:① BasePullToRefreshView刷新:
②BaseLoadMoreView加载更多:
自定义刷新的步骤:①自定义View继承BasePullToRefreshView,重写initView()、setRefreshTimeVisible(boolean show)、destroy()方法:
在initView()做自定义布局、相关动画的初始化,最后在initView()方法的最后面添加以下代码即可。
setRefreshTimeVisible(boolean show)是用来设置是否显示刷新时间控件,在默认刷新样式中通过mRecyclerView.setRefreshTimeVisible(false)即可隐藏刷新时间,如果在自定义的布局中没有这项这个方法就可以忽略。
destroy()是用来关掉改页面时把刷新View的一些动画等释放,防止内存泄漏。
②实现BasePullToRefreshView.OnStateChangeListener监听(重点,主要是进行状态切换后的相关操作逻辑)
在构造函数中
onStateChange的模板样式
自定义加载更多的步骤(包括没有没有更多数据显示的操作):①自定义View继承BaseLoadMoreView,重写initView()、setState()、destroy()方法:
在initView()做自定义布局、相关动画的初始化,最后在initView()方法的最后面添加以下代码即可。
destroy()是用来关掉改页面时把刷新View的一些动画等释放,防止内存泄漏。
在setState()进行状态切换后的相关操作逻辑,模板样式:
②注意:在自定义加载更多样式时,如果需要有没有更多加载更多数据提示同样需要在布局中写好,然后在onSatae中根据状态对加载和没有跟多显示提示进行显示隐藏操作。3、上拉加载更多配合SwipeRefreshLayout使用
(1)布局文件
(2)代码设置
(3)注意的问题
由于PullToRefreshRecyclerView的下拉刷新和下拉加载更多完成时会自动刷新Adapter,而SwipeRefreshLayout刷新完成时需要手动进行notifyDataSetChanged刷新适配器。
4、RecyclerView添加头部、空布局
(1)代码设置
5、上拉加载更多实现NoMoreData、自动刷新
(1)上拉加载更多数据的布局设置在上面的自定义LoadingMoreView中有介绍,如果要显示没有更多数据提示只需要在LoadMore返回数据之后设置:
(2)自动刷新需要列表已经填充了数据之后再做自动刷新操作才会生效:
6、PullToRefreshRecyclerView的其他使用(1)提供的使用方法
(2)刷新、加载更多接口回调,PullToRefreshRecyclerView.OnRefreshAndLoadMoreListener提供一下两个方法:
(3)使用实例部分代码:
①在设置RecyclerView是要设LayoutManager②如果使用PullToRefreshRecyclerView在Activty/Fragment中的onDestroy()调用mRecyclerView.destroy()防止内存泄漏。
四、BaseRecyclerViewAdapter的使用
1.BaseRecyclerViewAdapter的比原始Adapter的代码量减小
在BaseRecyclerViewAdapter中的BaseViewHolder进行布局转化,同时定义了一些比较基本的View操作,使用简单。
(1)使用代码:
①使用者需要在继承BaseRecyclerViewAdapter时传入一个数据实体类型,具体的操作在convert()方法中操作。②BaseViewHolder提供了一些常用View的基本操作,通过baseViewHolder.getView()可得到布局中的控件。(2)BaseRecyclerViewAdapter提供了两个构造函数
主要是对PullToRefreshRecyclerView和RecyclerView的适配,使用时适配器根据需要使用对应的构造函数。2.添加Item的点击和长按事件
(1) Item点击事件实现
(2)Item长按事件实现
(3)也可以实现BaseRecyclerViewAdapter.OnItemClickListener和BaseRecyclerViewAdapter.onItemLongClickListener
3.多布局的使用
https://upload-images.jianshu.io/upload_images/4361802-2a6c0f6834039c2a.gif?imageMogr2/auto-orient/strip
BaseRecyclerViewAdapter的多布局实现需要注意的四步:
①自定义Adapter需要继承BaseRecyclerViewMultiItemAdapter。② 数据实体类需要继承BaseMultiItemEntity,在getItemViewType()返回布局类型。③ 在自定义Adapter中的构造函数中通过addItemType()传入不同类型对应的布局。④在自定义Adapter中的convert进行类型判断,做相对应的操作。
4.添加拖拽、滑动删除
https://upload-images.jianshu.io/upload_images/4361802-110f412fd3c759e0.gif?imageMogr2/auto-orient/strip
局限:只针对RecyclerView,对本框架封装的PullToRefreshRecyclerView会出现混乱。
①BaseRecyclerViewAdapter和BaseRecyclerViewMultiItemAdapter都已经封装支持拖拽、滑动,适配器只需要根据需求继承其中一个即可。②框架提供了一个BaseRecycleItemTouchHelper,对于普通的左右滑动删除、拖拽已经实现,如果想自定义可以继承BaseRecycleItemTouchHelper类,再重写相对应的方法进行实现。④在Activity/Fragment中需要实现以下代码:
⑤BaseRecyclerViewAdapter.OnDragAndDeleteListener进行操作动作完成之后的回调。
注意:需要延时再进行逻辑操作,不然会出现数据混乱。五、MVP+RxJava+Retrofit的封装使用1.框架中的Retrofit+RxJava封装的了解(1)Retrofit:RetrofitManager提供getApiService()和getNoCacheApiService,分别可以获取到可以缓存的retrofit和没有缓存的retrofit,使用第一种在没有网络的时候可以根据缓存进行显示,缓存的相关配置下面会有介绍。(2)RxJava:提供了RxManager、RxObservableListener、RxSchedulers、RxSubscriber。
RxManager:对Observables 和 Subscribers管理。
RxObservableListener:对结果回调。
RxSchedulers:线程切换。
RxSubscriber:Observer的处理事件。
(3)网络请求管理RequestManager:提供对应的请求操作。
loadFormDiskResultListLimitTime():设置缓存时间,没超过设置的时间不请求网络,只返回缓存数据。结果为一个List。
loadFormDiskModeLimitTime():设置缓存时间,没超过设置的时间不请求网络,只返回缓存数据。结果为一个Model。
loadNoNetWorkWithCacheResultList():没有网络再请求缓存。结果为一个List。
loadNoNetWorkWithCacheModel():没有网络再请求缓存。结果为一个Model。
loadOnlyNetWorkSaveResult():把结果保存到本地,根据标志是否返回数据,如果本地存在则不需要下载。
loadOnlyNetWork():只通过网络返回数据。
前面5种请求方式主要是和自定缓存磁盘关联起来,配合RetrofitManager.getNoCacheApiService()使用,loadOnlyNetWork()和RetrofitManager.getApiService()结合使用,这样就可以实现OkHttp缓存和自定义磁盘缓存。2.使用框架在项目需要做的操作在使用Retrofit请求网络之前需要进行配置,在框架中提供了了Config配置类
在项目中需要根据项目需要进行配置,在Application中设置
根据项目需要定义一个通用的数据实体类,这是本例通用实体类
温馨提醒:由于每个项目返回来的json数据格式有所不同,如果Result中代表的字段例如newslist没有内容返回来的时候这个字段需要后台控制不返回,如果不做处理会报解析错误。定义一个ApiService类
3.MVP+RxJava+Retrofit+OkHttp的缓存机制RetrofitManager.getApiService()+RequestManager.loadOnlyNetWork()+缓存配置即可上面的缓存配置完成之后通过以下代码即可:https://upload-images.jianshu.io/upload_images/4361802-e0f0294088db24bd.gif?imageMogr2/auto-orient/strip
4.MVP+RxJava+Retrofit+自定义磁盘缓存机制RetrofitManager.getNoCacheApiService()+RequestManager提供的除了loadOnlyNetWork()的其他数据获取方式即可使用自定义磁盘缓存https://upload-images.jianshu.io/upload_images/4361802-04e2322fc5f515ee.gif?imageMogr2/auto-orient/strip
注意:①通过RequestManager提供的几种请求方式返回来一个DisposableObserver,需要把它通过rxManager.addObserver()添加进CompositeDisposable才能正常执行。②RxObservableListener有三个回调方法
只会重写onNext方法,其它两个方法可以自行选择重写。③RxObservableListener提供两个构造函数
这两个构造函数主要主要是为了统一处理onError的,如果要自定义错误提醒,则可以选择第二个构造函数。六、 Base的使用1.Base封装了MVP和项目的基类(1)MVP
BaseModel
BaseView
BasePresenter
(2)在项目中的网络请求+MVP的完整实现①定义一个contract类,内部分别继承上面的MVP base类,在这里定义操作。
②Presenter的具体执行类。
③Model的具体执行类。
④UI
2.UI Base(1)IBaseActivity
IBaseActivity:主要提供了一个页面的基本方法、处理了MVP之间的关联、使用者可以直接继承该类使用、也可以继承该类实现扩展。
IBaseActivity已经进行MVP之间的传递和关联。
处理好页面销毁之后Observables 和 Subscribers的解绑。
getLayoutId()设置布局、init()数据初始化、requestData()请求数据,执行顺序已经在IBaseActivity做好处理。
可以继承IBaseActivity进行扩展。
缺陷:如果对IBaseActivity进行扩展,在具体调用时需要类型才能调用相关方法。
(2)IBaseFragment
IBaseFragment:主要提供一个页面的基本方法,处理了MVP之间的关联,该类已经加入了懒人加载的控制方式、使用者可以直接继承该类使用、也可以继承该类实现扩展。
IBaseFragment已经进行MVP之间的传递和关联。
处理好页面销毁之后Observables 和 Subscribers的解绑。
加入了懒人加载方式,只有页面显示才会调用requestData()请求数据,并只会调用一次。
getLayoutId()设置布局、init()数据初始化、requestData()请求数据,执行顺序已经在IBaseFragment做好处理。
可以继承IBaseFragment进行扩展。
缺陷:如果对IBaseActivity进行扩展,在具体调用时需要类型才能调用相关方法。
3.UI状态控制StateView的使用
(1)StateView的四种状态:
(2)StateView的使用:①定义一个通用布局
②添加到Ui页面的layout中
注意:上面的语句添加的layout最外层最好是LinearLayout以及设置为android:orientation="vertical"③通过以下语句进行状态切换
④通过以下语句可以修改不同布局的内容以及样式
3.三步实现Permission(权限)设置
(1)设置好要请求的权限
(2)权限通过PermissionManager管理
(3)页面重写onRequestPermissionsResult
注意:如果有需求先判断是否所有权限都已经允许之后再进入主页面可以通过permissionManager.isLackPermission()进行判断,如果返回true则进行权限请求,如果返回false则进入主页面。
多个权限请求如果其中某一个被禁止提醒,会先把没有禁止提醒的权限处理完之后再进行处理。
如果是必要权限被禁止而没有选择禁止提醒退出之后下次会重新请求权限。
如果必要权限被禁止和选择了禁止提醒重新进入页面在onRequestPermissionsResult会重新回调方法。
使用者可以根据onRequestPermissionsResult()方法中返回来的标志PermissionManager.EXIST_NECESSARY_PERMISSIONS_PROHIBTED和PermissionManager.EXIST_NECESSARY_PERMISSIONS_PROHIBTED_NOT_REMIND做出对应的显示和操作(例如弹框提示跳转到设置页面或者toat提示)。
本文章会根据需要持续更新,建议点赞收藏,便于查看。也欢迎大家提出更多建议。
领取专属 10元无门槛券
私享最新 技术干货