分页加载是在应用程序开发过程中十分常见的需求,我们经常需要以列表的方式加载大量的数据,这些数据通常来自网络或本地数据库。然而,如果一次性将所有数据全部加载出来,必然会消耗大量的时间和数据流量,而且用户可能只是需要一部分数据就行。因此,Google便推出了paging组件,来实现分页加载;分页加载就是对数据进行按需加载,在不影响用户体验的同时,还能节省数据流量,提升应用的性能。
网络+数据库:出于用户的体验,通常我们会对网络数据进行缓存,以便用户下次打开应用程序时,应用程序可以先展示缓存数据,我们通常会利用数据库对网络数据进行缓存,但这也意味着我们需要同时处理好网络和数据库这两个数据源。但是,多个数据源会让业务逻辑变得更为复杂,所以我们通常采用单一数据源作为解决方案,即从网络获取的数据,直接缓存进数据库,列表仅从数据库这个唯一的数据源获取数据。
我们以从豆瓣网上获取热度最高的250部电影为例进行讲解,这里我们使用Retrofit+OkHttp进行网络数据的获取,如果对这两个网络请求工具不熟悉的话,可以看这篇博客:https://www.cnblogs.com/luqman/p/okhttp_retrofit.html
这里我们请求的api接口是https://movie.douban.com/j/chart/top_list?type=11&interval_id=100%3A90&action=&start=0&limit=250,接口返回的前五条数据如下所示:
- [{"rating":["9.7","50"],"rank":1,"cover_url":"https://img2.doubanio.com\/view\/photo\/s_ratio_poster\/public\/p480747492.webp","is_playable":true,"id":"1292052","types":["犯罪","剧情"],"regions":["美国"],"title":"肖申克的救赎","url":"https:\/\/movie.douban.com\/subject\/1292052\/","release_date":"1994-09-10","actor_count":25,"vote_count":2912430,"score":"9.7","actors":["蒂姆·罗宾斯","摩根·弗里曼","鲍勃·冈顿","威廉姆·赛德勒","克兰西·布朗","吉尔·贝罗斯","马克·罗斯顿","詹姆斯·惠特摩","杰弗里·德曼","拉里·布兰登伯格","尼尔·吉恩托利","布赖恩·利比","大卫·普罗瓦尔","约瑟夫·劳格诺","祖德·塞克利拉","保罗·麦克兰尼","芮妮·布莱恩","阿方索·弗里曼","V·J·福斯特","弗兰克·梅德拉诺","马克·迈尔斯","尼尔·萨默斯","耐德·巴拉米","布赖恩·戴拉特","唐·麦克马纳斯"],"is_watched":false},{"rating":["9.6","50"],"rank":2,"cover_url":"https://img1.doubanio.com\/view\/photo\/s_ratio_poster\/public\/p2561716440.webp","is_playable":true,"id":"1291546","types":["剧情","爱情","同性"],"regions":["中国大陆","中国香港"],"title":"霸王别姬","url":"https:\/\/movie.douban.com\/subject\/1291546\/","release_date":"1993-07-26","actor_count":28,"vote_count":2150114,"score":"9.6","actors":["张国荣","张丰毅","巩俐","葛优","英达","蒋雯丽","吴大维","吕齐","雷汉","尹治","马明威","费振翔","智一桐","李春","赵海龙","李丹","童弟","沈慧芬","黄斐","徐杰","黄磊","冯远征","杨立新","方征","周璞","隋永清","宋小川","杜广沛"],"is_watched":false},{"rating":["9.6","50"],"rank":3,"cover_url":"https://img2.doubanio.com\/view\/photo\/s_ratio_poster\/public\/p2578474613.webp","is_playable":true,"id":"1292063","types":["剧情","喜剧","爱情","战争"],"regions":["意大利"],"title":"美丽人生","url":"https:\/\/movie.douban.com\/subject\/1292063\/","release_date":"2020-01-03","actor_count":29,"vote_count":1332240,"score":"9.6","actors":["罗伯托·贝尼尼","尼可莱塔·布拉斯基","乔治·坎塔里尼","朱斯蒂诺·杜拉诺","赛尔乔·比尼·布斯特里克","玛丽萨·帕雷德斯","霍斯特·布赫霍尔茨","利迪娅·阿方西","朱利亚娜·洛约迪切","亚美利哥·丰塔尼","彼得·德·席尔瓦","弗朗西斯·古佐","拉法埃拉·莱博罗尼","克劳迪奥·阿方西","吉尔·巴罗尼","马西莫·比安奇","恩尼奥·孔萨尔维","吉安卡尔洛·科森蒂诺","阿伦·克雷格","汉尼斯·赫尔曼","弗兰科·梅斯科利尼","安东尼奥·普雷斯特","吉娜·诺维勒","理查德·塞梅尔","安德烈提多娜","迪尔克·范登贝格","奥梅罗·安东努蒂","沈晓谦","张欣"],"is_watched":false},{"rating":["9.6","50"],"rank":4,"cover_url":"https://img2.doubanio.com\/view\/photo\/s_ratio_poster\/public\/p492406163.webp","is_playable":true,"id":"1295124","types":["剧情","历史","战争"],"regions":["美国"],"title":"辛德勒的名单","url":"https:\/\/movie.douban.com\/subject\/1295124\/","release_date":"1993-11-30","actor_count":49,"vote_count":1110744,"score":"9.6","actors":["连姆·尼森","本·金斯利","拉尔夫·费因斯","卡罗琳·古多尔","乔纳森·萨加尔","艾伯丝·戴维兹","马尔戈萨·格贝尔","马克·伊瓦涅","碧翠斯·马科拉","安德烈·瑟韦林","弗里德里希·冯·图恩","克齐斯茨托夫·拉夫特","诺伯特·魏塞尔","维斯瓦夫·科马萨","布拉德·雅各布维茨","Maciej Orlos","皮奥特·赛尔沃斯","Tadeusz Huk","马丁·塞梅洛格","托马斯·德德克","奥拉夫·卢巴申科","马瑞安·格林卡","约亨·尼克尔","阿格涅兹卡·克鲁科沃娜","阿格尼兹卡·旺格","托马斯·莫里斯","佐久间玲","吴俊全","约阿希姆·保罗·阿斯波克","彭河","戈兹·奥托","玛雅·奥丝塔泽斯卡","Maciej Kozlowski","艾尔文·莱德","Eugeniusz Priwieziencew","Marta Bizon","埃兹拉·达甘","吉恩·莱赫纳","Razia Israeli","拉米·希尔伯格","布兰科·拉斯蒂格","路德格·皮斯特","埃琳娜·勒文松","胡契克·卡勒塔","塔德乌什·布拉德茨基","亨里克·比斯塔","帕维·德朗柯","耶日·诺瓦克","安娜·穆查"],"is_watched":false},{"rating":["9.6","50"],"rank":5,"cover_url":"https://img1.doubanio.com\/view\/photo\/s_ratio_poster\/public\/p1505392928.webp","is_playable":true,"id":"1296141","types":["剧情","犯罪","悬疑"],"regions":["美国"],"title":"控方证人","url":"https:\/\/movie.douban.com\/subject\/1296141\/","release_date":"1957-12-17","actor_count":51,"vote_count":564999,"score":"9.6","actors":["泰隆·鲍华","玛琳·黛德丽","查尔斯·劳顿","埃尔莎·兰彻斯特","约翰·威廉姆斯","亨利·丹尼尔","伊安·沃尔夫","托林·撒切尔","诺玛·威登","尤娜·奥康纳","茹塔·李","贝丝·弗劳尔斯","比尔·厄尔文","J·帕特·奥马利","本·怀特","Paul Kruger","Jack Raine","Paul Power","乔治·佩林","威廉·H·奥布莱恩","奥托拉内史密斯","Frank McClure","Colin Kenny","Jeanne Lafayette","Wilbur Mack","Fred Rapport","利奥达·理查德斯","Glen Walters","Arthur Tovey","伯特史蒂文斯","Cap Somers","Lucille Sewall","斯考特西顿","Norbert Schiller","杰弗里·塞尔","John Roy","Al Roberts","Art Howard","Stuart Hall","Francis Compton","Philip Tonge","帕特里克·艾亨","富兰克林·法纳姆","玛乔丽·伊顿","史蒂夫·卡鲁瑟斯","George Calliga","乔治布鲁格曼","丹尼·鲍沙其","Brandon Beach","埃迪·贝克","沃尔特·培根"],"is_watched":false}]
g.有了Factory类之后,接下来需要创建ViewModel类,在这个类中通过LivePagedListBuilder类创建和配置PagedList,并使用LiveData包装PagedList,然后在MainActivity中监测PagedList中数据的变化,并更新页面。
不过,我在写代码的时候,遇到了一个bug调了很久,就是当我在MainActivity中将activityMainBinding.recyclerView.setHasFixedSize(true);这句代码加上时,加载不出来任何的数据;但是如果我将RecyclerView组件的布局高度改成match_parent后,即使设置了setHasFixedSize(true)也能加载出来数据,也不知道咋回事。