companion object{
val POST_COMPARATOR = object : DiffUtil.ItemCallback
override fun areContentsTheSame(oldItem: Article, newItem: Article): Boolean =
oldItem == newItem
override fun areItemsTheSame(oldItem: Article, newItem: Article): Boolean =
oldItem.id == newItem.id
}
}
override fun onBindViewHolder(holder: ArticleViewHolder, position: Int) {
holder.tvName.text = getItem(position)?.title
}
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ArticleViewHolder {
return ArticleViewHolder(LayoutInflater.from(parent.context).inflate(R.layout.list_item,parent,false))
}
}
class ArticleViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView){
val tvName: TextView = itemView.findViewById(R.id.tvname)
}
写法跟写正常的RecyclerView.Adapter基本一样,就加了一样东西,需要在构造方法里传入一个DiffUtil.ItemCallback用来确定差量更新的时候的计算规则。
Adapter写完了,下面就是数据了,我们使用Retrofit和kotlin协程从网络获取数据之后将数据设置给Adapter
===========================================================================
从官网上来看,google提倡我使用三层架构来完成数据到Adapter的设置,比如官网上的下图
第一层 数据仓库层Repository
Repository层主要使用PagingSource这个分页组件来实现,每个PagingSource对象都对应一个数据源,以及该如何从该数据源中查找数据。PagingSource可以从任何单个数据源比如网络或者数据库中查找数据。
Repository层还有另一个分页组件可以使用RemoteMediator,它是一个分层数据源,比如有本地数据库缓存的网络数据源。
下面创建我们的PagingSource和Repository
class ArticleDataSource:PagingSource<Int,Article>() {
/**
* 实现这个方法来触发异步加载(例如从数据库或网络)。 这是一个suspend挂起函数,可以很方便的使用协程异步加载
*/
override suspend fun load(params: LoadParams): LoadResult<Int, Article> {
return try {
val page = params.key?:0
//获取网络数据
val result = WanRetrofitClient.service.getHomeList(page)
LoadResult.Page(
//需要加载的数据
data = result.data.datas,
//如果可以往上加载更多就设置该参数,否则不设置
prevKey = null,
//加载下一页的key 如果传null就说明到底了
nextKey = if(result.data.curPage==result.data.pageCount) null else page+1
)
}catch (e:Exception){
LoadResult.Error(e)
}
}
}
-
继承PagingSource,需要两个泛型,第一个表示下一页数据的加载方式,比如使用页码加载可以传Int,使用最后一条数据的某个属性来加载下一页就传别的类型比如String等
-
实现其load方法来触发异步加载,可以看到它是一个用suspend修饰的挂起函数,可以很方便的使用协程异步加载。
-
其参数LoadParams中有一个key值,我们可以拿出来用于加载下一页。
-
返回值是一个LoadResult,出现异常调用LoadResult.Error(e),正常强开情况下调用LoadResult.Page方法来设置从网络或者数据库获取到的数据
-
prevKey 和 nextKey 分别代表下次向上加载或者向下加载的时候需要提供的加载因子,比如我们通过page的不断增加来加载每一页的数据,nextKey就可以传入下一页page+1。如果设置为null的话说明没有数据了。
创建Repository
class ArticleRepository {
fun getArticleData() = Pager(PagingConfig(pageSize = 20)){
ArticleDataSource()
}.flow
}
代码虽少不过有两个重要的对象:Pager 和 PagingData
-
Pager是进入分页的主要入口,它需要4个参数:PagingConfig、Key、RemoteMediator、PagingSource其中第一个和第四个是必填的。
-
PagingConfig用来配置加载的时候的一些属性,比如多少条算一页,距离底部多远的时候开始加载下一页,初始加载的条数等等。
-
PagingData 用来存储每次分页数据获取的结果
-
flow是kotlin的异步数据流,点类似 RxJava 的 Observable
第二层ViewModel层
Repository最终返回一个异步流包裹的PagingDataFlow,PagingData存储了数据结果,最终可以使用它将数据跟UI界面关联。
ViewModel中一般都使用LiveData来跟UI层交互,Flow的扩展函数可以直接转换成一个LiveData可观察对象。
class PagingViewModel:ViewModel() {
private val repository:ArticleRepository by lazy { ArticleRepository() }
/**
* Pager 分页入口 每个PagingData代表一页数据 最后调用asLiveData将结果转化为一个可监听的LiveData
*/
fun getArticleData() = repository.getArticleData().asLiveData()
}
UI层
UI层其实就是到了我们的Activity中,给RecycleView设置Adapter,给Adater设置数据
class PagingActivity : AppCompatActivity() {
private val viewModel by lazy { ViewModelProvider(this).get(PagingViewModel::class.java) }
private val adapter: ArticleAdapter by lazy { ArticleAdapter() }
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_paging)
val refreshView:SmartRefreshLayout = findViewById(R.id.refreshView)
val recyclerView :RecyclerView = findViewById(R.id.recyclerView)
recyclerView.layoutManager = LinearLayoutManager(this)
recyclerView.adapter = adapter.withLoadStateFooter(PostsLoadStateAdapter(adapter))
//获取数据并渲染UI
viewModel.getArticleData().observe(this, Observer {
lifecycleScope.launchWhenCreated {
adapter.submitData(it)
Android开发除了flutter还有什么是必须掌握的吗?
相信大多数从事Android开发的朋友们越来越发现,找工作越来越难了,面试的要求越来越高了
除了基础扎实的java知识,数据结构算法,设计模式还要求会底层源码,NDK技术,性能调优,还有会些小程序和跨平台,比如说flutter,以思维脑图的方式展示在下图;
点击文档前往获取面试资料与视频教程;【阿里P7级别Android架构师技术脑图+全套视频】
自我介绍一下,小编13年上海交大毕业,曾经在小公司待过,也去过华为、OPPO等大厂,18年进入阿里一直到现在。
深知大多数初中级安卓工程师,想要提升技能,往往是自己摸索成长,但自己不成体系的自学效果低效又漫长,而且极易碰到天花板技术停滞不前!
因此收集整理了一份《2024年最新Android移动开发全套学习资料》送给大家,初衷也很简单,就是希望能够帮助到想自学提升又不知道该从何学起的朋友,同时减轻大家的负担。
由于文件比较大,这里只是将部分目录截图出来,每个节点里面都包含大厂面经、学习笔记、源码讲义、实战项目、讲解视频
如果你觉得这些内容对你有帮助,可以添加下面V无偿领取!(备注Android)
…(img-5wFPpSfK-1710970265941)]
[外链图片转存中…(img-LIWPKgRg-1710970265941)]
[外链图片转存中…(img-blPHXTpP-1710970265942)]
[外链图片转存中…(img-bawidk5K-1710970265942)]
由于文件比较大,这里只是将部分目录截图出来,每个节点里面都包含大厂面经、学习笔记、源码讲义、实战项目、讲解视频
如果你觉得这些内容对你有帮助,可以添加下面V无偿领取!(备注Android)
[外链图片转存中…(img-XwZKTUSQ-1710970265942)]