How to get the position for clicked button inside the RecyclerView items
Here's my onBindViewHolder :
public void onBindViewHolder(MyViewHolder holder, int position) {
Masar masar=masrList.get(position);
holder.masarName.setText(masar.getMasarTitle());
holder.masarDesc.setText(masar.getMasarDescreption());
//How to get the Position
holder.masarImg.setImageResource(masar.getMasarImg());
holder.mapBtn.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v ) {
//if you need position, just use recycleViewHolder.getAdapterPosition();
Intent intent = new Intent(v.getContext(), MapsActivity.class);
mContext.startActivity(intent);
}
});
}
If you need in onBindViewHolder only then you can use
holder.getAdapterPosition();
and if you need this position clicked in activity and fragment then you have to use callbacks from holder to activity and fragment and have to pass the same getAdapterPosition();
Edit: Added sample code for listening position click in fragment/activity
step 1: make an interface or callback
public interface RecyclerViewClickListener {
void onClick(View view, int position);
}
step 2: While initializing adapter class in fragment or activity pass the above-created reference as a parameter
public YourAdapter(List<SomeModel> modelList, RecyclerViewClickListener listener){
this.clickListener = listener;
}
step 3: In your ViewHolder or similar Class for view initialization do something like this
public class ViewHolder extends RecyclerView.ViewHolder implements View.OnClickListener {
private Button mapBtn;
ViewHolder(View v, RecyclerViewClickListener listener) {
super(v);
mapBtn = findViewById(R.id.mapBtn);
mListener = listener;
mapBtn.setOnClickListener(this);
}
#Override
public void onClick(View view) {
mListener.onClick(view, getAdapterPosition());
}
}
you will get the position in your fragment or activity where you have passed the callback reference while initializing the adapter.
Use holder.getAdapterPosition();
public void onBindViewHolder(final MyViewHolder holder, int position) {
Masar masar=masrList.get(position);
holder.masarName.setText(masar.getMasarTitle());
holder.masarDesc.setText(masar.getMasarDescreption());
//How to get the Position
holder.masarImg.setImageResource(masar.getMasarImg());
holder.mapBtn.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v ) {
Toast.makeText(getContext(), "The position is: "+holder.getAdapterPosition(), Toast.LENGTH_SHORT).show();
Intent intent = new Intent(v.getContext(), MapsActivity.class);
mContext.startActivity(intent);
}
});}
Related
I created six of CardView and linked them to RecyclerView , how when press on cardview postion[2]
I want to make every card view and guest a move to another activity
this my code.
public class MyMovieAdapter extends RecyclerView.Adapter<MyMovieAdapter.ViewHolder> {
MyMovieData[] myMovieData;
Context context;
public MyMovieAdapter(MyMovieData[] myMovieData,MainActivity activity) {
this.myMovieData = myMovieData;
this.context = activity;
}
#NonNull
#Override
public ViewHolder onCreateViewHolder(#NonNull ViewGroup parent, int viewType) {
LayoutInflater layoutInflater = LayoutInflater.from(parent.getContext());
View view = layoutInflater.inflate(R.layout.movie_item_list,parent,false);
ViewHolder viewHolder = new ViewHolder(view);
return viewHolder;
}
#Override
public void onBindViewHolder(#NonNull ViewHolder holder, int position) {
final MyMovieData myMovieDataList = myMovieData[position];
holder.textViewName.setText(myMovieDataList.getMovieName());
holder.textViewDate.setText(myMovieDataList.getMovieDate());
holder.movieImage.setImageResource(myMovieDataList.getMovieImage());
holder.itemView.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
Toast.makeText(context, myMovieDataList.getMovieName(), Toast.LENGTH_SHORT).show();
Intent intent = new Intent(v.getContext(), MainActivity2.class);//////////////// //this line //////////////////////// I want to position id
v.getContext().startActivity(intent);
}
});
}
you already have int position, just make it final and then you may use it inside onClick
#Override
public void onBindViewHolder(#NonNull ViewHolder holder, final int position) {
...
holder.itemView.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
Toast.makeText(context, myMovieDataList.getMovieName(), Toast.LENGTH_SHORT).show();
Intent intent = new Intent(v.getContext(), MainActivity2.class);
intent.putExtra("position", position);
// would be better to pass item id or name, much better approach
intent.putExtra("itemId", myMovieDataList.getMovieId());
v.getContext().startActivity(intent);
}
});
}
Answer by #snachman is perfectly right. But, it is not preferred by google. Use the method given below.
Create a new interface with name RecyclerViewItemClickListener.java
Add method void onClick(); to it;
Add that to the constructor of the adapter.
After adding the constructor, add it to your activity by implementing the interface
Add it in the activity by new RecyclerViewItemClickListener
Now in the activity, add the code to start the activity.
Hope it helps 😀
public void onBindViewHolder(#NonNull final myViewHolder holder, final int position) {
holder.tvItem.setText(itemList.get(position).getmTitle());
Picasso.get().load(itemList.get(position).geturl()).into(holder.imgFlag);
holder.cardView.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
final ModelClass model= itemList.get(position);
}
});
Here is an example you can follow this and fit as per your requirement-
Create an interface in your adapter
public interface OnItemClickListener {
void onItemClicked(int position, Object object);
}
in your adapter call
Adapter adapter = new Adapter(context, list, new Adapter.OnItemClickListener() {
#Override
public void onItemClicked(int position, Object object) {
// Handle Object of list item here
}
});
on your adapter
private OnItemClickListener onItemClickListener; // Global scope
in constructor call:
this.onItemClickListener = onItemClickListener;
on your item clicked event :
itemView.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
onItemClickListener.onItemClicked(position, _list.get(position));
}
});
You can use this one for single view and multiple view click
adapter viewholder class
public class MyViewHolder extends RecyclerView.ViewHolder implements
View.OnClickListener {
CircleImageView imgPlayer;
TextView playerRole;
public MyViewHolder(View itemView) {
super(itemView);
imgPlayer = itemView.findViewById(R.id.trnmt_player);
playerRole = itemView.findViewById(R.id.pRole_id);
playerRole .setOnClickListener(this);
imgPlayer.setOnClickListener(this);
}
#Override
public void onClick(View v) {
if (v == imgPlayer) {
onItemClickListener.onItemClicked(position,list.get(position));
} else if(v==playerRole){
}
}
}
}
interface
public interface OnItemClickListener {
void onItemClicked(int position, Object object);
}
inside adapter
private OnItemClickListener onItemClickListener;
It will be helpful if you provide some snapshot of your code.
Although you can get callback of click action on recycler view on your activity. So for this you need to create your own Listener and set to your Custom adapter.
Creation of a Action Listener
public interface ActionListener<T> {
void onClickAction(int positionOfItem, T object);//here T will be the type of object bound to your view.
}
Now create a method in your custom adapter to set this listener
private ActionListener mListener;
public void setActionListener(ActionListener listener){
mListener = listener;
}
Now use this listener to navigate the call back from your adapter.
public void onBindViewHolder(#NonNull final myViewHolder holder, final int position) {
holder.tvItem.setText(itemList.get(position).getmTitle());
Picasso.get().load(itemList.get(position).geturl()).into(holder.imgFlag);
holder.cardView.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
final ModelClass model= itemList.get(position);
listener.onClickAction(position, model);//this will pass the call to the listener.
}
});
}
Now set the listener to adapter in your activity class, where you just created the adapter instance. Here you need to invoke a method in your fragment. For getting the fragment you can use findFramgentById() or findFragmentByTag() methods.
adapter.setActionListener(new ActionListener<ModelClass>(){
void onClickAction(int positionOfItem, ModelClass object){
MyFragment fragment = (MyFragment) getSupportFragmentManager().findFragmentByTag();
fragment.updateActionData(object);
}
});
Please create a method in your fragment as given below :
public void updateActionData(ModelClass object){
//to do your work with object
}
Hope this will work.
This question already has answers here:
Why doesn't RecyclerView have onItemClickListener()?
(31 answers)
RecyclerView onClick
(49 answers)
Closed 3 years ago.
I am learning Android Development. Struggling with this issue since 24 hours, need help.
On my each recycle view item I've two views ePaper & Website. I want to attach different on click listeners on the entire item, ePaper view and website view
In the above image, I need to put 3 click listeners
1. Click on red block 1 - do X (Intent to another activity)
2. Click on red block 2 - do Y (Intent to another activity)
3. Click on green block, entire item view - do Z (Dialog)
Tried many solutions. But, when I click red block, the listener in green block also comes to action in addition to listener in red block.
In the MainActivity
recyclerView.addOnItemTouchListener(new RecyclerTouchListener(getApplicationContext(),
recyclerView, new ClickListener() {
String userid = Utils.getUserId(getApplicationContext());
#Override
public void onClick(View view, final int position) {
// Set listeners here for complete card view
final NewsPapersDataModel currentPaper = newsPapersList.get(position);
Log.d("TAG","Clicked 1");
newsSelectionDialog(currentPaper.getEpaper(),currentPaper.getWebsite());
}
#Override
public void onLongClick(View view, int position) {
Toast.makeText(MainActivity.this, "Long press on position :" + position, Toast.LENGTH_LONG).show();
}
}));
In the NewsPaperAdapter
public void onBindViewHolder(#NonNull final CustomViewHolder holder, int position) {
// Log.d("TAG","Holder is "+newsList);
final NewsPapersDataModel currentItem = newsList.get(position);
final String ePaperUrl = currentItem.getEpaper();
final String webSiteUrl = currentItem.getWebsite();
final String paperName = currentItem.getName();
holder.paperNameView.setText(newsList.get(position).getName());
if (TextUtils.isEmpty(currentItem.getEpaper())) {
// Log.d("TAGG","ePaper - "+currentItem.getEpaper()+" Website - "+currentItem.getWebsite());
holder.ePaperView.setVisibility(View.GONE);
} else if (TextUtils.isEmpty(currentItem.getWebsite())) {
holder.websiteView.setVisibility(View.GONE);
}
holder.ePaperView.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
saveLinksToDb(userid, "ePaper", ePaperUrl);
Intent intent = new Intent(context, NewsAdvancedWebViewActivity.class);
intent.putExtra("url", ePaperUrl);
context.startActivity(intent);
}
});
holder.websiteView.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
saveLinksToDb(userid, "Website", webSiteUrl);
Intent intent = new Intent(context, NewsAdvancedWebViewActivity.class);
intent.putExtra("url", webSiteUrl);
intent.putExtra("paperName",paperName);
context.startActivity(intent);
}
});
}
Please help me.
You need to create an interface in your adapter for click listeners and add onclick methods for every item you want.
Please look into the code below.
In your adapter, create interface
public interface OnClickListener {
void onPaperViewClick(View view, int position);
void onWebsiteViewClick(View view, int position);
}
And create method to set click listener from activity
public void setOnClickListener(OnClickListener listener) {
this.onClickListener= listener;
}
And in your onBindViewHolder method,
holder.ePaperView.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
onClickListener.onPaperViewClick(view, position);
});
holder.websiteView.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
onClickListener.onWebsiteViewClick(view, position);
});
and lastly, in your activity, set
recyclerViewAdapter.setOnClickListener(new NewsPaperAdapter.OnClickListener(){
#override
void onPaperViewClick(View view, int position){
// code to handle paper click
}
#override
void onPaperViewClick(View view, int position){
// code to handle website click
}
};
Remove your TouchListener from MainActivity and add ClickListener/ LonCkickListener inside your adapter.
onBindViewHolder(){
//rest of your code
holder.itemView.setOnClickListener(new OnClickListener{
#Override
public void onClick(View view) {
// Click implementation here
}
#Override
public void onLongClick(View view) {
// Long click implementation here
}
})
}
And inside your CustomViewHolder:
public class CustomViewHolder extends RecyclerView.ViewHolder{
// Other fields
View itemView;
public CustomViewHolder(View view){
// rest of initialization
itemView = view;
}
}
EDIT (OP wants to handle application logic inside Activity)
Create an interface class named RecyclerViewActionListener:
public interface RecyclerViewActionListener {
void onViewClicked(int clickedViewId, int clickedItemPosition);
void onViewLongClicked(int clickedViewId, int clickedItemPosition);
}
Then modify your RecyclerViewAdpater to have an additional field in constructor. We will pass listener from Activity to this adpater when we create Adapter:
public class RecyclerViewAdpater extends RecyclerView.Adapter<RecyclerViewAdpater.CustomViewHolder>{
private RecyclerViewActionListener mListener;
public RecyclerViewAdpater(ArrayList<Object> yourData,RecyclerViewActionListener mListener) {
this.mListener = mListener;
}
#NonNull
#Override
public CustomViewHolder onCreateViewHolder(#NonNull ViewGroup parent, int viewType) {
View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.item, parent, false );
final CustomViewHolder holder = new CustomViewHolder(view);
holder.webView.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
mListener.onViewClicked(view.getId(), holder.getAdapterPosition());
}
});
holder.paperView.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
mListener.onViewClicked(view.getId(), holder.getAdapterPosition());
}
});
holder.itemView.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
mListener.onViewClicked(view.getId(), holder.getAdapterPosition());
}
});
holder.itemView.setOnLongClickListener(new View.OnLongClickListener() {
#Override
public boolean onLongClick(View view) {
mListener.onViewLongClicked(view.getId(), holder.getAdapterPosition());
return false;
}
});
return holder;
}
public class CustomViewHolder extends RecyclerView.ViewHolder{
// Other fields
View itemView;
View webView;
View paperView;
public CustomViewHolder(View view){
super(view);
// rest of initialization
itemView = view;
}
}
}
And then implement RecyclerViewActionListener in your Activity and override methods from RecyclerViewActionListener:
public class MainActivity extends AppCompatActivity implements RecyclerViewActionListener {
RecyclerViewAdpater adapter;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main3);
// Skipped for the sake of brevity
// Pass your listener to adapter here
adapter = new RecyclerViewAdpater(yourData, this );
}
#Override
public void onViewClicked(int clickedViewId, int clickedItemPosition) {
switch (clickedItemPosition){
case R.id.web_view:
// Application logic when webview clicked
break;
case R.id.paper_view:
// Application logic when paperview clicked
break;
case R.id.recyclerview_item:
// Application logic when whole item clicked
break;
}
}
#Override
public void onViewLongClicked(int clickedViewId, int clickedItemPosition) {
switch (clickedViewId){
case R.id.recyclerview_item:
// Application logic when whole item long-clicked
break;
}
}
}
And in your xml file don't forget to assign ID to you views. Because we're detecting clicked view with their IDs.
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/recyclerview_item"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent">
<ImageView
android:id="#+id/web_view"
android:layout_width="wrap_content"
android:layout_height="match_parent"/>
<ImageView
android:id="#+id/paper_view"
android:layout_width="wrap_content"
android:layout_height="wrap_content"/>
</RelativeLayout>
try in your NewsPaperAdapter class onClickListner to parent layout of adapter like below
holder.parentLayout.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
final NewsPapersDataModel currentPaper = newsPapersList.get(position);
Log.d("TAG","Clicked 1");
newsSelectionDialog(currentPaper.getEpaper(),currentPaper.getWebsite());
}
});
here parentLayout is your adapter item layout root view like Relative/Linear Layout
#Override
public void onItemClick(AdapterView<?> adapterView, View view, int i, long l) {
String clicktemplate = modelClassesListt.get(i).getTitle();
Toast.makeText(Template.this ,modelClassesListt.get(i).getTitle() , Toast.LENGTH_SHORT).show();
}
I want to send this clicktemplate string value to other class
You have to put value in Intent or Bundle and send it to the next screen.
Here is an example for pass data in Activity.
Intent intent = new Intent(this, YourNextActivity.class);
intent.putExtra("key_clicktemplate", clicktemplate);
startActivity(intent);
To get value in next screen like below
String value = getIntent().getExtras().getString("key_clicktemplate");
You can use several approaches to implement your need.below thread will be useful to you.
How to pass values from RecycleAdapter to MainActivity or Other Activities
In your recyclerview class add onclicklistener interface and include your listener in constructor:
private final OnItemClickListener listener;
public interface OnItemClickListener {
void onItemClick(myObject item, int position, String message);
}
public MyRecyclerViewAdapter(Activity pActivity, ArrayList<myObject> pList, int pItemLayout, OnItemClickListener listener) {
activity = pActivity;
rewardsList = pList;
layoutID=pItemLayout;
this.listener = listener;
}
Then. in onCreateViewHolder:
#Override
public void onBindViewHolder(MyHolder holder, int position) {
myObject currentItem = rewardsList.get(position);
holder.bindList(currentItem, listener, position);
}
Next, in your ViewHolder add:
class MyHolder extends RecyclerView.ViewHolder {
View masterView;
MyHolder(View itemView) {
super(itemView);
masterView = itemView;
}
void bindList(final myObject item, final OnItemClickListener listener, int position){
masterView.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
listener.onItemClick(item, position,"edit");
}
});
...
Finally, in calling activity/fragment:
MyRecyclerViewAdapter adapter = new MyRecyclerViewAdapter(mActivity, list, R.layout.item, new MyRecyclerViewAdapter.OnItemClickListener() {
#Override
public void onItemClick(MyObject item, int position, String message) {
//item clicks handled here
switch (message){
case ITEM_OPEN:
// Do whatever you need with clicked item here
break;
case ITEM_EDIT:
// Do whatever you need with clicked item here
break;
}
}
}, mRecyclerView);
I want to open more details when I click on the item using the position and set the datils in the activity.
You can write your suggestion in Java or Kotlin :)
Create Constructor in adapter class :
public DataAdapter(List<Pojo> dataList, OnItemClickListener listener) {
this.dataList = dataList;
this.listener = listener;
}
Create OnBindViewHolder() method and get position :
#Override
public void onBindViewHolder(MyViewHolder holder, int position) {
final Pojo movie = dataList.get(position);
holder.Showid.setText(movie.getCatagory_id());
holder.fname.setText(movie.getCatagory_name());
holder.thumbNail.setImageUrl(movie.getCatagory_thumbnailUrl(), imageLoader);
holder.itemView.setOnClickListener(new View.OnClickListener() {
#Override public void onClick(View v) {
listener.onItemClick(movie.getSubCatagoryArrayList());
}
});
}
In MainActivity.class create on Interface :
public interface OnItemClickListener {
void onItemClick(ArrayList<Pojo2> item);
}
first of all recyclerView OnClick method to get position of Click item
like this method
int position=getAdapterPosition();
than get position of item (like modelArrayList.get(getAdapterPosition());)
than send id to next activity and id to get data in database and set all the details in next activity
final code
itemView.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
int position=getAdapterPosition();
ModelClass model = modelArrayList.get(getAdapterPosition());
Long id = model.getId();
Intent i = new Intent(v.getContext(), NextActivity.class);
i.putExtra("id",id);
v.getContext().startActivity(i);
}
});
and NextActivity code
Long id = getActivity().getIntent().getExtras().getLong("id", 0);