Android View之View绘制原理

1. View的绘制原理
android.graphics 相关类
Paint: 画笔
Cancas: 画布
Bitmap: Canvas背景图片
Color、Matrix、Drawable

简单绘制
 private Bitmap getBitmap(){
    int width = 300;
    int height = 300;
    Bitmap bmp = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888);

    Canvas canvas = new Canvas(bmp);

    Paint paint = new Paint();
    paint.setColor(Color.YELLOW);
    canvas.drawRect(0, 0, width, height, paint);

    Paint textPaint = new Paint();
    textPaint.setColor(Color.BLUE);
    textPaint.setTextSize(100);
    textPaint.setTypeface(Typeface.defaultFromStyle(Typeface.BOLD_ITALIC));
    textPaint.setTextAlign(Paint.Align.CENTER);
    canvas.drawText("Hello", width/2, height/2,textPaint);

    return bmp;
}



Android View之View绘制原理_第1张图片


2. 渐变颜色 Shader 着色器
Shader类子类
BitmapShader:图形渲染
LinearGradient:线性渐变
RadialGradient:环形渐变
SweepGradient:扫描渐变
ComposeShader:组合渲染
//配置渐变色,默认左上角开始斜着渐变
int[] colors =new int[]{Color.WHITE, Color.YELLOW, Color.GREEN};
float[] positions =new float[]{0.0f,0.5f,1.0f};
LinearGradient shader =newLinearGradient(0,0,width,height,colors, positions, Shader.TileMode.CLAMP);

//顺时针旋转45度
Matrix matrix =newMatrix();
matrix.setRotate(45,width/2, height/2);
shader.setLocalMatrix(matrix);
// 设置paint的shader
paint.setShader(shader);
Android View之View绘制原理_第2张图片


3. 重要绘制方法

3.1 绘制点和线
Bitmap bmp = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888);
Canvas canvas =newCanvas(bmp);
//解析颜色值
canvas.drawColor(Color.parseColor("#DDCC01"));

Paint paint =newPaint();
paint.setColor(Color.WHITE);
paint.setStrokeWidth(5);//设置线宽

float[] pts =new float[]{
20,20,
40,40,
80,80,
100,100
};

canvas.drawPoints(pts, paint);//画点,pts必须为2的倍数
canvas.drawLines(pts, paint);//画线,4个值为一条线

Android View之View绘制原理_第3张图片

3.2 绘制矩形
Bitmap bmp = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888);
Canvas canvas =newCanvas(bmp);
//解析颜色值
canvas.drawColor(Color.parseColor("#DDCC01"));

Paint paint =newPaint();
paint.setColor(Color.WHITE);
paint.setStrokeWidth(5);//设置线宽

canvas.drawRoundRect(newRectF(100,100,300,300),50,50, paint);

如需要画一个空心的矩形
paint.setStyle(Paint.Style.STROKE);//设置paint的style为STROKE

Android View之View绘制原理_第4张图片
Android View之View绘制原理_第5张图片

3.3 绘制路径

Path path =newPath();
path.moveTo(10.0f,10.0f);
path.lineTo(300.0f,30.0f);
path.lineTo(400.0f,500.0f);
path.lineTo(500.0f,300.0f);
canvas.drawPath(path, paint);

注:当画实心的时候,最后一个点会与第一个点粘上,画空心的时候则不会(即调用 paint .setStyle(Paint.Style. STROKE );)
Android View之View绘制原理_第6张图片

4 绘制表钟的实例
Bitmap bmp = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888);
Canvas canvas = new Canvas(bmp);
// 解析颜色值
canvas.drawColor(Color.parseColor("#FFFFFF"));

Paint paint = new Paint();
paint.setColor(Color.parseColor("#333333"));
paint.setStyle(Paint.Style.STROKE);
paint.setAntiAlias(true); // 消除锯齿的功能
paint.setStrokeWidth(4);

// 外围圆
float radius = width/2 - 4;
canvas.drawCircle(width/2, height/2, radius, paint);

// 内部实心圆
paint.setStyle(Paint.Style.FILL);
canvas.drawCircle(width/2, height/2, 10, paint);

// 循环画刻度
for(int i = 0; i < 12; i++){
    if(i % 3 == 0){
        paint.setStrokeWidth(10);
        canvas.drawLine(width/2 , height/2 + radius - 24, width/2, height/2 + radius, paint);
    }else{
        paint.setStrokeWidth(4);
        canvas.drawLine(width/2 , height/2 + radius - 20, width/2, height/2 + radius, paint);
    }
    canvas.rotate(30, width/2, height/2); // 注意:这里巧妙应用canvas旋转的思想
}


// 画时间指针
Calendar calendar = Calendar.getInstance();
int hour = calendar.get(Calendar.HOUR);
int minute = calendar.get(Calendar.MINUTE);
int second = calendar.get(Calendar.SECOND);

float lenH = radius * 0.7f;
float lenM = radius * 0.8f;
float lenS = radius * 0.9f;

float degree = hour * 30.0f + minute / 2;
paint.setStrokeWidth(10);
canvas.save(); // 第二种方法:先保存后restore
canvas.rotate(degree, width/2, height/2);
canvas.drawLine(width/2 , height/2, width/2, height/2 - lenH, paint);
// canvas.rotate(-degree, width/2, height/2); // 第一种方法,旋转回来
canvas.restore(); // 第二种方法:先保存后restore

// canvas.save();// save有count返回值
// canvas.restoreToCount(1);// restore到制定的count

// 画分钟
degree = minute * 6.0f + second / 10;
paint.setStrokeWidth(6);
canvas.save();
canvas.rotate(degree, width/2, height/2);
canvas.drawLine(width/2 , height/2, width/2, height/2 - lenM, paint);
canvas.restore();
// 画分钟
degree = second * 6.0f;
paint.setStrokeWidth(4);
canvas.save();
canvas.rotate(degree, width/2, height/2);
canvas.drawLine(width/2 , height/2, width/2, height/2 - lenS, paint);
canvas.restore();

// 要使表钟动起来,可新建一个AsyncTask,来在后台更新,如下简易版代码:

private class updateClock extends AsyncTask{

    @Override
    protected Void doInBackground(Void... params) {
        while(true){
            publishProgress();
            try {
                Thread.sleep(1000);
            }catch (InterruptedException e){

            }
        }
    }

    @Override
    protected void onProgressUpdate(Void... values) {
        super.onProgressUpdate(values);
        mImageView.setImageBitmap(getBitmap());
    }
}

Android View之View绘制原理_第7张图片


你可能感兴趣的:(Android应用)