This demo Application shows how to use PopupMenu with CardView inside RecyclerView . I have already written one post about using CardView with RecycleView . Refer that post before proceeding to this one.
http://androidtuts4u.blogspot.in/2017/09/android-card-view-example.html
ScreenShots of the demo application are
1.First we need to add the dependency for CardView and RecyclerView in app level build.gradle file .
build.gradle
apply plugin: 'com.android.application' android { compileSdkVersion 26 buildToolsVersion "26.0.1" defaultConfig { applicationId "com.androidtuts4u.arun.cardviewmenu" minSdkVersion 16 targetSdkVersion 26 versionCode 1 versionName "1.0" testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner" } buildTypes { release { minifyEnabled false proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro' } } } dependencies { compile fileTree(include: ['*.jar'], dir: 'libs') androidTestCompile('com.android.support.test.espresso:espresso-core:2.2.2', { exclude group: 'com.android.support', module: 'support-annotations' }) compile 'com.android.support:appcompat-v7:26.+' compile 'com.android.support.constraint:constraint-layout:1.0.0-beta4' testCompile 'junit:junit:4.12' compile 'com.android.support:cardview-v7:26.0.0-alpha1' compile 'com.android.support:recyclerview-v7:26.0.0-alpha1' }
2. Next we need to create Layout for our application . Our main layout activity_main.xml contains RecyclerView only
activity_main.xml
<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:app="http://schemas.android.com/apk/res-auto" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" tools:context="com.androidtuts4u.arun.cardviewmenu.MainActivity"> <android.support.v7.widget.RecyclerView android:id="@+id/rv_menu" android:layout_width="match_parent" android:layout_height="wrap_content"> </android.support.v7.widget.RecyclerView> </LinearLayout>
3. Next we need to create layout for each row in the RecyclerView . Our Each row is a card . So We need to create CardView with two ImageViews one for movie poster and one for PopupMenu icon , two Textviews for showing Movie name and director name and one Rating bar.
list_item.xml
<?xml version="1.0" encoding="utf-8"?> <android.support.v7.widget.CardView xmlns:android="http://schemas.android.com/apk/res/android" xmlns:app="http://schemas.android.com/apk/res-auto" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_margin="8dp" app:cardCornerRadius="2dp"> <android.support.constraint.ConstraintLayout android:layout_width="match_parent" android:layout_height="wrap_content"> <ImageView android:id="@+id/iv_poster" android:layout_width="100dp" android:layout_height="100dp" android:src="@drawable/sr" /> <TextView android:id="@+id/tv_film_name" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="fim name" android:textAppearance="?android:textAppearanceLarge" app:layout_constraintLeft_toRightOf="@+id/iv_poster" app:layout_constraintTop_toTopOf="parent" /> <TextView android:id="@+id/tv_director" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="director name" app:layout_constraintLeft_toRightOf="@+id/iv_poster" app:layout_constraintTop_toBottomOf="@+id/tv_film_name" /> <RatingBar android:id="@+id/ratingBar" style="?android:ratingBarStyleSmall" android:layout_width="wrap_content" android:layout_height="wrap_content" android:isIndicator="false" android:rating="4" android:stepSize="0.5" app:layout_constraintBottom_toBottomOf="parent" app:layout_constraintLeft_toRightOf="@+id/iv_poster" /> <ImageView android:id="@+id/iv_menu" android:layout_width="wrap_content" android:layout_height="wrap_content" android:src="@drawable/ic_more_vert_black" app:layout_constraintBottom_toBottomOf="parent" app:layout_constraintRight_toRightOf="parent" /> </android.support.constraint.ConstraintLayout> </android.support.v7.widget.CardView>
4. Next we need to create popup menu items. We need menu resource directory for this.
- If Menu directory is not present inside res directory add it by right clicking on res Directory
- res->new->Android resource directory , then select resource type as menu and click OK
- Right click on menu resource directory
- menu->new->menu resource file , Enter file name (card_menu)
<?xml version="1.0" encoding="utf-8"?> <menu xmlns:android="http://schemas.android.com/apk/res/android"> <item android:id="@+id/watch_later" android:title="Watch Later" /> <item android:id="@+id/favourite" android:title="Favourite" /> <item android:id="@+id/download" android:title="Download" /> </menu>5. Layout for our application is now finished . Now we need to write java classes .
6. We are using custom adpater for our RecyclerView , so we need a Model class . Model class contains getter and setter methods
Movies.java
package com.androidtuts4u.arun.cardviewmenu.model; public class Movies { private int imageId; private String movieName, director; private float rating; public float getRating() { return rating; } public void setRating(float rating) { this.rating = rating; } public int getImageId() { return imageId; } public void setImageId(int imageId) { this.imageId = imageId; } public String getMovieName() { return movieName; } public void setMovieName(String movieName) { this.movieName = movieName; }c public String getDirector() { return director; } public void setDirector(String director) { this.director = director; } }
6.Next our Adapter class
MovieAdapter.java
package com.androidtuts4u.arun.cardviewmenu.adapter; import android.content.Context; import android.support.v7.widget.PopupMenu; import android.support.v7.widget.RecyclerView; import android.view.LayoutInflater; import android.view.MenuItem; import android.view.View; import android.view.ViewGroup; import android.widget.ImageView; import android.widget.RatingBar; import android.widget.TextView; import android.widget.Toast; import com.androidtuts4u.arun.cardviewmenu.R; import com.androidtuts4u.arun.cardviewmenu.model.Movies; import java.util.List; public class MovieAdapter extends RecyclerView.Adapter<MovieAdapter.MovieViewHolder> { List<Movies> moviesList; Context context; public MovieAdapter(List<Movies> moviesList) { this.moviesList = moviesList; } @Override public MovieViewHolder onCreateViewHolder(ViewGroup parent, int viewType) { context = parent.getContext(); LayoutInflater inflater = LayoutInflater.from(context); View itemView = inflater.inflate(R.layout.list_item, parent, false); MovieViewHolder viewHolder = new MovieViewHolder(itemView); return viewHolder; } @Override public void onBindViewHolder(final MovieViewHolder holder, final int position) { Movies movies = moviesList.get(position); holder.movieName.setText(movies.getMovieName()); holder.director.setText(movies.getDirector()); holder.poster.setImageResource(movies.getImageId()); holder.ratingBar.setRating(movies.getRating()); holder.popmemu.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View view) { final Movies movies = moviesList.get(position); PopupMenu popupMenu = new PopupMenu(context, holder.popmemu); popupMenu.inflate(R.menu.card_menu); popupMenu.setOnMenuItemClickListener(new PopupMenu.OnMenuItemClickListener() { @Override public boolean onMenuItemClick(MenuItem item) { switch (item.getItemId()) { case R.id.watch_later: Toast.makeText(context, movies.getMovieName() + " added to watch later", Toast.LENGTH_LONG).show(); break; case R.id.favourite: Toast.makeText(context, movies.getMovieName() + " added to favourites", Toast.LENGTH_LONG).show(); break; case R.id.download: Toast.makeText(context, movies.getMovieName() + " started downloading", Toast.LENGTH_LONG).show(); break; } return false; } }); popupMenu.show(); } }); } @Override public int getItemCount() { return moviesList.size(); } public class MovieViewHolder extends RecyclerView.ViewHolder { public TextView movieName, director; public ImageView poster, popmemu; RatingBar ratingBar; public MovieViewHolder(View itemView) { super(itemView); movieName = (TextView) itemView.findViewById(R.id.tv_film_name); director = (TextView) itemView.findViewById(R.id.tv_director); ratingBar = (RatingBar) itemView.findViewById(R.id.ratingBar); poster = (ImageView) itemView.findViewById(R.id.iv_poster); popmemu = (ImageView) itemView.findViewById(R.id.iv_menu); } } }
7. next our MainActivity
MainActivity.java
package com.androidtuts4u.arun.cardviewmenu; import android.os.Bundle; import android.support.v7.app.AppCompatActivity; import android.support.v7.widget.LinearLayoutManager; import android.support.v7.widget.RecyclerView; import com.androidtuts4u.arun.cardviewmenu.adapter.MovieAdapter; import com.androidtuts4u.arun.cardviewmenu.model.Movies; import java.util.ArrayList; import java.util.List; public class MainActivity extends AppCompatActivity { List<Movies> moviesList; RecyclerView movieRecyclerView; RecyclerView.LayoutManager layoutManager; RecyclerView.Adapter movieAdapter; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); movieRecyclerView = (RecyclerView) findViewById(R.id.rv_menu); createMovieList(); layoutManager = new LinearLayoutManager(this); movieAdapter = new MovieAdapter(moviesList); movieRecyclerView.setLayoutManager(layoutManager); movieRecyclerView.setAdapter(movieAdapter); } private void createMovieList() { moviesList = new ArrayList<Movies>(); Movies movieListItem = new Movies(); movieListItem.setMovieName("Shawshank Redemption"); movieListItem.setDirector("Frank Darabont"); movieListItem.setImageId(R.drawable.sr); movieListItem.setRating(5.0f); moviesList.add(movieListItem); Movies movieListItem1 = new Movies(); movieListItem1.setMovieName("Forrest Gump"); movieListItem1.setDirector("Robert Zemeckis"); movieListItem1.setImageId(R.drawable.fg); movieListItem1.setRating(5.0f); moviesList.add(movieListItem1); Movies movieListItem2 = new Movies(); movieListItem2.setMovieName("Pulp Fiction"); movieListItem2.setDirector("Quentin Tarantino"); movieListItem2.setImageId(R.drawable.pf); movieListItem2.setRating(4.5f); moviesList.add(movieListItem2); Movies movieListItem3 = new Movies(); movieListItem3.setMovieName("Saving private Ryan"); movieListItem3.setDirector("Steven Spielberg"); movieListItem3.setImageId(R.drawable.sp); movieListItem3.setRating(4.5f); moviesList.add(movieListItem3); Movies movieListItem4 = new Movies(); movieListItem4.setMovieName("Django Unchained"); movieListItem4.setDirector("Quentin Tarantino"); movieListItem4.setImageId(R.drawable.du); movieListItem4.setRating(5.0f); moviesList.add(movieListItem4); Movies movieListItem5 = new Movies(); movieListItem5.setMovieName("The Dark knight"); movieListItem5.setDirector("Christopher Nolan"); movieListItem5.setImageId(R.drawable.dn); movieListItem5.setRating(4.5f); moviesList.add(movieListItem5); Movies movieListItem6 = new Movies(); movieListItem6.setMovieName("The Godfather"); movieListItem6.setDirector("Francis Ford coppola"); movieListItem6.setImageId(R.drawable.gf); movieListItem6.setRating(4.5f); moviesList.add(movieListItem6); Movies movieListItem7 = new Movies(); movieListItem7.setMovieName("The Silence of the Lambs"); movieListItem7.setDirector("Jonnathan Demme"); movieListItem7.setImageId(R.drawable.sl); movieListItem7.setRating(5.0f); moviesList.add(movieListItem7); } }
- We are using Arraylist for proving data to our adapter . An Arraylist is created with movie name , director name , ImageId and rating . Images are saved in drawable folder . This Arraylist is passed to our MovieAdapter
private void createMovieList() { moviesList = new ArrayList<Movies>(); Movies movieListItem = new Movies(); movieListItem.setMovieName("Shawshank Redemption"); movieListItem.setDirector("Frank Darabont"); movieListItem.setImageId(R.drawable.sr); movieListItem.setRating(5.0f); moviesList.add(movieListItem); Movies movieListItem1 = new Movies(); movieListItem1.setMovieName("Forrest Gump"); movieListItem1.setDirector("Robert Zemeckis"); movieListItem1.setImageId(R.drawable.fg); movieListItem1.setRating(5.0f); moviesList.add(movieListItem1); Movies movieListItem2 = new Movies(); movieListItem2.setMovieName("Pulp Fiction"); movieListItem2.setDirector("Quentin Tarantino"); movieListItem2.setImageId(R.drawable.pf); movieListItem2.setRating(4.5f); moviesList.add(movieListItem2); Movies movieListItem3 = new Movies(); movieListItem3.setMovieName("Saving private Ryan"); movieListItem3.setDirector("Steven Spielberg"); movieListItem3.setImageId(R.drawable.sp); movieListItem3.setRating(4.5f); moviesList.add(movieListItem3); Movies movieListItem4 = new Movies(); movieListItem4.setMovieName("Django Unchained"); movieListItem4.setDirector("Quentin Tarantino"); movieListItem4.setImageId(R.drawable.du); movieListItem4.setRating(5.0f); moviesList.add(movieListItem4); Movies movieListItem5 = new Movies(); movieListItem5.setMovieName("The Dark knight"); movieListItem5.setDirector("Christopher Nolan"); movieListItem5.setImageId(R.drawable.dn); movieListItem5.setRating(4.5f); moviesList.add(movieListItem5); Movies movieListItem6 = new Movies(); movieListItem6.setMovieName("The Godfather"); movieListItem6.setDirector("Francis Ford coppola"); movieListItem6.setImageId(R.drawable.gf); movieListItem6.setRating(4.5f); moviesList.add(movieListItem6); Movies movieListItem7 = new Movies(); movieListItem7.setMovieName("The Silence of the Lambs"); movieListItem7.setDirector("Jonnathan Demme"); movieListItem7.setImageId(R.drawable.sl); movieListItem7.setRating(5.0f); moviesList.add(movieListItem7); }
- We can use Linear layout manager , Grid Layout Manager , Staggered Grid layout manager for our RecyclerView . In this demo app we are using LinearLayoutManager.
movieRecyclerView = (RecyclerView) findViewById(R.id.rv_menu); createMovieList(); layoutManager = new LinearLayoutManager(this); movieAdapter = new MovieAdapter(moviesList); movieRecyclerView.setLayoutManager(layoutManager); movieRecyclerView.setAdapter(movieAdapter);
- Inside the onCreateViewHolder method in the MovieAdpater class each row(list_item.xml) is inflated to our RecyclerView
@Override public MovieViewHolder onCreateViewHolder(ViewGroup parent, int viewType) { context = parent.getContext(); LayoutInflater inflater = LayoutInflater.from(context); View itemView = inflater.inflate(R.layout.list_item, parent, false); MovieViewHolder viewHolder = new MovieViewHolder(itemView); return viewHolder; }
- Inside onBindViewHolder method in the MovieAdapter class Movie name, Director name , poster , rating from Arraylist is set to each Row. PopupMenu is also created inside this method.
@Override public void onBindViewHolder(final MovieViewHolder holder, final int position) { Movies movies = moviesList.get(position); holder.movieName.setText(movies.getMovieName()); holder.director.setText(movies.getDirector()); holder.poster.setImageResource(movies.getImageId()); holder.ratingBar.setRating(movies.getRating()); holder.popmemu.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View view) { final Movies movies = moviesList.get(position); PopupMenu popupMenu = new PopupMenu(context, holder.popmemu); popupMenu.inflate(R.menu.card_menu); popupMenu.setOnMenuItemClickListener(new PopupMenu.OnMenuItemClickListener() { @Override public boolean onMenuItemClick(MenuItem item) { switch (item.getItemId()) { case R.id.watch_later: Toast.makeText(context, movies.getMovieName() + " added to watch later", Toast.LENGTH_LONG).show(); break; case R.id.favourite: Toast.makeText(context, movies.getMovieName() + " added to favourites", Toast.LENGTH_LONG).show(); break; case R.id.download: Toast.makeText(context, movies.getMovieName() + " started downloading", Toast.LENGTH_LONG).show(); break; } return false; } }); popupMenu.show(); } }); }
- PopupMenu is created on clicking menu icon . Menu resource card_menu.xml is inflated to PopupMenu
holder.popmemu.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View view) { final Movies movies = moviesList.get(position); PopupMenu popupMenu = new PopupMenu(context, holder.popmemu); popupMenu.inflate(R.menu.card_menu); ............ ............ popupMenu.show(); } });
- OnMenuItemClickListener is used to show Toast on clicking each menu item.
popupMenu.setOnMenuItemClickListener(new PopupMenu.OnMenuItemClickListener() { @Override public boolean onMenuItemClick(MenuItem item) { switch (item.getItemId()) { case R.id.watch_later: Toast.makeText(context, movies.getMovieName() + " added to watch later", Toast.LENGTH_LONG).show(); break; case R.id.favourite: Toast.makeText(context, movies.getMovieName() + " added to favourites", Toast.LENGTH_LONG).show(); break; case R.id.download: Toast.makeText(context, movies.getMovieName() + " started downloading", Toast.LENGTH_LONG).show(); break; } return false; } });
- Source code for this Demo application can be downloaded from below Google Drive link
This comment has been removed by the author.
ReplyDelete