【发布时间】:2019-08-13 19:37:27
【问题描述】:
我正在使用 android studios 来构建一个字典应用程序。在 SO 社区的帮助下,一切进展顺利,现在我有另一个问题。
我已经设置了几个自定义词典,以便用户可以存储和查看不同词典中的单词。 (例如文学、编程、一般等)
这些将是单词实体中的 FK id,并在用户添加新单词时填充。
在 MainActivity 中,我有一个“更改字典”的选项菜单项。这会打开一个 AlertDialog,用户可以在其中更改字典并从理论上看到一组新单词。
这就是问题所在。当用户选择特定字典时,数据库不会发生任何更改,因此附加到 WordViewModel 的 getWordsByDictionaryId() 方法的 onChange 不会触发。因此,LiveData> 不会重新填充。
onCreate() 方法中的代码:
// get all words from WordDao
mWordViewModel = ViewModelProviders.of(MainActivity.this).get(WordViewModel.class);
mWordViewModel.getWordByDictionaryId(dictionaryId).observe(MainActivity.this, new Observer<List<Word>>() {
@Override
public void onChanged(@Nullable List<Word> words) {
mainAdapter.setWords(words);
mAllWords = words;
mainAdapter.notifyDataSetChanged();
}
});
OnOptionsItemSelected() 方法中的代码:
AlertDialog.Builder changeDictionaryDialog = new AlertDialog.Builder(MainActivity.this);
changeDictionaryDialog.setTitle("Select Dictionary:");
LayoutInflater inflater = (LayoutInflater) getSystemService(Context.LAYOUT_INFLATER_SERVICE);
View view = inflater.inflate(R.layout.alert_dialog_spinner_view, null);
mDictionaryStringList = new ArrayList<>();
mDictionaryStringList = convertToList(mDictionaryList);
final Spinner dictionarySpinner = (Spinner) view.findViewById(R.id.alert_dialog_spinner);
ArrayAdapter<String> spinnerAdapter = new ArrayAdapter(MainActivity.this, android.R.layout.simple_spinner_dropdown_item, mDictionaryStringList);
spinnerAdapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
dictionarySpinner.setAdapter(spinnerAdapter);
dictionarySpinner.setSelection(0);
changeDictionaryDialog.setView(view);
changeDictionaryDialog.setPositiveButton("OK", new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
final String dictionaryValue = dictionarySpinner.getSelectedItem().toString();
for (Dictionary dictionary : mDictionaryList) {
if (dictionary.getDictionaryName().trim().equals(dictionaryValue)) {
dictionaryId = dictionary.getDid();
LiveData<List<Word>> myNewList = mWordViewModel.getWordByDictionaryId(dictionaryId);
List<Word> testList = myNewList.
}
}
}
});
changeDictionaryDialog.setNegativeButton("Cancel", null);
changeDictionaryDialog.create();
changeDictionaryDialog.show();
WordViewModel 中的代码:
public LiveData<List<Word>> getWordByDictionaryId(long dictionaryId) {
return mWordRepository.getWordByDictionaryId(dictionaryId);
}
WordDao 中的代码:
@Query("SELECT * FROM word_table WHERE dictionary_id =:dictionaryId")
public LiveData<List<Word>> getWordsByDictionaryID(long dictionaryId);
最后是Word实体:
@Entity(tableName = "word_table",
indices = { @Index(value = "word", unique = true),
@Index("dictionary_id") })
public class Word {
@PrimaryKey(autoGenerate = true)
private long id;
private String word;
@ColumnInfo(name = "dictionary_id")
private long dictionaryId;
@Ignore
public Word(String word, long dictionaryId) {
this.word = word;
this.dictionaryId = dictionaryId;
}
public Word(long id, String word, long dictionaryId) {
this.id = id;
this.word = word;
this.dictionaryId = dictionaryId;
}
public long getId() {
return id;
}
public void setId(long id) {
this.id = id;
}
public String getWord() {
return word;
}
public void setWord(String word) {
this.word = word;
}
public long getDictionaryId() {
return dictionaryId;
}
public void setDictionaryId(long dictionaryId) {
this.dictionaryId = dictionaryId;
}
}
我曾尝试设置一个后台线程 (AsyncTask),但有一次我这样做了,结果是在我需要它们之后出现的,因此返回值为 null。一些 SO 开发人员说不要使用 Asynctask,但我认为问题仍然是时间......
我还阅读了一些关于生成回调的内容。这在这种情况下真的有效吗?在我看来,它可能会让我与后台线程处于同一条船上。
当涉及到通过房间持久性通过视图模型通过 LiveData 通过 ???whatever 从 SQLite 数据库中获取数据时,我一直在努力学习如何从这种“非常简单的创建数据库的方法”中获取数据接下来呢???有没有“谷歌”的方式来做到这一点?或者这就是 RxJava 和其他库发挥作用的地方?
所以我的问题就是“如果没有通过实时数据的 onChange 事件,我究竟如何从数据库中获取实体对象列表?”在没有 LiveData 包装器的情况下调用查询是否有最佳实践或正确方法?还是一种直接在 LiveData 包装器中访问查询而不需要更改数据来完成任务的方法?
【问题讨论】:
-
当你传递一个新的 dictionaryId 时,它会使用该参数构造一个新的 Query 并且你的观察者只监听 那个 查询,所以当你的字典 id 改变时,你将拥有再次从 viewmodel 调用 get 函数以构造一个新查询并将观察者添加到该查询返回的 Livedata
-
您要做的是在构造查询后更改查询参数,我检查了文档和资源,一旦构造查询就无法更改参数,所以我害怕没有其他选择
-
我不太明白你在说什么......我理解的内容刚好可以做我所做的事情,但是对经验的理解还没有。您能否提供我提供给您的代码示例,说明如何再次从视图模型中调用 get 函数?您是否将 getWordByDictionaryId() 方法称为“get”方法?如果是这样,当我在 AlertDialog 中调用 GetWordByDictionaryId() 方法时,我无法查看或访问数据。我以为是因为它是“LiveData”。
-
这就是我的意思,当用户在对话框中选择一个选项时,您发送告诉视图模型或活动以更新 dictionaryId,然后使用您从 AlertDialog 获得的这个新 id 调用 GetWordByDictionaryId()
-
好的,我正在查看 LiveData
- > myNewList 对象,但看不到其中的数据。它似乎已经运行,但我如何提取数据?
标签: android android-studio mvvm android-room android-livedata