Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Working with Long Click Listener with recycler-android

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?

like image 588
varsha valanju Avatar asked Oct 27 '16 16:10

varsha valanju


3 Answers

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.

like image 58
varsha valanju Avatar answered Nov 14 '22 21:11

varsha valanju


just make onLongClick(View v) returns return true instead of return false this solved my problem it should solve yours too

like image 4
Amir Eleuch Avatar answered Nov 14 '22 22:11

Amir Eleuch


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/

like image 3
Ogunde Kehinde Avatar answered Nov 14 '22 20:11

Ogunde Kehinde