如何在 android 的 ViewModel 中将数据从一个 LiveData 对象获取到另一个对象?
How to get data from one LiveData object to another within the ViewModel in android?
我正在尝试创建一个应用程序,它通过房间和 LiveData 使用 SQL 数据库。这是一个非常非常简单的测验应用程序。将显示一个问题和几个可能的答案。此外,还有一个用于浏览问题的下一个和上一个按钮。
有两个表:"table_question"和"table_answer"。
table_question 由以下列组成:id、question
table_answer: id, answer, id_question
id_question分配问题的答案,因为是1:n关系。
我从数据库中获取所有问题和所有答案的列表作为 LiveData 对象。另一方面,我想要一个 LiveData class QuizWorld 来处理所有需要显示在屏幕上的数据(已回答的问题、正确回答的问题、错误回答的问题、留下的问题等等)。 class 将被 Activity 观察到,因此可以更新 UI。
但是如何缩小两个 LiveData 列表 "questions" 和 "answers" 之间的差距以及创建 LiveData QuizWorld? QuizWorld 需要将这些信息保存在问题和答案中,但 LiveData 对象没有构造函数。
我有使用 Transformations.switchMap 的想法,但无法实现。即使我忘记了 QuizWorld class 并在 ViewModel 中做了所有事情,也会让我遇到无法访问 LiveData 列表的问题。
注意:实际上列表不一定是 LiveData 对象,因为 SQL 数据库在运行时不会更改。我只是不知道如何通过房间访问数据库。但如果将来数据库变得更加动态,这仍然是一个不错的功能,目前还没有计划。
这是部分代码:
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;
}
测验世界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;
}
}
主要Activity:
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
//...
}
}
}
}
我不完全确定你到底想要什么,但我宁愿建议你有一个包含一个问题及其答案的对象 QuestionWithAnswer 而不是两个不同的列表。然后你可以在 dao class 中查询谁会 return 那个 QuestionWithAnswer class (或者你的情况下这些对象的列表)
查看此 link 以查询多个表(包含用户和宠物的示例应该与您的相似)
在 Dao class 中,你会有这样的东西:
@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();
如果您想直接通过一个查询将对象包含在另一个对象中,另请参阅此 link。
或者,您可以进行转换,但我认为它不会非常有效,您会执行更多 SQL 查询,这通常对性能来说不是特别好(您不会注意到它如果你有一个小数据库,但其他样本有更多数据,你会)。
编辑:
如果需要转换 QuizWorld 对象中的列表,可以使用 Transformations.map 方法,如下所示:
quizWorldLiveData = Transformations.map(questionsWithAnswersLiveData, (data) -> new QuizWorld(data))
我正在尝试创建一个应用程序,它通过房间和 LiveData 使用 SQL 数据库。这是一个非常非常简单的测验应用程序。将显示一个问题和几个可能的答案。此外,还有一个用于浏览问题的下一个和上一个按钮。
有两个表:"table_question"和"table_answer"。
table_question 由以下列组成:id、question
table_answer: id, answer, id_question
id_question分配问题的答案,因为是1:n关系。
我从数据库中获取所有问题和所有答案的列表作为 LiveData 对象。另一方面,我想要一个 LiveData class QuizWorld 来处理所有需要显示在屏幕上的数据(已回答的问题、正确回答的问题、错误回答的问题、留下的问题等等)。 class 将被 Activity 观察到,因此可以更新 UI。
但是如何缩小两个 LiveData 列表 "questions" 和 "answers" 之间的差距以及创建 LiveData QuizWorld? QuizWorld 需要将这些信息保存在问题和答案中,但 LiveData 对象没有构造函数。
我有使用 Transformations.switchMap 的想法,但无法实现。即使我忘记了 QuizWorld class 并在 ViewModel 中做了所有事情,也会让我遇到无法访问 LiveData 列表的问题。
注意:实际上列表不一定是 LiveData 对象,因为 SQL 数据库在运行时不会更改。我只是不知道如何通过房间访问数据库。但如果将来数据库变得更加动态,这仍然是一个不错的功能,目前还没有计划。
这是部分代码:
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;
}
测验世界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;
}
}
主要Activity:
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
//...
}
}
}
}
我不完全确定你到底想要什么,但我宁愿建议你有一个包含一个问题及其答案的对象 QuestionWithAnswer 而不是两个不同的列表。然后你可以在 dao class 中查询谁会 return 那个 QuestionWithAnswer class (或者你的情况下这些对象的列表)
查看此 link 以查询多个表(包含用户和宠物的示例应该与您的相似) 在 Dao class 中,你会有这样的东西:
@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();
如果您想直接通过一个查询将对象包含在另一个对象中,另请参阅此 link。
或者,您可以进行转换,但我认为它不会非常有效,您会执行更多 SQL 查询,这通常对性能来说不是特别好(您不会注意到它如果你有一个小数据库,但其他样本有更多数据,你会)。
编辑:
如果需要转换 QuizWorld 对象中的列表,可以使用 Transformations.map 方法,如下所示:
quizWorldLiveData = Transformations.map(questionsWithAnswersLiveData, (data) -> new QuizWorld(data))