首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >Post或Set MutableLiveData -未调用的观察者onChanged

Post或Set MutableLiveData -未调用的观察者onChanged
EN

Stack Overflow用户
提问于 2017-12-30 10:38:13
回答 1查看 7.7K关注 0票数 6

我发现了新的android体系结构组件,我想通过一个小的测试应用程序来测试这对ViewModel / LiveData。后者有两个片段(在一个ViewPager中),第一个片段创建/更新一个卡片列表(通过一个EditText),第二个片段显示所有卡片。

My ViewModel:

代码语言:javascript
运行
复制
public class CardsScanListViewModel extends AndroidViewModel {

    private MutableLiveData> cardsLiveData = new MutableLiveData();
    private HashMap cardsMap = new HashMap();

    public CardsScanListViewModel(@NonNull Application application) {
        super(application);
    }

    public MutableLiveData> getCardsLiveData() {
        return this.cardsLiveData;
    }

    public void saveOrUpdateCard(String id) {
        if(!cardsMap.containsKey(id)) {
            cardsMap.put(id, new Card(id, new AtomicInteger(0)));
        }
        cardsMap.get(id).getCount().incrementAndGet();
        this.cardsLiveData.postValue(cardsMap);
    }
}

我的第二个片段:

代码语言:javascript
运行
复制
public class CardsListFragment extends Fragment {

    CardsAdapter cardsAdapter;

    RecyclerView recyclerCardsList;

    public CardsListFragment() {}

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        final CardsScanListViewModel viewModel =
                ViewModelProviders.of(this).get(CardsScanListViewModel.class);

        observeViewModel(viewModel);
    }

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
                             Bundle savedInstanceState) {
        View v = inflater.inflate(R.layout.fragment_cards_list, container, false);
        recyclerCardsList = v.findViewById(R.id.recyclerCardsList);
        recyclerCardsList.setLayoutManager(new LinearLayoutManager(getActivity()));
        cardsAdapter = new CardsAdapter(getActivity());
        recyclerCardsList.setAdapter(cardsAdapter);

        return v;
    }

    private void observeViewModel(CardsScanListViewModel viewModel) {
        viewModel.getCardsLiveData().observe(this, new Observer  > () {
            @Override
            public void onChanged(@Nullable HashMap  cards) {
                if (cards != null) {
                    cardsAdapter.setCardsList(cards.values());
                }
            }
        });
    }
}

HashMap和我的MutableLiveData一样,更新得很好,但是我的第二个片段没有通过观察者接收到信息。

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2018-01-01 06:01:23

您正在观察,新实例 of ViewModel,而不是观察First片段使用的相同ViewModel

代码语言:javascript
运行
复制
final CardsScanListViewModel viewModel =
            ViewModelProviders.of(this).get(CardsScanListViewModel.class);

上面的代码为您的第二个片段CardsScanListViewModel初始化新的CardsListFragment实例,因为您将this作为上下文传递。如果您从这个片段中更新任何数据,它将在这个实例 of ViewModel中更新。

它在您的第一个片段中工作,因为它更新数据并观察来自同一个ViewModel实例的数据。

通过在两个片段中传递ViewModels活动上下文而不是片段上下文,以保持数据在两个片段之间的公共关系。

代码语言:javascript
运行
复制
final CardsScanListViewModel viewModel =
            ViewModelProviders.of(getActivity()).get(CardsScanListViewModel.class);

这将创建单实例 of CardsScanListViewModel,并且数据将在片段之间共享,因为它们从ViewModel单实例中观察LiveData

要确认,需要在更新列表后添加notifyDataSetChanged(),如果还没有在适配器本身中这样做

代码语言:javascript
运行
复制
private void observeViewModel(CardsScanListViewModel viewModel) {
    viewModel.getCardsLiveData().observe(this, new Observer  > () {
        @Override
        public void onChanged(@Nullable HashMap  cards) {
            if (cards != null) {
                cardsAdapter.setCardsList(cards.values());
                cardsAdapter.notifyDataSetChanged();
            }
        }
    });
}
票数 11
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/48033119

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档