Заполнить Spinner из LiveData (база данных комнат)

Где я

Я пытаюсь заполнить счетчик данными из базы данных, используя Room. Данные представляют собой список терминов, с которыми связаны курсы.

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

В настоящее время счетчик не показывает параметр по умолчанию, но если вы щелкнете по счетчику, он отобразит список данных для выбора. После того, как вы выбрали что-то из счетчика, он не показывает, что вы выбрали.

spinner до/после выбора

spinner, показывающий доступные параметры

Вот мой код для загрузки данных в адаптер счетчика:

        termsList = new ArrayList<>();
        termIdList = new ArrayList<>();
        mTermViewModel = new ViewModelProvider(this).get(TermViewModel.class);
        mTermViewModel.getAllTerms().observe(this, new Observer<List<TermEntity>>() {
            @Override
            public void onChanged(@Nullable final List<TermEntity> terms) {
                for (TermEntity term : terms) {
                    termsList.add(term.getTermName());
                    termIdList.add(term.getTermId());
                }
            }
        });

        ArrayAdapter<String> adapter = new ArrayAdapter<>(getContext(), android.R.layout.simple_spinner_item, termsList);
        adapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
        mTermSpinner.setAdapter(adapter);
    }

Вот TermDAO

@Dao
public interface TermDAO {
    @Insert(onConflict = OnConflictStrategy.REPLACE)
    void insert(TermEntity term);

    @Query("DELETE FROM terms")
    void deleteAllTerms();

    @Query("SELECT * FROM terms ORDER BY termId ASC")
    LiveData<List<TermEntity>> getAllTerms();

    @Query("SELECT * FROM terms WHERE termId = :termId")
    LiveData<List<TermEntity>> getTerm(int termId);

    @Query("SELECT termId FROM terms WHERE termName = :termName")
    LiveData<List<TermEntity>> getTermIdByTermName(String termName);
}

Вот TermViewModel

public class TermViewModel extends AndroidViewModel {
    private SchoolTrackerRepository mRepository;
    private LiveData<List<TermEntity>> mAllTerms;

    public TermViewModel(@NonNull Application application) {
        super(application);
        mRepository = new SchoolTrackerRepository(application);
        mAllTerms = mRepository.getAllTerms();
    }

    public LiveData<List<TermEntity>> getAllTerms() {
        return mAllTerms;
    }

    public void insert(TermEntity termEntity) {
        mRepository.insert(termEntity);
    }
}

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

Что я пробовал

Я пытался использовать Mutable LiveData вместо LiveData, но когда я попытался запустить его, я получил сообщение об ошибке:

Ошибка: не знаю, как преобразовать Cursor в возвращаемый тип этого метода.

Я действительно в растерянности. Спасибо за любую помощь.

Добавлен репозиторий

public class SchoolTrackerRepository {
    private TermDAO mTermDAO;
    private CourseDAO mCourseDAO;
    int termId;
    private LiveData<List<TermEntity>> mAllTerms;
    private LiveData<List<CourseEntity>> mAllCourses;
    private LiveData<List<CourseEntity>> mAssociatedCourses;

    public SchoolTrackerRepository(Application application) {
        SchoolTrackerDatabase db = SchoolTrackerDatabase.getDatabase(application);
        mTermDAO = db.termDAO();
        mCourseDAO = db.courseDAO();

        mAllTerms = mTermDAO.getAllTerms();
        mAllCourses = mCourseDAO.getAllCourses();
    }

    public LiveData<List<TermEntity>> getAllTerms() {
        return mAllTerms;
    }

    public LiveData<List<CourseEntity>> getAllCourses() {
        return mAllCourses;
    }

    public LiveData<List<CourseEntity>> getmAssociatedCourses(int termId) {
        return mAssociatedCourses;
    }

    public void insert(TermEntity termEntity) {
        new insertAsyncTask1(mTermDAO).execute(termEntity);
    }

    private static class insertAsyncTask1 extends AsyncTask<TermEntity, Void, Void> {
        private TermDAO mAsyncTaskDAO;

        insertAsyncTask1(TermDAO dao) {
            mAsyncTaskDAO = dao;
        }

        @Override
        protected Void doInBackground(final TermEntity... params) {
            mAsyncTaskDAO.insert(params[0]);
            return null;
        }
    }

    public void insert(CourseEntity courseEntity) {
        new insertAsyncTask2(mCourseDAO).execute(courseEntity);
    }

    private static class insertAsyncTask2 extends AsyncTask<CourseEntity, Void, Void> {
        private CourseDAO mAsyncCourseDAO;

        insertAsyncTask2(CourseDAO dao) {
            mAsyncCourseDAO = dao;
        }

        @Override
        protected Void doInBackground(final CourseEntity... params) {
            mAsyncCourseDAO.insert(params[0]);
            return null;
        }
    }
}

person Mark Scheer    schedule 16.12.2019    source источник
comment
также запишите здесь свой SchoolTrackerRepository код   -  person Hanzala    schedule 16.12.2019
comment
Я добавил репозиторий.   -  person Mark Scheer    schedule 16.12.2019


Ответы (1)


Я предполагаю, что вы пропустили notifyDataSetChanged после обновления переменной termsList.

Попробуйте с этим:

ArrayAdapter<String> adapter = new ArrayAdapter<>(getContext(), android.R.layout.simple_spinner_item, termsList);
adapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
mTermSpinner.setAdapter(adapter);

mTermViewModel = new ViewModelProvider(this).get(TermViewModel.class);
mTermViewModel.getAllTerms().observe(this, new Observer<List<TermEntity>>() {
    @Override
    public void onChanged(@Nullable final List<TermEntity> terms) {
        for (TermEntity term : terms) {
            termsList.add(term.getTermName());
            termIdList.add(term.getTermId());
        }

        //notifyDataSetChanged after update termsList variable here
        adapter.notifyDataSetChanged();
    }
});
person duongdt3    schedule 16.12.2019
comment
Это сделало это! Мне пришлось объявить адаптер перед onChanged(). Большое спасибо. - person Mark Scheer; 16.12.2019