База данных комнаты: RecyclerView не обновляется после детального удаления данных - PullRequest
2 голосов
/ 01 октября 2019

Я использую 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.

Я надеюсь, что кто-то может помочь мне решить эту проблему. спасибо

...