携手创作,共同成长!这是我参与「掘金日新计划 · 8 月更文挑战」的第3天,点击查看活动详情
为什么我们需要自定义视图?
Android框架提供的组件包括Button、TextView、EditText、ListView、CheckBox、RadioButton和Spinner,布局包括LinearLayout、FrameLayout和RelativeLayout。
然而,在实际创建应用程序时,很多情况下很难或不可能通过上述视图创建满足规划者、设计者和用户(客户)要求的功能。
例如,您可以扩展 ImageView 以创建一个显示圆形缩略图的视图,或者您可以扩展 TextView 以创建一个仅显示部分文本并在您想要显示所有内容时展开的视图。
这种情况下,唯一的办法就是直接创建一个符合要求的View。
创建自定义视图的基本原则
- 继承现有的 View 类。
- 覆盖以关键字“on”开头的超类方法,例如 onDraw()、onMeasure()、onKeyDown()。
- 使用新创建的自定义视图。和过去使用的方法一样,用于xml布局等。
主要API
onDraw()
提供了一个 Canvas,开发人员可以实现他们想要的任何东西。您可以覆盖 onDraw() 并使用 Canvas 在屏幕上绘制您想要绘制的内容。
*注意:这不适用于 3D 图形,您需要继承 SurfaceView 而不是 View 才能在单独的线程中绘制。
onMeasure()
有点复杂,它测量视图及其内容以确定测量的宽度和高度。onMeasure() 由 measure(int,int) 调用。measure 方法测量视图的大小,而 onMeasure() 是执行实际测量大小的地方。
覆盖 onMeasure() 时,必须调用 setMeasuredDimension(int, int) 来存储测量的尺寸。调用 super.onMeasure() 可能是一种方式(因为它已经在 onMeasure 内部调用过一次......)
API调用时机
创建类型
- 构造函数:有两种情况,在运行时从代码创建视图和解析 xml 文件时调用它。
- onFinishInflate():在视图或视图组的情况下,当子视图完成膨胀时调用它。
布局类型
- onMeasure(int, int):在确定视图或子视图的大小时调用。
- onLayout(boolean, int,int, int, int):在确定视图或子视图的位置时调用。
- onSizeChanged(int, int,int, int):当视图大小改变时调用。
绘制类型
- onDraw(Canvas):当视图绘制其内容时调用。
事件处理类型
- onKeyDown(int, KeyEvent):当按键事件被按下时调用。
- onKeyUp(int, KeyEvent):按键松开时调用。
- onTrackballEvent(MotionEvent):当轨迹球事件发生时调用。
- onTouchEvent(MotionEvent):当屏幕上发生触摸事件时调用。
焦点类型
- onFocusChanged(boolean,int, Rect):焦点发生改变时调用 。
- onWindowFocusChanged(boolean):当窗口的包含视图获得或失去焦点时调用。
附加类型
- onAttachedToWindow():当视图附加到窗口时调用。
- onDetachedFromWindow():当视图从窗口落下时调用。
- onWindowVisibilityChanged(int):当窗口持有的视图的可见性改变时调用。