代码拉取完成,页面将自动刷新
以下只展示关键部分
dependencies {
...
// Paging 3.0
implementation 'androidx.paging:paging-runtime:3.0.0-beta01'
// 下拉刷新组件
implementation 'androidx.swiperefreshlayout:swiperefreshlayout:1.1.0'
// RecyclerView
implementation 'androidx.recyclerview:recyclerview:1.2.1'
...
}
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
tools:context=".MainActivity">
<androidx.swiperefreshlayout.widget.SwipeRefreshLayout
android:id="@+id/swipeRefreshLayout"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<FrameLayout
android:layout_width="match_parent"
android:layout_height="match_parent">
<androidx.recyclerview.widget.RecyclerView
android:id="@+id/recyclerview"
android:layout_width="match_parent"
android:layout_height="match_parent"/>
<ProgressBar
android:id="@+id/progress_bar"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center" />
</FrameLayout>
</androidx.swiperefreshlayout.widget.SwipeRefreshLayout>
</LinearLayout>
package com.lujianfei.plugin1_15
import android.content.Intent
import android.net.Uri
import android.view.View
import android.widget.ProgressBar
import android.widget.Toast
import androidx.lifecycle.ViewModelProvider
import androidx.lifecycle.viewModelScope
import androidx.paging.LoadState
import androidx.recyclerview.widget.DividerItemDecoration
import androidx.recyclerview.widget.LinearLayoutManager
import androidx.recyclerview.widget.RecyclerView
import androidx.swiperefreshlayout.widget.SwipeRefreshLayout
import com.lujianfei.module_plugin_base.base.BasePluginActivity
import com.lujianfei.module_plugin_base.beans.PluginActivityBean
import com.lujianfei.module_plugin_base.widget.PluginToolBar
import com.lujianfei.plugin1_15.adapter.FooterAdapter
import com.lujianfei.plugin1_15.adapter.MainAdapter
import com.lujianfei.plugin1_15.viewmodel.MainViewModel
import kotlinx.coroutines.flow.collect
import kotlinx.coroutines.launch
class MainActivity : BasePluginActivity() {
companion object {
const val TAG = "MainActivity"
}
private var recyclerview:RecyclerView ?= null
private var progress_bar:ProgressBar ?= null
private var swipeRefreshLayout:SwipeRefreshLayout ?= null
private val mAdapter by lazy { MainAdapter() }
private var mMainViewModel: MainViewModel?= null
override fun resouceId(): Int = R.layout.activity_main
override fun initView() {
swipeRefreshLayout = findViewById(R.id.swipeRefreshLayout)
progress_bar = findViewById(R.id.progress_bar)
recyclerview = findViewById(R.id.recyclerview)
recyclerview?.apply {
layoutManager = LinearLayoutManager(that)
addItemDecoration(DividerItemDecoration(that, DividerItemDecoration.VERTICAL))
adapter = mAdapter.withLoadStateFooter(
footer = FooterAdapter {
mAdapter.retry()
})
}
mMainViewModel = that?.let { ViewModelProvider(it).get(MainViewModel::class.java) }
swipeRefreshLayout?.isEnabled = false
}
override fun initData() {
that?.let {
mMainViewModel?.viewModelScope?.launch {
// 绑定数据
mMainViewModel?.getPagingData()?.collect { pagingData->
mAdapter.submitData(pagingData)
}
}
}
}
override fun initEvent() {
mAdapter.addLoadStateListener {
when (it.refresh) {
// 加载完毕
is LoadState.NotLoading -> {
// 下载组件激活
swipeRefreshLayout?.isEnabled = true
// 收起下拉刷新
swipeRefreshLayout?.isRefreshing = false
// 隐藏中间加载提示,显示列表
progress_bar?.visibility = View.INVISIBLE
recyclerview?.visibility = View.VISIBLE
}
// 加载中
is LoadState.Loading -> {
if (mAdapter.itemCount == 0) { // 空数据时
// 显示中间加载提示
progress_bar?.visibility = View.VISIBLE
recyclerview?.visibility = View.INVISIBLE
}
}
// 加载失败
is LoadState.Error -> {
// 收起下拉刷新
swipeRefreshLayout?.isRefreshing = false
val state = it.refresh as LoadState.Error
progress_bar?.visibility = View.INVISIBLE
Toast.makeText(that, "Load Error: ${state.error.message}", Toast.LENGTH_SHORT).show()
}
}
}
swipeRefreshLayout?.setOnRefreshListener {
mAdapter.refresh()
}
}
}
package com.lujianfei.plugin1_15.adapter
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.widget.TextView
import androidx.paging.PagingDataAdapter
import androidx.recyclerview.widget.DiffUtil
import androidx.recyclerview.widget.RecyclerView
import com.lujianfei.plugin1_15.R
import com.lujianfei.plugin1_15.model.MainBean
/**
* 我们可以理解为RecycleView.Adapter,实际上它也是实现的RecyclerView.Adapter。
* 这个方法中有 submit() 方法非常重要,这个方法是开启数据加载的最后一环,所以必须实现。
* 其中这个 adapter 中还包含 refresh() 和 retry() 的方法,顾名思义刷新和重试,
* 还有就是adapter.loadStateFlow的监听,用于监听数据加载的状态
*/
class MainAdapter : PagingDataAdapter<MainBean,RecyclerView.ViewHolder>(COMPARATOR) {
companion object {
private val COMPARATOR = object : DiffUtil.ItemCallback<MainBean>() {
override fun areItemsTheSame(oldItem: MainBean, newItem: MainBean): Boolean {
return oldItem.id == newItem.id
}
override fun areContentsTheSame(oldItem: MainBean, newItem: MainBean): Boolean {
return oldItem == newItem
}
}
}
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): RecyclerView.ViewHolder {
return MyViewHolder(LayoutInflater.from(parent.context).inflate(R.layout.adapter_main, parent, false))
}
override fun onBindViewHolder(holder: RecyclerView.ViewHolder, position: Int) {
if (holder is MyViewHolder) {
holder.setData(getItem(position))
}
}
class MyViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView) {
var title: TextView? = null
var summary: TextView? = null
init {
title = itemView.findViewById(R.id.title)
summary = itemView.findViewById(R.id.summary)
}
fun setData(mainBean: MainBean?) {
title?.text = mainBean?.title
summary?.text = mainBean?.summary
}
}
}
package com.lujianfei.plugin1_15.model
data class MainBean(
var id:Int,
var title: String,
var summary: String
)
package com.lujianfei.plugin1_15.viewmodel
import androidx.lifecycle.ViewModel
import androidx.lifecycle.viewModelScope
import androidx.paging.PagingData
import androidx.paging.cachedIn
import com.lujianfei.plugin1_15.data.MainRepository
import com.lujianfei.plugin1_15.model.MainBean
import kotlinx.coroutines.flow.Flow
class MainViewModel: ViewModel() {
fun getPagingData(): Flow<PagingData<MainBean>> {
return MainRepository.getPagingData().cachedIn(viewModelScope)
}
}
package com.lujianfei.plugin1_15.data
import androidx.paging.PagingSource
import androidx.paging.PagingState
import com.lujianfei.plugin1_15.model.MainBean
import kotlinx.coroutines.delay
/**
* MainPagingSource
* 主要承担的就是数据的获取,可以理解为,
* 我们的网络请求或者读取本地数据库的数据
*/
class MainPagingSource: PagingSource<Int,MainBean>() {
override fun getRefreshKey(state: PagingState<Int, MainBean>): Int? = null
override suspend fun load(params: LoadParams<Int>): LoadResult<Int, MainBean> {
val page = params.key ?: 1 // set page 1 as default
val pageSize = params.loadSize
val items = getData(page)
val prevKey = if (page > 1) page - 1 else null
val nextKey = if (items.isNotEmpty()) page + 1 else null
return LoadResult.Page(items, prevKey, nextKey)
}
private suspend fun getData(page:Int = 1):List<MainBean> {
delay(2000L)
val mData = arrayListOf<MainBean>()
when (page) {
1 -> {
for (idx in 0 until 20) {
mData.add(
MainBean(id = idx,title = "码农宝标题 $idx", summary = "码农宝简介:主要功能:\n" +
"- 快速查看安卓设备信息 (手机屏幕分辨率,手机型号,设备id, 可用内存等等)\n" +
"- 各类开发过程中常用代码及效果 Demo, 分别有\n" +
"- 列表, 容器,对话框,动画,翻页,图表,编码及算法,多媒体,传感器,实用工具等 $idx")
)
}
}
2 -> {
for (idx in 20 until 40) {
mData.add(
MainBean(id = idx,title = "码农宝标题 $idx", summary = "码农宝简介:主要功能:\n" +
"- 快速查看安卓设备信息 (手机屏幕分辨率,手机型号,设备id, 可用内存等等)\n" +
"- 各类开发过程中常用代码及效果 Demo, 分别有\n" +
"- 列表, 容器,对话框,动画,翻页,图表,编码及算法,多媒体,传感器,实用工具等 $idx")
)
}
}
}
return mData
}
}
package com.lujianfei.plugin1_15.data
import androidx.paging.Pager
import androidx.paging.PagingConfig
import androidx.paging.PagingData
import com.lujianfei.plugin1_15.model.MainBean
import kotlinx.coroutines.flow.Flow
object MainRepository {
private const val PAGE_SIZE = 20
fun getPagingData(): Flow<PagingData<MainBean>> {
return Pager(
config = PagingConfig(PAGE_SIZE),
pagingSourceFactory = { MainPagingSource() }
).flow
}
}
package com.lujianfei.plugin1_15.adapter
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.widget.Button
import android.widget.ProgressBar
import androidx.core.view.isVisible
import androidx.paging.LoadState
import androidx.paging.LoadStateAdapter
import androidx.recyclerview.widget.RecyclerView
import com.lujianfei.plugin1_15.R
/**
* 加载更多的 Footer
*/
class FooterAdapter(val retry: () -> Unit) : LoadStateAdapter<FooterAdapter.ViewHolder>() {
class ViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView) {
val progressBar: ProgressBar = itemView.findViewById(R.id.progress_bar)
val retryButton: Button = itemView.findViewById(R.id.retry_button)
}
override fun onCreateViewHolder(parent: ViewGroup, loadState: LoadState): ViewHolder {
val view = LayoutInflater.from(parent.context).inflate(R.layout.footer_item, parent, false)
val holder = ViewHolder(view)
holder.retryButton.setOnClickListener {
retry()
}
return holder
}
override fun onBindViewHolder(holder: ViewHolder, loadState: LoadState) {
holder.progressBar.isVisible = loadState is LoadState.Loading
holder.retryButton.isVisible = loadState is LoadState.Error
}
}
此处可能存在不合适展示的内容,页面不予展示。您可通过相关编辑功能自查并修改。
如您确认内容无涉及 不当用语 / 纯广告导流 / 暴力 / 低俗色情 / 侵权 / 盗版 / 虚假 / 无价值内容或违法国家有关法律法规的内容,可点击提交进行申诉,我们将尽快为您处理。