Skip to main content

Android Carview With PopupMenu example


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
    



Our Demo Application consist of List of cards . Each card contains movie poster , movie name , director name and popup menu icon . On clicking the popup menu icon popup Menu is shown with menu items. On clicking each menu item a Toast is shown .

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)
Our menu resource file , card_menu.xml 
<?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
https://drive.google.com/file/d/0BySLpWhqmbbdUkdRMjh6WTNucEU/view?usp=sharing

Comments

Post a Comment

Popular posts

Android List View using Custom Adapter and SQLite

following is a simple applicaton to create ListView using  Custom adapter.screenshot of the application  is like this . ListView is not used in android Anymore . We use  RecyclerView  and  CardView   in Android RecyclerView Demo is available on the following link http://androidtuts4u.blogspot.in/2017/04/android-recyclerview-example.html RecyclerView with Cardview Example is available on the following link http://androidtuts4u.blogspot.in/2017/09/android-card-view-example.html The ListView below the submit button is populated using Custom Adapter.Data is stored and retrieved using SQLite databsase. you can download the source code of this project from  google drive   https://drive.google.com/folderview?id=0BySLpWhqmbbdUXE5aTNhazludjQ&usp=sharing click on the above link ->sign into  your  google account ->add this to your google drive -> open it in google drive and download it. To create a simple application like this 1.  Create a class which extends  

Keytool is not recognized as internal or extenal command / Adding PATH in system variable

If you are running a keytool command  keytool -list -v -keystore C:\Users\arun\.android\debug.keystore -alias androiddebugkey -storepass android    and getting an error   'keytool' is not recognized as an internal or external command  If you are using any other commad like java,javac , etc.. and getting an error " is not recognized as an internal or external command"  you can also use this same steps  you are getting this error because keytool.exe , executable file which exists in the bin directory of your JDK  is not added to Path in your Environmental variables. To resolve this issue 1 .first we need to find the bin Directory of our jdk    Usually this will be in  C:\Program Files\Java\jre1.8.0_221\bin (jre1.8.0_221 - change this to your latest version , ). you can see keytool.exe file in the bin directory . (If you installed jdk in a different directory Find your Jdk installation folder and  use that path.) 2 . we need to add this bin directory

Simple Calculator With ViewModel and LIveData

This is a simple calculator with basic mathematical operations. You can download full source code of this project from Github https://github.com/arunkfedex/SimpleCalculator We are using ViewModel and LiveData so we need to add those dependencies in build.gradle file. build.gradle plugins { id 'com.android.application' id 'kotlin-android' } android { compileSdk 30 defaultConfig { applicationId "com.arun.androidtutsforu.simplecalculator" minSdk 21 targetSdk 30 versionCode 1 versionName "1.0" testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner" } buildTypes { release { minifyEnabled false proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro' } } compileOptions { sourceCompatibility JavaVersion.VERSION_1_8 ta