前回の記事ではPaging2.0の基本的な使い方について説明しました。
https://blog.csdn.net/Leo_Liang_jie/article/details/109473099
実際、Paging 3.0 は以前にリリースされており、その機能は次のようにさらに強力になります。
1: Kotlin コルーチンとプロセスに対する最高級のより優れたサポートを提供する
2: ページング データはメモリにキャッシュされ、アプリケーションがページ データを処理するときにシステム リソースをより効果的に使用できるようになります。
等
原則はこの 2.0 の記事ですでに述べられています。ここにコードを直接示します。
依存関係を 3.0 にアップグレードします。
implementation "androidx.paging:paging-runtime:3.0.0-alpha09"
読者は Android Studio を最新バージョンにアップグレードし、依存関係にマウスを置くと、Gradle が最新バージョンを通知します。
それでは、アダプターのコードに直接進みましょう。2.0 は PagedListAdapter を継承し、3.0 は PagingDataAdapter を継承します。これ以外の記述方法は同じです。
class MyPaged3ListAdapter extends PagingDataAdapter<MyDataBean, MyViewHolder> {
public MyPaged3ListAdapter() {
// 通过 构造方法 设置 DiffUtil.ItemCallback
super(DIFF_CALLBACK);
}
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);
}
};
@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));
}
}
DataSource をもう一度見てください。2.0 の場合は PositionalDataSource、3.0 の場合は PagingSource です。
class MyPagingSource : PagingSource<Int, MyDataBean>() {
/**
* params.key 是取 当前列表的起始节点
* params.loadSize 是获取当前列表的长度
* */
override suspend fun load(params: LoadParams<Int>): LoadResult<Int, MyDataBean> {
val startPosition = params.key ?: 0
val loadSize = params.loadSize
// 加载的数据
val data = getData(startPosition, loadSize)
return LoadResult.Page(
data,
// 往上加载的Key ,如果不可以往上加载就null
null,
// 加载下一页的key 如果传null就说明到底了
startPosition + data.size
)
}
/**
* 模拟网络获取数据
* */
private fun getData(startPosition: Int, pageSize: Int): MutableList<MyDataBean> {
val list = mutableListOf<MyDataBean>()
for (i in startPosition until startPosition + pageSize) {
list.add(MyDataBean(i))
}
return list
}
}
リポジトリを作成します。2.0 は DataSource.Factory を作成します。3.0 はカスタム クラスを作成し、Pager と PagingSource をバインドします。
class MyRepository {
/**
* pageSize = 20 设置每一页加载长度,
* 和 PagingSource 的 params.loadSize对应
* */
fun getData() = Pager(PagingConfig(pageSize = 20)) {
MyPagingSource()
}
}
ViewModel を作成し、リポジトリを LiveData にバインドする
class MyPaging3ViewModel : ViewModel() {
private val myRepository: MyRepository by lazy { MyRepository() }
fun getData() = myRepository.getData().asLiveData()
}
Activity を見てください。2.0 と違いはありません。つまり、Adapter.submitData がコルーチン内にある必要があります。
class MainActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
recyclerView.layoutManager = LinearLayoutManager(this)
val myPagedListAdapter = MyPaged3ListAdapter()
recyclerView.adapter = myPagedListAdapter
/**
* ViewModel 绑定 Activity 生命周期
* */
val myViewModel = ViewModelProviders.of(this).get(MyPaging3ViewModel::class.java)
/**
* ViewModel 感知数据变化,更新 Adapter 列表
* Adapter.submitData 这是一个用 suspend 修饰的方法,所以需要开启一个有生命周期的协程
* */
myViewModel.getData().observe(this, Observer {
lifecycleScope.launch {
myPagedListAdapter.submitData(it)
}
})
}
}
走行効果は2.0と同等、テストも問題なし
上記のコードテストには問題ありませんが、ご不明な点がございましたらメッセージを残してください。
ギットハブ接続:
https://github.com/LeoLiang23/PagingDemo.git
以下のリンクは、私が読んだ優れた Paging 記事です。こちらも参照してください。
https://mp.weixin.qq.com/s/qBxhtgjLluUZsHCinNHUAQ