我在ViewPager中有3个相同的片段,每个片段都包含一个ViewModel,每当列表更改时,我都会在其中观察片段的更改。
这里是观察者;
mReleasesViewModel = ViewModelProviders.of(this, new ReleasesViewModelFactory(filter)).get(ReleasesViewModel.class);
// livedata
mDatabaseLoading.setVisibility(View.VISIBLE);
mReleasesViewModel.getUpcomingReleases().observe(this, new Observer<List<_Release>>() {
@Override
public void onChanged(@Nullable List<_Release> releases) {
// whenever the list is changed
if (releases != null) {
mUpcomingGamesAdapter.setData(releases);
mUpcomingGamesAdapter.notifyDataSetChanged();
}
mDatabaseLoading.setVisibility(View.GONE);
}
});
现在MainActivity中有一个抽屉,其中包含可以从PC,Xbox和PS4等进行过滤的平台,当用户关闭抽屉时,我希望我的所有3个片段都可以优雅地更新,这是否可以通过viewmodel完成?像我如何观察列表更改和平台更改? “主活动”中的抽屉会将所选平台添加到Integer列表中,例如PS4的ID为3
我的ViewModel:
public class ReleasesViewModel extends ViewModel {
public static final String TAG = ViewModel.class.getSimpleName();
// Example: Whenever the value contained by this MutableLiveData changes, we will set the contained value to our TextView
// Livedata objects will usually be kept in the ViewModel class
private MutableLiveData<List<_Release>> upcomingReleases;
// this field [mMonthYearFilter] is passed by our fragment to the AndroidViewModel
// to pass additional argument to my custom AndroidViewModel I need a AndroidViewModelFactory
private String monthYearFilter;
private ReleasesRepository releasesRepository;
public ReleasesViewModel(String monthYearFilter) {
this.monthYearFilter = monthYearFilter;
}
public MutableLiveData<List<_Release>> getUpcomingReleases() {
if (upcomingReleases == null) {
upcomingReleases = new MutableLiveData<>();
// User settings region & platforms
String region = SharedPrefManager.read(SharedPrefManager.KEY_PREF_REGION, "North America");
Set<String> defaultPlatformsSet = new HashSet<>();
ArrayList<Integer> platforms = SharedPrefManager.read(SharedPrefManager.PLATFORM_IDS, defaultPlatformsSet);
releasesRepository = new ReleasesRepository(region, monthYearFilter, platforms);
loadReleases();
}
return upcomingReleases;
}
private void loadReleases() {
releasesRepository.addListener(new FirebaseDatabaseRepository.FirebaseDatabaseRepositoryCallback<_Release>() {
@Override
public void onSuccess(List<_Release> result) {
upcomingReleases.setValue(result);
}
@Override
public void onError(Exception e) {
Log.e(TAG, e.getMessage());
upcomingReleases.setValue(null);
}
});
}
}
答案 0 :(得分:1)
在活动级别仅创建1个ViewModel
并将其传递给片段。您的ViewModel
可以为每个片段提供3个LiveData
服务。假设您在一个片段中显示即将发布的版本,而在另一个片段中显示已经发布的游戏。因此,就像您即将发布的版本一样,请在ViewModel
中创建另一个方法,然后返回LiveData
,该方法将保存已发布游戏的列表。
在下面的代码mViewModel
中将传递给片段的视图模型。
mViewModel.getReleasedGames().observe(this, new Observer<List<_Release>>() {
@Override
public void onChanged(@Nullable List<_Release> released_games) {
// whenever the list is changed
if (released_games != null) {
mReleasedGamesAdapter.setData(releases);
mReleasedGamesAdapter.notifyDataSetChanged();
}
mDatabaseLoading.setVisibility(View.GONE);
}
});
答案 1 :(得分:1)
如果您想分享活动中的
ViewModel
,您所能做的就是 并使用其活动 context 对其进行分段重用。
因此,在活动级别上,请按以下方式使用:
mReleasesViewModel = ViewModelProviders.of(this, new ReleasesViewModelFactory(filter)).get(ReleasesViewModel.class); // this will make ViewModel on activity level.
当您的抽屉关闭事件被调用时,请使用此mReleasesViewModel
对象来调用您的load方法:
mReleasesViewModel.loadReleases(); // This will provide your list data to your LiveData object while observing on fragments.
现在,对于片段级别,使用活动上使用的ViewModel相同的对象,其上下文如下所示:
mReleasesViewModel = ViewModelProviders.of(getActivity()).get(ReleasesViewModel.class); // this will make same ViewModel object on fragment level as activity.
观察者调用的其余部分将如下所示:
mReleasesViewModel.getUpcomingReleases().observe(this, new Observer<List<_Release>>() {
@Override
public void onChanged(@Nullable List<_Release> releases) {
// whenever the list is changed
if (releases != null) {
mUpcomingGamesAdapter.setData(releases);
mUpcomingGamesAdapter.notifyDataSetChanged();
}
mDatabaseLoading.setVisibility(View.GONE);
}
});
让我知道是否仍然需要任何详细的说明,我将相应地修改答案。