写点什么

自定义 View:ViewGroup 与 View 的事件传递

作者:Changing Lin
  • 2021 年 11 月 18 日
  • 本文字数:1814 字

    阅读完需:约 6 分钟

1.知识点

  • ViewGroup.onInterceptTouchEvent 和 ViewGroup.onTouchEvent 两个接口的关系

  • 上述两者与子 View.onTouchEvent 接口的关系

  • 假设我们的布局如下所示:

<?xml version="1.0" encoding="utf-8"?><com.besmart.components.VirtualViewPager     xmlns:android="http://schemas.android.com/apk/res/android"    xmlns:app="http://schemas.android.com/apk/res-auto"    xmlns:tools="http://schemas.android.com/tools"    android:layout_width="match_parent"    android:layout_height="match_parent"    tools:context=".EmptyActivity">
<com.besmart.components.TestView android:background="#ff0000" android:layout_width="match_parent" android:layout_height="match_parent"/> <View android:background="#00ff00" android:layout_width="match_parent" android:layout_height="match_parent"/>
<View android:background="#0000ff" android:layout_width="match_parent" android:layout_height="match_parent"/>
</com.besmart.components.VirtualViewPager>
复制代码

2.原理

  • 如上图所示,仅有当 onInterceptTouchEvent 返回 false 的时候,子 View 才有可能收到 onTouchEvent。

  • 无论什么情况,onInterceptTouchEvent 总是会被调用,总可以接受到 ACTION_DOWN 事件

  • 结合 ViewGroup.onInterceptTouchEvent 和 ViewGroup.onTouchEvent,可以在父控件处理触摸事件,同时不影响子 View 的触摸事件响应

3.代码

  • VirtualViewPager.java

package com.besmart.components;
import android.content.Context;import android.util.AttributeSet;import android.util.Log;import android.view.MotionEvent;import android.view.View;import android.view.ViewGroup;
public class VirtualViewPager extends ViewGroup { private static final String TAG = "SimulatorViewPager";
public VirtualViewPager(Context context, AttributeSet attrs) { super(context, attrs); }
@Override protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { measureChildren(widthMeasureSpec, heightMeasureSpec); super.onMeasure(widthMeasureSpec, heightMeasureSpec); }
@Override protected void onLayout(boolean changed, int left, int top, int right, int bottom) { int count = getChildCount(); Log.e(TAG, String.format("onLayout: 当前有几个子View %d-%d-%d-%d-%d", count, left, top, right, bottom));
int childWidth = getWidth(); for (int i = 0; i < count; i++) { View child = getChildAt(i); child.layout(left, top, right, bottom); left += childWidth; right += childWidth; } }
@Override public boolean onTouchEvent(MotionEvent event) { Log.e(TAG, "onTouchEvent: "+event.toString()); return true; }
@Override public boolean onInterceptTouchEvent(MotionEvent ev) { Log.e(TAG, "onInterceptTouchEvent: "+ev.toString()); boolean result = false;
return result; }}
复制代码
  • TestView.java

package com.besmart.components;
import android.content.Context;import android.graphics.Canvas;import android.graphics.Color;import android.graphics.Paint;import android.graphics.Path;import android.graphics.PathMeasure;import android.util.AttributeSet;import android.util.Log;import android.view.MotionEvent;import android.view.View;
import androidx.annotation.Nullable;
import com.besmart.components.Util;
import java.util.Arrays;
public class TestView extends View { public static final String TAG = "TestView";
public TestView(Context context, @Nullable AttributeSet attrs) { super(context, attrs); }
@Override public boolean onTouchEvent(MotionEvent event) { Log.e(TAG, "onTouchEvent: "+event.toString()); return true; }}
复制代码


发布于: 2 小时前阅读数: 6
用户头像

Changing Lin

关注

获得机遇的手段远超于固有常规之上~ 2020.04.29 加入

我能做的,就是调整好自己的精神状态,以最佳的面貌去面对那些未曾经历过得事情,对生活充满热情和希望。

评论

发布
暂无评论
自定义View:ViewGroup与View的事件传递