Where I am
I am attempting to fill a spinner with data from a database, using Room. The data is a list of terms, which have courses associated with them.
I want to use the spinner when creating a new course, to select a term to associate it with.
Currently, the spinner does not show a default option, but if you click the spinner it shows a list of the data to select from. After you select something from the spinner, it does not show what you have selected.
Here is my code for loading data into the spinner's adapter:
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);
}
Here is the 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);
}
Here is the 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);
}
}
I want to show the term name in the spinner and use the corresponding termId to perform the query.
What I've tried
I have tried using Mutable LiveData instead of LiveData but when I attempted to run it, I got an error that said:
Error:Not sure how to convert a Cursor to this method's return type
I'm really at a loss. Thanks for any help.
Added Repository
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;
}
}
}
I guess that you missing notifyDataSetChanged after update the termsList
variable.
Take a try with this:
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();
}
});
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With