Привязка записей прядильщика

Я работаю над концепцией привязки данных к комнате. Я устанавливаю список для счетчика с помощью настраиваемого адаптера привязки. Но я получаю нулевые данные при первом извлечении из комнаты.

код:

     @Query("select * from Student")
        LiveData<List<Student>> getAllItems();


        @BindingAdapter({"bind:entries"})
            public static void customSpinnerBinding(AppCompatSpinner appCompatSpinner,LiveData<List<Student>> listLiveData){
                if(listLiveData != null && listLiveData.getValue().size() > 0){
                    ArrayAdapter<Student> spinnerArrayAdapter = new ArrayAdapter<Student>
                            (appCompatSpinner.getContext(), android.R.layout.simple_spinner_item,
                                    listLiveData.getValue()); //selected item will look like a spinner set from XML
                    spinnerArrayAdapter.setDropDownViewResource(android.R.layout
                            .simple_spinner_dropdown_item);
                    appCompatSpinner.setAdapter(spinnerArrayAdapter);
                }
            }

        public LiveData<List<Student>> getListLiveData() {
            if(listLiveData == null){
               listLiveData = studentDB.studentDao().getAllItems();
            }
            return listLiveData;
        }

        <android.support.v7.widget.AppCompatSpinner
                    android:id="@+id/spinner"
                    android:layout_width="0dp"
                    bind:entries="@{viewmodel.listLiveData}"
                    android:layout_height="wrap_content"
                    android:layout_marginStart="16dp"
                    android:layout_marginLeft="16dp"
                    android:layout_marginTop="16dp"
                    android:layout_marginEnd="16dp"
                    android:layout_marginRight="16dp"
                    android:layout_marginBottom="16dp"
                    app:layout_constraintBottom_toBottomOf="parent"
                    app:layout_constraintEnd_toEndOf="parent"
                    app:layout_constraintStart_toStartOf="parent"
                    app:layout_constraintTop_toTopOf="parent" />

but if i observe livedata in activity this is working

  mainViewModel.getListLiveData().observe(this, new Observer<List<Student>>() {
           @Override
           public void onChanged(@Nullable List<Student> students) {
               if(students.size() > 0){
                   ArrayAdapter<Student> spinnerArrayAdapter = new ArrayAdapter<Student>
                    (MainActivity.this, android.R.layout.simple_spinner_item,
                            students); //selected item will look like a spinner set from XML
            spinnerArrayAdapter.setDropDownViewResource(android.R.layout
                    .simple_spinner_dropdown_item);
            activityMainBinding.appbar.contentid.spinner.setAdapter(spinnerArrayAdapter);
               }
           }
       });

person skyshine    schedule 29.05.2019    source источник
comment
поделитесь своим кодом Viewmodel.   -  person Rajnish suryavanshi    schedule 29.05.2019
comment
все, чем я поделился, я просто устанавливаю список liveata на счетчик   -  person skyshine    schedule 29.05.2019
comment
Вы прикрепили модель просмотра для просмотра в действии.   -  person Rajnish suryavanshi    schedule 29.05.2019
comment
проверить обновленный код   -  person skyshine    schedule 29.05.2019
comment
проверить этот код stackoverflow.com/a/53660823/7592063.   -  person Rajnish suryavanshi    schedule 29.05.2019
comment
при использовании Room вы должны читать данные в фоновом потоке.   -  person Faisal    schedule 30.05.2019


Ответы (2)


Проверьте эти две вещи:

  1. Измените свой .customSpinnerBinding, чтобы принять List<Student> вместо LiveData<List<Student>>.

BindingAdapter принимает то, что находится внутри LiveData, а не сам LiveData. LiveData не тот, который меняется. Меняется только содержание уведомлений LiveData.

Пример BindingAdapter:

        @BindingAdapter({"bind:entries"})
        public static void customSpinnerBinding(AppCompatSpinner appCompatSpinner, List<Student> students) {

            ArrayAdapter<Student> spinnerArrayAdapter = new ArrayAdapter<Student>
                    (appCompatSpinner.getContext(), android.R.layout.simple_spinner_item,
                         students); //selected item will look like a spinner set from XML
            spinnerArrayAdapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
            appCompatSpinner.setAdapter(spinnerArrayAdapter);
        }


  1. Не ленивая загрузка listLiveData

Похоже, вашему представлению это все равно понадобится, какой смысл лениво загружать его? Это только сделает ваш код более сложным и трудным для отладки, сделав вашу модель просмотра более отслеживаемой. Просто загрузите список студентов и объявите его окончательным, чтобы сделать его еще лучше.

public final LiveData listLiveData = studentDB.studentDao().getAllItems();

Если вам нужна отложенная загрузка listLiveData, убедитесь, что она инициализирована. В вашем .xml:

    <android.support.v7.widget.AppCompatSpinner
                ...
                bind:entries="@{viewmodel.getListLiveData()}"
                ... />
person Sanlok Lee    schedule 30.05.2019
comment
на самом деле я получил решение bind: entries = @ {viewmodel.listLiveData.getValue ()}, но в любом случае вы упомянули то же самое - person skyshine; 30.05.2019
comment
Я не говорю о том же .. Обычно вы не должны использовать getValue в LiveData. getValue получает значение синхронно и только один раз, что лишает смысла использование LiveData. - person Sanlok Lee; 30.05.2019
comment
bind: entries = @ {viewmodel.getListLiveData ()}, если я предоставлю подобное, он не работает и возникает ошибка привязки - person skyshine; 31.05.2019
comment
насколько я понял, в xml мы не можем напрямую предоставить живые данные. - person skyshine; 31.05.2019
comment
Я получаю listLiveData.getValue () null в адаптере привязки счетчика viewmodel, я думаю, единственный способ использовать наблюдатели Liveata, только мы можем данные - person skyshine; 31.05.2019
comment
получение null на listLiveData.getValue() очень нормально, потому что getValue() буквально получает значение, даже если LiveData еще не имеет никакого значения. Вы пробовали другой подход - не загружать LiveData лениво? Насколько я знаю, вы МОЖЕТЕ напрямую предоставить LiveData, если вы определили свою модель просмотра в теге ‹data› и назначили viewModel в привязке в вашем Activity / Fragment. - person Sanlok Lee; 31.05.2019
comment
Я не определил liveata в теге данных, но все же я могу получить значения списка внутри адаптера привязки счетчика, потому что xml liveata извлекает значения асинхронно - person skyshine; 31.05.2019
comment
Позвольте нам продолжить это обсуждение в чате. - person Sanlok Lee; 31.05.2019

Пытаться

listLiveData = StudentDB.getAppDatabase(application).studentDao().getAllItems();
return listLiveData;
person Rajnish suryavanshi    schedule 29.05.2019
comment
Проверьте, возвращает ли этот studentDB.studentDao (). GetAllItems () данные или нет. - person Rajnish suryavanshi; 29.05.2019
comment
Я думаю, вы не наблюдаете за данными. Вот почему. Попробуйте listLiveData.setValue (список); - person Rajnish suryavanshi; 29.05.2019
comment
да, он возвращается, но он работает, если я делаю listLiveData.observe в действии - person skyshine; 29.05.2019
comment
Попробуйте сейчас этот код listLiveData.setValue (studentDB.studentDao (). GetAllItems ()); - person Rajnish suryavanshi; 29.05.2019
comment
вам не нужно устанавливать значение из комнаты, мы получаем listLiveData, который содержит список объектов - person skyshine; 29.05.2019
comment
Я получаю listlivedata из базы данных, вы можете еще раз проверить мой код - person skyshine; 29.05.2019