Итак, у меня странный сценарий.Я реализовал приложение, которое имеет одну активность и два фрагмента.Оба фрагмента имеют опцию фильтра, в которой они могут выбрать категорию.
В зависимости от категории текущий фрагмент обновит и извлечет данные с новой категорией.
Я использую ViewModel для извлечения данных и LiveData для наблюдения за изменениями.
Мой Фрагмент class и My ViewModel class
When a button is clicked in the Activity class, this method is called:
public static void replaceFragment(Activity activity,
int navId,
int selectedPosition) {
Bundle bundle = new Bundle();
bundle.putInt(INTENT_CATEGORY, selectedPosition);
Navigation.findNavController(activity, R.id.fragment_nav_host)
.navigate(navId, bundle, new NavOptions.Builder()
.setEnterAnim(R.anim.flip_right_in)
.setExitAnim(R.anim.flip_right_out)
.setPopEnterAnim(R.anim.flip_left_in)
.setPopExitAnim(R.anim.flip_left_out)
.build());
}
Я использую компонент навигации.Поэтому странная проблема заключается в том, что когда я обновляю фрагмент, LiveData вызывается несколько раз.Я понимаю, что когда фрагмент воссоздается или обновляется, экземпляр viewModel остается прежним.Но не уверен, почему эта проблема происходит.
Если кто-то может помочь решить эту проблему, был бы признателен.
Весь код приложения можно найти здесь
ОБНОВЛЕНИЕ: Так что если я изменю свой метод initialiseViewModel () с:
private void initialiseViewModel() {
moviesListViewModel = ViewModelProviders.of(this, viewModelFactory).get(MovieListViewModel.class);
moviesListViewModel.fetchMovies(MENU_MOVIE_ITEM.get(getArguments() == null ? 0: getArguments().getInt(INTENT_CATEGORY)));
moviesListViewModel.getMoviesLiveData().observe(this, resource -> {
if(resource.isLoading()) {
displayLoader();
} else if(resource.data != null && !resource.data.isEmpty()) {
handleSuccessResponse(resource.data);
} else handleErrorResponse();
});
}
TO
private void initialiseViewModel() {
AppDatabase appDatabase = Room.databaseBuilder(getContext(),
AppDatabase.class, "Entertainment.db")
.allowMainThreadQueries().build();
HttpLoggingInterceptor logging = new HttpLoggingInterceptor();
logging.setLevel(HttpLoggingInterceptor.Level.BODY);
OkHttpClient.Builder httpClient = new OkHttpClient.Builder();
httpClient.addInterceptor(logging);
httpClient.addNetworkInterceptor(new RequestInterceptor());
httpClient.connectTimeout(30, TimeUnit.SECONDS);
httpClient.readTimeout(30, TimeUnit.SECONDS);
MovieApiService movieApiService =
new Retrofit.Builder()
.addConverterFactory(GsonConverterFactory.create(new GsonBuilder().create()))
.addCallAdapterFactory(RxJava2CallAdapterFactory.create())
.baseUrl(BASE_URL)
.client(httpClient.build())
.build().create(MovieApiService.class);
// moviesListViewModel = ViewModelProviders.of(this, viewModelFactory).get(MovieListViewModel.class);
moviesListViewModel = new MovieListViewModel(appDatabase.movieDao(), movieApiService);
moviesListViewModel.fetchMovies(MENU_MOVIE_ITEM.get(getArguments() == null ? 0: getArguments().getInt(INTENT_CATEGORY)));
moviesListViewModel.getMoviesLiveData().observe(this, resource -> {
if(resource.isLoading()) {
displayLoader();
} else if(resource.data != null && !resource.data.isEmpty()) {
handleSuccessResponse(resource.data);
} else handleErrorResponse();
});
}
тогда проблема, кажется, уходит :(. Есть какие-нибудь указатели на то, почему?