Два RecyclerView и один onClick, показывающие содержимое выбранного элемента соответствующего RecyclerView

#java #android #android-recyclerview #onclick

#java #Android #android-recyclerview #onclick

Вопрос:

Проблема
В моем активе у меня есть два RecyclerViews, показывающих популярные фильмы и фильмы с самым высоким рейтингом соответственно. Когда я нажимаю на фильм в RecyclerView, этот фильм отправляется в действие с указанием его деталей. Я возвращаюсь домой, и если я нажимаю на фильм другого RecyclerView, отображается ранее выбранный фильм. Мне нужно показать подробную информацию о любом просмотренном фильме в любом RecyclerView.

У меня есть один ViewHolder (MovieViewHolder)

  public class MovieViewHolder extends RecyclerView.ViewHolder implements View.OnClickListener {

    //Widgets
    TextView title, rating;
    ImageView imageView;

    //Click listener
    OnMovieListener onMovieListener ;

    public MovieViewHolder(@NonNull View itemView, OnMovieListener onMovieListener) {
        super(itemView);

        this.onMovieListener = onMovieListener;

        title = itemView.findViewById(R.id.movie_title);
        imageView = itemView.findViewById(R.id.movie_img);
        rating = itemView.findViewById(R.id.rating_bar);

        itemView.setOnClickListener(this);
    }

    @Override
    public void onClick(View v) {

        onMovieListener.onMovieClick(getAdapterPosition());

    }
 

Интерфейс

 public interface OnMovieListener {

    void onMovieClick(int position);
    void onCategoryClick(String category);


}
 

Это два адаптера:
Это для популярных фильмов

 public class MovieRecyclerView extends RecyclerView.Adapter<RecyclerView.ViewHolder> {

    private List<MovieModel> mMovies;
    private final OnMovieListener onMovieListener;


    public MovieRecyclerView(OnMovieListener onMovieListener) {
        this.onMovieListener = onMovieListener;

    }


    @NonNull
    @Override
    public RecyclerView.ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
        View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.movie_item,
                parent, false);


        return new MovieViewHolder(view, onMovieListener);

    }

    @Override
    public void onBindViewHolder(@NonNull RecyclerView.ViewHolder holder, int position) {

        ((MovieViewHolder) holder).title.setText(mMovies.get(position).getTitle());
        ((MovieViewHolder) holder).rating.setText(String.valueOf((float) (mMovies.get(position).getVote_average())));

        //ImageView: Using Glide Library
        Glide.with(holder.itemView.getContext())
                .load("https://image.tmdb.org/t/p/w500/"
                          mMovies.get(position).getPoster_path())
                .into(((MovieViewHolder) holder).imageView);


    }

    @Override
    public int getItemCount() {
        if (mMovies != null) {
            return mMovies.size();
        }
        return 0;
    }

    public void setmMovies(List<MovieModel> mMovies) {
        this.mMovies = mMovies;
        notifyDataSetChanged();
    }

    //Getting the id of the movie clicked
    public MovieModel getSelectedMovie(int position) {
        if (mMovies != null) {
            if (mMovies.size() > 0) {
                return mMovies.get(position);
            }
        }
        return null;
    }
 

Это для top_rated

 public class MovieLatestRecyclerView extends RecyclerView.Adapter<RecyclerView.ViewHolder> {

    private List<MovieModel> mMoviesLatest;
    private OnMovieListener onMovieListener;

    public MovieLatestRecyclerView(OnMovieListener onMovieListener) {
        this.onMovieListener = onMovieListener;
    }

    @NonNull
    @Override
    public RecyclerView.ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
       View  view = LayoutInflater.from(parent.getContext()).inflate(R.layout.movie_item,
                parent, false);
        return new MovieViewHolder(view, onMovieListener);

    }



    @Override
    public void onBindViewHolder(@NonNull RecyclerView.ViewHolder holder, int position) {

        ((MovieViewHolder)holder).title.setText(mMoviesLatest.get(position).getTitle());
        ((MovieViewHolder)holder).rating.setText(String.valueOf((float) (mMoviesLatest.get(position).getVote_average())));

        //ImageView: Using Glide Library
        Glide.with(holder.itemView.getContext())
                .load("https://image.tmdb.org/t/p/w500/"
                          mMoviesLatest.get(position).getPoster_path())
                .into(((MovieViewHolder)holder).imageView);

    }

    @Override
    public int getItemCount() {
        if(mMoviesLatest != null) {
            return mMoviesLatest.size();
        }
        return 0;
    }

    public void setmMoviesLatest(List<MovieModel> mMoviesLatest) {
        this.mMoviesLatest = mMoviesLatest;
        notifyDataSetChanged();
    }

    //Getting the id of the movie clicked
    public MovieModel getSelectedMovie(int position){
        if(mMoviesLatest != null){
            if(mMoviesLatest.size() > 0){
                return mMoviesLatest.get(position);
            }
        }
        return null;
    }
 

В MainActivity я настраиваю RecyclerViews с помощью этого метода

  private void ConfigureRecyclerView() {
        movieRecyclerViewAdapter = new MovieRecyclerView(this);
        movieLatestRecyclerViewAdapter = new MovieLatestRecyclerView(this);

        recyclerView_popular.setAdapter(movieRecyclerViewAdapter);
        recyclerView_popular.setLayoutManager(new LinearLayoutManager(this, LinearLayoutManager.HORIZONTAL, false));

        recyclerView_latest.setAdapter(movieLatestRecyclerViewAdapter);
        recyclerView_latest.setLayoutManager(new LinearLayoutManager(this, LinearLayoutManager.HORIZONTAL, false));

        //RecyclerView Pagination
        //Loading next page of api response
        recyclerView_popular.addOnScrollListener(new RecyclerView.OnScrollListener() {
            @Override
            public void onScrollStateChanged(@NonNull RecyclerView recyclerView, int newState) {
                if (!recyclerView.canScrollVertically(1)) {
                    //Here we need to display the next search result
                    movieListViewModel.searchNextPage();
                }
            }
        });
        recyclerView_latest.addOnScrollListener(new RecyclerView.OnScrollListener() {
            @Override
            public void onScrollStateChanged(@NonNull RecyclerView recyclerView, int newState) {
                if (!recyclerView.canScrollVertically(1)) {
                    //Here we need to display the next search result
                    movieListViewModel.searchNextPage();
                }
            }
        });

    }
 

И я использую это для передачи выбранного фильма другому действию

  @Override
    public void onMovieClick(int position) {
        //WE don't need position of the movie in recyclerView
        // We need the ID of the movie in order to get all it's details
        Intent intent = new Intent(this, MovieDetails.class);


            intent.putExtra("movie", movieRecyclerViewAdapter.getSelectedMovie(position));
            startActivity(intent);


    }
 

Кто бы вы ни читали мой вопрос, я благодарю вас за ваше время и прошу прощения за определенную банальность и длину.

Комментарии:

1. Итак, в чем конкретно ваш вопрос? вы сталкиваетесь с какими-либо проблемами?

2. Если у меня есть два RecyclerView «Популярный» и «Самый рейтинговый», если первый фильм, который я нажимаю, находится в популярном, когда я нажимаю на фильм в Top Rated, он показывает мне фильм, который я нажал первым в «Популярном».

Ответ №1:

На этой линии:

 intent.putExtra("movie", movieRecyclerViewAdapter.getSelectedMovie(position));
 

Вы получаете фильм от movieRecyclerViewAdapter . Этот адаптер используется только с «Популярным» просмотром Movie Recycler.

onMovieClick используется как для «популярных», так и для «самых рейтинговых» просмотров recycler. Таким образом, при нажатии на элемент из списка «Самый рейтинговый» будет предпринята попытка использовать элемент из списка «Популярный».

Чтобы исправить это, щелчок по кнопке «Top Rated» не должен приводить к получению товара movieRecyclerViewAdapter .

Вы могли бы сделать что-то вроде изменения onMovieClick(int position) onMovieClick(MovieModel movie) , поэтому вам не нужно беспокоиться о том, с какого адаптера получить фильм.