繁体   English   中英

如何在分页库的PagedList中添加项目

[英]How to add Item in PagedList of Paging Library

我试图在我的应用程序中添加评论功能。 就像Instagram或Facebook一样,在将评论成功保存到数据库后,它们会添加到评论列表中。 我正在使用Android体系结构组件 (ViewModel,LiveData和分页库)。

这是我的ViewModel,我认为我应该更新我的PagedList

class CommentsViewModel : ViewModel() {
lateinit var networkState: LiveData<NetworkState>
private val executor: Executor
private lateinit var tDataSource: LiveData<CommentsDataSource>
private lateinit var dataFactory: CommentsDataFactory
private var repository: CommentsRepository
private var commentsList: LiveData<PagedList<Comment>>? = null

init {
    executor = Executors.newFixedThreadPool(5)
    repository = CommentsRepository()
}

fun getComments(postId: Int): LiveData<PagedList<Comment>>? {
    dataFactory = CommentsDataFactory(executor, postId)

    tDataSource = dataFactory.mutableLiveData

    networkState = Transformations.switchMap(dataFactory.mutableLiveData) {
        it.networkState
    }

    val pagedListConfig = PagedList.Config.Builder()
            .setEnablePlaceholders(true)
            .setInitialLoadSizeHint(Constants.INITIAL_LOAD)
            .setPageSize(Constants.PAGE_SIZE)
            .build()

    commentsList = LivePagedListBuilder(dataFactory, pagedListConfig)
            .setFetchExecutor(executor)
            .build()
    return commentsList
}

//This method here brings errors.
fun addComment(comment: Comment) {
    commentsList?.value?.add(comment)
}

fun postComment(map: Map<String, String>): LiveData<NetworkState> {
    repository.postComment(map)
    return repository.mNetworkState
}}

如何正确执行?

CommentsDataFactory

class CommentsDataFactory(private val executor: Executor, private val postId: Int)
: DataSource.Factory<Int, Comment>() {

val mutableLiveData = MutableLiveData<CommentsDataSource>()

override fun create(): DataSource<Int, Comment>? {
    val dataSource = CommentsDataSource(executor, postId)
    mutableLiveData.postValue(dataSource)
    return dataSource
}}

CommentsDataSource

class CommentsDataSource(private val retryExecutor: Executor, private val post_id: Int)
: PageKeyedDataSource<Int, Comment>() {

private var retry: (() -> Any)? = null
private val apiClient = getClient()

val networkState = MutableLiveData<NetworkState>()

val initialLoad = MutableLiveData<NetworkState>()

fun retryAllFailed() {
    val prevRetry = retry
    retry = null
    prevRetry?.let {
        retryExecutor.execute {
            it.invoke()
        }
    }
}

override fun loadBefore(
        params: LoadParams<Int>,
        callback: LoadCallback<Int, Comment>) {
}

override fun loadAfter(params: LoadParams<Int>, callback: LoadCallback<Int, Comment>) {
    networkState.postValue(NetworkState.LOADING)
    apiClient.getComments(post_id, params.key).enqueue(
            object : retrofit2.Callback<List<Comment>> {
                override fun onFailure(call: Call<List<Comment>>, t: Throwable) {
                    retry = {
                        loadAfter(params, callback)
                    }
                    networkState.postValue(NetworkState.error(t.message ?: "unknown err"))
                }

                override fun onResponse(
                        call: Call<List<Comment>>,
                        response: Response<List<Comment>>) {
                    when {
                        response.isSuccessful -> {
                            retry = null
                            callback.onResult(response.body() as MutableList<Comment>, params.key + 10)
                            networkState.postValue(NetworkState.LOADED)
                        }
                        response.code() == 404 -> networkState.postValue(NetworkState.END)
                        else -> {
                            retry = {
                                loadAfter(params, callback)
                            }
                            networkState.postValue(
                                    NetworkState.error("error code: ${response.code()}"))
                        }
                    }
                }
            }
    )
}

override fun loadInitial(
        params: LoadInitialParams<Int>,
        callback: LoadInitialCallback<Int, Comment>) {

    val request = apiClient.getComments(post_id, 0)

    networkState.postValue(NetworkState.LOADING)
    initialLoad.postValue(NetworkState.LOADING)

    try {
        retry = null
        val response = request.execute()

        when {
            response.isSuccessful -> {
                networkState.postValue(NetworkState.LOADED)
                initialLoad.postValue(NetworkState.LOADED)
                callback.onResult(response.body() as MutableList<Comment>, 0, 10)
            }
            response.code() == 404 -> networkState.postValue(NetworkState.END)
            else -> networkState.postValue(
                    NetworkState.error("error code: ${response.code()}"))
        }

    } catch (ioException: IOException) {
        retry = {
            loadInitial(params, callback)
        }
        val error = NetworkState.error(ioException.message ?: "unknown error")
        networkState.postValue(error)
        initialLoad.postValue(error)
    }
}}

正确的方法是:

  1. 将您新添加的注释发送到远程服务器(基于您的代码,您将从服务器获取所有注释)。 为此,您将调用一些ViewModel方法,例如addComment() 它将从您的apiClient调用一些方法。

  2. 在您的DataSource上调用invalidate (即使在ViewModel ,即使在相同的addComment()方法中),它也会触发您的PagedList更新。

     commentsDataSource.invalidate(); 

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM