Android UI 自定义控件
自绘控件(图表等无交互的控件)
主要重写onDraw()方法
举个例子:转圆圈的小车
public class CarView extends View {
private Bitmap carBitmap;
private Path path;
// 路径计算(主要使用到PathMeasure)
private PathMeasure pathMeasure;
private float distanceRatio = 0;
// 画圆圈的画笔
private Paint circlePaint;
// 画小车的画笔
private Paint carPaint;
// 针对car bitmap图片操作的矩阵
private Matrix carMatrix;
public CarView(Context context) {
super(context);
init();
}
public CarView(Context context, AttributeSet attrs) {
super(context, attrs);
}
public CarView(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
}
private void init() {
carBitmap = BitmapFactory.decodeResource(getResources(), R.drawable.icon_car);
path = new Path();
path.addCircle(0, 0, 200, Path.Direction.CW);
pathMeasure = new PathMeasure(path, false);
circlePaint = new Paint();
circlePaint.setStrokeWidth(5);
circlePaint.setStyle(Paint.Style.STROKE);
circlePaint.setAntiAlias(true);
circlePaint.setColor(Color.BLACK);
carPaint = new Paint();
carPaint.setColor(Color.DKGRAY);
carPaint.setStrokeWidth(2);
carPaint.setStyle(Paint.Style.STROKE);
carMatrix = new Matrix();
}
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
canvas.drawColor(Color.WHITE);
int width = getWidth();
int height = getHeight();
// 移动canvas坐标系到中心
canvas.translate(width / 2, height / 2);
carMatrix.reset();
distanceRatio += 0.006f;
if(distanceRatio >=1){
distanceRatio = 0;
}
// 0 - 1
float[] pos = new float[2]; //记录位置
float[] tan = new float[2]; //记录切点值xy
float distance = pathMeasure.getLength() * distanceRatio;
pathMeasure.getPosTan(distance, pos, tan);
// 计算小车本身要旋转的角度
float degree = (float) (Math.atan2(tan[1], tan[0]) * 180 / Math.PI);
// 设置旋转角度和旋转中心
carMatrix.postRotate(degree, carBitmap.getWidth() / 2, carBitmap.getHeight() / 2);
// 这里要将设置到小车的中心点
carMatrix.postTranslate(pos[0] - carBitmap.getWidth() / 2, pos[1] - carBitmap.getHeight() / 2);
canvas.drawPath(path, circlePaint);
canvas.drawBitmap(carBitmap, carMatrix, carPaint);
invalidate();
}
}
组合控件
主要体现封装思想:组合系统控件
继承控件
继承原生控件,重写部分方法
事件类控件
通常需要处理触摸事件
容器类控件
PS:后续补充上其他自定义控件Demo