Android Working With Recycler View

Android RecyclerView is more advanced and flexible version of the listview.  RecyclerView is a container for displaying large sets of data that can be scrolled efficiently. Use RecyclerView when you have large data sets whose elements change at runtime.

In this tutorial, we will create RecyclerView with custom layout  and custom Adapter.

So Let’s Start

  1. .Open  Android Studio -> New Project->Android Application Project-> Name of Application-> Follow all instructions and complete by clicking on Finish.
  2. To use Recycler View in our Project we need to add Following dependencies in build.gradle as follows
    dependencies {
        compile fileTree(dir: 'libs', include: ['*.jar'])
        compile 'com.android.support:appcompat-v7:23.1.1'
        compile 'com.android.support:design:23.1.1'
        compile 'com.android.support:recyclerview-v7:23.1.1'
    }
  3. Now we will make Model class as User.java and declare name, age, interests and getters and setters for variables as follows
    package com.coderzpassion.recyclersample;
    
    /**
     * Created by coderzpassion on 28/02/16.
     */
    public class User {
        private String name,age,interests;
    
        public User()
        {
    
        }
        public User(String name,String age,String interests)
        {
            this.name=name;
            this.age=age;
            this.interests=interests;
        }
    
        public String getName() {
            return name;
        }
    
        public void setName(String name) {
            this.name = name;
        }
    
        public String getAge() {
            return age;
        }
    
        public void setAge(String age) {
            this.age = age;
        }
    
        public String getInterests() {
            return interests;
        }
    
        public void setInterests(String interests) {
            this.interests = interests;
        }
    }
    

    4. Now we will create layout file for adapter and for each row of recyclerview as

          user_layout.xml

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="vertical"
    android:layout_width="match_parent"
    android:layout_height="match_parent">

    <TextView
        android:id="@+id/user_name"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_alignParentTop="true"/>
    <TextView
        android:id="@+id/user_age"
        android:layout_alignParentRight="true"

        android:layout_width="wrap_content"
        android:layout_height="wrap_content" />
    <TextView
        android:id="@+id/user_interests"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_below="@+id/user_name"/>

</RelativeLayout>

5. Now Create CustomAdapter for RecyclerView as follows and override necessary methods

CustomRecyclerAdapter.java

package com.coderzpassion.recyclersample;

import android.content.Context;
import android.support.v7.widget.RecyclerView;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.TextView;

import java.util.List;

/**
 * Created by coderzpassion on 28/02/16.
 */
public class CustomRecyclerAdapter extends RecyclerView.Adapter<CustomRecyclerAdapter.MyCustomViewHolder> {

    private List<User> userslist;
    Context con;
    class MyCustomViewHolder extends RecyclerView.ViewHolder
    {
        public TextView name,age,interests;

        public MyCustomViewHolder(View v)
        {
            super(v);
            name=(TextView)v.findViewById(R.id.user_name);
            age=(TextView)v.findViewById(R.id.user_age);
            interests=(TextView)v.findViewById(R.id.user_interests);
        }
    }

    public CustomRecyclerAdapter(Context c,List<User> users)
    {
        this.con=c;
        this.userslist=users;
    }

    @Override
    public MyCustomViewHolder onCreateViewHolder(ViewGroup viewGroup, int i) {
        View usersview= LayoutInflater.from(con).inflate(R.layout.user_layout,viewGroup,false);

        return new MyCustomViewHolder(usersview);
    }

    @Override
    public void onBindViewHolder(MyCustomViewHolder myCustomViewHolder, int i) {
        User user=userslist.get(i);
        myCustomViewHolder.name.setText(user.getName());
        myCustomViewHolder.age.setText(user.getAge());
        myCustomViewHolder.interests.setText(user.getInterests());
    }

    @Override
    public int getItemCount() {
        return userslist.size();
    }
}

6. Now we create a layout for our MainActivity.java which will be our main screen of our app.This layout will contain RecyclerView

activity_main.xml

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:paddingLeft="@dimen/activity_horizontal_margin"
    android:paddingRight="@dimen/activity_horizontal_margin"
    android:paddingTop="@dimen/activity_vertical_margin"
    android:paddingBottom="@dimen/activity_vertical_margin"
    tools:context=".MainActivity"
    android:orientation="vertical">

    <android.support.v7.widget.RecyclerView
        android:id="@+id/myrecyclerview"
        android:scrollbars="vertical"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        />

</LinearLayout>

7. RecyclerDivider.java which is as a divider between recycler view elements.

package com.coderzpassion.recyclersample;

import android.content.Context;
import android.content.res.TypedArray;
import android.graphics.Canvas;
import android.graphics.Rect;
import android.graphics.drawable.Drawable;
import android.support.v7.widget.LinearLayoutManager;
import android.support.v7.widget.RecyclerView;
import android.view.View;

/**
 * Created by coderzpassion on 28/02/16.
 */
public class RecyclerDivider extends RecyclerView.ItemDecoration {
    private static final int [] Attri=new int[]{android.R.attr.listDivider};

    public static final int HORIZONTAL_LIST= LinearLayoutManager.HORIZONTAL;

    public static final int VERTICAL_LIST=LinearLayoutManager.VERTICAL;

    private Drawable divider;

    private int ORIENTATION;

    public RecyclerDivider (Context context,int orientation)
    {
        final TypedArray aray=context.obtainStyledAttributes(Attri);
        divider=aray.getDrawable(0);
        aray.recycle();
        setOrientationOFRecylerView(orientation);
    }

    public void setOrientationOFRecylerView(int orient)
    {
        if(orient!= HORIZONTAL_LIST && orient!=VERTICAL_LIST)
        {
            throw new IllegalArgumentException("invalid orientation");
        }
        ORIENTATION=orient;
    }

    @Override
    public void onDrawOver(Canvas c, RecyclerView parent, RecyclerView.State state) {
        if(ORIENTATION==VERTICAL_LIST)
        {
            drawVerticalDivider(c,parent);
        }
        else {
            drawHorizontalDivider(c,parent);
        }
    }

    public void drawVerticalDivider(Canvas c,RecyclerView parent)
    {
        final int left=parent.getPaddingLeft();
        final int right=parent.getWidth()-parent.getPaddingRight();
        final int childCount=parent.getChildCount();
        for (int idx=0;idx<childCount;idx++)
        {
            final View child=parent.getChildAt(idx);
            final RecyclerView.LayoutParams params=(RecyclerView.LayoutParams)child.getLayoutParams();
            final int top=child.getBottom() + params.bottomMargin;
            final int bottom=top+divider.getIntrinsicHeight();
            divider.setBounds(left,top,right,bottom);
            divider.draw(c);
        }
    }
    public void drawHorizontalDivider(Canvas c,RecyclerView parent)
    {
        final int top = parent.getPaddingTop();
        final int bottom = parent.getHeight() - parent.getPaddingBottom();

        final int childCount = parent.getChildCount();
        for (int i = 0; i < childCount; i++) {
            final View child = parent.getChildAt(i);
            final RecyclerView.LayoutParams params = (RecyclerView.LayoutParams) child
                    .getLayoutParams();
            final int left = child.getRight() + params.rightMargin;
            final int right = left + divider.getIntrinsicHeight();
            divider.setBounds(left, top, right, bottom);
            divider.draw(c);
        }
    }

    @Override
    public void getItemOffsets(Rect outRect, View view, RecyclerView parent, RecyclerView.State state) {
        if(ORIENTATION==VERTICAL_LIST)
        {
            outRect.set(0,0,0,divider.getIntrinsicHeight());
        }
        else
        {
            outRect.set(0,0,divider.getIntrinsicWidth(),0);
        }
    }
}

 

8. Finally, we will create MainActivity.java containing RecyclerView and bound adapter to RecyclerView and implement onItemTouchListner that will be called by clicking RecyclerView Item

MainActivity.java

package com.coderzpassion.recyclersample;

import android.content.Context;
import android.graphics.Movie;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.support.v7.widget.DefaultItemAnimator;
import android.support.v7.widget.LinearLayoutManager;
import android.support.v7.widget.RecyclerView;
import android.view.GestureDetector;
import android.view.Menu;
import android.view.MenuItem;
import android.view.MotionEvent;
import android.view.View;
import android.widget.Toast;

import java.util.ArrayList;
import java.util.List;

public class MainActivity extends AppCompatActivity {
    // list containing dummy data of all users
    private List<User> users=new ArrayList<>();
    // Recycler view
    private RecyclerView recyclerView;
   //CustomRecycler Adapter
    private CustomRecyclerAdapter adapter;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        recyclerView=(RecyclerView)findViewById(R.id.myrecyclerview);
        //prepare dummy data for adapter
        prepareDummyData();
        adapter=new CustomRecyclerAdapter(MainActivity.this,users);
        RecyclerView.LayoutManager mLayoutManager = new LinearLayoutManager(getApplicationContext());
        recyclerView.setLayoutManager(mLayoutManager);
        recyclerView.setItemAnimator(new DefaultItemAnimator());
        // add divider between Recycler view items
        recyclerView.addItemDecoration(new RecyclerDivider(this,LinearLayoutManager.VERTICAL));
        // bound adapter to recycler view
        recyclerView.setAdapter(adapter);
        // set itemTouchListener for recyclerview
        recyclerView.addOnItemTouchListener(new CustomRecyclerTouchListener(getApplicationContext(), recyclerView, new ClickListener() {
            @Override
            public void onClick(View view, int position) {
                User user=users.get(position);
                Toast.makeText(MainActivity.this,user.getName()+" is clicked",Toast.LENGTH_SHORT).show();
            }

            @Override
            public void onLongClick(View view, int position) {
                User user=users.get(position);
                Toast.makeText(MainActivity.this,user.getName()+" is long clicked",Toast.LENGTH_SHORT).show();
            }
        }));
    }
     public void prepareDummyData()
     {
         User user =new User("Ayush","20","playing badminton,snooker");
         users.add(user);
         user=new User("Pardeep","18","playing football,reading");
         users.add(user);
         user=new User("Vibhor","22","playing cricket,reading");
         users.add(user);
         user=new User("Jatin","18","playing games,doing gym");
         users.add(user);
         user=new User("Ankur","19","playing Clash of clan,reading");
         users.add(user);
         user=new User("Ankush","20","playing football,reading");
         users.add(user);
         user=new User("Hemant","21","playing Rugby,watching movies");
         users.add(user);
         user=new User("Harprett","24","playing Handball,chilling with friends");
         users.add(user);
         user=new User("Honey","18","playing football,reading");
         users.add(user);


     }
    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        // Inflate the menu; this adds items to the action bar if it is present.
        getMenuInflater().inflate(R.menu.menu_main, menu);
        return true;
    }

    @Override
    public boolean onOptionsItemSelected(MenuItem item) {
        // Handle action bar item clicks here. The action bar will
        // automatically handle clicks on the Home/Up button, so long
        // as you specify a parent activity in AndroidManifest.xml.
        int id = item.getItemId();

        //noinspection SimplifiableIfStatement
        if (id == R.id.action_settings) {
            return true;
        }

        return super.onOptionsItemSelected(item);
    }
    // creating interface to handle clicks for Recycler view items
    public interface ClickListener
    {
        void onClick(View view,int position);
        void onLongClick(View view,int position);
    }
    public static class CustomRecyclerTouchListener implements RecyclerView.OnItemTouchListener
    {
        private GestureDetector gestureDetector;
        private MainActivity.ClickListener clickListener;

        public CustomRecyclerTouchListener(Context context,final RecyclerView recyclerView,final MainActivity.ClickListener clickListener)
        {
            this.clickListener=clickListener;
            gestureDetector=new GestureDetector(context,new GestureDetector.SimpleOnGestureListener()
            {
                @Override
                public boolean onSingleTapUp(MotionEvent e) {
                    return true;
                }

                @Override
                public void onLongPress(MotionEvent e) {
                   View child=recyclerView.findChildViewUnder(e.getX(),e.getY());
                    if(child!=null && clickListener !=null)
                    {
                        clickListener.onLongClick(child,recyclerView.getChildPosition(child));
                    }
                }
            });
        }

        @Override
        public boolean onInterceptTouchEvent(RecyclerView recyclerView, MotionEvent motionEvent) {
            View child=recyclerView.findChildViewUnder(motionEvent.getX(),motionEvent.getY());
            if(child!=null && clickListener!=null && gestureDetector.onTouchEvent(motionEvent))
            {
                clickListener.onClick(child,recyclerView.getChildPosition(child));
            }
            return false;
        }

        @Override
        public void onTouchEvent(RecyclerView recyclerView, MotionEvent motionEvent) {

        }

        @Override
        public void onRequestDisallowInterceptTouchEvent(boolean b) {

        }
    }
}

AndroidManifest.xml

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.coderzpassion.recyclersample" >

    <application
        android:allowBackup="true"
        android:icon="@mipmap/ic_launcher"
        android:label="@string/app_name"
        android:theme="@style/AppTheme" >
        <activity
            android:name=".MainActivity"
            android:label="@string/app_name" >
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />

                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
    </application>

</manifest>

 

Output

Screenshot_2016-02-28-23-01-13 Screenshot_2016-02-28-23-01-24 Screenshot_2016-02-28-23-01-21