RecyclerAdapter-无法为父级和子级设置长时间和正常点击监听器

时间:2019-11-06 07:33:15

标签: android onclicklistener viewgroup onlongclicklistener viewchild

我有一个简单的RecyclerView,其中一个行项目包含一个图像。

我想为ImageView设置普通的onClickListener,并为longClickListener本身设置itemView

问题在于这样做时-他们似乎无法彼此共处。如果我为父viewGroup分配了长按,又为子imageView单击了-只有子单击有效。如果我只删除普通点击侦听器的代码,那么长点击将开始起作用。

这是我的适配器-

public class HorizontalRecyclerAdapter extends RecyclerView.Adapter<HorizontalRecyclerAdapter.ViewHolder> {


    @NonNull
    @Override
    public ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
        View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.horizontal_row_item, parent, false);
        return new ViewHolder(view);
    }

    @Override
    public void onBindViewHolder(@NonNull final ViewHolder holder, int position) {
        holder.itemView.setOnLongClickListener(new View.OnLongClickListener() {
            @Override
            public boolean onLongClick(View v) {
                Toast.makeText(holder.imageView.getContext(), "Long Click!", Toast.LENGTH_SHORT).show();
                return true;
            }
        });
        holder.imageView.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                Toast.makeText(holder.imageView.getContext(), "Normal Click", Toast.LENGTH_SHORT).show();
            }
        });
    }

    @Override
    public int getItemCount() {
        return 10;
    }

    class ViewHolder extends RecyclerView.ViewHolder {

        private ImageView imageView;


        public ViewHolder(@NonNull View itemView) {
            super(itemView);
            imageView = itemView.findViewById(R.id.imageView);
        }
    }
}

编辑-

这是我的xml行项目-

<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:layout_width="100dp"
    android:layout_height="100dp"
    android:layout_margin="10dp">

    <ImageView
        android:id="@+id/imageView"
        android:layout_width="50dp"
        android:layout_height="50dp"
        android:src="@drawable/image1"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent" />

</androidx.constraintlayout.widget.ConstraintLayout>

2 个答案:

答案 0 :(得分:0)

您必须给match_parent赋予imageview的高度和宽度。在这种情况下,itemview将不会捕获click事件,因为imageview会在此之前捕获该事件。如果这样的话,也可以在图像视图上设置长按。

答案 1 :(得分:0)

首先-在onBindViewHolder中使用OnClickListener是初学者的一个基本错误。使用我的解决方案,可以解决您的问题和好处:避免内存泄漏。

1)创建此类:

public class RecyclerTouchListener implements RecyclerView.OnItemTouchListener {
    private OnItemClickListener mListener;

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

        public void onLongItemClick(View view, int position);
    }

    GestureDetector mGestureDetector;

    public RecyclerTouchListener(Context context, final RecyclerView recyclerView, OnItemClickListener listener) {
        mListener = listener;
        mGestureDetector = new GestureDetector(context, new GestureDetector.SimpleOnGestureListener() {
            @Override
            public boolean onSingleTapUp(MotionEvent e) {
                return true;
            }

            @Override
            public void onLongPress(MotionEvent e) {
                View child = recyclerView.findChildViewUnder(e.getX(), e.getY());
                if (child != null && mListener != null) {
                    mListener.onLongItemClick(child, recyclerView.getChildAdapterPosition(child));
                }
            }
        });
    }

    @Override public boolean onInterceptTouchEvent(RecyclerView view, MotionEvent e) {
        View childView = view.findChildViewUnder(e.getX(), e.getY());
        if (childView != null && mListener != null && mGestureDetector.onTouchEvent(e)) {
            mListener.onItemClick(childView, view.getChildAdapterPosition(childView));
            return true;
        }
        return false;
    }

    @Override public void onTouchEvent(RecyclerView view, MotionEvent motionEvent) { }

    @Override
    public void onRequestDisallowInterceptTouchEvent (boolean disallowIntercept){}
}

2)将其附加到您的RecyclerView:

yourRecyclerView.addOnItemTouchListener(new RecyclerTouchListener(context, yourRecyclerView, new RecyclerTouchListener.OnItemClickListener() {
                    @Override
                    public void onItemClick(View view, int position) {
                        //do some work
                    }

                    @Override
                    public void onLongItemClick(View view, int position) {
                        //do some work
                    }
                }));

祝你好运!