Recyclerview数据在设备旋转时消失

问题描述 投票:0回答:1

即使我使用ViewModel,只要旋转设备,Recyclerview中的数据就会消失。我必须将makeSearch()方法放在onClick()方法内,因为我需要获取按钮抓取的文本并将其用作搜索参数。有没有更好的办法可以解决这个问题呢?我的代码就在这里:

SearchActivity:

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_search);

// What happens when the search button is clicked
materialButton.setOnClickListener(new View.OnClickListener() {
    @Override
     public void onClick(View v) {
        if (Objects.requireNonNull(textInputEditText.getText()).toString().isEmpty()) {
             textInputEditText.setError("Type a search query");
            } else {
                mSearchInput = Objects.requireNonNull(textInputEditText.getText()).toString();
                textInputEditText.setText("");
                makeSearch();
            }
        }
    });
}

// Gets the ViewModel, Observes the Question LiveData and delivers it to the Recyclerview
private void makeSearch() {
    final SearchAdapter searchAdapter = new SearchAdapter();
    SearchViewModel mSearchViewModel = new ViewModelProvider(this,
            new CustomSearchViewModelFactory(new SearchRepository())).get(SearchViewModel.class);
    mSearchViewModel.setQuery(mSearchInput);
    mSearchViewModel.getQuestionLiveData().observe(this, new Observer<List<Question>>() {
            @Override
            public void onChanged(List<Question> questions) {
                    mQuestions = questions;
                    searchAdapter.setQuestions(questions);
            }
        });
        mRecyclerView.setAdapter(searchAdapter);
        searchAdapter.setOnClickListener(mOnClickListener);
}

SearchViewModel:

public class SearchViewModel extends ViewModel {

private SearchRepository mSearchRepository;
private MutableLiveData<String> mSearchLiveData = new MutableLiveData<>();
private LiveData<List<Question>> mQuestionLiveData = Transformations.switchMap(mSearchLiveData, (query) -> {
    return mSearchRepository.getQuestions(query);
});

SearchViewModel(SearchRepository searchRepository) {
    this.mSearchRepository = searchRepository;
}

public LiveData<List<Question>> getQuestionLiveData() {
    return mQuestionLiveData;
}

public void setQuery(String query) {
    mSearchLiveData.setValue(query);
}
}

SearchRepository:

public class SearchRepository {

//private String inTitle;
private MutableLiveData<List<Question>> mQuestions = new MutableLiveData<>();

public SearchRepository() {
    //getQuestionsWithTextInTitle();
}

private void getQuestionsWithTextInTitle(String inTitle) {
    ApiService apiService = RestApiClient.getApiService(ApiService.class);
    Call<QuestionsResponse> call = apiService.getQuestionsWithTextInTitle(inTitle);
    call.enqueue(new Callback<QuestionsResponse>() {
        @Override
        public void onResponse(Call<QuestionsResponse> call, Response<QuestionsResponse> response) {
            QuestionsResponse questionsResponse = response.body();
            if (questionsResponse != null) {
                mQuestions.postValue(questionsResponse.getItems());
                //shouldShowData = true;
            } else {
                Log.d("SearchRepository", "No matching question");
                //shouldShowData = false;
            }
        }

        @Override
        public void onFailure(Call<QuestionsResponse> call, Throwable t) {
            //shouldShowData = false;
            t.printStackTrace();
        }
    });
}

public LiveData<List<Question>> getQuestions(String inTitle) {
    getQuestionsWithTextInTitle(inTitle);
    return mQuestions;
}
}
android android-activity android-recyclerview activity-lifecycle
1个回答
1
投票

您将搜索输入通过CustomSearchViewModelFactory传递到ViewModel的构造函数以及SearchRepository的构造函数的方法在任何情况下都行不通。第一次搜索CustomSearchViewModelFactory创建ViewModel时,第二次单击搜索时,SearchViewModel已经创建,并且工厂没有第二次被调用,这意味着您永远不会获得第二个查询。

相反,您应该归档ViewModel Overview documentation,并使用Transformations.switchMap()将输入(搜索字符串)转换为该给定查询的新LiveData<List<Question>>

这意味着您的ViewModel看起来像

public class SearchViewModel extends ViewModel {

    private SearchRepository mSearchRepository;
    private MutableLiveData<String> mSearchLiveData = new MutableLiveData<String>();
    private LiveData<List<Question>> mQuestionLiveData =
        Transformations.switchMap(mSearchLiveData, (query) -> {
            return mSearchRepository.getQuestions(query);
         });

    public SearchViewModel() {
        mSearchRepository = new SearchRepository();
    }

    public void setQuery(String query) {
        mSearchLiveData.setValue(query);
    }

    public LiveData<List<Question>> getQuestionLiveData() {
        return mQuestionLiveData;
    }
}

然后您将活动更新为:

  1. 始终观察getQuestionLiveData()(请注意,直到您实际设置了第一个查询,您才会获得对观察者的回调)
  2. setQuery()中的SearchViewModel上呼叫makeSearch()
  3. 完全删除CustomSearchViewModelFactory(不再需要)。>>
© www.soinside.com 2019 - 2024. All rights reserved.