我不是在问如何处理触摸事件,而是在幕后发生了什么?如果有几个嵌套的小部件,他们看到的事件是什么顺序?开发人员是否可以控制它?理想情况下,我想要一个关于这个主题的文件.
Activity当用户在屏幕的任何位置提供正确的滑动时,我必须完成.我已经尝试过,GestureDetector如果在其他视图中既不存在ScrollView又不RescyclerView存在也不允许检测滑动它们,那就可以正常工作.所以我尝试了一种不同的方式,通过以编程方式将视图叠加到所有这些视图的顶部,然后尝试检测其上的滑动事件.ActivityonClickListener
private void swipeOverToExit(ViewGroup rootView) {
OverlayLayout child = new OverlayLayout(this);
ViewGroup.LayoutParams layoutParams =
new ViewGroup.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT);
child.setLayoutParams(layoutParams);
rootView.addView(child);
}
Run Code Online (Sandbox Code Playgroud)
OverlayLayout
public class OverlayLayout extends RelativeLayout {
private float x1, x2;
private final int MIN_DISTANCE = 150;
public OverlayLayout(Context context) {
super(context);
}
public OverlayLayout(Context context, AttributeSet attrs) {
super(context, attrs);
}
public OverlayLayout(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
}
@TargetApi(Build.VERSION_CODES.LOLLIPOP)
public OverlayLayout(Context context, AttributeSet attrs, int …Run Code Online (Sandbox Code Playgroud) sdk说:
3,只要你从这个函数返回false,每个跟随事件(直到并包括最后一个)将首先在这里传递给目标的onTouchEvent().
4,如果从此处返回true,则不会收到任何后续事件:目标视图将收到相同的事件,但行动为ACTION_CANCEL,所有其他事件将传递给您的onTouchEvent()方法,此处不再显示.
但是当我使用这个方法时,无论onInterceptTouchEvent()返回什么,它都会做同样的工作!并且此方法从未捕获过MotionEvent.ACTION_MOVE或MotionEvent.ACTION_UP.任何人都可以帮我搞清楚吗?
部份!
我在尝试控制RecycleView中的触摸事件传播时遇到了一些问题.所以我有一个RecyclerView填充一组模仿卡片堆栈的CardView(因此它们相互重叠并具有一定的位移,尽管它们具有不同的高程值).我目前的问题是每张卡都有一个按钮,因为相对卡位移小于按钮的高度,导致按钮重叠的情况,每当调度触摸事件时,它开始从视图层次结构的底部传播(来自儿童)最高的孩子数).
根据我读过的文章(这个,这个和这个视频),触摸传播取决于父视图中的视图顺序,因此触摸将首先传递给具有最高索引的子项,而我希望仅处理触摸事件通过最顶层视图和RecyclerView的可触摸(它还必须处理拖动和拖动手势).目前我正在使用卡片,这些卡片知道他们在父视图层次结构中的位置,以防止错误的孩子处理触摸,但这是非常难看的方式.我的假设是我必须覆盖RecyclerView的dispatchTouchEvent方法,并且只将触摸事件正确地发送给最顶层的子节点.但是,当我尝试这种方式时(这也有点笨拙):
@Override
public boolean dispatchTouchEvent(MotionEvent ev) {
View topChild = getChildAt(0);
for (View touchable : topChild.getTouchables()) {
int[] location = new int[2];
touchable.getLocationOnScreen(location);
RectF touchableRect = new RectF(location[0],
location[1],
location[0] + touchable.getWidth(),
location[1] + touchable.getHeight());
if (touchableRect.contains(ev.getRawX(), ev.getRawY())) {
return touchable.dispatchTouchEvent(ev);
}
}
return onTouchEvent(ev);
}
Run Code Online (Sandbox Code Playgroud)
只有DOWN事件被传递到卡内的按钮(没有触发点击事件).我将非常感谢有关扭转触摸事件传播顺序或将触摸事件委托给特定视图的方法的任何建议.非常感谢你提前.
编辑:这是示例卡堆栈的样子的截图

示例适配器代码:
public class TestAdapter extends RecyclerView.Adapter {
List<Integer> items;
public TestAdapter(List<Integer> items) {
this.items = items;
}
@Override
public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int …Run Code Online (Sandbox Code Playgroud) 我知道这经常被问到,但所有的解决方案(我发现)都不适合我.
我所拥有的是带有OnClickListener制作Toast(#toast1)的CardView.在CardView内部,有多个视图和WebView.
如其他地方所述,要通过WebView点击进入CardView,我已经完成了以下操作:
android:clickable="false"在WebView XML中设置插入以下 CardView.setOnClickListener(...)
WebView.setOnTouchListener( (view, event) -> true);
我还用匿名方法替换了lambda,看看它是否只是这个.没变.
现在发生的事情是:
true,它会被触发.我期待的是:
有点令人困惑的是,在OnTouchListener的文档中,返回如下:
如果侦听器已使用该事件,则为true,否则为false.
对我来说,这意味着:
true:当侦听器使用它时,不要将点击传递给下面的视图false:通过点击查看以下视图,因为侦听器没有使用它但设置为false并没有改变任何东西.
我有一个充满卡片的父回收视图,每张卡片内部都有一个内部回收视图。
卡片内内部 recyclerview 的滚动已被禁用,但这也影响了内部 recyclerview 接收点击事件的能力。
为了禁用滚动,我遵循了与 Lucas Crawford 的回答非常相似的方法here,它建议您创建一个自定义的 recyclerview 类并覆盖 dispatchTouchEvent: Disable Scrolling in child Recyclerview android
我的课是这样的:
public class ScrollThroughRecyclerView extends RecyclerView {
private boolean isOnClick;
public ScrollThroughRecyclerView(Context context) {
super(context);
}
public ScrollThroughRecyclerView(Context context, AttributeSet attrs) {
super(context, attrs);
}
public ScrollThroughRecyclerView(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
}
@Override
public boolean dispatchTouchEvent(MotionEvent ev) {
final int action = ev.getAction();
final int actionMasked = action & MotionEvent.ACTION_MASK;
Log.e("actionmasked", "" + actionMasked);
switch (actionMasked) …Run Code Online (Sandbox Code Playgroud) 我有一个列表视图,其项目是一个linearlayout,它有一个按钮作为它的子视图.我希望linearlayout的ontouchLIstener能够正常工作.我不想用onInterceptTouchEvent.有没有办法可以通过触摸将该按钮传递给父列表视图.我试过这个 - 从按钮的onTouchListener返回true
private View.OnTouchListener buttonListener = new View.OnTouchListener() {
@Override
public boolean onTouch(View view, MotionEvent motionEvent) {
Log.i(TAG, "Button On Touch");
return true;
}
};
Run Code Online (Sandbox Code Playgroud)
但这不起作用.它不会将触摸事件传递给线性布局onTouchListener.
一定有它应该工作.