Sunday, August 27, 2017

android - RecyclerView item click programmatically

activity_main.xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
    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:id="@+id/root_layout"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:padding="16dp"
    android:orientation="vertical"
    android:background="#bde295"
    >
    <Button
        android:id="@+id/btn"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="Click Item No : 1"
        />
    <android.support.v7.widget.RecyclerView
        android:id="@+id/recycler_view"
        android:layout_width="match_parent"
        android:layout_height="0dp"
        android:layout_weight="1"
        />
</LinearLayout>
custom_view.xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/linear_layout"
    android:orientation="vertical"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    >
    <TextView
        android:id="@+id/text_view"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:textStyle="bold"
        android:textSize="25sp"
        />
</LinearLayout>
ColorsAdapter.java

package com.cfsuman.me.androidcodesnippets;


import android.app.Activity;
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.LinearLayout;
import android.widget.TextView;
import android.widget.Toast;


public class ColorsAdapter extends RecyclerView.Adapter<ColorsAdapter.ViewHolder>{
    private Context mContext;
    private Activity mActivity;
    private String[] colors;

    public ColorsAdapter(Context context, Activity activity){
        mContext = context;
        mActivity = activity;
        colors = new String[]{"Red","Green","Blue","Yellow","Black"};
    }

    public static class ViewHolder extends RecyclerView.ViewHolder{
        public LinearLayout linear_layout;
        public TextView text_view;

        public ViewHolder(View v){
            super(v);
            text_view = v.findViewById(R.id.text_view);
            linear_layout = v.findViewById(R.id.linear_layout);
        }
    }

    @Override
    public void onBindViewHolder(ViewHolder holder, final int position){
        holder.text_view.setText(""+ (position+1) + ". "+ colors[position]);

        // Set a click listener for linear layout
        holder.linear_layout.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                Toast.makeText(mContext,"Clicked : " + colors[position],Toast.LENGTH_SHORT).show();
            }
        });
    }

    @Override
    public ColorsAdapter.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType){
        View v = LayoutInflater.from(parent.getContext()).inflate(R.layout.custom_view,parent,false);
        ViewHolder holder = new ViewHolder(v);
        return holder;
    }

    @Override
    public int getItemCount(){
        return colors.length;
    }
}
MainActivity.java

package com.cfsuman.me.androidcodesnippets;

import android.app.Activity;
import android.content.Context;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.support.v7.widget.GridLayoutManager;
import android.support.v7.widget.RecyclerView;
import android.view.View;
import android.widget.Button;
import android.widget.LinearLayout;


public class MainActivity extends AppCompatActivity {
    private Context mContext;
    private Activity mActivity;

    private LinearLayout mRootLayout;
    private Button mButton;

    private RecyclerView mRecyclerView;
    private RecyclerView.Adapter mAdapter;
    private RecyclerView.LayoutManager mLayoutManager;

    private int mIndexCount;
    private int mIndex = 0;


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

        // Get the application context
        mContext = getApplicationContext();
        mActivity = MainActivity.this;

        // Get the widgets reference from xml layout
        mButton = findViewById(R.id.btn);
        mRecyclerView = findViewById(R.id.recycler_view);

        // Set the recycler view adapter and layout
        mAdapter = new ColorsAdapter(mContext,mActivity);
        mRecyclerView.setAdapter(mAdapter);
        mLayoutManager = new GridLayoutManager(mContext,1);
        mRecyclerView.setLayoutManager(mLayoutManager);

        // Count recycler view item
        mIndexCount = mRecyclerView.getAdapter().getItemCount()-1;

        // Set a click listener for button widget
        mButton.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                if(mIndex <= mIndexCount){
                    /*
                        RecyclerView.ViewHolder findViewHolderForAdapterPosition (int position)
                            Return the ViewHolder for the item in the given position of the data set.
                            Unlike findViewHolderForLayoutPosition(int) this method takes into
                            account any pending adapter changes that may not be reflected to the
                            layout yet. On the other hand, if notifyDataSetChanged() has been called
                            but the new layout has not been calculated yet, this method will
                            return null since the new positions of views are unknown until
                            the layout is calculated.

                            This method checks only the children of RecyclerView. If the item at the
                            given position is not laid out, it will not create a new one.

                            When the ItemAnimator is running a change animation, there might be 2
                            ViewHolders representing the same Item. In this case, the updated
                            ViewHolder will be returned.

                        Parameters
                            position int : The position of the item in the data set of the adapter

                        Returns
                            RecyclerView.ViewHolder : The ViewHolder at position or null if
                                                      there is no such item
                    */

                    // Programmatically click the recycler view item
                    mRecyclerView.findViewHolderForAdapterPosition(mIndex).itemView.performClick();

                    // If index reach at the end
                    if(mIndex == mIndexCount){
                        mIndex = 0;
                    }else {
                        // For next index
                        mIndex += 1;
                    }
                    // Set the button new text
                    mButton.setText("Click Item No : " + (mIndex+1));
                }
            }
        });
    }
}