Post 或设置 MutableLiveData - 未调用 Observer onChanged
Post or Set MutableLiveData - Observer onChanged not called
我发现了新的 android 架构组件,我想通过一个小型测试应用程序来测试这对 ViewModel / LiveData。后者有两个片段(在 ViewPager
中),第一个 creates/updates 卡片列表(通过 EditText
),第二个显示所有卡片。
我的视图模型:
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);
}
}
我的第二个片段:
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
一样,更新很好,但我的第二个片段没有通过观察者接收信息。
您正在观察ViewModel
的新实例,而不是观察您使用的相同ViewModel
第一个片段。
final CardsScanListViewModel viewModel =
ViewModelProviders.of(this).get(CardsScanListViewModel.class);
以上代码为您的第二个片段 CardsListFragment
初始化 CardsScanListViewModel
的新实例,因为您将 this
作为上下文传递。
如果您更新此片段中的任何数据,它将 update in this instance of ViewModel
.
它适用于您的第一个片段,因为它更新数据并观察来自 ViewModel
的同一实例的数据
为了保持 ViewModel 之间的数据通用,通过在两个片段中传递 activity 上下文 而不是片段上下文来启动视图模型。
final CardsScanListViewModel viewModel =
ViewModelProviders.of(getActivity()).get(CardsScanListViewModel.class);
这将创建 CardsScanListViewModel
的 单个实例 并且数据将在片段之间共享,因为它们从 单个实例观察 LiveData
个 ViewModel
。
为了确认,您需要在更新列表后添加 notifyDataSetChanged()(如果您尚未在适配器中添加)
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();
}
}
});
}
我发现了新的 android 架构组件,我想通过一个小型测试应用程序来测试这对 ViewModel / LiveData。后者有两个片段(在 ViewPager
中),第一个 creates/updates 卡片列表(通过 EditText
),第二个显示所有卡片。
我的视图模型:
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);
}
}
我的第二个片段:
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
一样,更新很好,但我的第二个片段没有通过观察者接收信息。
您正在观察ViewModel
的新实例,而不是观察您使用的相同ViewModel
第一个片段。
final CardsScanListViewModel viewModel =
ViewModelProviders.of(this).get(CardsScanListViewModel.class);
以上代码为您的第二个片段 CardsListFragment
初始化 CardsScanListViewModel
的新实例,因为您将 this
作为上下文传递。
如果您更新此片段中的任何数据,它将 update in this instance of ViewModel
.
它适用于您的第一个片段,因为它更新数据并观察来自 ViewModel
为了保持 ViewModel 之间的数据通用,通过在两个片段中传递 activity 上下文 而不是片段上下文来启动视图模型。
final CardsScanListViewModel viewModel =
ViewModelProviders.of(getActivity()).get(CardsScanListViewModel.class);
这将创建 CardsScanListViewModel
的 单个实例 并且数据将在片段之间共享,因为它们从 单个实例观察 LiveData
个 ViewModel
。
为了确认,您需要在更新列表后添加 notifyDataSetChanged()(如果您尚未在适配器中添加)
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();
}
}
});
}