I made a movie search feature with searchview. when I do the first search, then the data or list will appear, but when I want to search again with a new search word and then I submit, the next data or list does not appear and only displays the previous data. there is not even a reaction to finding the next data. when I go out and return to the fragment, the search will go on as before, is there a solution to this? thank you
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);
}
}
Viewmodel
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;
}
}
Repository
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;
}
SOLVED
I found the problem in my repository and then I replaced it with LiveData and added postValue as the recipient of the new value. Besides, I tried to put the adapter in my observer and changed a bit to the setupRecyclerView method. until finally the search feature can run properly, thanks for those who have helped
MovieFragment
@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;
}
}
Repository
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;
}