Java 在使用viewModel翻转景观后保存应用程序状态

Java 在使用viewModel翻转景观后保存应用程序状态,java,android,Java,Android,我试图在旋转到横向(配置更改)后保持活动状态。在官方文档中,它说使用viewModel应该处理这个问题,但实际上不是。显然,调用onCreate并重新记录所有内容。我的应用程序显示从api调用的图像列表。尝试了SaveStateHandle,但我认为它无法与Singleton中完成的ViewModel一起工作。不过我想了一件事,当我调用一次callApi方法时(如果调用了,我会设置一个静态标志),它工作得很好(在向下滚动并更改为横向后,它会停留在我滚动的地方) 回购: 视图模型: public

我试图在旋转到横向(配置更改)后保持活动状态。在官方文档中,它说使用viewModel应该处理这个问题,但实际上不是。显然,调用onCreate并重新记录所有内容。我的应用程序显示从api调用的图像列表。尝试了SaveStateHandle,但我认为它无法与Singleton中完成的ViewModel一起工作。不过我想了一件事,当我调用一次callApi方法时(如果调用了,我会设置一个静态标志),它工作得很好(在向下滚动并更改为横向后,它会停留在我滚动的地方)

回购:

视图模型:

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