10

I am developing a simple notepad app first i used listView to show all the notes.But now I am using RecyclerView. While i am using listview i used OnItemClickListener to pass the Data to another activity for editing the note now i am confuse what to do in Recylerview

For listView i am using this

 listView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
        @Override
        public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
            name = filenames.get(position).getName();
            note = filenames.get(position).getShorttext();
            Alert(); // this method is in main activity 

        }
    });*/  


  public void Alert()
   {
    final AlertDialog dialog;
    View mview = getLayoutInflater().inflate(R.layout.dialog_pass,null);
    final EditText mEdittext = (EditText) mview.findViewById(R.id.Epass);
    AlertDialog.Builder mBuilder = new AlertDialog.Builder(MainActivity.this);
    mBuilder.setView(mview);
    mBuilder.setPositiveButton("Ok", new DialogInterface.OnClickListener() {
        @Override
        public void onClick(DialogInterface dialog, int which) {
            String col = mEdittext.getText().toString();
            String password = dBhelper.searchpass(col);
            if (col.equals(password)) {
                Intent intent =  new Intent(MainActivity.this,Note2.class);
                intent.putExtra("Name",name);
                intent.putExtra("Note",note);
                startActivity(intent);
            } else {
                Toast temp = Toast.makeText(MainActivity.this, "Password does not match", Toast.LENGTH_SHORT);
                temp.show();
            }

        }
    });
    mBuilder.setNegativeButton("Cancel",null);
    mBuilder.setCancelable(false);
    dialog = mBuilder.create();
    dialog.show();

     }

Now What Should i Do for Recycle View Please Help

  public class RecycleViewAdapter extends 
  RecyclerView.Adapter<RecycleViewHolder> {// Recyclerview will extend to
  private List<FileName> fileNames;
  private Context context;

  public RecycleViewAdapter(Context context,List<FileName> fileNames) {
    this.context = context;
    this.fileNames = fileNames;

}

@Override
public RecycleViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
    LayoutInflater mInflater = LayoutInflater.from(parent.getContext());

    ViewGroup mainGroup = (ViewGroup) mInflater.inflate(
            R.layout.grid_item, parent, false);
    RecycleViewHolder listHolder = new RecycleViewHolder(mainGroup);
    return listHolder;

}

@Override
public void onBindViewHolder(RecycleViewHolder holder, final int position) {
    final FileName model = fileNames.get(position);
    RecycleViewHolder mainHolder = (RecycleViewHolder) holder;// holder
    mainHolder.title.setText(model.getName());
    mainHolder.note.setText(model.getShorttext());

}

@Override
public int getItemCount() {
    return (null != fileNames ? fileNames.size() : 0);
  }
faiz mir
  • 165
  • 1
  • 1
  • 10
  • https://stackoverflow.com/questions/24885223/why-doesnt-recyclerview-have-onitemclicklistener-and-how-recyclerview-is-dif – PEHLAJ May 24 '17 at 07:43
  • https://stackoverflow.com/a/40134429/2058260 – H4SN May 24 '17 at 07:44
  • Possible duplicate of [how to implement a SetOnItemClickListener FirebaseRecyclerViewAdapter](https://stackoverflow.com/questions/34110497/how-to-implement-a-setonitemclicklistener-firebaserecyclerviewadapter) – H4SN May 24 '17 at 07:45

8 Answers8

32

You can handle this using two ways

1). Gesture touch https://www.google.co.in/amp/sapandiwakar.in/recycler-view-item-click-handler/amp/

2).Using interface in adapter https://antonioleiva.com/recyclerview-listener/

I suggest second way using interface

How to use interface for recycleritemclick

public class RecycleViewAdapter extends 
  RecyclerView.Adapter<RecycleViewHolder> {// Recyclerview will extend to
  private List<FileName> fileNames;
  private Context context;

//declare interface 
  private OnItemClicked onClick;

//make interface like this
  public interface OnItemClicked {
        void onItemClick(int position);
  }

  public RecycleViewAdapter(Context context,List<FileName> fileNames) {
    this.context = context;
    this.fileNames = fileNames;
  }

Now assign click to interface

@Override
public void onBindViewHolder(RecycleViewHolder holder, final int position) {
  //............//
  holder.title.setOnClickListener(new View.OnClickListener() {
     @Override
     public void onClick(View v) {
        onClick.onItemClick(position);
     }
  });
}

At the end of the adapter class up from finishing bracket make one method to assign itemclick to interface

public void setOnClick(OnItemClicked onClick){
    this.onClick=onClick;
}

In MainActivity.java Bind the item click with adapter

public class MainActivity extends Activity implements OnItemClicked {
 
    private RecyclerView mRecyclerView;
    private CityAdapter mAdapter;
    private List<City> cities;
 
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_city);

        mRecyclerView = (RecyclerView)findViewById(R.id.list);
        mRecyclerView.setLayoutManager(new LinearLayoutManager(this));
        
        mAdapter = new CityAdapter(cities, R.layout.row_city, this);
        mRecyclerView.setAdapter(mAdapter);
 
        mAdapter.setOnClick(MainActivity.this); // Bind the listener
    }
 
    @Override
    public void onItemClick(int position) {
    // The onClick implementation of the RecyclerView item click
    //ur intent code here
    }
}

For Kotlin code please refer How to handle recyclerview item click in kotlin?

More queries? comment.

Sayooj
  • 766
  • 5
  • 23
Lokesh Desai
  • 2,607
  • 16
  • 28
11

Simplest solution would be to access the "itemView" public variable of holder class and set onClickListener on this.

@Override
public void onBindViewHolder(ViewHolder holder, final int position) {
        holder.itemView.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                Intent intent = new Intent(context, NewActivity.class);
                intent.putExtra("FileName", list.get(position));
                context.startActivity(intent);
            }
        });        
}
Vipul Kumar
  • 653
  • 8
  • 14
1

Change your adapter to this

    public class RecycleViewAdapter extends
        RecyclerView.Adapter<RecycleViewHolder> {// Recyclerview will extend to
    private List<FileName> fileNames;
    private Context context;
    private OnItemClicked listener;

    public RecycleViewAdapter(Context context, List<FileName> fileNames, OnItemClicked  listener) {
        this.context = context;
        this.fileNames = fileNames;
        this.listener = listener;
    }

    public BookingHistoryFragment() {
        // Required empty public constructor
    }

    @Override
    public RecycleViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
        LayoutInflater mInflater = LayoutInflater.from(parent.getContext());

        ViewGroup mainGroup = (ViewGroup) mInflater.inflate(
                R.layout.grid_item, parent, false);
        RecycleViewHolder listHolder = new RecycleViewHolder(mainGroup);

        return listHolder;

    }

    @Override
    public void onBindViewHolder(RecycleViewHolder holder, final int position) {
        final FileName model = fileNames.get(position);
        RecycleViewHolder mainHolder = (RecycleViewHolder) holder;// holder
        mainHolder.title.setText(model.getName());
        mainHolder.note.setText(model.getShorttext());

        // Add click listener for root view
        view.getRootView().setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View view) {
            listener.onItemClick(view, position)
        }
        });
    }

    @Override
    public int getItemCount() {
        return (null != fileNames ? fileNames.size() : 0);
    }

    public interface OnItemClicked {
        void onItemClick(View view, int position);
    }
}

Now pass ItemClickInterface to the adapter constructor while initializing from activity or fragment. Instead of:

RecycleViewAdapter adapter = new RecycleViewAdapter(this, filenames);

Use this:

RecycleViewAdapter adapter = new RecycleViewAdapter(this, filenames, new RecycleViewAdapter.OnItemClicked () {
@Override
      public void onItemClick(View view, Position position) {

      }
});
Hammad Akram
  • 573
  • 3
  • 9
1

First add this class to your package

public class MyTouchListener implements RecyclerView.OnItemTouchListener {


/*Change these as per your need*/
private static final int SWIPE_MIN_DISTANCE = 120;
private static final int SWIPE_THRESHOLD_VELOCITY = 200;
private static final int SWIPE_MAX_OFF_PATH = 250;

private OnTouchActionListener mOnTouchActionListener;
private GestureDetectorCompat mGestureDetector;

public static interface OnTouchActionListener {
    public void onLeftSwipe(View view, int position);
    public void onRightSwipe(View view, int position);
    public void onClick(View view, int position);
}

public MyTouchListener(Context context, final RecyclerView recyclerView,
                             OnTouchActionListener onTouchActionListener){

    mOnTouchActionListener = onTouchActionListener;
    mGestureDetector = new GestureDetectorCompat(context,new GestureDetector.SimpleOnGestureListener(){

        @Override
        public boolean onSingleTapConfirmed(MotionEvent e) {
            // Find the item view that was swiped based on the coordinates
            View child = recyclerView.findChildViewUnder(e.getX(), e.getY());
            int childPosition = recyclerView.getChildPosition(child);
            mOnTouchActionListener.onClick(child, childPosition);
            return false;
        }

        @Override
        public boolean onFling(MotionEvent e1, MotionEvent e2,
                               float velocityX, float velocityY) {

            try {
                if (Math.abs(e1.getY() - e2.getY()) > SWIPE_MAX_OFF_PATH) {
                    return false;
                }

                // Find the item view that was swiped based on the coordinates
                View child = recyclerView.findChildViewUnder(e1.getX(), e1.getY());
                int childPosition = recyclerView.getChildPosition(child);

                // right to left swipe
                if (e1.getX() - e2.getX() > SWIPE_MIN_DISTANCE && Math.abs(velocityX) > SWIPE_THRESHOLD_VELOCITY) {

                    if (mOnTouchActionListener != null && child != null) {
                        mOnTouchActionListener.onLeftSwipe(child, childPosition);
                    }

                } else if (e2.getX() - e1.getX() > SWIPE_MIN_DISTANCE && Math.abs(velocityX) > SWIPE_THRESHOLD_VELOCITY) {
                    if (mOnTouchActionListener != null && child != null) {
                        mOnTouchActionListener.onRightSwipe(child, childPosition);
                    }
                }
            } catch (Exception e) {
                // nothing
            }

            return false;
        }
    });
}

@Override
public boolean onInterceptTouchEvent(RecyclerView rv, MotionEvent e) {
    mGestureDetector.onTouchEvent(e);
    return false;
}

@Override
public void onTouchEvent(RecyclerView rv, MotionEvent e) {
}

@Override
public void onRequestDisallowInterceptTouchEvent(boolean disallowIntercept) {
    // do nothing
}}

Then addOnItemTouchListener like this:

myRecyclerView.addOnItemTouchListener(new MyTouchListener(mContext,
            myRecyclerView,
            new MyTouchListener.OnTouchActionListener() {
                @Override
                public void onLeftSwipe(View view, int position) {//code as per your need
                }

                @Override
                public void onRightSwipe(View view, int position) {//code as per your need
                }

                @Override
                public void onClick(View view, int position) {//code as per your need
                }
            }));
Suraj Vaishnav
  • 7,777
  • 4
  • 43
  • 46
0

Add this code in your RecyclerView adapter

    private OnItemClicked mListener;

    public RecycleViewAdapter(Context context, OnItemClicked listener, List<FileName> fileNames) {
        //............//
        this.mListener = listener;
    }

    @Override
    public void onBindViewHolder(RecycleViewHolder holder, final int position) {
        //............//
        mainHolder.title.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                mListener.onItemClick(position);
            }
        });

    }

    public interface OnItemClicked {
        void onItemClick(int position);
    }

And implement your Activity/Fragment to RecyclerViewAdapter.OnItemClicked

To pass via Intent you can write below code in your Activity/Fragment

    @Override
    public void onItemClick(int position) {
        Intent intent = new Intent(mContext, YourActivity.class);
        intent.putExtra(YourActivity.ARG_FILE, filnames.get(position));
        startActivity(intent);
    }
Krunal Kapadiya
  • 2,853
  • 3
  • 16
  • 37
0

So, not sure anyone's interested or if there are problems with my method, but I came up with a much simpler method for my own personal use.

Xml of the item:

<?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="?android:attr/listPreferredItemHeightLarge"
    android:background="@drawable/recycborder">


    <TextView
        android:id="@+id/recycText"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:gravity="center_vertical|center"
        android:onClick="recycClick"
        android:textColor="@color/black"
        android:textSize="16sp" />

</RelativeLayout>

Inside of onBindViewHolder, set the tag equal to whatever info you need. The name, position, text displayed, pic displayed, whatever.

@Override
    public void onBindViewHolder(ViewHolder holder, final int position) {
        holder.recycText.setText(lstAllInfo.get(position));
        holder.recycText.setTag(lstAllInfo.get(position));

    }

In your method where you want to handle the item click:

 public void recycClick(View v) {
        String test = v.getTag().toString();
        Toast.makeText(getApplicationContext(), ("You clicked: "  + test), Toast.LENGTH_LONG).show();
    }

I assume there are limitations to this. Tag may not be able to hold the data you need, or it's possible that the recycle view couldn't access the right activity for the on click. Personally I'm using it for Android Wear and it works great, so thought I'd post just in case, since it's a lot less work than the other methods.

0

Try this code into your holder class.... It will work and easy to use:

public class RecyclerViewHolder extends RecyclerView.ViewHolder {

        public ItemHolder(@NonNull final View recyclerView) {
            super(recyclerView)

            recyclerView.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View view) {
                    int position = getAdapterPosition();

                }
            });
        }
    }
Saeed
  • 3,294
  • 5
  • 35
  • 52
0

Recyclerview with click listener

On your adapter class create an interface.

public interface SelectedUser{

    void selectedUser(UserModel userModel);

}

In your adapter view holder class listen to click event.

        itemView.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                selectedUser.selectedUser(userModelList.get(getAdapterPosition()));
            }
        });

finally implement your interface in your activity and override the method.

   @Override
    public void selectedUser(UserModel userModel) {

        startActivity(new Intent(MainActivity.this, SelectedUserActivity.class).putExtra("data",userModel));



    }

Full tutorial and source code use the link below. Recyclerview with click listener

Richard Kamere
  • 749
  • 12
  • 10