Android ListView ContextMenu - LongPress,Handle Events

October 17, 2017 Oclemy Android Menu, Android ListView 8 minutes, 38 seconds

ContextMenu support has been in android since API level 1. It's an extension of menu and implements Menu interface. It's actually an interface itself.

ContextMenus are usually shown when users long click view. It's shown by registering contextmenu using the registerForContextMenu(view) and then overriding onCreateContextMenu().

In this example we look at showing a contextmenu when user long clicks/presses a listview item. We also see how to handle contextmenu items action events, in this case only showing a toast message when user selects a context menuitem.

You can find more details about ContextMenu here.

Screenshot

  • Here's the screenshot of the project.

Android Contextmenu ListView example. Android ContextMenu

Common Questions this example explores

  • How to use ContextMenu with Example.
  • What is ContextMenu?
  • Show ContextMenu onLongClick.
  • Show ContextMenu on ListView.
  • ContextMenu items action events.
  • Get selected contextmenu item.

Tools Used

This example was written with the following tools:

  • Windows 8
  • AndroidStudio IDE
  • Genymotion Emulator

Let's go.

Lets jump directly to the source code.

1. Build.Gradle

  • Normally in android projects, there are two build.gradle files. One is the app level build.gradle, the other is project level build.gradle. The app level belongs inside the app folder and its where we normally add our dependencies and specify the compile and target sdks.
  • Also Add dependencies for AppCompat and Design support libraries.
  • Our MainActivity shall derive from AppCompatActivity while we shall also use Floating action button from design support libraries.
  • We also add CardView. Our ListView shall comprise cardviews with images and text.
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'
}

2. Movie.java

  • Data Object.
  • Represents a single movie with its properties like name and image.
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;
    }
}

 

LongClickListener.java

  • An interface.
  • Defines the signature on onLongClick() method.
package com.tutorials.hp.listviewcontextmenu;

public interface LongClickListener {

    void onItemLongClick();

}

3. MyViewHolder.java

  • Our ViewHolder class.
  • Will hold imageview and textview for recycling.
  • Implements LongClicklistener.
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.
  • Adapt our movies collection to our views for display.
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

  • Launcher activity.
  • ActivityMain.xml inflated as the contentview for this activity.
  • We initialize views and widgets inside this activity.
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;

    }
}

6. ActivityMain.xml

  • Template layout.
  • Contains our ContentMain.xml.
  • Also defines the appbarlayout, toolbar as well as floatingaction buttton.
<?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>

7. ContentMain.xml

  • Content Layout.
  • Defines the views and widgets to be displayed inside the MainActivity.
  • Will contain our ListView in this case.
<?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>

8. Model.xml

  • Definition of a single movie cardview for our listview.
<?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>

Conclusion.

We saw a simple android ContextMenu Example with a Custom ListView with Images and Text. User long presses a listview item and contextmenu is shown. We also see how to handle the ContextMenu items action events, that is what the user actually chooses from the context menu.

How To Run

  1. Download the project.
  2. You'll get a zipped file,extract it.
  3. Open the Android Studio.
  4. Now close, already open project.
  5. From the Menu bar click on File >New> Import Project.
  6. Now Choose a Destination Folder, from where you want to import project.
  7. Choose an Android Project.
  8. Now Click on “OK“.
  9. Done, your done importing the project,now edit it.

More Resources

Resource Link
GitHub Browse Browse
GitHub Download Link Download

Good day.

Comments