Я использую RecyclerView
для отображения списка избранных фильмов, когда пользователь click
для элемента в моем списке RecyclerView
откроет DetailActivity
, и в этом Activity
пользователь может удалить данные из избранногосписок. когда пользователь нажимает onBackPressed
в DetailActivity
, в моем RecyclerView
ничего не происходит, он по-прежнему показывает данные, которые были удалены.
это мой фрагмент Movie:
public class MovieFragment extends BaseFragment<FragmentMovieBinding, MovieViewModel>
implements MovieNavigator, MovieAdapter.MovieAdapterListener {
@Inject
MovieAdapter adapter;
@Inject
LinearLayoutManager mLayoutManager;
@Inject
ViewModelProviderFactory factory;
FragmentMovieBinding fragmentMovieBinding;
private MovieViewModel movieViewModel;
private static final String ARG_PARAM = "flag_data";
private int mData;
public static MovieFragment newInstance(int data) {
Bundle args = new Bundle();
MovieFragment fragment = new MovieFragment();
args.putInt(ARG_PARAM, data);
fragment.setArguments(args);
return fragment;
}
@Override
public int getBindingVariable() {
return BR.viewModel;
}
@Override
public int getLayoutId() {
return R.layout.fragment_movie;
}
@Override
public MovieViewModel getViewModel() {
movieViewModel = ViewModelProviders.of(this, factory).get(MovieViewModel.class);
return movieViewModel;
}
@Override
public void handleError(String error) {
// handle error
}
@Override
public void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
if (getArguments() != null) {
mData = getArguments().getInt(ARG_PARAM);
}
movieViewModel.setNavigator(this);
adapter.setListener(this);
movieViewModel.fetchData(mData);
subscribeToLiveData();
}
@Override
public void onRetryClick() {
movieViewModel.fetchData(mData);
}
@Override
public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState);
fragmentMovieBinding = getViewDataBinding();
setUp();
}
private void subscribeToLiveData() {
movieViewModel.getMovieListLiveData().observe(this, movieList -> {
movieViewModel.setMovieDataList(movieList);
adapter.setData(movieList);
});
}
@Override
public void updateData(List<Movie> movieList) {
adapter.addItems(movieList);
}
private void setUp() {
mLayoutManager.setOrientation(LinearLayoutManager.VERTICAL);
fragmentMovieBinding.recyclerMovie.setLayoutManager(mLayoutManager);
fragmentMovieBinding.recyclerMovie.setItemAnimator(new DefaultItemAnimator());
fragmentMovieBinding.recyclerMovie.setAdapter(adapter);
adapter.notifyDataSetChanged();
}
}
Это мой адаптер:
public class MovieAdapter extends RecyclerView.Adapter<BaseViewHolder> {
public static final int VIEW_TYPE_EMPTY = 0;
public static final int VIEW_TYPE_NORMAL = 1;
private List<Movie> mMovieList;
private MovieAdapterListener mListener;
private Context mContext;
public MovieAdapter(Context context, List<Movie> movieList) {
this.mContext = context;
this.mMovieList = movieList;
}
@Override
public int getItemCount() {
if (mMovieList != null && mMovieList.size() > 0) {
return mMovieList.size();
} else {
return 1;
}
}
@Override
public int getItemViewType(int position) {
if (mMovieList != null && !mMovieList.isEmpty()) {
return VIEW_TYPE_NORMAL;
} else {
return VIEW_TYPE_EMPTY;
}
}
@Override
public void onBindViewHolder(BaseViewHolder holder, int position) {
holder.onBind(position);
}
@Override
public BaseViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
switch (viewType) {
case VIEW_TYPE_NORMAL:
ItemMovieBinding itemMovieBinding = ItemMovieBinding.inflate(LayoutInflater.from(parent.getContext()),
parent, false);
return new MovieViewHolder(itemMovieBinding);
case VIEW_TYPE_EMPTY:
default:
ItemEmptyMovieBinding emptyViewBinding = ItemEmptyMovieBinding.inflate(LayoutInflater.from(parent.getContext()),
parent, false);
return new EmptyViewHolder(emptyViewBinding);
}
}
public void addItems(List<Movie> movieList) {
mMovieList.addAll(movieList);
notifyDataSetChanged();
}
public void setData(List <Movie> movieList){
if (mMovieList !=null&& mMovieList.size()>0){
mMovieList.clear();
mMovieList.addAll(movieList);
}
notifyDataSetChanged();
}
public void clearItems() {
mMovieList.clear();
}
public void setListener(MovieAdapterListener listener) {
this.mListener = listener;
}
public interface MovieAdapterListener {
void onRetryClick();
}
public class MovieViewHolder extends BaseViewHolder implements MovieItemViewModel.MovieItemViewModelListener {
private ItemMovieBinding mBinding;
private MovieItemViewModel mMovieItemViewModel;
public MovieViewHolder(ItemMovieBinding binding) {
super(binding.getRoot());
this.mBinding = binding;
}
@Override
public void onBind(int position) {
final Movie movie = mMovieList.get(position);
mMovieItemViewModel = new MovieItemViewModel(movie, this);
mBinding.setViewModel(mMovieItemViewModel);
mBinding.executePendingBindings();
}
@Override
public void onItemClick(int id) {
Intent intent = DetailActivity.newIntent(mContext);
intent.putExtra(INTENT_ID, id);
intent.putExtra(INTENT_FLAG, 1);
mContext.startActivity(intent);
}
}
public class EmptyViewHolder extends BaseViewHolder implements MovieEmptyItemViewModel.MovieEmptyItemViewModelListener {
private ItemEmptyMovieBinding mBinding;
public EmptyViewHolder(ItemEmptyMovieBinding binding) {
super(binding.getRoot());
this.mBinding = binding;
}
@Override
public void onBind(int position) {
MovieEmptyItemViewModel emptyItemViewModel = new MovieEmptyItemViewModel(this);
mBinding.setViewModel(emptyItemViewModel);
}
@Override
public void onRetryClick() {
mListener.onRetryClick();
}
}
}
это мой MovieViewModel
. класс:
public class MovieViewModel extends BaseViewModel<MovieNavigator> {
private final MutableLiveData<List<Movie>> movieListLiveData;
private final ObservableList<Movie> movieDataList = new ObservableArrayList<>();
public MovieViewModel(DataManager dataManager, SchedulerProvider schedulerProvider) {
super(dataManager, schedulerProvider);
movieListLiveData = new MutableLiveData<>();
// fetchData();
}
public void fetchData(int data) {
setIsLoading(true);
if (data == 1) {
getCompositeDisposable().add(getDataManager()
.getApiHelper().doMovieCall(URLConfig.API_KEY, getDataManager().getLanguage())
.subscribeOn(getSchedulerProvider().io())
.observeOn(getSchedulerProvider().ui())
.subscribe(movieResponse -> {
if (movieResponse != null && movieResponse.getResults() != null) {
movieListLiveData.setValue(movieResponse.getResults());
}
setIsLoading(false);
}, throwable -> {
setIsLoading(false);
}));
}else if (data == 2){
getCompositeDisposable().add(getDataManager()
.getDbHelper().getAllFavMovie()
.subscribeOn(getSchedulerProvider().io())
.observeOn(getSchedulerProvider().ui())
.subscribe(movieResponse -> {
if (movieResponse != null) {
movieListLiveData.setValue(movieResponse);
}
setIsLoading(false);
}, throwable -> {
setIsLoading(false);
}));
}
}
public LiveData<List<Movie>> getMovieListLiveData() {
return movieListLiveData;
}
public ObservableList<Movie> getMovieDataList() {
return movieDataList;
}
public void setMovieDataList(List<Movie> movies) {
movieDataList.clear();
movieDataList.addAll(movies);
}
}
Для деталей, это мой DetailActivity
:
public class DetailActivity extends BaseActivity<ActivityDetailBinding, DetailViewModel> implements DetailNavigator {
@Inject
ViewModelProviderFactory factory;
private DetailViewModel detailViewModel;
public static final String INTENT_ID = "id_intent";
public static final String INTENT_FLAG = "id_flag";
private ActivityDetailBinding mActivityDetailBinding;
public static Intent newIntent(Context context) {
return new Intent(context, DetailActivity.class);
}
@Override
public int getBindingVariable() {
return BR.viewModel;
}
@Override
public int getLayoutId() {
return R.layout.activity_detail;
}
@Override
public DetailViewModel getViewModel() {
detailViewModel = ViewModelProviders.of(this, factory).get(DetailViewModel.class);
return detailViewModel;
}
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
mActivityDetailBinding = getViewDataBinding();
detailViewModel.setNavigator(this);
initData(savedInstanceState);
initView();
}
private void initData(Bundle savedInstanceState) {
if (savedInstanceState == null) {
Bundle extras = getIntent().getExtras();
if (extras != null) {
int id = extras.getInt(INTENT_ID, 0);
int flag = extras.getInt(INTENT_FLAG, 0);
if (isNetworkConnected()) {
detailViewModel.fetchDetail(id, flag);
detailViewModel.setIsConnected(true);
} else {
detailViewModel.setIsConnected(false);
CommonUtils.ShowSnackBars(mActivityDetailBinding.getRoot(), getString(R.string.msg_error_connection), 0, this);
}
}
}
}
private void initView() {
if (getSupportActionBar() != null) {
getSupportActionBar().hide();
}
getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN, WindowManager.LayoutParams.FLAG_FULLSCREEN);
}
@Override
public void ShowProgressDialog(Boolean loading) {
if (loading) {
showLoading();
} else {
hideLoading();
}
}
@Override
public void onBackArrowClick() {
onBackPressed();
}
@Override
public void onFavProcess(int flag) {
if (flag == 0) {
CommonUtils.ShowSnackBars(mActivityDetailBinding.getRoot(), getString(R.string.msg_success_add_fav), 1, this);
}else {
CommonUtils.ShowSnackBars(mActivityDetailBinding.getRoot(), getString(R.string.msg_success_remove_fav), 1, this);
}
}
@Override
public String noDesc() {
return getResources().getString(R.string.no_desc);
}
}
, а это мой DetailViewModel
класс:
public class DetailViewModel extends BaseViewModel<DetailNavigator> {
private final ObservableField<String> originalName = new ObservableField<>();
private final ObservableField<String> releaseDate = new ObservableField<>();
private final ObservableField<String> overview = new ObservableField<>();
private final ObservableField<String> genreMovie = new ObservableField<>();
private final ObservableField<String> posterPath = new ObservableField<>();
private final ObservableField<String> voteAverage = new ObservableField<>();
private MutableLiveData<Integer> idDetail = new MutableLiveData<>();
private MutableLiveData<Boolean> flagDetail = new MutableLiveData<>();
private MutableLiveData<Integer> flagScreen = new MutableLiveData<>();
private Movie movie;
private TvShow tvShow;
public DetailViewModel(DataManager dataManager, SchedulerProvider schedulerProvider) {
super(dataManager, schedulerProvider);
}
public void fetchDetail(int id, int flag) {
if (flag == 1) {
getNavigator().ShowProgressDialog(true);
getCompositeDisposable().add(getDataManager()
.getApiHelper().doDetailMovie(id, URLConfig.API_KEY, getDataManager().getLanguage())
.subscribeOn(getSchedulerProvider().io())
.observeOn(getSchedulerProvider().ui())
.subscribe(detailResponse -> {
flagScreen.setValue(flag);
setUpData(detailResponse);
getNavigator().ShowProgressDialog(false);
}, throwable -> {
getNavigator().ShowProgressDialog(false);
}));
} else if (flag == 2) {
getNavigator().ShowProgressDialog(true);
getCompositeDisposable().add(getDataManager()
.getApiHelper().doDetailTV(id, URLConfig.API_KEY, getDataManager().getLanguage())
.subscribeOn(getSchedulerProvider().io())
.observeOn(getSchedulerProvider().ui())
.subscribe(detailResponse -> {
flagScreen.setValue(flag);
setUpData(detailResponse);
getNavigator().ShowProgressDialog(false);
}, throwable -> {
getNavigator().ShowProgressDialog(false);
}));
}
}
private void setUpData(DetailResponse detailResponse) {
if (flagScreen.getValue() == 1) {
movie = new Movie();
movie.setId(detailResponse.getId());
movie.setTitle(detailResponse.getOriginal_title());
movie.setPoster_path(detailResponse.getPoster_path());
movie.setRelease_date(detailResponse.getRelease_date());
movie.setVote_average(detailResponse.getVote_average());
} else {
tvShow = new TvShow();
tvShow.setId(detailResponse.getId());
tvShow.setTitle(detailResponse.getOriginal_name());
tvShow.setPoster_path(detailResponse.getPoster_path());
tvShow.setFirst_air_date(detailResponse.getFirst_air_date());
tvShow.setVote_average(detailResponse.getVote_average());
}
if (detailResponse.getOriginal_name() != null) {
originalName.set(detailResponse.getOriginal_name());
} else if (detailResponse.getOriginal_title() != null) {
originalName.set(detailResponse.getOriginal_title());
} else {
}
if (detailResponse.getFirst_air_date() != null) {
releaseDate.set(detailResponse.getFirst_air_date());
} else {
releaseDate.set(detailResponse.getRelease_date());
}
if (!detailResponse.getOverview().equals("")) {
overview.set(detailResponse.getOverview());
} else {
overview.set(getNavigator().noDesc());
}
posterPath.set(String.valueOf(detailResponse.getPoster_path()));
voteAverage.set(String.valueOf(detailResponse.getVote_average()));
String genres = "";
for (int i = 0; i < detailResponse.getGenreList().size(); i++) {
genres = genres + detailResponse.getGenreList().get(i).getName();
if (i != detailResponse.getGenreList().size() - 1) {
genres = genres + ", ";
}
}
genreMovie.set(genres);
idDetail.setValue(detailResponse.getId());
setUpFlagFav();
}
private void setUpFlagFav() {
if (flagScreen.getValue() == 1) {
getCompositeDisposable().add(getDataManager()
.getDbHelper().getMovie(idDetail.getValue())
.subscribeOn(getSchedulerProvider().io())
.observeOn(getSchedulerProvider().ui())
.subscribe(response -> {
if (response.size() > 0) {
flagDetail.setValue(true);
} else {
flagDetail.setValue(false);
}
Log.i("CEK INSERT", String.valueOf(flagDetail.getValue()));
}, throwable -> {
flagDetail.setValue(false);
}));
}else if (flagScreen.getValue() == 2) {
getCompositeDisposable().add(getDataManager()
.getDbHelper().getTv(idDetail.getValue())
.subscribeOn(getSchedulerProvider().io())
.observeOn(getSchedulerProvider().ui())
.subscribe(response -> {
if (response.size() > 0) {
flagDetail.setValue(true);
} else {
flagDetail.setValue(false);
}
Log.i("CEK INSERT", String.valueOf(flagDetail.getValue()));
}, throwable -> {
flagDetail.setValue(false);
}));
}
}
public void onBackArrowClick() {
getNavigator().onBackArrowClick();
}
public void onFavClick() {
if (flagScreen.getValue() == 1) {
if (flagDetail.getValue()) {
getCompositeDisposable().add(getDataManager()
.getDbHelper().deleteMovie(idDetail.getValue())
.flatMap(aBoolean -> getDataManager().getDbHelper().deleteMovie(idDetail.getValue()))
.subscribeOn(getSchedulerProvider().io())
.observeOn(getSchedulerProvider().ui())
.subscribe(aBoolean -> {
getNavigator().onFavProcess(1);
flagDetail.setValue(false);
Log.i("CEK delete", String.valueOf(aBoolean));
}, throwable -> {
getNavigator().onFavProcess(1);
}));
} else {
getCompositeDisposable().add(getDataManager()
.getDbHelper().saveMovie(movie)
.flatMap(aBoolean -> getDataManager().getDbHelper().saveMovie(movie))
.subscribeOn(getSchedulerProvider().io())
.observeOn(getSchedulerProvider().ui())
.subscribe(aBoolean -> {
getNavigator().onFavProcess(0);
flagDetail.setValue(true);
Log.i("CEK INSERT", String.valueOf(aBoolean));
}, throwable -> {
getNavigator().onFavProcess(0);
}));
}
}else {
if (flagDetail.getValue()) {
getCompositeDisposable().add(getDataManager()
.getDbHelper().deleteTv(idDetail.getValue())
.flatMap(aBoolean -> getDataManager().getDbHelper().deleteMovie(idDetail.getValue()))
.subscribeOn(getSchedulerProvider().io())
.observeOn(getSchedulerProvider().ui())
.subscribe(aBoolean -> {
getNavigator().onFavProcess(1);
flagDetail.setValue(false);
}, throwable -> {
getNavigator().onFavProcess(1);
}));
} else {
getCompositeDisposable().add(getDataManager()
.getDbHelper().saveTv(tvShow)
.flatMap(aBoolean -> getDataManager().getDbHelper().saveMovie(movie))
.subscribeOn(getSchedulerProvider().io())
.observeOn(getSchedulerProvider().ui())
.subscribe(aBoolean -> {
getNavigator().onFavProcess(0);
flagDetail.setValue(true);
}, throwable -> {
getNavigator().onFavProcess(0);
}));
}
}
}
public ObservableField<String> getOriginalName() {
return originalName;
}
public ObservableField<String> getReleaseDate() {
return releaseDate;
}
public ObservableField<String> getOverview() {
return overview;
}
public ObservableField<String> getGenreMovie() {
return genreMovie;
}
public ObservableField<String> getPosterPath() {
return posterPath;
}
public ObservableField<String> getVoteAverage() {
return voteAverage;
}
public MutableLiveData<Boolean> getFlagDetail() {
return flagDetail;
}
}
вещьменя смущает то, что я уже подписался на LiveData
в MovieFragment
, используя этот код:
private void subscribeToLiveData () {
movieViewModel.getMovieListLiveData (). observe (this, movieList -> {
movieViewModel.setMovieDataList (movieList);
adapter.setData (movieList);
});
}
, но когда я делаю onBackPressed
в DetailActivity
, в RecyclerView
нет изменений. Но данные изменятся, если я сначала перейду к другому меню, например Catalog
, и снова вернусь к Favorite
, тогда изменится RecyclerView
.
Я надеюсь, что кто-то может помочь мне решить эту проблему. спасибо