1
自定义 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
版权声明: 本文为 InfoQ 作者【Changing Lin】的原创文章。
原文链接:【http://xie.infoq.cn/article/3b50c52718ab8ec01bb24aa62】。文章转载请联系作者。
Changing Lin
关注
获得机遇的手段远超于固有常规之上~ 2020.04.29 加入
我能做的,就是调整好自己的精神状态,以最佳的面貌去面对那些未曾经历过得事情,对生活充满热情和希望。
评论