【发布时间】:2019-10-26 20:31:52
【问题描述】:
我正在使用 MutableLiveData 开发一个活动,以使我的片段与从搜索中检索到的结果保持同步,但在结果列表更新后未触发观察者。
在主要活动中,我有一个 EditText,我在其中键入要搜索的内容,在它的正下方,有一个带有三个选项的 ViewPager 小部件,其中结果被细分为三个类别(在三个不同的片段上)。当我第一次进入活动时,我运行初始搜索以检索数据并填充三个片段。这非常有效。
SearchActivity.java
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_search);
mViewModel = ViewModelProviders.of(this).get(SearchViewModel.class);
/* Init TabMenu */
TabLayout tabSearchMenu = findViewById(R.id.tabSearchMenu);
ViewPager vpSearch = findViewById(R.id.vpSearchResult);
TabSearchPageAdapter tabSearchPageAdapter = new TabSearchPageAdapter(getSupportFragmentManager(), tabSearchMenu.getTabCount());
vpSearch.setAdapter(tabSearchPageAdapter);
vpSearch.addOnPageChangeListener(new TabLayout.TabLayoutOnPageChangeListener(tabSearchMenu));
/* Init Search */
etxtSearch = findViewById(R.id.etxtSearch);
etxtSearch.setOnEditorActionListener((textView, actionId, keyEvent) -> {
if (actionId == EditorInfo.IME_ACTION_SEARCH || actionId == EditorInfo.IME_ACTION_DONE
|| keyEvent.getAction() == KeyEvent.ACTION_DOWN || keyEvent.getAction() == KeyEvent.KEYCODE_ENTER) {
mViewModel.searchText(etxtSearch.getText().toString());
}
return false;
});
}
SearchViewModel.java
public class SearchViewModel extends ViewModel {
private MutableLiveData<List<ProductItemModel>> listProducts = new MutableLiveData<>(new ArrayList<>());
private List<ProductItemModel> mProducts = new ArrayList<>();
[...]
public void searchText(String text) {
// make search...
// ...
// ...
// Process Json result.
CompletionHandler completionHandler = (content, error) -> {
if (content != null && content.length() > 0) {
Log.d(TAG, content.toString());
Log.d(TAG, "searchText: found result.");
listProducts = new MutableLiveData<>(new ArrayList<>());
mProducts = new ArrayList<>();
try {
JSONArray products = content.getJSONArray("hits");
for (int i = 0; i < products.length(); i++) {
JSONObject prodObject = products.getJSONObject(i);
ProductItemModel prodItem = new ProductItemModel(prodObject);
mProducts.add(prodItem);
Log.d(TAG, "searchText: " + prodObject.toString());
}
listProducts.setValue(mProducts);
} catch (JSONException e) {
e.printStackTrace();
}
} else {
Log.d(TAG, "searchText: no hits");
}
};
}
[...]
MutableLiveData<List<ProductItemModel>> getProductList() {
if (listProducts == null)
return new MutableLiveData<>(new ArrayList<>());
return listProducts;
}
}
搜索产品片段
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
InitFragment();
}
[...]
private void InitFragment() {
mViewModel = ViewModelProviders.of(Objects.requireNonNull(getActivity())).get(SearchViewModel.class);
mViewModel.SearchProducts();
final Observer<List<ProductItemModel>> listObserver = result -> {
Log.d(TAG, "listObserver: observer modified.");
if (result.size() > 0) {
InitProductList(result);
}
};
mViewModel.getProductList().observe(getActivity(), listObserver);
}
已经尝试将片段内的方法InitFragment() 移动到OnActivityCreated,但也没有成功。
我知道一个事实是,观察者没有被触发是行不通的。我已经用断点进行了测试。
正如你们所看到的,当片段初始化时,方法SearchProducts() 被调用,结果完美地发送到 MutableLiveData 并触发观察者。但是每当我运行调用函数searchText() 的搜索,从中检索结果,并更新我的变量的值(到目前为止工作完美),观察者不会被触发。
额外信息:
- 我尝试在 查看页面。两者都不起作用。
有什么想法吗?
【问题讨论】:
-
我不能 100% 确定,但我相信 Android 团队的 this video 谈到了您面临的问题。
标签: java android mvvm mutablelivedata