电脑知识|欧美黑人一区二区三区|软件|欧美黑人一级爽快片淫片高清|系统|欧美黑人狂野猛交老妇|数据库|服务器|编程开发|网络运营|知识问答|技术教程文章 - 好吧啦网

您的位置:首頁技術文章
文章詳情頁

Android Jetpack- Paging的使用詳解

瀏覽:19日期:2022-09-21 18:22:35

Google 推出 Jetpack 組件化已經有相當一段時間了。各種組件也層出不窮。

Jetpack 的東西也不少,

Android Jetpack- Paging的使用詳解

今天就搞一下這個 Paging

Paging 的出現,就是用作列表的分頁加載。其實現在已經有非常多成熟高效的開源列表加載控件了,比如:Smartrefreshlayout等。但Google推出的,必然有它的有點,當然也有它的局限性。

先說優點吧,Paging 的使用,需要配合ViewModle,LiveData等控件,數據的請求感知并綁定頁面的生命周期,避免了內存泄漏。還需要綁定DataSource和DataSource的Factory,能無痕加載更多數據,一定程度上提高用戶體驗。

主要流程是:

1:自定義 PositionalDataSource,里面的功能是進行數據分頁請求。

2:自定義 DataSource.Factory,把 PositionalDataSource 綁定 LiveData

3:Activity 自定義 ViewModel,把 PositionalDataSource 和 Factory 綁定,讓 ViewModel 感知數據的變化

4:ViewModel感知數據的變更,并更新 PagedListAdapter 的 submitList。

最先看看導入那些依賴:

implementation 'androidx.paging:paging-runtime:3.0.0-alpha04' implementation ’androidx.recyclerview:recyclerview:1.1.0’ implementation ’com.squareup.retrofit2:retrofit:2.9.0’ implementation 'android.arch.lifecycle:extensions:1.1.1'

【1】先看 Activity 代碼:

class MainActivity : AppCompatActivity() { override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) setContentView(R.layout.activity_main) val myPagedListAdapter = MyPagedListAdapter() recyclerView.layoutManager = LinearLayoutManager(this) recyclerView.adapter = myPagedListAdapter /** * ViewModel 綁定 Activity 生命周期 * */ val myViewModel = ViewModelProviders.of(this).get(MyViewModel::class.java) /** * ViewModel 感知數據變化,更新 Adapter 列表 * */ myViewModel.getConvertList().observe(this, Observer { myPagedListAdapter.submitList(it) }) } }

【2】看 Adapter代碼:

這里要用的是 PagedListAdapter,其實它是繼承了 RecyclerView.Adapter 的,所以用起來沒和 RecyclerView.Adapter 多大區別,就是多了一個內部需要實現 DiffUtil.ItemCallback 來。具體 DiffUtil.ItemCallback 的原理就不在這說了,博主也沒有細究,它是用來比較數據的。其內部實現方法也基本上可以寫死。

class MyPagedListAdapter extends PagedListAdapter<MyDataBean, MyViewHolder> { private static DiffUtil.ItemCallback<MyDataBean> DIFF_CALLBACK = new DiffUtil.ItemCallback<MyDataBean>() { @Override public boolean areItemsTheSame(MyDataBean oldConcert, MyDataBean newConcert) { // 比較兩個Item數據是否一樣的,可以簡單用 Bean 的 hashCode來對比 return oldConcert.hashCode() == newConcert.hashCode(); } @Override public boolean areContentsTheSame(MyDataBean oldConcert, MyDataBean newConcert) { // 寫法基本上都這樣寫死即可 return oldConcert.equals(newConcert); } }; public MyPagedListAdapter() { // 通過 構造方法 設置 DiffUtil.ItemCallback super(DIFF_CALLBACK); } @NonNull @Override public MyViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) { View inflate = LayoutInflater.from(parent.getContext()).inflate(R.layout.item_my, parent, false); return new MyViewHolder(inflate); } @Override public void onBindViewHolder(@NonNull MyViewHolder holder, int position) { // getItem() 是 PagedListAdapter 內部方法,通過此方法可以獲取到對應位置Item 的數據 holder.bindData(getItem(position)); } }

順便也把 ViewHolder 和 MyDataBean 貼一下

ViewHolder :

class MyViewHolder(val itemV: View) : RecyclerView.ViewHolder(itemV) { fun bindData(data: MyDataBean) { itemV.findViewById<TextView>(R.id.tvNum).text = data.position.toString() if (data.position % 2 == 0){ itemV.findViewById<TextView>(R.id.tvNum).setBackgroundColor(itemV.context.resources.getColor(R.color.colorAccent)) }else{ itemV.findViewById<TextView>(R.id.tvNum).setBackgroundColor(itemV.context.resources.getColor(R.color.colorPrimaryDark)) } }}

MyDataBean :

data class MyDataBean(val position: Int)

【3】看 DataSource 代碼:

PositionalDataSource,里面的功能是進行數據分頁請求。

需要實現兩個方法:

loadInitial():第一次打開頁面,需要回調此方法來獲取數據

loadRange(): 當有了初始化數據之后,滑動的時候如果需要加載數據的話,會調用此方法。

class MyDataSource : PositionalDataSource<MyDataBean>() { /** * 第一次打開頁面,需要回調此方法來獲取數據 * */ override fun loadInitial(params: LoadInitialParams, callback: LoadInitialCallback<MyDataBean>) { // 獲取網絡數據 val list = getData(params.requestedStartPosition, params.pageSize) /** * 這個方法是返回數據,讓 綁定ViewModel 感知。 這里要用對方法 * @param1 數據列表 * @param2 數據為起始位置 * @param3 數據列表總長度,這個一定要設置好哦,如果設置了50, * 當列表的長度為50時,列表再也無法出發 loadRange() 去加載更多了 * 如果不知道列表總長度,可以設置 Int 的最大值 999999999 * 這里設置 10000 * */ callback.onResult(list, 0, 10000) } /** * 當有了初始化數據之后,滑動的時候如果需要加載數據的話,會調用此方法。 * */ override fun loadRange(params: LoadRangeParams, callback: LoadRangeCallback<MyDataBean>) { /** * params.startPosition 列表需要從 startPosition 加載更多 * params.loadSize 列表需要從 startPosition 加載長度 為 loadSize的數據 * */ val list = getData(params.startPosition, params.loadSize) callback.onResult(list) } /** * 模擬網絡獲取數據 * */ private fun getData(startPosition: Int, pageSize: Int): MutableList<MyDataBean> { Handler(Looper.getMainLooper()).post { Toast.makeText( MyApplication.instant, '加載數據 從 $startPosition 加載到 ${startPosition + pageSize}', Toast.LENGTH_SHORT ).show() } val list = mutableListOf<MyDataBean>() for (i in startPosition until startPosition + pageSize) { list.add(MyDataBean(i)) } return list }}

【4】看 DataSource.Factory代碼:

把 PositionalDataSource 綁定 LiveData

class DataFactory: DataSource.Factory<Int, MyDataBean>() { private val mSourceLiveData: MutableLiveData<MyDataSource> = MutableLiveData<MyDataSource>() override fun create(): DataSource<Int, MyDataBean> { val myDataSource = MyDataSource() mSourceLiveData.postValue(myDataSource) return myDataSource } }

【5】最后看 ViewModel代碼:

class MyViewModel : ViewModel() { private var mDataSource : DataSource<Int, MyDataBean> private var mDataList: LiveData<PagedList<MyDataBean>> init { // 把 PositionalDataSource 和 Factory 綁定,讓 ViewModel 感知數據的變化 var dataFactory = DataFactory() mDataSource = dataFactory.create() /** * @param1 dataFactory 設定 dataFactory * @param2 設定每一次加載的長度 * 這個和 PositionalDataSource 回調方法 loadSize 一致的 * */ mDataList = LivePagedListBuilder(dataFactory, 20).build() } // 暴露方法,讓Activity 感知數據變化,去驅動 Adapter更新列表 fun getConvertList(): LiveData<PagedList<MyDataBean>> { return mDataList }}

【5】最后再看一下 Activity 代碼:

class MainActivity : AppCompatActivity() { override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) setContentView(R.layout.activity_main) val myPagedListAdapter = MyPagedListAdapter() recyclerView.layoutManager = LinearLayoutManager(this) recyclerView.adapter = myPagedListAdapter /** * ViewModel 綁定 Activity 生命周期 * */ val myViewModel = ViewModelProviders.of(this).get(MyViewModel::class.java) /** * ViewModel 感知數據變化,更新 Adapter 列表 * */ myViewModel.getConvertList().observe(this, Observer { myPagedListAdapter.submitList(it) }) } }

貼一下 activity_main.xml 的代碼

<?xml version='1.0' encoding='utf-8'?><androidx.constraintlayout.widget.ConstraintLayout xmlns:android='http://schemas.android.com/apk/res/android' xmlns:app='http://schemas.android.com/apk/res-auto' xmlns:tools='http://schemas.android.com/tools' android:layout_width='match_parent' android:layout_height='match_parent' tools:context='.MainActivity'> <androidx.recyclerview.widget.RecyclerView android: android:layout_width='0dp' android:layout_height='0dp' app:layout_constraintLeft_toLeftOf='parent' app:layout_constraintRight_toRightOf='parent' app:layout_constraintTop_toTopOf='parent' app:layout_constraintBottom_toBottomOf='parent'> </androidx.recyclerview.widget.RecyclerView> </androidx.constraintlayout.widget.ConstraintLayout>

運行一下看一下效果:

Android Jetpack- Paging的使用詳解

運行成功,沒有問題。

最開始說Paging有缺點,其實Paging是沒有下拉刷新的,只有上拉加載更多功能。這個并不滿足很多列表場合。

但是如果只需要上拉加載更多的話,Paging還是推薦使用的,畢竟是Google提供的。

上面代碼親測沒問題,有問題請留言。

代碼地址:https://github.com/LeoLiang23/PagingDemo.git

到此這篇關于Android Jetpack- Paging的使用詳解的文章就介紹到這了,更多相關Android Jetpack Paging內容請搜索好吧啦網以前的文章或繼續瀏覽下面的相關文章希望大家以后多多支持好吧啦網!

標簽: Android
相關文章:
主站蜘蛛池模板: 紧急切断阀_气动切断阀_不锈钢阀门_截止阀_球阀_蝶阀_闸阀-上海上兆阀门制造有限公司 | 桂林腻子粉_内墙外墙抗裂砂浆腻子粉推荐广西鑫达涂料厂家供应 | 手持气象站_便携式气象站_农业气象站_负氧离子监测站-山东万象环境 | BOE画框屏-触摸一体机-触控查询一体机-触摸屏一体机价格-厂家直销-触发电子 | 河南生物显微镜,全自动冰冻切片机-河南荣程联合科技有限公司 | 山西3A认证|太原AAA信用认证|投标AAA信用证书-山西AAA企业信用评级网 | 土壤检测仪器_行星式球磨仪_土壤团粒分析仪厂家_山东莱恩德智能科技有限公司 | 锂电池砂磨机|石墨烯砂磨机|碳纳米管砂磨机-常州市奥能达机械设备有限公司 | 背压阀|减压器|不锈钢减压器|减压阀|卫生级背压阀|单向阀|背压阀厂家-上海沃原自控阀门有限公司 本安接线盒-本安电路用接线盒-本安分线盒-矿用电话接线盒-JHH生产厂家-宁波龙亿电子科技有限公司 | 金属管浮子流量计_金属转子流量计厂家-淮安润中仪表科技有限公司 | 沈阳庭院景观设计_私家花园_别墅庭院设计_阳台楼顶花园设计施工公司-【沈阳现代时园艺景观工程有限公司】 | 山东商品混凝土搅拌楼-环保型搅拌站-拌合站-分体仓-搅拌机厂家-天宇 | 刚性-柔性防水套管-橡胶伸缩接头-波纹管补偿器-启腾供水材料有限公司 | 复合土工膜厂家|hdpe防渗土工膜|复合防渗土工布|玻璃纤维|双向塑料土工格栅-安徽路建新材料有限公司 | 贵州科比特-防雷公司厂家提供贵州防雷工程,防雷检测,防雷接地,防雷设备价格,防雷产品报价服务-贵州防雷检测公司 | 广州展览制作工厂—[优简]直营展台制作工厂_展会搭建资质齐全 | 地磅-地秤-江阴/无锡地磅-江阴天亿计量设备有限公司_ | 净化车间_洁净厂房_净化公司_净化厂房_无尘室工程_洁净工程装修|改造|施工-深圳净化公司 | 铝镁锰板厂家_进口钛锌板_铝镁锰波浪板_铝镁锰墙面板_铝镁锰屋面-杭州军晟金属建筑材料 | 利浦顿蒸汽发生器厂家-电蒸汽发生器/燃气蒸汽发生器_湖北利浦顿热能科技有限公司官网 | 耐火浇注料-喷涂料-浇注料生产厂家_郑州市元领耐火材料有限公司 耐力板-PC阳光板-PC板-PC耐力板 - 嘉兴赢创实业有限公司 | 点焊机-缝焊机-闪光对焊机-电阻焊设备生产厂家-上海骏腾发智能设备有限公司 | 镀锌角钢_槽钢_扁钢_圆钢_方矩管厂家_镀锌花纹板-海邦钢铁(天津)有限公司 | 污水处理设备,一体化泵站,一体化净水设备-「梦之洁环保设备厂家」 | 影像测量仪_三坐标测量机_一键式二次元_全自动影像测量仪-广东妙机精密科技股份有限公司 | 全自动翻转振荡器-浸出式水平振荡器厂家-土壤干燥箱价格-常州普天仪器 | 高柔性拖链电缆-聚氨酯卷筒电缆-柔性屏蔽电缆厂家-玖泰电缆 | 不锈钢监控杆_监控立杆厂家-廊坊耀星光电科技有限公司 | 手持式3d激光扫描仪-便携式三维立体扫描仪-北京福禄克斯 | 一体式钢筋扫描仪-楼板测厚仪-裂缝检测仪-泰仕特(北京) | 校服厂家,英伦校服定做工厂,园服生产定制厂商-东莞市艾咪天使校服 | 胶辊硫化罐_胶鞋硫化罐_硫化罐厂家-山东鑫泰鑫智能装备有限公司 意大利Frascold/富士豪压缩机_富士豪半封闭压缩机_富士豪活塞压缩机_富士豪螺杆压缩机 | 北京租车公司_汽车/客车/班车/大巴车租赁_商务会议/展会用车/旅游大巴出租_北京桐顺创业租车公司 | 深圳品牌设计公司-LOGO设计公司-VI设计公司-未壳创意 | 电动手术床,医用护理床,led手术无影灯-曲阜明辉医疗设备有限公司 | 锂电池砂磨机|石墨烯砂磨机|碳纳米管砂磨机-常州市奥能达机械设备有限公司 | CE认证_产品欧盟ROHS-REACH检测机构-商通检测 | 废气处理设备-工业除尘器-RTO-RCO-蓄热式焚烧炉厂家-江苏天达环保设备有限公司 | 杭州中央空调维修_冷却塔/新风机柜/热水器/锅炉除垢清洗_除垢剂_风机盘管_冷凝器清洗-杭州亿诺能源有限公司 | 信阳网站建设专家-信阳时代网联-【信阳网站建设百度推广优质服务提供商】信阳网站建设|信阳网络公司|信阳网络营销推广 | 真石漆,山东真石漆,真石漆厂家,真石漆价格-山东新佳涂料有限公司 |