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