Я разрабатываю действие, используя MutableLiveData, чтобы мои фрагменты были в курсе последних результатов поиска, но Observer не запускается после обновления списка результатов.
У меня естьна основном задании - 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;
}
}
SearchProductFragment
@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()
, извлекаю из нее результаты и обновляю значение моей переменной (до этой точки работает отлично), наблюдатель не срабатывает.
Дополнительная информация:
- Я попытался включить и выключить поиск, чтобы активировать его в ViewPager. Оба не сработали.
Есть идеи?