分页库 (LivePagedListBuilder) 不注意 return 分页数据
PagingLibrary (LivePageListBuilder) does not not return PagedData
我正在使用 Android 分页库,但无法从我的数据源取回结果。
我基本上是从我的 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
BEFORE 你调用 fetchWorkPackages()
.当 fetchWorkPackages()
被调用时,它会创建一个 new LiveData 并将新的分配给 workPackages
。但是你之前只观察到 workPackages
中的 old LiveData,所以这个新的没有任何活跃的观察者,因此它永远不会触发 loadInitial()
您可以尝试将 fetchWorkPackages()
放入 ViewModel 的 init {}
中,或者为 workPackages
AFTER 设置 observe
调用 fetchWorkPackages()
在你的 Activity 或 Fragment
我正在使用 Android 分页库,但无法从我的数据源取回结果。
我基本上是从我的 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
BEFORE 你调用 fetchWorkPackages()
.当 fetchWorkPackages()
被调用时,它会创建一个 new LiveData 并将新的分配给 workPackages
。但是你之前只观察到 workPackages
中的 old LiveData,所以这个新的没有任何活跃的观察者,因此它永远不会触发 loadInitial()
您可以尝试将 fetchWorkPackages()
放入 ViewModel 的 init {}
中,或者为 workPackages
AFTER 设置 observe
调用 fetchWorkPackages()
在你的 Activity 或 Fragment