前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >Android开发笔记(十三)视图绘制的几个方法

Android开发笔记(十三)视图绘制的几个方法

作者头像
aqi00
发布2019-01-18 10:32:26
1.1K0
发布2019-01-18 10:32:26
举报
文章被收录于专栏:老欧说安卓

三个可进行绘制的方法

在自定义视图中,有三个函数可以重写用于界面绘制,在视图创建过程中,三个函数的执行顺序依次是:onLayout、onDraw、dispatchDraw。 1、onLayout(boolean changed, int left, int top, int right, int bottom) :  onLayout用于定位该视图在上级视图中的位置,从其参数中就可以看出来。由于该函数没有画布,因此只适合绘制现成的视图控件。 2、onDraw(Canvas canvas) :  自定义控件一般是重写onDraw方法,在画布中绘制各种图形。 3、dispatchDraw(Canvas canvas) :  dispatchDraw与onDraw的区别在于:onDraw在绘制下级视图之前,而dispatchDraw在绘制下级视图之后,所以如果不想自己的绘图被下级视图覆盖的话,就要在dispatchDraw中进行绘制操作。为方便记忆,只要是从ViewGroup衍生出的视图,都用dispatchDraw,其他小控件都用onDraw。

Canvas画布的使用

Canvas是Android提供的图形操作类,Canvas的使用不难,多练习几次就熟练了。下面列出Canvas的常用方法:

划定可绘制的区域(裁剪区域)

虽然本视图内的所有区域都是可以绘制的,但是有时候我们还是只想在某个圆形区域或者矩形区域内部画画,那么在绘制之前就得指定允许绘制的区域大小 clipPath : 裁剪不规则曲线区域 clipRect : 裁剪矩形区域 clipRegion : 裁剪一块组合区域

在区域内部绘制图形

drawArc : 绘制扇形 drawBitmap : 绘制图像 drawCircle : 绘制圆形 drawLine : 绘制直线 drawOval : 绘制椭圆 drawPath : 绘制路径,即不规则曲线 drawPoint : 绘制点 drawRect : 绘制矩形 drawRoundRect : 绘制圆角矩形 drawText : 绘制文本

移动整个画布

rotate : 旋转画布 scale : 缩放画布 translate : 平移画布

存取画布的状态

Canvas的不同绘制操作会互相影响,比如说我们想对整个画布做旋转,除了某个直线(即该直线保持不动),如果没有状态机制,那么该直线也只能跟着旋转。有了状态机制,我们就可以在绘制该直线前保存画布状态(保存旋转操作),然后画直线,最后再恢复画布状态。这样在save-restore代码之间绘制的任何图形,都不会收到save-restore代码以外其他图形操作的影响。 save : 保存画布状态 restore : 恢复画布状态

画笔Paint的使用

在上述绘制图形函数当中,都需要指定Paint,Paint上定义了画笔的颜色、样式、粗细、阴影、下划线等等。Paint的常用操作包括: setAntiAlias : 设置是否使用抗锯齿功能,主要用于画圆圈等曲线 setColor : 设置画笔的颜色 setShader : 设置画笔的渐变效果 setShadowLayer :  设置画笔的阴影 setStyle : 设置画笔的样式(线条还是填充) setStrokeWidth : 设置线条的粗细 setUnderlineText : 设置文本的下划线 setStrikeThruText : 设置文本的删除线

代码示例

下面是一个自定义签名控件的代码示例:

代码语言:javascript
复制
import java.util.ArrayList;

import com.example.exmcustom.R;

import android.annotation.SuppressLint;
import android.content.Context;
import android.content.res.TypedArray;
import android.graphics.Bitmap;
import android.graphics.Bitmap.Config;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.Path;
import android.util.AttributeSet;
import android.util.Log;
import android.view.MotionEvent;
import android.view.View;

public class SignatureView extends View {
	private static final String TAG = "SignatureView";
	private Paint paint;
	private Canvas cacheCanvas;
	private Bitmap cachebBitmap;
	private Path path;
	private int paint_color = Color.BLACK;
	private int stroke_width = 3;
	private PathPosition pos = new PathPosition();
	private ArrayList<PathPosition> pathArray = new ArrayList<PathPosition>();
	private int mWidth=0, mHeight=0;

	public SignatureView(Context context,AttributeSet attrs) {
		super(context, attrs);
		if (attrs != null) {
        	TypedArray attrArray=getContext().obtainStyledAttributes( attrs, R.styleable.SignatureView);
        	paint_color = attrArray.getColor(R.styleable.SignatureView_paint_color, Color.BLACK);
        	stroke_width = attrArray.getInt(R.styleable.SignatureView_stroke_width, 3);
        	attrArray.recycle();
		}
	}
	
	public SignatureView(Context context, AttributeSet attrs, int defStyleAttr) {
		super(context, attrs, defStyleAttr);
		if (attrs != null) {
        	TypedArray attrArray=getContext().obtainStyledAttributes( attrs, R.styleable.SignatureView);
        	paint_color = attrArray.getColor(R.styleable.SignatureView_paint_color, Color.BLACK);
        	stroke_width = attrArray.getColor(R.styleable.SignatureView_stroke_width, 3);
        	attrArray.recycle();
		}
	}

	public SignatureView(Context context) {
		super(context);
	}

	@Override
	protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
		super.onMeasure(widthMeasureSpec, heightMeasureSpec);
		mWidth = this.getMeasuredWidth();
		mHeight = this.getMeasuredHeight();
		Log.d(TAG, "onMeasure width="+mWidth+",height="+mHeight);
		init(mWidth, mHeight);
	}
	
	public SignatureView(Context context, int width, int height) {
		super(context);
		init(width, height);
	}
	
	public int getPaintColor() {
		return paint_color;
	}
	
	public void setPaintColor(int paint_color) {
		this.paint_color = paint_color;
	}

	public int getStrokeWidth() {
		return stroke_width;
	}
	
	public void setStrokeWidth(int stroke_width) {
		this.stroke_width = stroke_width;
	}

	public Bitmap getCachebBitmap() {
		return getDrawingCache();
	}

	private void init(int width, int height) {
		paint = new Paint();
		paint.setAntiAlias(true);
		paint.setStrokeWidth(stroke_width);
		paint.setStyle(Paint.Style.STROKE);
		paint.setColor(paint_color);
		path = new Path();

		setDrawingCacheEnabled(true);
		cachebBitmap = Bitmap.createBitmap(width, height, Config.ARGB_8888);
		cacheCanvas = new Canvas(cachebBitmap);
		cacheCanvas.drawColor(Color.WHITE);
	}

	public void clear() {
		if (cacheCanvas != null) {
			pathArray.clear();
			cacheCanvas.drawRGB(255, 255, 255);
			invalidate();
		}
	}

	public void revoke() {
		if (pathArray.size() > 0) {
			pathArray.remove(pathArray.size()-1);
			cacheCanvas.drawRGB(255, 255, 255);
			for (int i=0; i<pathArray.size(); i++) {
				Path posPath = new Path();
				posPath.moveTo(pathArray.get(i).firstX, pathArray.get(i).firstY);
				posPath.quadTo(pathArray.get(i).firstX, pathArray.get(i).firstY, 
						pathArray.get(i).nextX, pathArray.get(i).nextY);
				cacheCanvas.drawPath(posPath, paint);
			}
			invalidate();
		}
	}

	@SuppressLint("DrawAllocation")
	@Override
	protected void onDraw(Canvas canvas) {
		canvas.drawBitmap(cachebBitmap, 0, 0, null);
		canvas.drawPath(path, paint); //这个是需要的,最近一次的路径保存在这里
	}

	private float cur_x, cur_y;

	@SuppressLint("ClickableViewAccessibility")
	@Override
	public boolean onTouchEvent(MotionEvent event) {

		float x = event.getX();
		float y = event.getY();

		switch (event.getAction()) {
		case MotionEvent.ACTION_DOWN:
			cur_x = x;
			cur_y = y;
			path.moveTo(cur_x, cur_y);
			pos.firstX = cur_x;
			pos.firstY = cur_y;
			break;
		case MotionEvent.ACTION_MOVE:
			path.quadTo(cur_x, cur_y, x, y);
			cur_x = x;
			cur_y = y;
			pos.nextX = cur_x;
			pos.nextY = cur_y;
			pathArray.add(pos);
			pos = new PathPosition();
			pos.firstX = cur_x;
			pos.firstY = cur_y;
			break;
		case MotionEvent.ACTION_UP:
			cacheCanvas.drawPath(path, paint);
			path.reset();
			break;
		}

		invalidate();
		return true;
	}
}

点此查看Android开发笔记的完整目录

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2015年12月08日,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 三个可进行绘制的方法
  • Canvas画布的使用
    • 划定可绘制的区域(裁剪区域)
      • 在区域内部绘制图形
        • 移动整个画布
          • 存取画布的状态
          • 画笔Paint的使用
          • 代码示例
          领券
          问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档