Android Custom ListView with CardViews - LongClick


This is a custom listview with images and text tutorial. We see how to handle the OnLongClickListeners and show a toast message.

Gradle Scripts

We'll add some dependencies from the support library to our app level build.gadle:

Build.gradle

    apply plugin: 'com.android.application'

    android {
        compileSdkVersion 23
        buildToolsVersion "23.0.2"

        defaultConfig {
            applicationId "com.tutorials.hp.listviewlongclick"
            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'
    }

LAYOUTS

We'll have three layouts.

1. activity_main.xml

  • This is the layout that will get inflated into the MainActivity's user interface.
  • It's root tag is CordinatorLayout
  • First it will include the content_main.xml which will host our listview.
  • This layout defines the appbar, toolbar and floating action button codes.
    <?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.listviewlongclick.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 layout will host our ListView.
  • It defines the main content of the main activity.
  • It will be interpolated into 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.listviewlongclick.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

  • We call it model because it will model for us a single view item in our ListView.
  • Each view item will comprise an image and text.
  • And will actually be wrapped inside a CardView.
    <?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 now come to our custom Java classes:

1. Movie.java

  • This class is a POJO(Plain Old Java Object). It's our data object.
  • It represents a single movie.
  • Each movie has its properties like name and image.
  • Each movie will be rendered in a CardView.
    package com.tutorials.hp.listviewlongclick;

    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. ItemLongClickLister.java

  • This is an interface.
  • It defines the signature for our onItemLongClick() method.
    package com.tutorials.hp.listviewlongclick;

    import android.view.View;

    public interface ItemLongClickListener {

        void onLongItemClick(View v);

    }

3. MyViewHolder.java

  • Our ViewHolder class. It will hold imageview and textview for recycling by our adapter class.
  • It will implement View.OnLongClickListener. This will help us in listening to long click events.
    package com.tutorials.hp.listviewlongclick;

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

    public class MyViewHolder implements View.OnLongClickListener {

        ImageView img;
        TextView nameTxt;
        ItemLongClickListener itemLongClickListener;

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

            v.setOnLongClickListener(this);

        }

        public void setItemLongClickListener(ItemLongClickListener ic)
        {
            this.itemLongClickListener=ic;
        }

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

4. CustomAdapter.java

  • Our adapter class.
  • Dervies from android.widget.BaseAdapter;.
  • It will adapt our adapter to our custom views in our listview.
    package com.tutorials.hp.listviewlongclick;

    import android.content.Context;
    import android.view.LayoutInflater;
    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;

        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;
        }

        //SHALL RETURN A ROW
        @Override
        public View getView(final int position, View convertView, ViewGroup parent) {

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

            //CONVERT FROM XML TO JAVA
            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.setItemLongClickListener(new ItemLongClickListener() {
                @Override
                public void onLongItemClick(View v) {
                    Toast.makeText(c,movies.get(position).getName(),Toast.LENGTH_SHORT).show();
                }
            });

            return convertView;
        }
    }

5. MainActivity.java

  • Our launcher and only activity.
  • We initialize our ListView.
  • We also instantiate our CustomAdapter here. Then set it to our ListView.
    package com.tutorials.hp.listviewlongclick;

    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.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());

            //SET ADAPTER
            lv.setAdapter(adapter);

        }

        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("Fruts",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 code here.

How do You Feel after reading this?

According to scientists, we humans have 8 primary innate emotions: joy, acceptance, fear, surprise, sadness, disgust, anger, and anticipation. Feel free to tell us how you feel about this article using these emotes or via the comment section. This feedback helps us gauge our progress.

Help me Grow.

I set myself some growth ambitions I desire to achieve by this year's end regarding this website and my youtube channel. Am halfway. Help me reach them by:




Recommendations


What do You Think


Previous Post Next Post