gpt4 book ai didi

java - MutableLiveData 的观察者未被触发

转载 作者:行者123 更新时间:2023-12-02 09:22:38 27 4
gpt4 key购买 nike

我正在使用 MutableLiveData 开发一个 Activity ,以使我的 fragment 与从搜索检索到的结果保持同步,但在更新结果列表后不会触发观察者。

我在主要 Activity 上有一个 EditText,我可以在其中输入要搜索的内容,在它的正下方有一个带有三个选项的 ViewPager 小部件,其中结果被分割为三个类别(在三个不同的 fragment 上)。当我第一次进入 Activity 时,我运行初始搜索来检索数据并填充三个 fragment 。这非常有效。

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;
}
}

搜索产品 fragment

    @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);
}

已经尝试将 fragment 内的方法 InitFragment() 移至 OnActivityCreated,但也没有成功。我知道一个事实是,观察者没有被触发是不起作用的。我已经用断点进行了测试。

正如你们所看到的,当 fragment 初始化时,将调用 SearchProducts() 方法,并将结果完美地发送到 MutableLiveData 并触发观察者。但是,每当我调用函数 searchText() 运行搜索、从中检索结果并更新变量的值(到目前为止工作完美)时,观察者就不会被触发。

额外信息:

  • 我尝试在 fragment 处于 Activity 状态时进行搜索查看分页器。两者都不起作用。

有什么想法吗?

最佳答案

问题是您返回了 MutableLiveData 的不同实例,但您的 fragment 仅观察它在 InitFragment() 方法中获取的第一个实例。

您还将 listProducts 设置为 MutableLiveData 的多个实例(首先在其声明站点,然后再次在 searchText() 方法中)而不仅仅是更新它所拥有的值。

详细来说,您不需要在 getProductsList() 方法中进行 null 检查,因为 listProducts 已初始化为 MutableLiveData 的新实例> 创建 View 模型时。

现在,MutableLiveData 实例所持有的值可能为 null..,您应该通过 setValue() 更新该值。对 MutableLiveData 值的任何 null 检查都可以在您在 fragment 中创建的 Observer 中完成。

关于java - MutableLiveData 的观察者未被触发,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58574481/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com