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;
}
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);
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个值为一条线
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
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
);)
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());
}
}