目录
一图概览
界面实现方式
XML布局方式
JAVA或Kotlin代码布局
Android定制控件
Android原生核心控件
为什么不用原生?
定制控件三大方法
定制控件流程
触摸事件(input事件处理)流程
分发 (dispatchTouchEvent)
拦截 (onInterceptTouchEvent)
处理 (onTouchEvent)
实例Demo
优化界面
资源优化
代码优化
控件优化
一图概览
界面实现方式
XML布局方式
- xml文件添加控件,设置其属性和布局约束
- 可以在其他xml文件通过layout="@layout/资源布局id",导入其他xml文件作一个控件
JAVA或Kotlin代码布局
- 创建控件容器
- 创建具体控件
- 将创建控件添加到父容器
- 加载到Content
Android定制控件
Android原生核心控件
为什么不用原生?
-
原生过于刻板,无法满足一些特别需求(炫酷动画,创新功能)
-
布局层次过于复杂,影响程序性能
定制控件三大方法
- 基于现有控件继承扩展
- 通过现有控件组合布局
- 直接继承View,深度自定义
定制控件流程
-
构造函数负责属性的解析与初始化
-
View由onMeasure()尺寸计算
-
ViewGroup考虑子View布局位置
-
内容绘制,onDraw()实现形状、颜色、阴影等
-
交互实现Input事件的处理
-
提供外部调用的接口
触摸事件(input事件处理)流程
分发 (dispatchTouchEvent
)
- 当触摸事件发生时,事件首先被传递给
ViewGroup
的dispatchTouchEvent
方法。 - 如果
ViewGroup
有一个子视图可以处理该事件(即子视图的onTouchEvent
方法返回true
),则事件会被传递给子视图。 - 如果没有子视图可以处理该事件(返回false),事件会传递给父视图。
拦截 (onInterceptTouchEvent
)
- 在触摸事件被传递给子视图之前,
ViewGroup
的onInterceptTouchEvent
方法会被调用。 - 如果
onInterceptTouchEvent
返回true
,事件将被此父视图拦截,并且不会传递给子视图。 - 如果
onInterceptTouchEvent
返回false
,事件将传递给子视图。
处理 (onTouchEvent
)
- 如果触摸事件没有被拦截,它将传递给子视图的
onTouchEvent
方法进行处理。 - 如果子视图的
onTouchEvent
返回true
,表示子视图已经处理了该事件。 - 如果子视图的
onTouchEvent
返回false
,事件将传递回父视图处理。
实例Demo
public class MyLinearLayout extends LinearLayout {
private float initialX;
public MyLinearLayout(Context context) {
super(context);
}
public MyLinearLayout(Context context, AttributeSet attrs) {
super(context, attrs);
}
public MyLinearLayout(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
}
@Override
public boolean onInterceptTouchEvent(MotionEvent ev) {
final int action = ev.getAction();
switch (action) {
case MotionEvent.ACTION_DOWN:
initialX = ev.getX();
break;
case MotionEvent.ACTION_MOVE:
float diffX = Math.abs(initialX - ev.getX());
if (diffX > 10) { // 如果手指移动超过10像素,则拦截事件
return true;
}
break;
}
return super.onInterceptTouchEvent(ev);
}
}