首页 > 解决方案 > 为什么当我返回活动时 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来获取和显示数据。ViewModelBookDetailActivityonCreate() 方法中初始化。

 @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文件中,BookDetailActivityMainActivity作为其父活动。用户可以通过按左上角的后退按钮返回MainActivity 。

图书视图模型

BookViewModel扩展了ViewModel类。它具有book、book detail 和 status的三个LiveData 对象Book LiveDataMainActivity观察。它返回书籍列表。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 类的扩展视图模型

标签: androidandroid-activityviewmodel

解决方案


使用下面的构造函数在 LiveData 的帮助下设置 ViewModel 中的数据

public BookViewModel(){
        repository = new BookRepository();
        bookList = repository.getBookList();
        status = repository.getStatus();
        bookDetail = repository.getBookDetail();
    }

或者通过setVlaue()方法在ViewModel 类中创建静态方法来设置 List 中的数据。

还请提供您在 ViewModel 中设置数据的类。


推荐阅读