协程扩展功能

时间:2020-10-28 10:05:34

标签: android kotlin kotlin-coroutines android-paging kotlin-extension

我正在使用扩展功能将列表数据绑定到recyclerview,使用pagedlist不需要任何协程

@BindingAdapter("pagedListAdapterData")
fun <T : Any> submitPagedList(recyclerView: RecyclerView, list: PagedList<T>?) {
    if (list != null && recyclerView.adapter is PagedListAdapter<*, *>) {
        (recyclerView.adapter as? PagedListAdapter<T, RecyclerView.ViewHolder>)?.submitList((list))
    }
}

        pagedListAdapterData="@{viewModel.list}"

但是随着即时消息升级到Paging 3.0,它需要使用协程

@BindingAdapter("pagingDataAdapter")
fun <T : Any> submitPagingDataList(recyclerView: RecyclerView, list: PagingData<T>?) {
    if (list != null && recyclerView.adapter is PagingDataAdapter<*, *>) {
        GlobalScope.launch {
            (recyclerView.adapter as? PagingDataAdapter<T, RecyclerView.ViewHolder>)?.submitData((list))
        }
    }
}

这很好用,但是我担心的是使用Globalscope,由于没有建议使用globalScope,因此似乎有更好的方法

2 个答案:

答案 0 :(得分:1)

实际上,使用GlobalScopeaccording to the documentation submitData()应该在'lifecycleScope'内部运行不是一个好主意。您可以从视图中获取“ lifecycleScope”,但这需要一些样板:

package com.test.pagingadapter

import android.app.Activity
import android.content.Context
import android.content.ContextWrapper
import android.view.View
import androidx.activity.ComponentActivity
import androidx.databinding.BindingAdapter
import androidx.fragment.app.Fragment
import androidx.fragment.app.findFragment
import androidx.lifecycle.LifecycleOwner
import androidx.lifecycle.lifecycleScope
import androidx.paging.PagingData
import androidx.paging.PagingDataAdapter
import androidx.recyclerview.widget.RecyclerView
import kotlinx.coroutines.launch

/**
 * https://stackoverflow.com/a/58249983/4858777
 */
tailrec fun Context?.getActivity(): Activity? = when (this) {
    is Activity -> this

    else -> {
        val contextWrapper = this as? ContextWrapper
        contextWrapper?.baseContext?.getActivity()
    }
}

val View.lifecycleOwner: LifecycleOwner? get() = try {
    val fragment = findFragment<Fragment>()
    fragment.viewLifecycleOwner
} catch (e: IllegalStateException) {
    when (val activity = context.getActivity()) {
        is ComponentActivity -> activity
        else -> null
    }
}

@BindingAdapter("pagingDataAdapter")
fun <T : Any> submitPagingDataList(recyclerView: RecyclerView, data: PagingData<T>?) {
    val adapter = recyclerView.adapter
    if (data != null && adapter is PagingDataAdapter<*, *>) {
        // but it isn't a perfect solution because the cast is required
        @Suppress("UNCHECKED_CAST")
        val castedAdapter = adapter as PagingDataAdapter<T, RecyclerView.ViewHolder>

        recyclerView.lifecycleOwner?.lifecycleScope?.launch {
            castedAdapter.submitData(data)
        }
    }
}

答案 1 :(得分:1)

androidx.lifecycle 有一个扩展函数 View.findViewTreeLifecycleOwner,所以你不必自己创建:

view.findViewTreeLifecycleOwner()?.lifecycleScope?.launch {
  ...
}