Android ListView - ContextMenu

August 20, 2017 Oclemy Android Menu 7 minutes, 18 seconds

In this class we'll work with a listview and contextmenu.

The ListView will have a List of items. The user can then right click a given item and a contextmenu gets displayed.

Gradle Files

First we add dependencies in the app level build.gradle file.

1. Build.gradle

  • Let's add some dependencies. Our ListView will comprise cardviews:
    apply plugin: 'com.android.application'

    android {
        compileSdkVersion 23
        buildToolsVersion "23.0.2"

        defaultConfig {
            applicationId "com.tutorials.hp.listviewcontextmenu"
            minSdkVersion 15
            targetSdkVersion 23
            versionCode 1
            versionName "1.0"
        }
        buildTypes {
            release {
                minifyEnabled false
                proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
            }
        }
    }

    dependencies {
        compile fileTree(dir: 'libs', include: ['*.jar'])
        testCompile 'junit:junit:4.12'
        compile 'com.android.support:appcompat-v7:23.2.1'
        compile 'com.android.support:design:23.2.1'
        compile 'com.android.support:cardview-v7:23.2.1'
    }

LAYOUT FILES

Let's see our layout files. We'll have three of them:

  1. activity_main.xml
  2. content_main.xml
  3. model.xml

1. activity_main.xml

  • Our template layout for main activity.
  • It will get inflated to the view for mainactivity.
  • It will contain the content_main.xml.
    <?xml version="1.0" encoding="utf-8"?>
    <android.support.design.widget.CoordinatorLayout 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"
        android:fitsSystemWindows="true"
        tools:context="com.tutorials.hp.listviewcontextmenu.MainActivity">

        <android.support.design.widget.AppBarLayout
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:theme="@style/AppTheme.AppBarOverlay">

            <android.support.v7.widget.Toolbar
                android:id="@+id/toolbar"
                android:layout_width="match_parent"
                android:layout_height="?attr/actionBarSize"
                android:background="?attr/colorPrimary"
                app:popupTheme="@style/AppTheme.PopupOverlay" />

        </android.support.design.widget.AppBarLayout>

        <include layout="@layout/content_main" />

        <android.support.design.widget.FloatingActionButton
            android:id="@+id/fab"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_gravity="bottom|end"
            android:layout_margin="@dimen/fab_margin"
            android:src="@android:drawable/ic_dialog_email" />

    </android.support.design.widget.CoordinatorLayout>

2. content_main.xml

  • This will hold our ListView.
  • It will get included inside the activity_main.xml.
    <?xml version="1.0" encoding="utf-8"?>
    <RelativeLayout 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"
        android:paddingBottom="@dimen/activity_vertical_margin"
        android:paddingLeft="@dimen/activity_horizontal_margin"
        android:paddingRight="@dimen/activity_horizontal_margin"
        android:paddingTop="@dimen/activity_vertical_margin"
        app:layout_behavior="@string/appbar_scrolling_view_behavior"
        tools:context="com.tutorials.hp.listviewcontextmenu.MainActivity"
        tools:showIn="@layout/activity_main">

        <ListView
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:id="@+id/lv"

            android:layout_alignParentLeft="true"
            android:layout_alignParentStart="true" />
    </RelativeLayout>

3. model.xml

  • Is our custom listview row layout.
  • Will get inflated into a single row.
  • Contains a cardview with images and text.
    <?xml version="1.0" encoding="utf-8"?>
    <android.support.v7.widget.CardView xmlns:android="http://schemas.android.com/apk/res/android"
        android:orientation="horizontal" android:layout_width="match_parent"
        xmlns:card_view="http://schemas.android.com/apk/res-auto"
        android:layout_margin="10dp"
        card_view:cardCornerRadius="10dp"
        card_view:cardElevation="10dp"

        android:layout_height="wrap_content">

        <RelativeLayout
            android:layout_width="match_parent"
            android:layout_height="match_parent">

            <ImageView
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:id="@+id/movieImage"
                android:padding="10dp"
                android:src="@drawable/ghost" />

            <TextView
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:textAppearance="?android:attr/textAppearanceLarge"
                android:text="Name"
                android:id="@+id/nameTxt"
                android:padding="10dp"
                android:textColor="@color/colorAccent"
                android:layout_below="@+id/movieImage"
                android:layout_alignParentLeft="true"
                 />

            <TextView
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:textAppearance="?android:attr/textAppearanceLarge"
                android:text=" John Doe a former FBI Agent and now Physics teacher .is wrongly accussed of murdering an innocent child.He makes it his business to find the bad guys who did taht.He convinces hacker Aram to join him.....
                "
                android:id="@+id/descTxt"
                android:padding="10dp"
                android:layout_below="@+id/nameTxt"
                android:layout_alignParentLeft="true"
                />

            <TextView
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:textAppearance="?android:attr/textAppearanceMedium"
                android:text="TV Show"
                android:id="@+id/posTxt"
                android:padding="10dp"

                android:layout_below="@+id/movieImage"
                android:layout_alignParentRight="true" />

            <CheckBox
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:id="@+id/chk"
                android:layout_alignParentRight="true"
                />

        </RelativeLayout>
    </android.support.v7.widget.CardView>

JAVA CLASSES

We'll have 5 classes:

1. Movie.java

  • Is our data object, a POJO class.
  • Represents a single movie object with various properties.
  • Each CardView will hold a movie.
    package com.tutorials.hp.listviewcontextmenu;

    public class Movie {

        private String name;
        private int image;

        public Movie(String name, int image) {
            this.name = name;
            this.image = image;
        }

        public String getName() {
            return name;
        }

        public int getImage() {
            return image;
        }
    }

2. LongClickListener

  • Is an interface.
  • Contains the signature for our LongClick listener.
    package com.tutorials.hp.listviewcontextmenu;

    public interface LongClickListener {
        void onItemLongClick();
    }

3. MyViewHolder.java

  • Our ViewHolder class.
  • Will hold views to be recycled.
  • Will implement View.OnLongClickListener and View.OnCreateContextMenuListener.
    package com.tutorials.hp.listviewcontextmenu;

    import android.view.ContextMenu;
    import android.view.View;
    import android.widget.ImageView;
    import android.widget.TextView;

    public class MyViewHolder implements View.OnLongClickListener,View.OnCreateContextMenuListener {

        ImageView img;
        TextView nameTxt;
        LongClickListener longClickListener;

        public MyViewHolder(View v) {
            img= (ImageView) v.findViewById(R.id.movieImage);
            nameTxt= (TextView) v.findViewById(R.id.nameTxt);

            v.setOnLongClickListener(this);
            v.setOnCreateContextMenuListener(this);
        }

        public void setLongClickListener(LongClickListener lc)
        {
            this.longClickListener=lc;
        }

        @Override
        public boolean onLongClick(View v) {
            this.longClickListener.onItemLongClick();
            return false;
        }

        @Override
        public void onCreateContextMenu(ContextMenu menu, View v, ContextMenu.ContextMenuInfo menuInfo) {
            menu.add(0,0,0,"Share");
            menu.add(0,1,0,"Rate");
            menu.add(0,2,0,"Watch");
        }
    }

4. CustomAdapter.java

  • Our adapter class.
  • Derives from BaseAdapter.
  • Will adapt our data to our custom views.
    package com.tutorials.hp.listviewcontextmenu;

    import android.content.Context;
    import android.view.LayoutInflater;
    import android.view.MenuItem;
    import android.view.View;
    import android.view.ViewGroup;
    import android.widget.BaseAdapter;
    import android.widget.Toast;

    import java.util.ArrayList;

    public class CustomAdapter extends BaseAdapter {
        Context c;
        ArrayList<Movie> movies;
        LayoutInflater inflater;
        String name;

        public CustomAdapter(Context c, ArrayList<Movie> movies) {
            this.c = c;
            this.movies = movies;
        }

        @Override
        public int getCount() {
            return movies.size();
        }

        @Override
        public Object getItem(int position) {
            return movies.get(position);
        }

        @Override
        public long getItemId(int position) {
            return position;
        }

        @Override
        public View getView(final int position, View convertView, ViewGroup parent) {

            if(inflater==null)
            {
                inflater= (LayoutInflater) c.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
            }

            if(convertView==null)
            {
                convertView=inflater.inflate(R.layout.model,parent,false);
            }

            //BIND DATA TO VIEWS
            MyViewHolder holder=new MyViewHolder(convertView);
            holder.nameTxt.setText(movies.get(position).getName());
            holder.img.setImageResource(movies.get(position).getImage());

            holder.setLongClickListener(new LongClickListener() {
                @Override
                public void onItemLongClick() {
                    name=movies.get(position).getName();
                    Toast.makeText(c,name,Toast.LENGTH_SHORT).show();
                }
            });

            return convertView;
        }

        public void getSelecetedItem(MenuItem item)
        {
            Toast.makeText(c,name+" "+item.getTitle(),Toast.LENGTH_SHORT).show();
        }
    }

5. MainActivity.java

  • Our MainActivity.
  • References ListView from layout.
  • Instantiates the CustomAdapter and sets it to our ListView.
    package com.tutorials.hp.listviewcontextmenu;

    import android.os.Bundle;
    import android.support.design.widget.FloatingActionButton;
    import android.support.design.widget.Snackbar;
    import android.support.v7.app.AppCompatActivity;
    import android.support.v7.widget.RecyclerView;
    import android.support.v7.widget.Toolbar;
    import android.view.View;
    import android.view.Menu;
    import android.view.MenuItem;
    import android.widget.AdapterView;
    import android.widget.ListView;

    import java.util.ArrayList;

    public class MainActivity extends AppCompatActivity {

       ListView lv;
        CustomAdapter adapter;

        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_main);
            Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
            setSupportActionBar(toolbar);

            FloatingActionButton fab = (FloatingActionButton) findViewById(R.id.fab);
            fab.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View view) {
                    Snackbar.make(view, "Replace with your own action", Snackbar.LENGTH_LONG)
                            .setAction("Action", null).show();
                }
            });

            lv= (ListView) findViewById(R.id.lv);
            adapter=new CustomAdapter(this,getMovies());

            lv.setAdapter(adapter);

        }

        @Override
        public boolean onContextItemSelected(MenuItem item) {

             adapter.getSelecetedItem(item);
            return super.onContextItemSelected(item);
        }

        private ArrayList<Movie> getMovies() {
            //COLECTION OF CRIME MOVIES
            ArrayList<Movie> movies=new ArrayList<>();

            Movie movie=new Movie("Shuttle Carrier",R.drawable.shuttlecarrier);

            //ADD ITR TO COLLECTION
            movies.add(movie);

            movie=new Movie("Fruits",R.drawable.fruits);
            movies.add(movie);

            movie=new Movie("Breaking Bad",R.drawable.breaking);
            movies.add(movie);

            movie=new Movie("Crisis",R.drawable.crisis);
            movies.add(movie);

            movie=new Movie("Ghost Rider",R.drawable.rider);
            movies.add(movie);

            movie=new Movie("Star Wars",R.drawable.starwars);
            movies.add(movie);

            movie=new Movie("BlackList",R.drawable.red);
            movies.add(movie);

            movie=new Movie("Men In Black",R.drawable.meninblack);
            movies.add(movie);

            movie=new Movie("Game Of Thrones",R.drawable.thrones);
            movies.add(movie);

            return movies;

        }
    }

Download the project here.

Comments