android - 为什么当我返回活动时 ViewModel 不提供数据?
问题描述
MainActivity使用ViewModel显示书籍列表。当我从DetailActivity返回 MainActivity时。MainActivity不再有该列表。
为什么返回 MainActivity 时 ViewModel 不提供列表?
如何保留 MainActivity 的列表?
MainActivity 显示书籍列表。当用户触摸列表项时。它使用以下方法启动BookDetailActivity 。
private void startDetailActivity(String id){
Intent detailActivity = new Intent(this,BookDetailActivity.class);
detailActivity.putExtra("id",id);
startActivity(detailActivity);
}
它使用ViewModel来获取和显示图书列表。ViewModel就是通过这个方法初始化的。
@Override
protected void onResume(){
super.onResume();
bookViewModel = ViewModelProviders.of(this).get(BookViewModel.class);
//book list live data observer
bookViewModel.getBookList().observe(this, new Observer<ArrayList<Book>>() {
@Override
public void onChanged(@Nullable ArrayList<Book> books) {
Log.i("Adapter",""+books.size());
adapter.clear();
adapter.setData(books);
adapter.notifyDataSetChanged();
progressBar.setVisibility(View.GONE);
}
});
//status live data observer
bookViewModel.getStatus().observe(this, new Observer<Boolean>() {
@Override
public void onChanged(@Nullable Boolean aBoolean) {
showErrorMessage();
}
});
}
BookDetailActivity
此活动从数据中加载书籍详细信息。它还使用相同的ViewModel来获取和显示数据。ViewModel在BookDetailActivity的onCreate() 方法中初始化。
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_book_detail);
getSupportActionBar().setDisplayHomeAsUpEnabled(true);
Intent data = getIntent();
String id = data.getStringExtra("id");
viewModel = ViewModelProviders.of(this).get(BookViewModel.class);
//book detail observer
viewModel.getBookDetail().observe(this, new Observer<BookDetail>() {
@Override
public void onChanged(@Nullable BookDetail bookDetail) {
setDetail(bookDetail);
}
});//end of observer
viewModel.getBookDetail(id);
}
在Manifest文件中,BookDetailActivity将MainActivity作为其父活动。用户可以通过按左上角的后退按钮返回MainActivity 。
图书视图模型
BookViewModel扩展了ViewModel类。它具有book、book detail 和 status的三个LiveData 对象。Book LiveData由MainActivity观察。它返回书籍列表。BookDetailActivity观察书籍详细信息LiveData。它返回一个 BookDetail 对象。两个活动都观察网络请求状态的状态。
package com.google.firebase.udacity.findabook.viewmodel;
import android.app.Application;
import android.arch.lifecycle.AndroidViewModel;
import android.arch.lifecycle.LiveData;
import android.arch.lifecycle.ViewModel;
import android.util.Log;
import com.google.firebase.udacity.findabook.model.BookDetail;
import com.google.firebase.udacity.findabook.repository.BookRepository;
import com.google.firebase.udacity.findabook.model.Book;
import java.util.ArrayList;
public class BookViewModel extends ViewModel {
private LiveData<ArrayList<Book>> bookList;
private LiveData<Boolean> status;
private LiveData<BookDetail> bookDetail;
private BookRepository repository;
public BookViewModel(){
repository = new BookRepository();
bookList = repository.getBookList();
status = repository.getStatus();
bookDetail = repository.getBookDetail();
}
public LiveData<ArrayList<Book>> getBookList(){ return bookList;}
public LiveData<Boolean> getStatus(){return status;}
public LiveData<BookDetail> getBookDetail(){return bookDetail;}
public void searchByBookName(String bookName){
repository.makeRequestBasedOnBookName(bookName);
}
public void getBookDetail(String id){
repository.getBookDetail(id);
}
@Override
protected void onCleared() {
super.onCleared();
Log.i("Book view model","Cleared");
}
}
我努力了 -
-> 将视图模型的初始化从 resume 移动到 start 方法。
-> 来自 AndroidViewModel 类的扩展视图模型
解决方案
使用下面的构造函数在 LiveData 的帮助下设置 ViewModel 中的数据
public BookViewModel(){
repository = new BookRepository();
bookList = repository.getBookList();
status = repository.getStatus();
bookDetail = repository.getBookDetail();
}
或者通过setVlaue()方法在ViewModel 类中创建静态方法来设置 List 中的数据。
还请提供您在 ViewModel 中设置数据的类。
推荐阅读
- linux - 在 Linux 内核 4+ 中查找和更改伙伴分配器使用的位图
- android - Chrome/Android is prompting to save username on a search input
- javascript - 如何仅在当前路线上挂起“活动”课程?
- prolog - 有没有办法使用库函数删除列表的最后一个元素?
- node.js - 理解 nodejs `readline` 行为
- angular - PrimeNG (5.2.4) 树 - 无法通过单击展开树节点
- mapbox - 设置更改属性值后映射消隐
- xslt - 使用 xslt 的 msword 中的动态并排表
- sql - First Part of column values 选择 Distinct,但最后一部分(票号)需要是通配符
- angular - 如何将动态值传递给 matIcon?