RecyclerAdapter - невозможно установить прослушиватели длинных и обычных щелчков для родительского и дочернего элементов - PullRequest
0 голосов
/ 06 ноября 2019

У меня есть простой RecyclerView с элементом строки, содержащим одно изображение.

Я хочу установить нормальный onClickListener для ImageView и 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);
        }
    }
}

edit -

Вот мой элемент строки 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 голосов
/ 06 ноября 2019

Первое - это основная ошибка новичка - использовать OnClickListener в onBindViewHolder. Воспользуйтесь моим решением, которое решит вашу проблему и бонус: избавит вас от утечек памяти.

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

Удачи!

0 голосов
/ 06 ноября 2019

Вы должны указать match_parent для высоты и ширины просмотра изображения. в этом случае itemview не будет перехватывать событие click, потому что imageview перехватит его до этого. если это так, установите слишком длинный щелчок на изображении.

...