1

I can't find a better way to change listId of my VideosDataSource methods like load initial. I'm using view pager so it load 2 fragment at a time that's why i can't use getter/setter to set listId of my data source. here my data source class:

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) })
                    }
            )
    )
}

here i'm trying to change listId in my view pager fragment.

my data source factory:

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
}

}

my view model:

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()
}

In fragmnet onClick() i want to send listId to data source.

Whit some approaches like getter/setter i can be able to send listId to data source but view pager create two or three fragment at a time the value is override in getter/setter. I'm looking for the better way to send data from fragment to data source.

Hussnain Haidar
  • 2,200
  • 19
  • 30

1 Answers1

1

I did it. The idea of constructor is good but not works for me because of init method of view model called before setting the id to factory constructor. But thanks to mr.pskink for his comments to use parameter constructor.

So here's how i did it. In fragment i set list to view model.

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) ?: "")
    }
}

In view model i create a method:

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

In data source factory i craete a variable:

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
}

And then get it via constructor of data source here:

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) })
                    }
            )
    )
}
Hussnain Haidar
  • 2,200
  • 19
  • 30