Java 在使用viewModel翻转景观后保存应用程序状态
我试图在旋转到横向(配置更改)后保持活动状态。在官方文档中,它说使用viewModel应该处理这个问题,但实际上不是。显然,调用onCreate并重新记录所有内容。我的应用程序显示从api调用的图像列表。尝试了SaveStateHandle,但我认为它无法与Singleton中完成的ViewModel一起工作。不过我想了一件事,当我调用一次callApi方法时(如果调用了,我会设置一个静态标志),它工作得很好(在向下滚动并更改为横向后,它会停留在我滚动的地方) 回购: 视图模型:Java 在使用viewModel翻转景观后保存应用程序状态,java,android,Java,Android,我试图在旋转到横向(配置更改)后保持活动状态。在官方文档中,它说使用viewModel应该处理这个问题,但实际上不是。显然,调用onCreate并重新记录所有内容。我的应用程序显示从api调用的图像列表。尝试了SaveStateHandle,但我认为它无法与Singleton中完成的ViewModel一起工作。不过我想了一件事,当我调用一次callApi方法时(如果调用了,我会设置一个静态标志),它工作得很好(在向下滚动并更改为横向后,它会停留在我滚动的地方) 回购: 视图模型: public
public class PictureListViewModel extends ViewModel{
private MutableLiveData<List<Pictures>> pictureList = new MutableLiveData<>();
private PictureRepository pictureRepository;
public PictureListViewModel(SavedStateHandle savedStateHandle) {
pictureRepository = PictureRepository.getInstance();
}
//Gets its liveData from Repository
public LiveData<List<Pictures>> getPictures(){
return pictureRepository.getPictures();
}
public void picturesApi(String page, String limit) {
pictureRepository.picturesApi(page, limit);
}
}
公共类PictureListViewModel扩展了ViewModel{
私有MutableLiveData pictureList=新的MutableLiveData();
私人图片收藏图片收藏;
公共PictureListViewModel(SavedStateHandle SavedStateHandle){
pictureRepository=pictureRepository.getInstance();
}
//从存储库获取其liveData
公共LiveData getPictures(){
返回pictureRepository.getPictures();
}
公共无效图片API(字符串页,字符串限制){
pictureRepository.picturesApi(页数,限制);
}
}
主要活动:
public class MainActivity extends AppCompatActivity {
public static List<Pictures> imageList;
private MyRecycleAdapter recyclerAdapter;
private PictureListViewModel pictureListViewModel;
private ActivityMainBinding activityMainBinding;
private static boolean isNew = false;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
activityMainBinding = DataBindingUtil.setContentView(this, R.layout.activity_main);
pictureListViewModel = new ViewModelProvider(this).get(PictureListViewModel.class);
initRecyclerView();
subscribeObservers();
callAPI();
}
private void subscribeObservers()
{
//This is where Activity is observing the livedata in the ViewModel
pictureListViewModel.getPictures().observe(this, (List<Pictures> pictures) -> {
recyclerAdapter.updateRecycleAdapter(pictures);
});
}
private void initRecyclerView()
{
imageList = new ArrayList<>();
RecyclerView recycleView = findViewById(R.id.linear_layout_with_recycleView_ID);
GridLayoutManager gridLayoutManager = new GridLayoutManager(this, 2);
recycleView.setLayoutManager(gridLayoutManager);
recyclerAdapter = new MyRecycleAdapter(MainActivity.this, imageList);
recycleView.setAdapter(recyclerAdapter);
}
//MainActivity <-- PictureListViewModel <-- PictureRepository <-- PictureApiClient
private void picturesApi(String page, String limit)
{
pictureListViewModel.picturesApi(page, limit);
}
//Temp workaround for changing to landscape and saving state
private void callAPI(){
// if (!isNew)
// {
//Number of pages and number of images
picturesApi("4", "40");
isNew = true;
// }
}
}
public类MainActivity扩展了AppCompatActivity{
公共静态列表;
私人MyRecycleAdapter回收适配器;
私有PictureListViewModel PictureListViewModel;
私人活动主绑定活动主绑定;
私有静态布尔值isNew=false;
@凌驾
创建时受保护的void(Bundle savedInstanceState){
super.onCreate(savedInstanceState);
activityMainBinding=DataBindingUtil.setContentView(this,R.layout.activity_main);
pictureListViewModel=新的ViewModelProvider(this.get)(pictureListViewModel.class);
initRecyclerView();
subscribeObservers();
callAPI();
}
私有void subscribeObservators()
{
//这就是活动在ViewModel中观察livedata的地方
pictureListViewModel.getPictures()。观察(此,(列出图片)->{
recyclerAdapter.updateRecycleAdapter(图片);
});
}
私有void initRecyclerView()
{
imageList=新的ArrayList();
RecyclerView recycleView=findViewById(R.id.linear_layout_与_recycleView_id);
GridLayoutManager GridLayoutManager=新的GridLayoutManager(这个,2);
setLayoutManager(gridLayoutManager);
recyclerAdapter=新的MyRecycleAdapter(MainActivity.this,imageList);
recycleView.setAdapter(recyclerAdapter);
}
//MainActivity公共类PictureListViewModel扩展了ViewModel{
私人最终图片存储图片存储;
私人最终现场数据图片;
公共PictureListViewModel(SavedStateHandle SavedStateHandle){
pictureRepository=pictureRepository.getInstance();
pictures=pictureRepository.getPictures();
图片存储。图片API(“4”,“40”);
}
公共LiveData getPictures(){
返回图片;
}
公共无效图片API(字符串页,字符串限制){
pictureRepository.picturesApi(页数,限制);
}
}
及
public类MainActivity扩展了AppCompatActivity{
私人MyRecycleAdapter回收适配器;
私有PictureListViewModel PictureListViewModel;
私人活动主绑定活动主绑定;
@凌驾
创建时受保护的void(Bundle savedInstanceState){
super.onCreate(savedInstanceState);
activityMainBinding=DataBindingUtil.setContentView(this,R.layout.activity_main);
pictureListViewModel=新的ViewModelProvider(this.get)(pictureListViewModel.class);
initRecyclerView();
pictureListViewModel.getPictures()。观察(此,(列出图片)->{
recyclerAdapter.updateRecycleAdapter(图片);
});
}
私有void initRecyclerView(){
RecyclerView recycleView=findViewById(R.id.linear_layout_与_recycleView_id);
GridLayoutManager GridLayoutManager=新的GridLayoutManager(这个,2);
setLayoutManager(gridLayoutManager);
recyclerAdapter=new MyRecycleAdapter(MainActivity.this,Collections.emptyList());
recycleView.setAdapter(recyclerAdapter);
}
}
是的,如果您获取数据onCreate()
,则会出现上述情况。有两种方法可以处理此问题-
调用从ViewModel本身获取数据的方法
用这个-
如果(!::mBinding.i初始化){
}
使用此块,就像绑定已经初始化一样,它不会再这样做。@dreenko是一个很好的答案,但它与这个问题无关。这是关于在Java中正确使用ViewModel和LiveData的问题。@EpicPandaForce是对的,您提供的链接与MVVM和实时数据无关。您是对的,我将数据提取移到了vieModel和它的工作。谢谢!非常感谢你们,终于按预期工作。这是一个很好的教训,不要把Api调用放在Mainactivity中
public class PictureListViewModel extends ViewModel {
private final PictureRepository pictureRepository;
private final LiveData<List<Pictures>> pictures;
public PictureListViewModel(SavedStateHandle savedStateHandle) {
pictureRepository = PictureRepository.getInstance();
pictures = pictureRepository.getPictures();
pictureRepository.picturesApi("4", "40");
}
public LiveData<List<Pictures>> getPictures(){
return pictures;
}
public void picturesApi(String page, String limit) {
pictureRepository.picturesApi(page, limit);
}
}
public class MainActivity extends AppCompatActivity {
private MyRecycleAdapter recyclerAdapter;
private PictureListViewModel pictureListViewModel;
private ActivityMainBinding activityMainBinding;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
activityMainBinding = DataBindingUtil.setContentView(this, R.layout.activity_main);
pictureListViewModel = new ViewModelProvider(this).get(PictureListViewModel.class);
initRecyclerView();
pictureListViewModel.getPictures().observe(this, (List<Pictures> pictures) -> {
recyclerAdapter.updateRecycleAdapter(pictures);
});
}
private void initRecyclerView() {
RecyclerView recycleView = findViewById(R.id.linear_layout_with_recycleView_ID);
GridLayoutManager gridLayoutManager = new GridLayoutManager(this, 2);
recycleView.setLayoutManager(gridLayoutManager);
recyclerAdapter = new MyRecycleAdapter(MainActivity.this, Collections.emptyList());
recycleView.setAdapter(recyclerAdapter);
}
}