当Android自带的view无法满足业务需求的时候,我们就需要定制view来达到自己的需求。
常用的重新方法:
构造器 | 重写构造器是定制View的最基本方式,当Java或Kotin代码创建一个View 实例,或根据XML布局文件加载并构建界面时将需要调用该构造器 |
onFinishInflate() | 这是一个回调方法,当应用从XML布局文件加载该组件并利用它来构建界面之后,该方法将会被回调 |
onMeasure(int, int) | 调用该方法来检测View组件及其所包含的所有子组件的大小 |
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 gainFocus, int direction, Rect previouslyFocusedRet) | 当该组件焦点发生改变时触发该方法 |
onWindowFocusChanged(boolean) | 当包含该组件的窗口失去或得到焦点时触发该方法 |
onAttachedToWindow() | 当把该组件放入某个窗口中时触发该方法 |
onDetachedFromWindow() | 当把该组件从某个窗口中分离时触发该方法 |
onWindowVisibilityChanged(int) | 当包含该组件的窗口的可见性发生改变时触发该方法 |
根据自己的需求,重写方法完成自定义view就行。
下面引入学的小demo:实现跟随手指移动的小球。
演示效果:
新建一个类继承view:
package com.example.demos.ui;
import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.util.AttributeSet;
import android.view.MotionEvent;
import android.view.View;
public class DrawView extends View {
private float currentX = 40f;
private float currentY = 50f;
// 定义并创建画笔
private Paint p = new Paint();
public DrawView(Context context){
super(context);
}
public DrawView(Context context, AttributeSet set){
super(context,set);
}
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
// 设置画笔颜色
p.setColor(Color.BLUE);
// 绘制一个小球(横坐标,纵坐标,半径,画笔)
canvas.drawCircle(currentX,currentY,15f,p);
}
// 重写组件触碰事件处理方法
@Override
public boolean onTouchEvent(MotionEvent event) {
// 动态修改小球坐标
currentX = event.getX();
currentY = event.getY();
// 通知组件重新绘制
invalidate();
// 返回true表示该方法已经处理该事件
return true;
}
}
在activity_main.xml中使用该view:
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout 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"
android:id="@+id/main_layout"
tools:context=".MainActivity">
<com.example.demos.ui.DrawView
android:layout_width="match_parent"
android:layout_height="match_parent"/>
</androidx.constraintlayout.widget.ConstraintLayout>
由上至下一 一解释:
public DrawView(Context context){
super(context);
}
public DrawView(Context context, AttributeSet set){
super(context,set);
}
此处的两个构造方法,是在自定义view里面常用的两个构造方法。
第一个构造方法是提供给我们在代码中生成控件使用的; 第二个方法是在XML布局文件中插入控件使用的,其中attrs参数就是我们在XML中定义控件的属性(包含自定义的属性),由于只是初步了解自定义view,并没有对两个构造方法进行深入了解。
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
// 设置画笔颜色
p.setColor(Color.BLUE);
// 绘制一个小球(横坐标,纵坐标,半径,画笔)
canvas.drawCircle(currentX,currentY,15f,p);
}
// 重写组件触碰事件处理方法
@Override
public boolean onTouchEvent(MotionEvent event) {
// 动态修改小球坐标
currentX = event.getX();
currentY = event.getY();
// 通知组件重新绘制
invalidate();
// 返回true表示该方法已经处理该事件
return true;
}
根据注释,已经很好理解了。
重写onDraw()方法,绘制出我们的小球,主要包括起始位置和大小,如果开头定义currentX,currentY时不设定值,那么在触碰屏幕之前,小球是不可见的。
重写onTouchEvent()方法,完成小球坐标的变化和小球的重新绘制,从而达到小球跟随手指移动的效果。
最后在布局文件中应用即可。