Лучший способ изменить listId / запрос в пейджинге источника данных - PullRequest
0 голосов
/ 07 февраля 2019

Я не могу найти лучший способ изменить listId моих методов VideosDataSource, таких как load initial.Я использую пейджер просмотра, поэтому он загружает 2 фрагмента за раз, поэтому я не могу использовать getter / setter для установки listId моего источника данных.вот мой класс источника данных:

class VideosDataSource(
private val networkService: NetworkService,
private val compositeDisposable: CompositeDisposable
): PageKeyedDataSource<String, Item>() {
var state: MutableLiveData<State> = MutableLiveData()
private var retryCompletable: Completable? = null
private var listId = "PL8fVUTBmJhHKEJjTNWn-ykf67rVrFWYtC"

override fun loadInitial(params: LoadInitialParams<String>, callback: LoadInitialCallback<String, Item>) {
    updateState(State.LOADING)
    compositeDisposable.add(
            networkService.getPlaylistVideos(listId
            ,""
            ,Constants.API_KEY)
            .subscribe( { response ->
                updateState(State.DONE)
                callback.onResult(response.items, response.prevPageToken, response.nextPageToken)
            },
                    {
                        updateState(State.ERROR)
                        setRetry(Action { loadInitial(params,callback) })
                    }
            )
    )
}

здесь я пытаюсь изменить listId в моем фрагменте пейджера просмотра.

моя фабрика источника данных:

class VideosDataSourceFactory(
private val compositeDisposable: CompositeDisposable,
private val networkService: NetworkService
):  DataSource.Factory<String, Item>() {

val videosDataSourceLiveData = MutableLiveData<VideosDataSource>()

override fun create(): DataSource<String, Item> {
    val videosDataSource = VideosDataSource(networkService, 
compositeDisposable)
    videosDataSourceLiveData.postValue(videosDataSource)
    return videosDataSource
}

}

моймодель просмотра:

class PageViewModel(application: Application) : 
AndroidViewModel(application) {

//paging
private val networkService = NetworkService.getService()
var videosList: LiveData<PagedList<Item>>
private val compositeDisposable = CompositeDisposable()
private val pageSize = 50
private val videosDataSourceFactory: VideosDataSourceFactory

init {
    //paging
    videosDataSourceFactory = VideosDataSourceFactory(compositeDisposable, networkService)
    val config = PagedList.Config.Builder()
        .setPageSize(pageSize)
        .setInitialLoadSizeHint(pageSize)
        .setEnablePlaceholders(false)
        .build()
    videosList = LivePagedListBuilder<String, Item>(videosDataSourceFactory, config).build()
}

В fragmnet onClick () я хочу отправить listId источнику данных.

С некоторыми подходами, такими как getter / setter, я могу отправить listId источнику данных, ноПросмотр пейджера создает два или три фрагмента за раз, значение переопределяется в getter / setter.Я ищу лучший способ отправки данных из фрагмента в источник данных.

1 Ответ

0 голосов
/ 07 февраля 2019

Я сделал это.Идея конструктора хороша, но не работает для меня из-за метода инициализации модели представления, вызываемого перед установкой идентификатора в конструктор фабрики.Но спасибо mr.pskink за его комментарии по использованию конструктора параметров.

Итак, вот как я это сделал.Во фрагменте я устанавливаю список для просмотра модели.

companion object {
    private const val ARG_SECOND = "arg_second"

    @JvmStatic
    fun newInstance(second: Array<Pair<String, String>>): PlaceholderFragment {
        return PlaceholderFragment().apply {
            arguments = Bundle().apply {
                putString(ARG_SECOND,second[0].second)
            }
        }
    }
}

override fun onCreate(savedInstanceState: Bundle?) {
    super.onCreate(savedInstanceState)
    viewModel = ViewModelProviders.of(this).get(PageViewModel::class.java).apply {
        setListId(arguments?.getString(ARG_SECOND) ?: "")
    }
}

В модели представления я создаю метод:

 fun setListId(listId: String){
    videosDataSourceFactory.listId = listId
}

В фабрике источников данных я создаю переменную:

val videosDataSourceLiveData = MutableLiveData<VideosDataSource>()
lateinit var listId:String

override fun create(): DataSource<String, Item> {
    val videosDataSource = VideosDataSource(networkService, compositeDisposable,listId)
    videosDataSourceLiveData.postValue(videosDataSource)
    return videosDataSource
}

А затем получить его через конструктор источника данных здесь:

class VideosDataSource(
private val networkService: NetworkService,
private val compositeDisposable: CompositeDisposable,
private val listId: String
): PageKeyedDataSource<String, Item>() {
var state: MutableLiveData<State> = MutableLiveData()
private var retryCompletable: Completable? = null

override fun loadInitial(params: LoadInitialParams<String>, callback: 
LoadInitialCallback<String, Item>) {
    updateState(State.LOADING)
    compositeDisposable.add(
            networkService.getPlaylistVideos(listId
            ,""
            ,Constants.API_KEY)
            .subscribe( { response ->
                updateState(State.DONE)
                callback.onResult(response.items, response.prevPageToken, response.nextPageToken)
            },
                    {
                        updateState(State.ERROR)
                        setRetry(Action { loadInitial(params,callback) })
                    }
            )
    )
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...