使用recycleler-android使用Long Click Listener

时间:2016-10-27 16:34:38

标签: android android-recyclerview

我正在研究像Android应用程序项目这样的游戏。我已经实施了回收商。 我的项目包含扩展RecyclerView.Adapter<NotesAdapter.ViewHolder>的NotedAdaper类 在该类中使用以下代码我使用了点击监听器,

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);

    }
}}   

它绝对有效的发现。在单击Recycler中的项目时,它使用该项目的位置检索数据。并在另一项活动中展示。 就像,假设一个活动显示用户创建的笔记列表。并点击任何一个音符,它会显示该音符的全部内容。

但现在我想在项目上实现Long click listener。并得到这个位置。 所以,我使用以下代码...

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;
            }
        });  

所以,它也有效。 但我想要的是,长按一下,它应该只显示Toast。 但它不仅显示长按烤面包。但也识别点击监听器并在显示toast&gt;&gt;之后“长按:...”它执行为单击事件编写的代码。 我不想要它。 两个听众都应该分开工作。 但为什么它长时间点击后执行单击???任何想法??? 我在哪里弄错了?

4 个答案:

答案 0 :(得分:19)

所以,我的代码中的以下更改,帮助我实现我的输出。 1)每次将视图与数据绑定时,都会调用onBindViewHolder方法。所以没有设置点击监听器的最佳位置。您不必为一个View多次设置OnClickListener。这就是为什么,我在ViewHolder中写了点击监听器,(实际上这不是我的问题,但我在某处读到这将是最好的做法,这就是为什么我要关注它)

像这样,

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();
                }
            });
        }
    }  

您可能会注意到,在onLongClick中,我已经返回&#34; true&#34;,默认情况下它是&#34; false&#34;。 这个改变对我有用。

答案 1 :(得分:2)

只需让onLongClick(View v)返回return true而不是return false 这解决了我的问题,它应该解决你的问题

答案 2 :(得分:1)

我认为您应该从ViewHolder类设置两个侦听器。

itemView.setOnClickListener(...);
itemView.setOnLongClickListener(...);

getAdapterPosition()调用ViewHolder以获取项目的适配器位置。

您可以签出以下资源。 https://www.bignerdranch.com/blog/recyclerview-part-1-fundamentals-for-listview-experts/

答案 3 :(得分:0)

我认为这是将 onClick 和 longClickListeners 实现到 RecyclerViews 的一种更简单的方法。这是我的代码片段。我已经从这里删除了不必要的代码。

public class PrescriptionAdapter  extends RecyclerView.Adapter<PrescriptionAdapter.ViewHolder> {
    static final String TAG = "RecyclerViewAdapterMedicineFrequency";
    ArrayList<Prescription> pdata;
    Context context;
    OnItemClickListener onItemClickListener;
    OnItemLongClickListener onItemLongClickListener;


    public PrescriptionAdapter(Context context, ArrayList<Prescription> presData, OnItemClickListener onItemClickListener, OnItemLongClickListener onItemLongClickListener) {
        this.pdata = presData;
        this.context = context;
        this.onItemClickListener = onItemClickListener;
        this.onItemLongClickListener = onItemLongClickListener;
    }

    public class ViewHolder extends RecyclerView.ViewHolder implements View.OnClickListener, View.OnLongClickListener {
        TextView pName, totalMeds;
        ImageView pImage;
        OnItemClickListener onItemClickListener;
        OnItemLongClickListener onItemLongClickListener;

        public ViewHolder(View itemView, OnItemClickListener onItemClickListener,  OnItemLongClickListener onItemLongClickListener) {
            super(itemView);
            pName = (TextView) itemView.findViewById(R.id.prescriptionName);
            totalMeds = (TextView) itemView.findViewById(R.id.totalMeds);
            pImage = (ImageView) itemView.findViewById(R.id.prescriptionImage);
            this.onItemClickListener = onItemClickListener;
            this.onItemLongClickListener = onItemLongClickListener;
            itemView.setOnClickListener(this);
            itemView.setOnLongClickListener(this);
        }

        @Override
        public void onClick(View v) {
            onItemClickListener.onItemClick(getAdapterPosition());
        }


        @Override
        public boolean onLongClick(View v) {
            onItemLongClickListener.onItemLongClick(getAdapterPosition());
            return true;
        }
    }

    public interface OnItemClickListener {
        void onItemClick(int i);
    }
    public interface OnItemLongClickListener {
        void onItemLongClick(int i);
    }

}