Skip to main content

Implementing RecyclerView

I'm working on Android hybrid apps from last 5 years, its very tough to stay in touch with Native android UI, Now I started learning through sample applications, so thought of sharing my learning here.
         
RecyclerView has came with Material design in Android Lollipop, RecyclerView is advanced, flexible version of Listview, RecyclerView uses the view holder pattern  and improve the performance by reusing off screen views and rebinds them to the data which is scrolling on the screen, now lets see the difference between list view and recyclerview.

Difference between RecyclerView and Listview :-

1. RecyclerView forces to use RecyclerView.ViewHolder(Inbuilt view Holder) to hold the elements, to reuse the cells while scrolling, which was optional in Listview which we used to create in adapters getView() method.

2. Animation while adding list items or removing list items are already added in the recyclerview.

3. List views were only of vertical types, however with recyclerview we can create list items displaying in vertical or horizontal by Setting recyclerView.setLayoutManager to LinearLayout.

4. RecyclerView list items can by displayed like Gallery app by setting recyclerView.setLayoutManager to GridLayoutManager.

5. RecyclerView list items can be displayed like staggered Gridview by setting recyclerView.setLayoutManager to StaggeredLayoutManager.

6. Listview creates its items based on its position in the adapter, where as RecyclerView creates items based on item types if there is another item of  same type may be placed in a cache for later reuse can be used to display which will improve the performance.

Implementing RecyclerView :- 

RecyclerView is delivered as a library so add the latest version of this library as a dependencies the build.gradle file,

dependencies {
 compile 'com.android.support:recyclerview-v7:24.2.1' 
} 
Define the layout "activity_main.xml" for MainActivity.java

<android.support.v7.widget.RecyclerView
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:id="@+id/myrvlist">
            </android.support.v7.widget.RecyclerView>


Define list row item view layout "recycleritem.xml",
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
        android:layout_height="wrap_content"
        android:layout_width="wrap_content"
        android:id="@+id/lay_item"
        >
        <TextView
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="Emp Name"
            android:id="@+id/txt_name"/>

        <TextView
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="Emp AGE"
            android:id="@+id/txt_age"
            android:layout_below="@+id/txt_name"/>

    </RelativeLayout>
Now create an object of RecyclerView by using findViewById() in MainActivity oncreate() method,
@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);
    RecyclerView myRVList = (RecyclerView) findViewById(R.id.myrvlist);
}
You can set the layout manager dynamically using,
 LinearLayoutManager mgr = new LinearLayoutManager(this);
myRVList.setLayoutManager(mgr);
Create static class to hold list data,
 public static class Employee {
    String name = "";
    String age = "";
    Employee(String name , String age){
        this.name = name;
        this.age = age;
    }
}
Initialize the data and set Adapter to recyclerview,
private void initData(){
    mEmployee = new ArrayList<>();
    mEmployee.add(new Employee("Emp1" , "31"));
    mEmployee.add(new Employee("Emp2" , "32"));
    mEmployee.add(new Employee("Emp3" , "33"));
    mEmployee.add(new Employee("Emp4" , "35"));
    mEmployee.add(new Employee("Emp5" , "31"));
}
Set Adapter to the recyclerview,
RecyclerViewAdapter adapter = new RecyclerViewAdapter(mEmployee);
myRVList.setAdapter(adapter);

getItemCount()returns total number of items in the list.

onCreateViewHolder() This method inflate the view for the view holder and pass to the new view holder object, it wont have any contents , only views will be set, Recyclerview creates views as an when necessary after some count it wont create new views only data will be bind to the already created views, views will be reused.

onBindViewHolder(MyViewHolder holder, int position) Finds the data of given position and binds to the view holder.

public class RecyclerViewAdapter extends RecyclerView.Adapter<RecyclierViewAdapter.MyViewHolder>{

    List<Employee> mListData = null;

    public RecyclierViewAdapter(List<Employee> mList) {

        this.mListData = mList;
    }

     public MyViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
        View v = LayoutInflater.from(parent.getContext()).inflate(R.layout.recycleritem, parent,false);
        MyViewHolder mv = new MyViewHolder(v);
        return mv;
    }

    @Override    
	public void onBindViewHolder(MyViewHolder holder, int position) {
        holder.txt_name.setText(mListData.get(position).name);
        holder.txt_age.setText(mListData.get(position).age);

    }

    @Override    
	public void onAttachedToRecyclerView(RecyclerView recyclerView) {
        super.onAttachedToRecyclerView(recyclerView);
    }

    @Override    
	public void onBindViewHolder(MyViewHolder holder, int position, List<Object> payloads) {
        super.onBindViewHolder(holder, position, payloads);
    }

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

    public static  class MyViewHolder extends RecyclerView.ViewHolder{
        RelativeLayout relativeLayout = null;
        TextView txt_name ;
        TextView txt_age ;
        MyViewHolder(View itemView){
            super(itemView);
            relativeLayout = (RelativeLayout) itemView.findViewById(R.id.lay_item);
            txt_name  = (TextView) itemView.findViewById(R.id.txt_name);
            txt_age  = (TextView) itemView.findViewById(R.id.txt_age);
        }
    }

// To add items and refresh list
public void addNewItem(Employee empObj, int index) {
    mListData.add(empObj);
    notifyItemInserted(index);
}
// Delete list items and refresh list
public void deleteListItem(int index) {
    mListData.remove(index);
    notifyItemRemoved(index);
}

}
Recyclerview does not display any space or divider between list items, so we need to add the item decoration to display divider between list items , The version 25.0.0 of Android Support library introduced DividerItemDecoration class:
DividerItemDecoration.java Set item decoration to the recyclerview,
RecyclerView.ItemDecoration itemDecoration =

        new DividerItemDecoration(this, LinearLayoutManager.VERTICAL);
myRVList.addItemDecoration(itemDecoration);
Handling onItemClickListener for RecyclerView :-

RecyclerView doesn't have default onItemclickListener implementation, Here is the way we can have our own custom onitemclicklistener,

Define an custom interface with onItemClick() method,

public interface MyOnRecyclerViewItemListener{
    public void onItemClick(int position , View v);
}

Implement MyOnRecyclerViewItemListener in the MainActivity and register for onItemclick() events,
public class MainActivity extends Activity implements MyOnRecyclerViewItemListener {

	 protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        RecyclerView rvList = (RecyclerView) findViewById(R.id.rvlist);
        LinearLayoutManager mgr = new LinearLayoutManager(this);
        rvList.setLayoutManager(mgr);
        rvList.setHasFixedSize(true);
        initData();
        RecyclierViewAdapter adapter = new RecyclierViewAdapter(mPersons);
        rvList.setAdapter(adapter);
        RecyclerView.ItemDecoration itemDecoration =
                new DividerItemDecoration(this, LinearLayoutManager.VERTICAL);
        rvList.addItemDecoration(itemDecoration);
        adapter.registerListItemClickListner(this);
    }
Add below code in adapter,
// Define item click listener,
private MyOnRecyclerViewItemListener itemClickLister = null;
      
// listener will be set for MainActivity.java 
public void registerListItemClickListner(MyOnRecyclerViewItemListener listner){
        this.itemClickLister = listner;
}

// Implement view onlclicklister and pass to the MainActivity 
 public class MyViewHolder extends RecyclerView.ViewHolder implements View.OnClickListener{

        RelativeLayout relativeLayout = null;
        TextView txt_name ;
        TextView txt_age ;
        MyViewHolder(View itemView){
            super(itemView);
            relativeLayout = (RelativeLayout) itemView.findViewById(R.id.lay_item);
            txt_name  = (TextView) itemView.findViewById(R.id.txt_name);
            txt_age  = (TextView) itemView.findViewById(R.id.txt_age);
            itemView.setOnClickListener(this);
        }

        @Override
        public void onClick(View v) {
            itemClickLister.onItemClick(getPosition(),v);
        }
}

Comments

Popular posts from this blog

Launch an Android application on Bootup

If you want to start an android application on device restarts, you need to listen for BOOT_COMPLETED broadcast in the manifest file and launch the Launcher activity in onreceive of BOOT_COMPLETED broadcast receiver. Follow below steps to launch activity on device boot up :- 1. Register for Boot completed receiver in Android Manifest file. Add below Permission to receive BOOT_COMPLETED broadcast, <uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" /> Register for Boot completed broadcast receiver , <receiver android:name="AppAutostartReceiver" android:enabled="true" > <intent-filter> <action android:name="android.intent.action.BOOT_COMPLETED" /> </intent-filter> </receiver> 2. Add custom Broadcast receiver in the application, public class AppAutostartReceiver extends BroadcastReceiver { @Override public void onReceive(Context cont

Whitelist an android application on android 6.0/Marshmallow

Whitelist wont disable doze mode for your app, however can use network and hold wake lock. Whitelist an android application through code, boolean isIgnoringBatteryOptimizations = pm.isIgnoringBatteryOptimizations(getPackageName()); if(!isIgnoringBatteryOptimizations){   Intent intent = new Intent();   intent.setAction(Settings.ACTION_REQUEST_IGNORE_BATTERY_OPTIMIZATIONS);   intent.setData(Uri.parse("package:" + getPackageName()));   startActivityForResult(intent, MY_IGNORE_OPTIMIZATION_REQUEST);   }                             Check for the result, @Override protected void onActivityResult(int requestCode, int resultCode, Intent data) {     if (requestCode == MY_IGNORE_OPTIMIZATION_REQUEST) {          PowerManager pm = (PowerManager)getSystemService(Context.POWER_SERVICE);          boolean isIgnoringBatteryOptimizations = pm.isIgnoringBatteryOptimizations(getPackageName());          if(isIgnoringBatteryOptimizations){             // Ignoring battery opti