CustomView2.md

Android自定义View(二)

目录:

自定义View绘制流程

image

构造函数

四种重载:

//一般在直接New一个View的时候调用。
public void SimpleView(Context context) {}
//一般在layout文件中使用的时候会调用,关于它的所有属性(包括自定义属性)都会包含在attrs中传递进来。
public void SimpleView(Context context, AttributeSet attrs) {}
//调用了三个参数的构造函数,必须明确指定第三个参数,第三个参数是默认的Style(当前Application或Activity所用的Theme中的默认Style)。
public void SimpleView(Context context, AttributeSet attrs, int defStyleAttr) {}
public void SimpleView(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {}

使用:

在activity中:

SimpleView view=new SimpleView(this);

在layout中:

<com.lcfu1.view.SimpleView
  android:layout_width"wrap_content"
  android:layout_height"wrap_content"/>

onMeasure()

测量View大小,View的大小不仅由自身所决定,同时也会受到父控件的影响。

@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        super.onMeasure(widthMeasureSpec, heightMeasureSpec);

        int widthMode = MeasureSpec.getMode(widthMeasureSpec);
        int widthSize = MeasureSpec.getSize(widthMeasureSpec);
        int heightMode = MeasureSpec.getMode(heightMeasureSpec);
        int heightSize = MeasureSpec.getSize(heightMeasureSpec);
}

widthMeasureSpec 和 heightMeasureSpec两个 int 类型的参数,是由宽、高和各自方向上对应的测量模式来合成的一个值。getMode():测量模式,getSize():确切数值。

SpecMode类型:

onSizeChanged()

@Override
protected void onSizeChanged(int w, int h, int oldw, int oldh) {
	super.onSizeChanged(w, h, oldw, oldh);
}

在视图大小发生改变时调用。w和h就是View最终的大小。

onLayout()
@Override
protected void onLayout(boolean changed, int left, int top, int right, int bottom) {
	super.onLayout(changed, left, top, right, bottom);
}

确定布局的函数,用于确定子View的位置,在自定义ViewGroup中会用到,他调用的是子View的layout函数。

在自定义ViewGroup中,onLayout一般是循环取出子View,然后经过计算得出各个子View位置的坐标值。

对于非ViewGroup类型来说,它需要做的工作只是测量尺寸与绘制自身内容。

onDraw()

@Override
public void onDraw(Canvas canvas)
{
	super.onDraw(canvas);
}

就是实际绘制内容。

绘制随手移动的小球

package com.lcfu1.view;

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
{
	//小球的初始位置
	public float currentX = 50;
	public float currentY = 50;

	// 定义、并创建画笔
	Paint p = new Paint();

	public DrawView(Context context)
	{
		super(context);
	}
	public DrawView(Context context , AttributeSet set)
	{
		super(context,set);
	}
	
	//绘制内容
	@Override
	public void onDraw(Canvas canvas)
	{
		super.onDraw(canvas);
                // 设置画布的颜色
		canvas.drawColor(Color.GRAY);
		// 设置画笔的颜色
		p.setColor(Color.RED);
		// 绘制一个小圆(作为小球)
		canvas.drawCircle(currentX, currentY, 15, p);
	}
	// 为该组件的触碰事件重写事件处理方法
	@Override
	public boolean onTouchEvent(MotionEvent event)
	{
		// 修改currentX、currentY两个属性
		currentX = event.getX();
		currentY = event.getY();
		// 通知当前组件重绘自己
		invalidate();
		// 返回true表明该处理方法已经处理该事件
		return true;
	}
}

在现实中要画东西就需要画纸,而要在屏幕上面画东西,则需要Canvas,也就是画布。

Canvas

常用方法如下:

image.png

例:

canvas.drawColor(Color.GRAY);
canvas.drawPoint(10,10,paint); 
canvas.drawPoints(new float[]{100,100,130,100},paint);
canvas.drawLine(100,100,200,100,paint);
canvas.drawLines(new float[]{100,100,200,100,100,200,200,200},paint);
canvas.drawCircle(100, 100, 15, paint);
canvas.drawRect(100,100,200,200,paint);
canvas.drawRoundRect(100,100,200,200,20,20,paint);
RectF rectF=new RectF(100,100,200,200);
canvas.drawRoundRect(rectF,20,20,paint);
canvas.drawOval(100,100,200,200,paint);
RectF rectF = new RectF(100,100,200,200);
canvas.drawOval(rectF,paint);
canvas.drawArc(100,100,200,200,0,90,false,paint);
RectF rectF = new RectF(100,100,200,200);
canvas.drawArc(rectF,0,90,true,paint);
//设置画笔颜色
mPaint.setColor(Color.BLACK);
canvas.translate(100,100);
canvas.drawCircle(0,0,10,mPaint);
canvas.translate(100,100);
canvas.drawCircle(0,0,10,mPaint);
canvas.translate(100,-100);
canvas.drawCircle(0,0,10,mPaint);

image.png

mPaint.setColor(Color.BLACK);//设置画笔颜色
canvas.translate(100,100);//移动坐标系原点到(100,100)
canvas.drawCircle(0,0,100,mPaint);//画圆
canvas.scale(0.5f,0.5f);// 画布缩放
mPaint.setColor(Color.YELLOW);// 改变画笔颜色为黄色
canvas.drawCircle(0,0,100,mPaint);//画圆

image.png

mPaint.setColor(Color.BLACK);//设置画笔颜色
canvas.translate(100,100);//移动坐标系原点到(100,100)
canvas.drawCircle(0,0,100,mPaint);//画圆
canvas.scale(0.5f,0.5f,0,0);// 画布缩放
mPaint.setColor(Color.YELLOW);// 改变画笔颜色为黄色
canvas.drawCircle(0,0,100,mPaint);//画圆

image.png

mPaint.setColor(Color.BLACK);//设置画笔颜色
mPaint.setStyle(Paint.Style.STROKE);//描边
mPaint.setStrokeWidth(20f);//设置画笔宽度为10px
canvas.translate(100,100);//移动坐标系原点到(100,100)
canvas.drawCircle(0,0,100,mPaint);//画圆
canvas.scale(0.5f,0.5f);// 画布缩放
canvas.drawCircle(0,0,100,mPaint);//画圆
canvas.scale(0.5f,0.5f);// 画布缩放
canvas.drawCircle(0,0,100,mPaint);//画圆

image.png

mPaint.setColor(Color.BLACK);//设置画笔颜色
canvas.translate(100,100);//移动坐标系原点到(100,100)
canvas.drawRect(0,0,100,100,mPaint);//画距形
canvas.rotate(90);//旋转90度
mPaint.setColor(Color.YELLOW);//改变画笔颜色
canvas.drawRect(0,0,100,100,mPaint);//画距形

image.png

mPaint.setColor(Color.BLACK);//设置画笔颜色
canvas.translate(100,100);//移动坐标系原点到(100,100)
canvas.drawRect(0,0,100,100,mPaint);//画距形
canvas.skew(1,0);//1=tan45度,在x轴方向上倾斜45度
mPaint.setColor(Color.YELLOW);//改变画笔颜色
canvas.drawRect(0,0,100,100,mPaint);//画距形

image.png

Paint

上面简述了Canvas的使用,要想在Canvas上画东西,肯定不能少了Paint,也就是画笔。

Paint部分函数:

image.png

例:

// 定义、并创建画笔
Paint paint = new Paint();
//设置画笔颜色
paint.setColor(Color.RED);
//设置画笔模式为填充,STROKE:描边、FILL:填充、FILL_AND_STROKE:描边加填充
paint.setStyle(Paint.Style.FILL); 
//设置画笔宽度为10px
paint.setStrokeWidth(20f);
//抗锯齿功能
paint.setAntiAlias(true);
//设置画笔的样式 Paint.Cap.Round:圆形、Paint.Cap.SQUARE:方形
paint.setStrokeCap(Paint.Cap.ROUND);
//结合处为圆弧
paint.setStrokeJoin(Paint.Join.ROUND);

参考