0

I am creating a movie app using TMDB api, Retrofit, Gson and Glide. I have two recyclerView and two layout to inflate. But I am unable to inflate 2 layout in recyclerView adapter.

I have already implemented popular and upcoming movie list in 2 different recyclerView. But they are showing using 1 single layout. I want to inflate popular movies in one layout and upcoming movies in another layout. I can't set the condition for getItemViewType() method. How can I check for popular and upcoming movies list in getItemViewType() method and implement it on onCreateViewHolder() method of recyclerView.

MovieAdapter class:

public class MovieAdapter extends RecyclerView.Adapter<MovieAdapter.MovieViewHolder> {
    private Context context;
    private ArrayList<Movie> movieArrayList;

    public MovieAdapter(Context context, ArrayList<Movie> movieArrayList) {
        this.context = context;
        this.movieArrayList = movieArrayList;
    }

    @NonNull
    @Override
    public MovieViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {

        View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.movie_list_item, parent, false);
        return new MovieViewHolder(view);
    }

    @Override
    public int getItemViewType(int position) {
        return super.getItemViewType(position);
    }

    @Override
    // Set values to the list item components
    public void onBindViewHolder(@NonNull MovieViewHolder holder, int position) {
        holder.movieTitle.setText(movieArrayList.get(position).getOriginalTitle());
        holder.rating.setText(String.valueOf(movieArrayList.get(position).getVoteAverage()));
        String imagePath = "https://image.tmdb.org/t/p/w500" + movieArrayList.get(position).getPosterPath();

        Glide.with(context)
                .load(imagePath)
                .placeholder(R.drawable.loading)
                .into(holder.movieImage);
    }

    @Override
    public int getItemCount() {
        return movieArrayList == null ? 0 : movieArrayList.size();
    }

    public class MovieViewHolder extends RecyclerView.ViewHolder {

        TextView movieTitle, rating;
        ImageView movieImage;

        public MovieViewHolder(@NonNull View itemView) {
            super(itemView);

            movieImage = itemView.findViewById(R.id.ivMovieImage);
            movieTitle = itemView.findViewById(R.id.tvTitle);
            rating = itemView.findViewById(R.id.tvRating);

            itemView.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View view) {
                    int position = getAdapterPosition();

                    if (position != RecyclerView.NO_POSITION) {
                        Movie selectedMovie = movieArrayList.get(position);

                        Intent intent = new Intent(context, MovieActivity.class);
                        intent.putExtra("movie", selectedMovie);
                        context.startActivity(intent);
                    }
                }
            });
        }
    }
}

MainActivity class:

public class MainActivity extends AppCompatActivity {

    private ArrayList<Movie> popularMovie, topRatedMovie;

    private RecyclerView recyclerViewPopular, recyclerViewUpcoming;
    private MovieAdapter movieAdapter, upcomingAdapter;
    private SwipeRefreshLayout swipeRefreshLayout;

    private static ViewPager mPager;
    private static int currentPage = 0;
    private static int NUM_PAGES = 0;

    String[] urls = new String[] {
            "https://image.tmdb.org/t/p/w500/udDclJoHjfjb8Ekgsd4FDteOkCU.jpg",
            "https://image.tmdb.org/t/p/w500//2bXbqYdUdNVa8VIWXVfclP2ICtT.jpg",
            "https://image.tmdb.org/t/p/w500//zfE0R94v1E8cuKAerbskfD3VfUt.jpg",
            "https://image.tmdb.org/t/p/w500//lcq8dVxeeOqHvvgcte707K0KVx5.jpg",
            "https://image.tmdb.org/t/p/w500//w9kR8qbmQ01HwnvK4alvnQ2ca0L.jpg"
    };

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        initSlider();

        getPopularMovies();

        getUpcomingMovies();

        swipeRefreshLayout = findViewById(R.id.swipe_layout);
        swipeRefreshLayout.setColorSchemeResources(R.color.colorPrimaryDark);
        swipeRefreshLayout.setOnRefreshListener(new SwipeRefreshLayout.OnRefreshListener() {
            @Override
            public void onRefresh() {

                getPopularMovies();

                new Handler().postDelayed(new Runnable() {
                    @Override
                    public void run() {

                        swipeRefreshLayout.setRefreshing(false);
                    }
                }, 4000);
            }
        });

    }

    public void getPopularMovies() {
        MovieDataService movieDataService = RetrofitInstance.getService();

        Call<MovieDBResponse> callPopular = movieDataService.getPopularMovies(this.getString(R.string.apiKey));
        callPopular.enqueue(new Callback<MovieDBResponse>() {
            @Override
            public void onResponse(Call<MovieDBResponse> call, Response<MovieDBResponse> response) {
                MovieDBResponse movieDBResponse = response.body();


                if(movieDBResponse!=null && movieDBResponse.getMovies()!=null) {
                    popularMovie = (ArrayList<Movie>) movieDBResponse.getMovies();

                    showOnRecyclerView();
                }
            }
            @Override
            public void onFailure(Call<MovieDBResponse> call, Throwable t) { }
        });
    }

    public void getUpcomingMovies() {
        MovieDataService movieDataService = RetrofitInstance.getService();


        Call<MovieDBResponse> callUpcoming = movieDataService.getUpcomingMovies(this.getString(R.string.apiKey));
        callUpcoming.enqueue(new Callback<MovieDBResponse>() {
            @Override
            public void onResponse(Call<MovieDBResponse> call, Response<MovieDBResponse> response) {
                MovieDBResponse movieDBResponse = response.body();

                if(movieDBResponse!=null && movieDBResponse.getMovies()!=null) {
                    topRatedMovie = (ArrayList<Movie>) movieDBResponse.getMovies();

                    showOnRecyclerView();
                }
            }
            @Override
            public void onFailure(Call<MovieDBResponse> call, Throwable t) { }
        });
    }

    private void showOnRecyclerView() {
        recyclerViewPopular = findViewById(R.id.rvMovies);
        recyclerViewUpcoming = findViewById(R.id.rvTopMovies);

        RecyclerView.LayoutManager popularLayoutManager = new LinearLayoutManager(this);
        RecyclerView.LayoutManager upcomingLayoutManager = new LinearLayoutManager(this, LinearLayoutManager.HORIZONTAL, false);

        recyclerViewUpcoming.setLayoutManager(upcomingLayoutManager);
        recyclerViewPopular.setLayoutManager(popularLayoutManager);


        movieAdapter = new MovieAdapter(this, popularMovie);
        upcomingAdapter = new MovieAdapter(this, topRatedMovie);


        if (this.getResources().getConfiguration().orientation == Configuration.ORIENTATION_PORTRAIT) {
            recyclerViewPopular.setLayoutManager(new GridLayoutManager(this, 2));

        }else {
            recyclerViewPopular.setLayoutManager(new GridLayoutManager(this, 4));
        }

        recyclerViewPopular.setItemAnimator(new DefaultItemAnimator());
        recyclerViewUpcoming.setItemAnimator(new DefaultItemAnimator());

        recyclerViewPopular.setAdapter(movieAdapter);
        recyclerViewUpcoming.setAdapter(upcomingAdapter);

        movieAdapter.notifyDataSetChanged();
        upcomingAdapter.notifyDataSetChanged();
    }

}

I want to inflate 2 different layout "movie_list_item.xml" and "upcoming_movie_list_item.xml" in onCreateViewHolder() method.

EstevaoLuis
  • 2,422
  • 7
  • 33
  • 40
Delowar Hossain
  • 687
  • 10
  • 18
  • Does this answer your question? [How to create RecyclerView with multiple view type?](https://stackoverflow.com/questions/26245139/how-to-create-recyclerview-with-multiple-view-type) – Vinay Prajapati Oct 30 '19 at 09:46

2 Answers2

0

With in your adapter class(MovieAdapter) create a new constructor and add extra params of Int or enum whatever simple for you i am just giving you simple example:-

public class MovieAdapter extends RecyclerView.Adapter<MovieAdapter.MovieViewHolder> {
    private Context context;
    private ArrayList<Movie> movieArrayList;
    private int viewType;

        public MovieAdapter(Context context, ArrayList < Movie > movieArrayList, int viewType) {
        this.context = context;
        this.movieArrayList = movieArrayList;
        this.viewType=viewType;
    }

    @NonNull
    @Override
    public MovieViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
        View view;
        if (viewType == 1) {
            //Popular movie layout
            view = LayoutInflater.from(parent.getContext()).inflate(R.layout.movie_list_item, parent, false); 
        } else {
            //upcoming movie layout
            view = LayoutInflater.from(parent.getContext()).inflate(R.layout.movie_list_item, parent, false);
        }

        return new MovieViewHolder(view);
    }

    @Override
    public int getItemViewType(int position) {
        if (viewType == 1)
            return 1; //Popular Movie Layout
        else
            return 2; //Upcoming Movie Layout
        //    return super.getItemViewType(position);
    }

    @Override
    // Set values to the list item components
    public void onBindViewHolder(@NonNull MovieViewHolder holder, int position) {
        holder.movieTitle.setText(movieArrayList.get(position).getOriginalTitle());
        holder.rating.setText(String.valueOf(movieArrayList.get(position).getVoteAverage()));
        String imagePath = "https://image.tmdb.org/t/p/w500" + movieArrayList.get(position).getPosterPath();

        Glide.with(context)
            .load(imagePath)
            .placeholder(R.drawable.loading)
            .into(holder.movieImage);
    }

    @Override
    public int getItemCount() {
        return movieArrayList == null ? 0 : movieArrayList.size();
    }

    public class MovieViewHolder extends RecyclerView.ViewHolder {

        TextView movieTitle, rating;
        ImageView movieImage;

        public MovieViewHolder(@NonNull View itemView) {
            super(itemView);

            movieImage = itemView.findViewById(R.id.ivMovieImage);
            movieTitle = itemView.findViewById(R.id.tvTitle);
            rating = itemView.findViewById(R.id.tvRating);

            itemView.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View view) {
                    int position = getAdapterPosition();

                    if (position != RecyclerView.NO_POSITION) {
                        Movie selectedMovie = movieArrayList.get(position);

                        Intent intent = new Intent(context, MovieActivity.class);
                        intent.putExtra("movie", selectedMovie);
                        context.startActivity(intent);
                    }
                }
            });
        }
    }

and within your activity change on this method only

    private void showOnRecyclerView() {
    recyclerViewPopular = findViewById(R.id.rvMovies);
    recyclerViewUpcoming = findViewById(R.id.rvTopMovies);

    RecyclerView.LayoutManager popularLayoutManager = new LinearLayoutManager(this);
    RecyclerView.LayoutManager upcomingLayoutManager = new LinearLayoutManager(this, LinearLayoutManager.HORIZONTAL, false);

    recyclerViewUpcoming.setLayoutManager(upcomingLayoutManager);
    recyclerViewPopular.setLayoutManager(popularLayoutManager);


    movieAdapter = new MovieAdapter(this, popularMovie,1);
    upcomingAdapter = new MovieAdapter(this, topRatedMovie,2);


    if (this.getResources().getConfiguration().orientation == Configuration.ORIENTATION_PORTRAIT) {
        recyclerViewPopular.setLayoutManager(new GridLayoutManager(this, 2));

    } else {
        recyclerViewPopular.setLayoutManager(new GridLayoutManager(this, 4));
    }

    recyclerViewPopular.setItemAnimator(new DefaultItemAnimator());
    recyclerViewUpcoming.setItemAnimator(new DefaultItemAnimator());

    recyclerViewPopular.setAdapter(movieAdapter);
    recyclerViewUpcoming.setAdapter(upcomingAdapter);

    movieAdapter.notifyDataSetChanged();
    upcomingAdapter.notifyDataSetChanged();
}
Ajay Rawat
  • 168
  • 1
  • 7
0

Create layout for movie_empty_item

public class MovieAdapter extends RecyclerView.Adapter<MovieAdapter.MovieViewHolder> {
        private Context context;
        private ArrayList<Movie> movieArrayList;

        //add this two line
        private static final int EMPTY_VIEW_TYPE = 0;
        private static final int NORMAL_VIEW_TYPE = 1;

        public MovieAdapter(Context context, ArrayList<Movie> movieArrayList) {
            this.context = context;
            this.movieArrayList = movieArrayList;
        }

        @NonNull
        @Override
        public MovieViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {

            //return viewholder replace like this
            if(viewType == NORMAL_VIEW_TYPE) {
                View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.movie_list_item, parent, false);
                return new MovieViewHolder(view);
            }else {
                View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.movie_empty_item, parent, false);
                return new EmptyViewHolder(view); 
            };
        }

       //getItemViewType return replace like this
        @Override
        public int getItemViewType(int position) {
            return movieArrayList.size()>0?NORMAL_VIEW_TYPE:EMPTY_VIEW_TYPE;
        }

        @Override
        // Set values to the list item components
        public void onBindViewHolder(@NonNull MovieViewHolder holder, int position) {
            holder.movieTitle.setText(movieArrayList.get(position).getOriginalTitle());
            holder.rating.setText(String.valueOf(movieArrayList.get(position).getVoteAverage()));
            String imagePath = "https://image.tmdb.org/t/p/w500" + movieArrayList.get(position).getPosterPath();

            Glide.with(context)
                    .load(imagePath)
                    .placeholder(R.drawable.loading)
                    .into(holder.movieImage);
        }

        @Override
        public int getItemCount() {
            return movieArrayList.size() ? movieArrayList.size():1 ;
        }

        public class MovieViewHolder extends RecyclerView.ViewHolder {

            TextView movieTitle, rating;
            ImageView movieImage;

            public MovieViewHolder(@NonNull View itemView) {
                super(itemView);

                movieImage = itemView.findViewById(R.id.ivMovieImage);
                movieTitle = itemView.findViewById(R.id.tvTitle);
                rating = itemView.findViewById(R.id.tvRating);

                itemView.setOnClickListener(new View.OnClickListener() {
                    @Override
                    public void onClick(View view) {
                        int position = getAdapterPosition();

                        if (position != RecyclerView.NO_POSITION) {
                            Movie selectedMovie = movieArrayList.get(position);

                            Intent intent = new Intent(context, MovieActivity.class);
                            intent.putExtra("movie", selectedMovie);
                            context.startActivity(intent);
                        }
                    }
                });
            }
        }


        public class EmptyViewHolder extends RecyclerView.ViewHolder {


            public EmptyViewHolder(@NonNull View itemView) {
                super(itemView);

            }
        }

    }