RecyclerView

Android RecyclerView is more advanced version of ListView with improved performance and other benefits. RecyclerView is mostly used to design the user interface with the fine-grain control over the lists and grids of android application. As RecyclerView is advanced version of ListView we highly recommend to user RecyclerView

public class RecyclerView extends ViewGroup implements ScrollingView, NestedScrollingChild2, NestedScrollingChild3
java.lang.Object
↳ android.view.View
  ↳ android.view.ViewGroup
    ↳ androidx.recyclerview.widget.RecyclerView

We Recommend to use new UI components i.e. androidx components


RecyclerView Vs ListView

ListView RecyclerView
Adapters do not require the use of the ViewHolder pattern to improve performance Implementing an adapter for RecyclerView requires the use of the ViewHolder pattern for which it uses RecyclerView.Viewholder
Can only layout items in a vertical linear arrangement and this cannot be customized Has a RecyclerView.LayoutManager that allows any item layouts including horizontal lists or staggered grids.
Contains no special provisions through which one can animate the addition or deletion of items Has the RecyclerView.ItemAnimator class for handling item animations
Had adapters for different sources such as ArrayAdapter and CursorAdapter for arrays and database results respectively The RecyclerView.Adapter requires a custom implementation to supply the data to the adapter.
Has the android:divider property for easy dividers between items in the list Requires the use of a RecyclerView.ItemDecoration object to setup much more manual divider decorations.
Has a AdapterView.OnItemClickListener interface for binding to the click events for individual items in the list Only has support for RecyclerView.OnItemTouchListener which manages individual touch events but has no built-in click handling.

Note: A RecyclerView needs to have a layout manager and an adapter to be instantiated. A layout manager positions item views inside a RecyclerView and determines when to reuse item views that are no longer visible to the user.

RecyclerView provides following built-in layout managers:

  • LinearLayoutManager shows items in a vertical or horizontal scrolling list.
  • GridLayoutManager shows items in a grid.
  • StaggeredGridLayoutManager shows items in a staggered grid.

Note: Make sure the RecyclerView AndroidX library is listed as a dependency in your app/build.gradle:

dependencies {
    ...
    // check for latest version
    implementation 'androidx.recyclerview:recyclerview:1.1.0'
}

Now let's create a complete example, for understanding better, we are going to create a project containing RecylerView having an employee name, age, salary and employee type, We start step by step.

First we create a empty project, after that we will create layout xml file i.e. listview_activity.xml

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

    <androidx.appcompat.widget.AppCompatButton
        android:id="@+id/btnAdd"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_below="@+id/empType"
        android:onClick="addRecord"
        android:text="Add Record" />

    <androidx.appcompat.widget.AppCompatEditText
        android:id="@+id/empName"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:hint="Enter employee name"
        android:layout_below="@+id/empId" />

    <androidx.appcompat.widget.AppCompatEditText
        android:id="@+id/empSalary"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_below="@+id/empName"
        android:hint="Enter employee salary"
        android:inputType="numberDecimal" />

    <androidx.appcompat.widget.AppCompatEditText
        android:id="@+id/empType"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_below="@+id/empSalary"
        android:hint="Entere employee type"
        android:inputType="number" />

    <androidx.appcompat.widget.AppCompatEditText
        android:id="@+id/empId"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:hint="Enter employee id"
        android:layout_alignParentTop="true" />

    <androidx.recyclerview.widget.RecyclerView
        android:id="@+id/rvEmpList"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:layout_below="@id/btnAdd"
        android:layout_marginTop="10dp" />

</RelativeLayout>

Now we create item xml to which will be display in RecyclerView list i.e. recycler_view_item.xml

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

    <RelativeLayout
        android:id="@+id/listId"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_alignParentTop="true">

        <androidx.appcompat.widget.AppCompatTextView
            android:id="@+id/empRowId"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_alignParentLeft="true"
            android:text="Row Id" />

        <androidx.appcompat.widget.AppCompatTextView
            android:id="@+id/empId"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_marginLeft="10dp"
            android:layout_toRightOf="@+id/empRowId"
            android:text="(EmpId)"
            android:textStyle="bold" />

        <androidx.appcompat.widget.AppCompatTextView
            android:id="@+id/btnEdit"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_marginRight="10dp"
            android:layout_toLeftOf="@+id/btnDelete"
            android:clickable="true"
            android:focusable="true"
            android:text="Edit"
            android:textColor="@android:color/holo_blue_light"
            android:textSize="8pt" />

        <androidx.appcompat.widget.AppCompatTextView
            android:id="@+id/btnDelete"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_alignParentRight="true"
            android:layout_marginRight="10dp"
            android:clickable="true"
            android:focusable="true"
            android:text="Delete"
            android:textColor="@android:color/holo_blue_light"
            android:textSize="8pt" />

    </RelativeLayout>

    <RelativeLayout
        android:id="@+id/rlDetails"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_below="@+id/listId"
        android:orientation="horizontal">

        <androidx.appcompat.widget.AppCompatTextView
            android:id="@+id/empName"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_alignParentLeft="true"
            android:text="Emp Name" />


        <androidx.appcompat.widget.AppCompatTextView
            android:id="@+id/empSalary"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_toRightOf="@+id/empName"
            android:layout_marginLeft="20dp"
            android:text="(Emp Type)" />

        <androidx.appcompat.widget.AppCompatTextView
            android:id="@+id/empType"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_toRightOf="@+id/empSalary"
            android:layout_marginLeft="20dp"
            android:text="(Emp Type)" />
    </RelativeLayout>

    <View
        android:layout_width="match_parent"
        android:layout_height="2dp"
        android:layout_marginTop="5dp"
        android:layout_below="@+id/rlDetails"
        android:background="@android:color/darker_gray"/>

</RelativeLayout>

Now we will create adapter that will help to show data into list i.e. EmployeeListAdapater.java

EmployeeListAdapater.java
package com.theitbulls.contentproviderex;

import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;

import androidx.annotation.NonNull;
import androidx.appcompat.widget.AppCompatTextView;
import androidx.recyclerview.widget.RecyclerView;

import com.theitbulls.contentproviderex.room.Employee;

import java.util.List;

public class EmployeeListAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder> {
    private MainActivity activity;
    private final List<Employee> items;

    public EmployeeListAdapter(MainActivity activity, List<Employee> items) {
        this.activity = activity;

        this.items = items;
    }

    @NonNull
    @Override
    public RecyclerView.ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
        final View itemView = LayoutInflater.from(parent.getContext()) .inflate(R.layout.recycler_view_item, parent, false);
        return new EmployeeViewHolder(itemView);
    }

    @Override
    public void onBindViewHolder(@NonNull RecyclerView.ViewHolder holder, int position) {
        final EmployeeViewHolder empHolder = (EmployeeViewHolder) holder;
        final Employee employee = items.get(position);

        empHolder.tvRowId.setText(String.valueOf(employee.id) + ": ");

        empHolder.tvEmpId.setText(employee.empId);
        empHolder.tvEmpName.setText(employee.name);
        empHolder.tvEmpSalary.setText(String.valueOf(employee.salary));
        empHolder.tvEmpType.setText(String.valueOf(employee.type));

        empHolder.btnEdit.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                activity.edit(employee);
            }
        });

        empHolder.btnDelete.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                activity.delete(employee.id);
            }
        });
    }

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

    public class EmployeeViewHolder extends RecyclerView.ViewHolder {
        private final AppCompatTextView tvRowId;

        public AppCompatTextView tvEmpId;
        public AppCompatTextView tvEmpName;
        public AppCompatTextView tvEmpSalary;
        public AppCompatTextView tvEmpType;

        public AppCompatTextView btnEdit;
        public AppCompatTextView btnDelete;

        public EmployeeViewHolder(@NonNull View itemView) {
            super(itemView);

            tvRowId = itemView.findViewById(R.id.empRowId);

            tvEmpId = itemView.findViewById(R.id.empId);
            tvEmpName = itemView.findViewById(R.id.empName);
            tvEmpSalary = itemView.findViewById(R.id.empSalary);
            tvEmpType = itemView.findViewById(R.id.empType);

            btnEdit = itemView.findViewById(R.id.btnEdit);
            btnDelete = itemView.findViewById(R.id.btnDelete);
        }
    }
}


Now we will create MainActivity.java, here we store data into a hashtable you can save as your project requirements

MainActivity.java
package com.theitbulls.rvdemo;

import android.os.Bundle;
import android.view.View;
import android.widget.Toast;

import androidx.annotation.Nullable;
import androidx.appcompat.app.AppCompatActivity;
import androidx.appcompat.widget.AppCompatButton;
import androidx.appcompat.widget.AppCompatEditText;
import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.recyclerview.widget.RecyclerView;

import java.util.ArrayList;
import java.util.Enumeration;
import java.util.Hashtable;
import java.util.List;

public class MainActivity extends AppCompatActivity {
    public Hashtable<Long, Employee> empLists = new Hashtable<>();

    private RecyclerView recyclerView;
    private AppCompatEditText etEmpId;
    private AppCompatEditText etEmpName;
    private AppCompatEditText etEmpSalary;
    private AppCompatEditText etEmpType;

    private boolean toUpdate;
    private Employee employee;

    @Override
    protected void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main_activity);

        etEmpId = findViewById(R.id.empId);
        etEmpName = findViewById(R.id.empName);
        etEmpSalary = findViewById(R.id.empSalary);
        etEmpType = findViewById(R.id.empType);

        LinearLayoutManager llm = new LinearLayoutManager(this);
        llm.setOrientation(LinearLayoutManager.VERTICAL);

        recyclerView = findViewById(R.id.rvEmpList);
        recyclerView.setLayoutManager(llm);

        AppCompatButton btnAdd = findViewById(R.id.btnAdd);
        btnAdd.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {

                try {
                    Employee employee = getEmployee();
                    if(MainActivity.this.employee == null) {
                        // to add record
                        empLists.put(employee.id, employee);
                    } else {
                        // to update record
                        employee.id = MainActivity.this.employee.id;
                        empLists.put(employee.id, employee);
                    }

                    initRecyclerView();
                } catch (Exception e) {
                    Toast.makeText(MainActivity.this, "Record added error: " + e.toString(), Toast.LENGTH_SHORT).show();
                }
            }
        });

    }

    public void edit(Employee employee) {
        this.employee = employee;

        etEmpId.setText(employee.empId);
        etEmpName.setText(employee.name);
        etEmpSalary.setText(String.valueOf(employee.salary));
        etEmpType.setText(String.valueOf(employee.type));
    }

    public void delete(long id) {
        empLists.remove(id);
        initRecyclerView();
    }

    private Employee getEmployee() {
        Employee employee = new Employee();
        employee.id = empLists.size() + 1;

        employee.empId = etEmpId.getText().toString();
        employee.name = etEmpName.getText().toString();

        String salary = etEmpSalary.getText().toString();
        employee.salary = Double.parseDouble(salary);

        String type = etEmpType.getText().toString();
        employee.type = Integer.parseInt(type);
        return employee;
    }

    private void initRecyclerView() {
        List<Employee> items = new ArrayList<>();
        Enumeration<Employee> employees = empLists.elements();
        while(employees.hasMoreElements()) {
            items.add(employees.nextElement());
        }

        EmployeeListAdapter adapter = new EmployeeListAdapter(this, items);
        recyclerView.setAdapter(adapter);
    }
}



You can download complete working example below, you can update, delete and insert Employee record's. Happy coding developer's

Download: RecyclerViewExample.zip