【问题标题】:Android - Searchview can only do one search onlyAndroid - Searchview 只能进行一次搜索
【发布时间】:2019-10-01 17:43:59
【问题描述】:

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

电影搜索片段

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

【问题讨论】:

  • 在java中尝试类似“recyclerView.adapter.notifyD..()”,我不确定java,但它在Kotlin中有效。
  • 好的,我会试试的

标签: android viewmodel searchview android-mvvm


【解决方案1】:

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

【讨论】:

    【解决方案2】:

    已解决

    我在我的存储库中发现了问题,然后我将其替换为 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);
    }
    

    视图模型

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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-05-10
      相关资源
      最近更新 更多