i am working on a notapad like android app project. i which i have implemented recycler.
My project contains NotedAdaper class that extends RecyclerView.Adapter<NotesAdapter.ViewHolder>
in that class using the below code i used click listener,
public class NotesAdapter extends RecyclerView.Adapter<NotesAdapter.ViewHolder> {
private List<Notes> mNotes;
private Context mContext;
public NotesAdapter(Context context, List<Notes> notes) {
mNotes = notes;
mContext = context;
}
@Override
public NotesAdapter.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
Context context = parent.getContext();
LayoutInflater inflater = LayoutInflater.from(context);
// Inflate the custom layout
View notesView = inflater.inflate(R.layout.items_notes, parent, false);
// Return a new holder instance
ViewHolder viewHolder = new ViewHolder(notesView);
return viewHolder;
}
// Easy access to the context object in the recyclerview
private Context getContext() {
return mContext;
}
@Override
public void onBindViewHolder(NotesAdapter.ViewHolder viewHolder, final int position) {
// Get the data model based on position
Notes notes = mNotes.get(position);
// Set item views based on your views and data model
TextView textView = viewHolder.preTitle;
textView.setText(notes.getTitle());
TextView textView1 = viewHolder.preText;
textView1.setText(notes.getText());
String color=notes.getColor();
CardView preCard=viewHolder.preCard;
preCard.setBackgroundColor(Color.parseColor(color));
ImageView img = viewHolder.preImage;
img.setVisibility(View.GONE);
viewHolder.itemView.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
Notes notes = mNotes.get(position);
Intent intent = new Intent(view.getContext(),EditNote.class);
Bundle bundle = new Bundle();
bundle.putSerializable("DATA",notes);
intent.putExtras(bundle);
getContext().startActivity(intent);
Toast.makeText(getContext(), "Recycle Click" + position+" ", Toast.LENGTH_SHORT).show();
}
});
}
// Returns the total count of items in the list
@Override
public int getItemCount() {
return mNotes.size();
}
public static class ViewHolder extends RecyclerView.ViewHolder {
// Your holder should contain a member variable
// for any view that will be set as you render a row
public RobotoTextView preTitle, preText;
public ImageView preImage;
public CardView preCard;
public ViewHolder(View itemView) {
super(itemView);
preTitle = (RobotoTextView) itemView.findViewById(R.id.preTitle);
preText = (RobotoTextView) itemView.findViewById(R.id.preText);
preImage=(ImageView) itemView.findViewById(R.id.preImage);
preCard=(CardView) itemView.findViewById(R.id.preCard);
}
}}
And its absolutely working find. on clicking of a item in recycler, it retrieves the data using position of that item. and showing in another activity. just like, suppose a activity shows the list of notes created by user. and clicking on any note, it shows the full content of that note.
but now i want to implement Long click listener on the item. and get the position. so that, i used the following code ...
viewHolder.itemView.setOnLongClickListener(new View.OnLongClickListener() {
@Override
public boolean onLongClick(View view) {
Notes notes = mNotes.get(position);
Toast.makeText(getContext(), "long Click" + position+" ", Toast.LENGTH_SHORT).show();
return false;
}
});
so, its also working.
but what i want is, on long click, it should only show that Toast.
but its not only showing the long click toast. but also recognising click listener and after showing the toast>> "Long click: ..." it executing the the code written for single click event.
n i dont want it.
both listeners should work separately.
but why its executing single click after long click??? any idea???
Am i making mistake anywhere?
So, the following changes in my code, help me to achieve my output. 1) The method onBindViewHolder is called every time when you bind your view with data. So there is not the best place to set click listener. You don't have to set OnClickListener many times for the one View. Thats why, i wrote click listeners in ViewHolder, (actually that was not my question, but i read somewhere that it would be the best practice, thats why i am following it)
like this,
public static class ViewHolder extends RecyclerView.ViewHolder {
// Your holder should contain a member variable
// for any view that will be set as you render a row
public ImageView preImage;
public CardView preCard;
// We also create a constructor that accepts the entire item row
// and does the view lookups to find each subview
public ViewHolder(final View itemView) {
// Stores the itemView in a public final member variable that can be used
// to access the context from any ViewHolder instance.
super(itemView);
itemView.findViewById(R.id.preTitle);
preImage=(ImageView) itemView.findViewById(R.id.preImage);
preCard=(CardView) itemView.findViewById(R.id.preCard);
itemView.setOnLongClickListener(new View.OnLongClickListener() {
@Override
public boolean onLongClick(View view) {
int p=getLayoutPosition();
System.out.println("LongClick: "+p);
return true;// returning true instead of false, works for me
}
});
itemView.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
int p=getLayoutPosition();
Notes notes = mNotes.get(p);
Toast.makeText(getContext(), "Recycle Click" + p +" ", Toast.LENGTH_SHORT).show();
}
});
}
}
You may notice that, in onLongClick, i have returned "true", bydefault it was "false". and this change works for me.
just make onLongClick(View v)
returns return true
instead of return false
this solved my problem it should solve yours too
i think you should set both the listeners from ViewHolder
class.
itemView.setOnClickListener(...);
itemView.setOnLongClickListener(...);
And call getAdapterPosition()
from ViewHolder
to get the adapter position of the item.
You can checkout the following resource. https://www.bignerdranch.com/blog/recyclerview-part-1-fundamentals-for-listview-experts/
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With