Reputation: 589
I am trying to create an app which uses a SQL database via room and LiveData. It's a very very simple Quiz App. There will be a question and couple of possible answers displayed. Additionally there is a next and previous button to navigate through the questions.
There are two tables: "table_question" and "table_answer".
table_question consists of following columns: id, question
table_answer: id, answer, id_question
id_question allocates the answers to the questions because it is a 1:n relationship.
I get a list of all questions and all answers from the database as a LiveData object. On the other hand I would like to have a LiveData class QuizWorld which handles all the data necessary to be displayed on the screen (questions answered, right answered, wrongly answered, questions left and so on). This class will be observed by the Activity so the UI can be updated.
But how do I close the gap between the two LiveData Lists "questions" and "answers" and the creation of the LiveData QuizWorld? QuizWorld will need those information saved in questions and answers but a LiveData object doesn't have a constructor.
I had the idea of using Transformations.switchMap but I couldn't make it work. Even if I forget the QuizWorld class and do everything within ViewModel leaves me with the Problem that I cannot access the LiveData Lists.
Note: It is actually not necessary that the Lists are LiveData objects because the SQL database doesn't change during runtime. I just had no other idea how to access the database via room. But it would still be a nice feature to have if in future the database becomes more dynamically which is not planned yet.
Here is a part of the code:
public class MyViewModel extends AndroidViewModel{
private Repository mRepository;
private LiveData<List<Question>> questions;
private LiveData<List<Answer>> answers;
private LiveData<QuizWorld> mQuizWorld;
public MyViewModel (Application application) {
super(application);
mRepository = new Repository(application);
questions = mRepository.getQuestions;
answers = mRepository.getAnswers;
!!!!!Here should be the missing code I have no idea for!!!!!
}
public LiveData<QuizWorld> getQuizWorld(){
return mQuizWorld;
}
The QuizWorld class:
public class QuizWorld{
private List<Question> questions;
private List<Answer> answers;
private int score;
public QuizWorld(List<Question> questions, List<Answer> answers){
this.questions = questions;
this.answers = answers;
init();
}
private void init() {
//do things with the questions and answers list
}
public int getScore(){
return score;
}
}
MainActivity:
public class MainActivity {
private LiveData<QuizWorld> mQuizWorld;
private MyViewModel myViewModel;
private TextView tvScore;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedinstanceState);
setContenView(...);
tvScore = (TextView) findViewById(R.id.tv_Score);
myViewModel = ViewModelProvider.of(this).get(MyViewModel.class)
mQuizViewModel.getQuizWorld().observe(this, new
Observer<QuizWorld>() {
@Override
public void onChanged(QuizWorld quizWorld){
tvScore.setText(quizWorld.getScore));
//show count of questions wrongly answered
//show count of questions remaining
//...
}
}
}
}
Upvotes: 2
Views: 2806
Reputation: 1424
I am not completely sure about what you want exactly, but I would rather suggest you to have an object QuestionWithAnswer containing one question and its answers instead of two different lists. Then you could make a query in the dao class who would return that QuestionWithAnswer class (or a list of these objects in your case)
See this link for querying multiple tables (the sample with user and pet should look like yours) In the Dao class, you would have something like :
@Query("SELECT id as isQuestion, question, id as idAnswer, answer " +
"FROM table_question " +
"LEFT JOIN table_answer on table_question.id = table_answer.id_question")
public LiveData<List<QuestionWithAnswer>> loadResults();
See also this link if you want to have objects inside an other object directly with one query.
Alternatively, you could make a Transformation but I don't think it would be very efficient, you would do more SQL queries and that is generally not super good for performances (you wouldn't notice it if you have a small database, but with other samples with more data you would).
EDIT :
If you need to convert the List in a QuizWorld object, you can use the Transformations.map method like this :
quizWorldLiveData = Transformations.map(questionsWithAnswersLiveData, (data) -> new QuizWorld(data))
Upvotes: 1