我正在使用Android Paging Library,但无法从DataSource获取结果。
我基本上是从LivePagedListBuilder获取一个空的LiveData。不知道我在做什么错。我的loadInitial也从未调用过。
这是我的ViewModel:
class WorkPackagesViewModel: ViewModel() {
companion object {
const val PAGING_LIMIT_DEFAULT = 10
}
var workPackages: LiveData<PagedList<WorkPackagesQuery.WorkPackage>>? = null
fun fetchWorkPackages(isOnline: Boolean, workWeeK: Configurations.AppWeek, pagingStart: Int?, pagingLimit: Int?) {
val myConfig = PagedList.Config.Builder()
.setInitialLoadSizeHint(pagingLimit ?: PAGING_LIMIT_DEFAULT)
.setPageSize(pagingLimit ?: PAGING_LIMIT_DEFAULT )
.build()
val workPackageDataFactory = WorkPackageDataFactory(workWeeK)
workPackageDataFactory.create()
workPackages = LivePagedListBuilder(workPackageDataFactory, myConfig)
.setInitialLoadKey(pagingStart)
.setFetchExecutor(Executors.newFixedThreadPool(5))
.build()
}
}
}
这是我的DataSource.Factory:
class WorkPackageDataFactory(
private val workWeek : Configurations.AppWeek
) : DataSource.Factory<Int, WorkPackagesQuery.WorkPackage>() {
private var mutableLiveData: MutableLiveData<WorkPackageDataSource>? = MutableLiveData()
override fun create(): DataSource<Int, WorkPackagesQuery.WorkPackage> {
val workPackageDataSource = WorkPackageDataSource(workWeek)
mutableLiveData?.postValue(workPackageDataSource)
return workPackageDataSource
}
}
这是我的数据源文件:
class WorkPackageDataSource(
private val workWeek : Configurations.AppWeek
) : PageKeyedDataSource<Int, WorkPackagesQuery.WorkPackage>(), KoinComponent
{
val client : PipefighterApi by inject()
private var parentJob = Job()
private val coroutineContext: CoroutineContext get() = parentJob + Dispatchers.Main
private val scope = CoroutineScope(coroutineContext)
override fun loadInitial( //DOES NOT GET CALLED
params: LoadInitialParams<Int>,
callback: LoadInitialCallback<Int, WorkPackagesQuery.WorkPackage>
) {
scope.launch {
val workPackages = getWorkPackages(1,params.requestedLoadSize)?.workPackages() as MutableList<WorkPackagesQuery.WorkPackage>
callback.onResult(workPackages, null, params.requestedLoadSize + 1 )
}
}
override fun loadAfter(
params: LoadParams<Int>,
callback: LoadCallback<Int, WorkPackagesQuery.WorkPackage>
) {
scope.launch {
val workPackages = getWorkPackages(params.key,params.requestedLoadSize)?.workPackages() as MutableList<WorkPackagesQuery.WorkPackage>
var nextKey : Int? = null
if (params.key.plus(0) != workPackages.size) {
nextKey = params.key.plus(1)
}
callback.onResult(workPackages, nextKey )
}
}
override fun loadBefore(
params: LoadParams<Int>,
callback: LoadCallback<Int, WorkPackagesQuery.WorkPackage>
) {
}
suspend fun getWorkPackages(
initialPage : Int,
requestedLoadSize : Int
) : WorkPackagesQuery.Result? {
return withContext(Dispatchers.IO) {
async { client.workPackages(
workWeek.currentWeekStart(),
workWeek.currentWeekEnd(),
initialPage,
requestedLoadSize
) }.await().response
}
}
}
这是我的片段
class WorkPackagesFragment : Fragment(), WorkPackagesRecyclerAdapter.OnClickWorkPackage {
companion object {
private const val VERTICAL_ITEM_SPACE = 30
const val PAGING_START = 1
const val PAGING_LIMIT = 10
}
private val workPackagesViewModel: WorkPackagesViewModel by viewModel()
private val mainViewModel : MainViewModel by sharedViewModel()
private val networkConnection: NetworkConnectionHelper by inject()
private lateinit var binding: FragmentWorkPackagesBinding
private lateinit var adapter: WorkPackagesRecyclerAdapter
override fun onCreateView(
inflater: LayoutInflater, container: ViewGroup?,
savedInstanceState: Bundle?
): View? {
binding = DataBindingUtil.inflate(
inflater,
com.bechtel.pf.R.layout.fragment_work_packages,
container,
false
)
mainViewModel.week.observe(this, Observer {
it ?: return@Observer
workPackagesViewModel.fetchWorkPackages(networkConnection.connected(), it, PAGING_START, PAGING_LIMIT)
})
binding.lifecycleOwner = viewLifecycleOwner
binding.viewModel = workPackagesViewModel
workPackagesViewModel.workPackages?.observe(this, Observer {
it ?: return@Observer
adapter = WorkPackagesRecyclerAdapter(this)
adapter.submitList(it)
binding.workPackagesRecyclerView.adapter = adapter
adapter.notifyDataSetChanged()
})
return binding.root
}
}
最佳答案
我看不到在哪里观察到workPackages
,但是我想问题是您在调用workPackages
之前观察到了fetchWorkPackages()
。调用fetchWorkPackages()
时,它将创建一个新的LiveData并将新的LiveData分配给workPackages
。但是您之前只观察了workPackages
中的旧LiveData,因此该新监视者没有任何活动的观察者,因此它永远不会触发loadInitial()
您可以尝试在ViewModel的fetchWorkPackages()
中放入init {}
,或在Activity或Fragment中调用observe
之后将workPackages
设置为fetchWorkPackages()