【问题标题】:RecyclerView's children onTouchEventRecyclerView 的孩子 onTouchEvent
【发布时间】:2015-01-13 16:18:22
【问题描述】:

我正在使用 RecyclerView,最近我在应该打开 PopoupWindow 的每一行上添加了一个 3 点菜单。问题是我无法处理 3 点菜单图标上的触摸,因为该行消耗了触摸事件。我在搞乱 onInterceptTouchEvent 但我找不到检测菜单触摸的方法..

这基本上是我的 RecyclerView.OnItemTouchListener 代码:

    public class RecyclerItemTouchListener implements RecyclerView.OnItemTouchListener {


    @Override
    public boolean onInterceptTouchEvent(RecyclerView view, MotionEvent e) {

        View childView = view.findChildViewUnder(e.getX(), e.getY());

        //need a way to detect if the user touches the menu icon!!
        boolean touchOccurredOnMenu = ?????;

        if(childView != null && touchOccurredOnMenu) {

            //here the menu will handle the touch event
            return false;

        }


        //here the recycler item will handle the touch event
        return true;

    }

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

        Toast.makeText(getApplicationContext(), "touch on the row", Toast.LENGTH_SHORT).show();


    }
}

我在 RecyclerView.Adapter 的 onBindViewHolder 方法中为菜单图标设置了 touchListener,如下所示:

holder.overflowMenuIcon.setOnTouchListener(new View.OnTouchListener() {

    @Override
    public boolean onTouch(View v, MotionEvent event) {

        Toast.makeText(getApplicationContext(), "touch on the menu!!", Toast.LENGTH_SHORT).show();

        return false;
    }
});

【问题讨论】:

  • 您是否尝试在使用触摸事件的行中添加 android:focusable="false"?
  • 感谢您的建议,但触摸该行将启动一个新活动,因此我无法将可聚焦属性设置为 false..
  • 我不认为设置 focusable=false 不会让它无法点击。它只会说视图是否可以聚焦。
  • 仍然不适用于 focusable=false
  • 您找到了解决问题的好方法吗?我的解决方案是在适配器内为每个项目和视图使用 onClickListener,但我不喜欢这样。

标签: android touch-event android-recyclerview


【解决方案1】:

在 RecyclerView 的行中添加溢出按钮时,我遇到了同样的问题。诀窍是,在您的手势检测器中,您获取被单击视图的视图,计算按钮的命中矩形坐标(在我的情况下为“溢出”),如果命中矩形包含事件坐标,则使用事件,否则你点击你的行。

mRecyclerView.addOnItemTouchListener(mTouchListener);
mGestureDetector = new GestureDetectorCompat(getActivity(), new RecyclerViewOnGestureListener());

private final RecyclerView.OnItemTouchListener mTouchListener = new RecyclerView.OnItemTouchListener() {
    @Override
    public boolean onInterceptTouchEvent(RecyclerView rv, MotionEvent e) {
        mGestureDetector.onTouchEvent(e);
        return false;
    }

    @Override
    public void onTouchEvent(RecyclerView rv, MotionEvent e) {
    }

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

private class RecyclerViewOnGestureListener extends GestureDetector.SimpleOnGestureListener {
    @Override
    public boolean onSingleTapConfirmed(MotionEvent e) {
        View view = mRecyclerView.findChildViewUnder(e.getX(), e.getY());
        RecyclerView.ViewHolder viewHolder = view != null ? mRecyclerView.getChildViewHolder(view) : null;
        View overflow = viewHolder != null ? ((DataViewHolder) viewHolder).mOverflow : null;
        if (overflow != null) {
            Rect rect = new Rect();
            overflow.getHitRect(rect);
            rect.top += view.getTop();
            rect.bottom += view.getTop();
            int x = (int) (e.getX() + .5f);
            int y = (int) (e.getY() + .5f);
            if (!rect.contains(x, y)) {
                onClick(view);
            }
            // else event consumed by overflow button
        } else {
            onClick(view);
        }
        return super.onSingleTapConfirmed(e);
    }

    public void onLongPress(MotionEvent e) {
    }
}

【讨论】:

  • .5f 是什么?
  • 这是将浮点值四舍五入到最接近的整数,而不是将浮点数截断为整数。如果你愿意,你可以跳过它。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-06-15
  • 2017-05-21
  • 1970-01-01
相关资源
最近更新 更多