Android - привязка пользовательских данных с объектом LiveData - PullRequest
0 голосов
/ 20 апреля 2020

У меня есть следующая схема XML:

<layout ....>
    <data>
        <variable
            name="viewModel"
            type="com.example.myrecyclerview.CategoryListFragmentViewModel" />
    </data>
    <androidx.constraintlayout.widget.ConstraintLayout
        ...
        ...>
        <androidx.recyclerview.widget.RecyclerView
            android:id="@+id/category_recyclerview"
            ...
            <!-- this line below, does not work very well -->
            app:categoryListData="@{viewModel.retrieveCategories()}"

            <!-- the line below works perfect 
            app:categoryListData="@{viewModel.categories}"
            -->

            app:layoutManager="androidx.recyclerview.widget.LinearLayoutManager"
            ... />
    </androidx.constraintlayout.widget.ConstraintLayout>
</layout>

Как вы можете видеть, с помощью концепции Data Binding я передаю ссылку на класс ViewModel. Используя эту ссылку ViewModel, я звоню retrieveCategories(). Вот содержимое класса ViewModel:

class CategoryListFragmentViewModel(private val repository: CategoryDataRepository): ViewModel() {

    fun retrieveCategories() = repository.getCategories()  // <--- but this does not work

    //val categories= repository.getCategories()   <--- this works
}

Как видите, список объектов данных предоставляется методом, определенным в классе Repository. Обратите внимание, что getCategories() обрабатывает все содержимое библиотеки подкачки Android (см. Ниже в конце этого вопроса).

Итак, и теперь я хочу перейти к моему вопросу: как вы можете прочитать из моих комментариев выше, когда у меня app:categoryListData="@{viewModel.categories}" в моем макете XML, библиотека подкачки справляется со своей задачей очень хорошо (когда RecyclerView нужны данные, она предоставляет данные и уменьшает количество запросов к веб-сервису).

Но когда у меня есть app:categoryListData="@{viewModel.retrieveCategories()}", как упомянуто выше, внезапно количество запросов увеличивается, и приложение начинает делать запросы все время. Я не могу понять, почему, поскольку они имеют один и тот же тип - тип categories совпадает с типом возврата retrieveCategories().

Для полноты изложения здесь приведены недостающие части реализации. :

class CategoryDataRepository(private val dataSource: MyRoomDatabase,
                           private val categoryRemoteDataSource: CategoryRemoteDataSource) {

    fun getCategories() : LiveData<PagedList<Category>>{

        val dataSourceFactory = dataSource.categoryDao().getCategories()

        // CategoryBoundaryCallback class overrides onZeroItemsLoaded() & onItemAtEndLoaded so that each these methods are invoked, a request to the service is triggered
        val boundaryCallback = CategoryBoundaryCallback(dataSource, categoryRemoteDataSource)

        return LivePagedListBuilder(dataSourceFactory, DATABASE_PAGE_SIZE)
            .setBoundaryCallback(boundaryCallback)
            .build()
    }

    companion object {
        private const val DATABASE_PAGE_SIZE = 10
    }
}

И, наконец, пользовательский адаптер привязки:

@BindingAdapter("categoryListData")
fun bindRecyclerViewCategoryList(recyclerView: RecyclerView, data: PagedList<Category>?){
    val adapter = recyclerView.adapter as CategoryListAdapter
    adapter.submitList(data)
}

Возвращаясь к моему вопросу: почему DataBinding работает, когда я использую переменную объекта LiveData, но не работает, когда я использую метод, возвращающий тот же тип.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...