Android - Searchview 只能进行一次搜索

Android - Searchview can only do one search only

我用 searchview 做了一个电影搜索功能。当我第一次搜索时,数据或列表会出现,但是当我想用新的搜索词再次搜索然后提交时,下一个数据或列表不会出现,只显示以前的数据。甚至没有找到下一个数据的反应。当我出去 return 到片段时,搜索会像以前一样继续,有解决办法吗?谢谢

MovieSearchFragment

@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
    View view = inflater.inflate(R.layout.fragment_search_movie, container, false);

    recyclerView = view.findViewById(R.id.recyclerView);
    searchView = view.findViewById(R.id.searchView);
    searchView.setOnQueryTextListener(this);

    setupRecyclerView();

    return view;
}    

private void loadMovie(String search) {

    search = searchView.getQuery().toString();

    SearchMovieViewModel viewModel = ViewModelProviders.of(Objects.requireNonNull(getActivity())).get(SearchMovieViewModel.class);
    viewModel.init(search);
    viewModel.getSeacrhMovie().observe(this, new Observer<MovieResponse>() {
        @Override
        public void onChanged(MovieResponse movieResponse) {
            if (movieResponse != null) {
                List<Movie> movies = movieResponse.getResults();
                searchMovieList.addAll(movies);
                adapter.notifyDataSetChanged();
                showLoading(false);
            } else {
                showLoading(false);
                showError();
            }
        }
    });
}

@Override
public boolean onQueryTextSubmit(String query) {
    showLoading(true);
    loadMovie(query);
    return false;
}

@Override
public boolean onQueryTextChange(String s) {
    return false;
}

private void setupRecyclerView() {
    if (adapter == null) {
        adapter = new MovieAdapter(getActivity(), searchMovieList);
        recyclerView.setLayoutManager(new LinearLayoutManager(getActivity()));
        recyclerView.setAdapter(adapter);
        recyclerView.setItemAnimator(new DefaultItemAnimator());
        recyclerView.setNestedScrollingEnabled(true);
    }
}

视图模型

public class SearchMovieViewModel extends ViewModel {
    private MutableLiveData<MovieResponse> mutableLiveData;

    public void init(String movieTitle) {
        if (mutableLiveData != null) {
            return;
        }

        Repository repository = Repository.getInstance();
        mutableLiveData = repository.getSearchMovie(BuildConfig.API_KEY, movieTitle);
    }

    public MutableLiveData<MovieResponse> getSeacrhMovie() {
       return mutableLiveData;
    }
}

存储库

public MutableLiveData<MovieResponse> getSearchMovie(String apiKey, String movieTitle) {
    final MutableLiveData<MovieResponse> searchData = new MutableLiveData<>();
    api.getSearchMovie(BuildConfig.API_KEY, movieTitle).enqueue(new Callback<MovieResponse>() {
        @Override
        public void onResponse(Call<MovieResponse> call, Response<MovieResponse> response) {
            if (response.isSuccessful()) {
                searchData.setValue(response.body());
            } else {
                searchData.setValue(null);
            }
        }

        @Override
        public void onFailure(Call<MovieResponse> call, Throwable t) {
            searchData.setValue(null);
        }
    });
    return searchData;
}

我认为问题出在您的存储库中,您在每次调用时都在其中实例化了新的 MutableLiveData。您应该观察一个 MutableLiveData,并且您应该在每次收到新响应时对该 MutableLiveData 调用 postValue,以便观察者(在 Activity/Fragment 中)获取新数据。

已解决

我在我的存储库中发现了问题,然后我将其替换为 LiveData 并添加了 postValue 作为新值的接收者。此外,我尝试将适配器放在我的观察者中,并对 setupRecyclerView 方法进行了一些更改。终于搜索功能可以运行正常了,感谢大家的帮助

电影片段

  @Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
    View view = inflater.inflate(R.layout.fragment_search_movie, container, false);

    progressBar = view.findViewById(R.id.progressBar);
    recyclerView = view.findViewById(R.id.recyclerView);
    searchView = view.findViewById(R.id.searchView);
    searchView.setOnQueryTextListener(new SearchView.OnQueryTextListener() {
        @Override
        public boolean onQueryTextSubmit(String query) {
            showLoading(true);
            loadMovie(query);
            return false;
        }

        @Override
        public boolean onQueryTextChange(String newText) {
            return false;
        }
    });

    setupRecyclerView();

    return view;
}

private void loadMovie(String title) {
    title = searchView.getQuery().toString();

    SearchMovieViewModel viewModel = ViewModelProviders.of(this).get(SearchMovieViewModel.class);
    viewModel.init(title);
    viewModel.getSearchMovie().observe(this, new Observer<MovieResponse>() {
        @Override
        public void onChanged(MovieResponse movieResponse) {
            if (movieResponse != null) {
                List<Movie> movieList = movieResponse.getResults();
                adapter = new MovieAdapter(getActivity(), movieList);
                recyclerView.setAdapter(adapter);
                adapter.notifyDataSetChanged();
                showLoading(false);
            } else {
                showLoading(false);
                showError();
            }
        }
    });
}

private void setupRecyclerView() {
    recyclerView.setLayoutManager(new LinearLayoutManager(getActivity()));
    recyclerView.setItemAnimator(new DefaultItemAnimator());
    recyclerView.setNestedScrollingEnabled(true);
}

ViewModel

public class SearchMovieViewModel extends ViewModel {
private LiveData<MovieResponse> movieLiveData;

public void init(String movieTitle) {
    Repository repository = Repository.getInstance();
    movieLiveData = repository.getSearchMovie(BuildConfig.API_KEY, movieTitle);
}

public LiveData<MovieResponse> getSearchMovie() {
    return movieLiveData;
}
}

存储库

  public LiveData<MovieResponse> getSearchMovie(String apiKey, String movieTitle) {
    final MutableLiveData<MovieResponse> searchData = new MutableLiveData<>();
    api.getSearchMovie(BuildConfig.API_KEY, movieTitle).enqueue(new Callback<MovieResponse>() {
        @Override
        public void onResponse(Call<MovieResponse> call, Response<MovieResponse> response) {
            if (response.isSuccessful()) {
                searchData.postValue(response.body());
                searchData.setValue(response.body());
            } else {
                searchData.setValue(null);
            }
        }

        @Override
        public void onFailure(Call<MovieResponse> call, Throwable t) {
            searchData.setValue(null);
        }
    });
    return searchData;
}