简体   繁体   English

如何点击回收站视图?

[英]How to click through a recyclerview?

First of all I am struggling with this issue for a long time.首先,我在这个问题上挣扎了很长时间。 I don't know how to figure out things, so I followed these steps and tutorials with no luck.我不知道如何解决问题,所以我没有走运就按照这些步骤和教程进行操作。

  1. Click through recycler view empty space 点击回收站查看空白空间
  2. Click through a recyclerview list item 单击回收者视图列表项

and a bunch of questions on StackOverflow.和一堆关于 StackOverflow 的问题。 I wrote my own code also.我也写了自己的代码。 May be I am doing something silly but am not able to figure it out.可能是我在做一些愚蠢的事情,但无法弄清楚。

mRecyclerView.setOnTouchListener((v, event) -> {
    RectF rectf = new RectF((int) event.getX(), 
                            (int) event.getY(), 
                            0, 0);
    boolean contains = getCenter(mHeaderPopUp).contains(rectf);
    if (contains) {
        Toast.makeText(mContext, "Clicked", Toast.LENGTH_SHORT).show();
    }
    return false;
});

private RectF getCenter(View view) {
    Rect rect = new Rect();
    view.getLocalVisibleRect(rect);
    RectF dimens = new RectF((rect.left + rect.width() / 2), 
                             (int) (rect.top + rect.height() / 2),
                             0, 0);
    return dimens;
}

So now I have tried all of these things but I am not able to click through recyclerview to the view which is below recyclerview which you can see in the below image.所以现在我已经尝试了所有这些东西,但我无法点击 recyclerview 到 recyclerview 下方的视图,您可以在下图中看到。 recyclerview overlays all the views on the screen and I need to pass the click to below recyclerview I don't want to put those views above the recyclerview as when you scroll recyclerview it will be animatated and would cover all the views with its items. recyclerview 覆盖了屏幕上的所有视图,我需要将点击传递到下面的 recyclerview 我不想将这些视图放在 recyclerview 上方,因为当您滚动 recyclerview 时,它会被动画化并覆盖所有视图及其项目。 Thanks in advance.提前致谢。 This is the image这是图像

I think I found it.我想我找到了。

Use recycler.setLayoutFrozen(true);使用recycler.setLayoutFrozen(true);

You can still assign onClickListeners to your items, but if you don't, the click will go through.您仍然可以将 onClickListeners 分配给您的项目,但如果您不这样做,点击将通过。

From the source code of RecyclerView.java :RecyclerView.java的源代码:

@Override
public boolean onTouchEvent(MotionEvent e) {
    if (mLayoutFrozen || mIgnoreMotionEventTillDown) {
        return false; // <= This will prevent the RecyclerView from getting the MotionEvent
    }
...
}

https://android.googlesource.com/platform/frameworks/support/+/refs/heads/master/v7/recyclerview/src/android/support/v7/widget/RecyclerView.java#2795 https://android.googlesource.com/platform/frameworks/support/+/refs/heads/master/v7/recyclerview/src/android/support/v7/widget/RecyclerView.java#2795

Hello I found an answer.你好,我找到了答案。 I have card below RecyclerView and recyclerView has padding from left and I set clipToFading=false.我在 RecyclerView 下方有卡片,recyclerView 从左边开始填充,我设置了 clipToFading=false。 To make card below recyclerView clickable I created RecyclerTouch event class and when clicked childView is null it means it is outside childs and open space and I give touch event to my card.为了使 recyclerView 下方的卡片可点击,我创建了 RecyclerTouch 事件类,当点击 childView 为 null 时,这意味着它在 childs 和开放空间之外,我给我的卡片提供了触摸事件。 Here is Code这是代码

public class RecyclerTouchEvent implements RecyclerView.OnItemTouchListener {
    private GestureDetector gestureDetector;
    ClickListener clickListener;

    public RecyclerTouchEvent(Context context, final RecyclerView recyclerView, final ClickListener clickListener) {
        this.clickListener = clickListener;
        gestureDetector = new GestureDetector(context, new GestureDetector.SimpleOnGestureListener() {
            @Override
            public boolean onSingleTapUp(MotionEvent e) {

                return super.onSingleTapUp(e);
            }

            @Override
            public void onLongPress(MotionEvent e) {
                super.onLongPress(e);
            }

        });

    }

    @Override
    public boolean onInterceptTouchEvent(final RecyclerView rv, MotionEvent e) {
        final View childView = rv.findChildViewUnder(e.getX(), e.getY());


        if (childView != null && clickListener != null) {
            clickListener.onClick(childView);
        }else if (childView==null&&clickListener!=null){
            clickListener.onOutsideClick(e);
        }

        return false;
    }

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

    }

    @Override
    public void onRequestDisallowInterceptTouchEvent(boolean disallowIntercept) {

    }
}

public static interface ClickListener {
    public void onClick(View view);
    public void onOutsideClick(MotionEvent event);
}

AND

recyclerViewLends.addOnItemTouchListener(new RecyclerTouchEvent(getContext(), recyclerViewLends, new ClickListener() {
            @Override
            public void onClick(View view) {

            }

            @Override
            public void onOutsideClick(MotionEvent e) {
                rippleLayoutAddLend.dispatchTouchEvent(e);
            }
        }));

rippleLayoutAddLend is a View below recyclerView that has to be clicked rippleLayoutAddLend 是 recyclerView 下的一个视图,必须点击

I had situation when my RecyclerView header item is fully transparent and need catch click behind it.当我的RecyclerView标题项完全透明并且需要在其后面单击时,我遇到了情况。

Inside Activity function:内部Activity功能:

override fun dispatchTouchEvent(ev: MotionEvent?): Boolean

I call extension function RecyclerView.suppressOnHeader :我调用扩展函数RecyclerView.suppressOnHeader

/**
 * If [onView] returns true -> it means what need skip this touch action for [RecyclerView]:
 * - Set true for [RecyclerView.suppressLayout], that makes list not scrollable and 
 *   transparent for clicking.
 *
 * If [onView] returns false -> it means what need vice versa make [RecyclerView] 
 * scrollable  and not transparent for clicking:
 * - Set false for [RecyclerView.suppressLayout], turn on touch events and scrolling for list.
 * - Need call [RecyclerView.onInterceptTouchEvent], this need for reset key
 *   [RecyclerView.mIgnoreMotionEventTillDown], which was setup when we call
 *   [RecyclerView.suppressLayout]. If skip this step when first [RecyclerView] click
 *   will be ignored. For information see [RecyclerView.onTouchEvent].
 * - And in the end call [RecyclerView.onTouchEvent], like we make a touch event.
 */
fun RecyclerView.suppressOnHeader(ev: MotionEvent?) {
    if (ev?.action != MotionEvent.ACTION_DOWN) return

    val holderView = findViewHolderForAdapterPosition(0)?.itemView

    if (ev.onView(holderView)) {
        if (!isLayoutSuppressed) {
           suppressLayout(true)
        }
    } else {
        if (isLayoutSuppressed) {
            suppressLayout(false)
            onInterceptTouchEvent(ev)
            onTouchEvent(ev)
        }
    }
}

fun MotionEvent?.onView(view: View?): Boolean {
    if (view == null || this == null) return false

    return Rect().apply {
        view.getGlobalVisibleRect(this)
    }.contains(rawX.toInt(), rawY.toInt())
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM