Я пытаюсь добавить функциональность комментариев в свое приложение. Так же, как Instagram или Facebook, где комментарий будет добавлен в список комментариев после успешного сохранения в базе данных. Я использую Компоненты архитектуры Android (ViewModel, LiveData и Paging Library).
Вот моя 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)
}
}}