先看一下关于bitmap 配置的理解:
跳转:关于ARGB_8888、ALPHA_8、ARGB_4444、RGB_565的理解
再看一个关于path的几种画法:
arcTo
用于绘制弧线(实际是截取圆或椭圆的一部分) --> 这个可以画半圆
跳转:Android中moveTo、lineTo、quadTo、cubicTo、arcTo详解(实例
一、Android提供了一系列用于二维绘制的APIs,当绘制2D图形时,通常有两种选择:
1.在一个View对象中绘制。继承View类,在子类的 onDraw()方法中写入自己定义的绘制代码。
res/values/colors.xml --> 一些颜色,方便使用
<?xml version="1.0" encoding="utf-8"?> <resources> <color name="red">#f00</color> <color name="green">#0f0</color> <color name="blue">#0000ff</color> <color name="black">#000</color> <color name="blue_light">#33b5e5</color> <color name="blue_dark">#0099cc</color> <color name="purple_light">#aa66cc</color> <color name="purple_dark">#9933cc</color> <color name="green_light">#99cc00</color> <color name="green_dark">#669900</color> <color name="yellow_light">#ffbb33</color> <color name="yellow_dark">#ff8800</color> <color name="red_light">#ff4444</color> <color name="red_dark">#cc0000</color> </resources>
java/view/MyPaintView.java
package view; import android.content.Context; import android.content.res.Resources; import android.graphics.Bitmap; import android.graphics.Canvas; import android.graphics.Paint; import android.graphics.Path; import android.util.AttributeSet; import android.view.MotionEvent; import android.view.View; import com.example.administrator.test.R; /** * Created by Administrator on 2016/1/8. */ public class MyPaintView extends View { private Resources myResources; // 画笔,定义绘制属性 private Paint myPaint; private Paint mBitmapPaint; // 绘制路径 private Path myPath; // 画布及其底层位图 private Bitmap myBitmap; private Canvas myCanvas; private float mX, mY; private static final float TOUCH_TOLERANCE = 4; // 记录宽度和高度 private int mWidth; private int mHeight; public MyPaintView(Context context) { super(context); initialize(); } public MyPaintView(Context context, AttributeSet attrs, int defStyle) { super(context, attrs, defStyle); initialize(); } public MyPaintView(Context context, AttributeSet attrs) { super(context, attrs); initialize(); } /** * 初始化工作 */ private void initialize() { // Get a reference to our resource table. myResources = getResources(); // 绘制自由曲线用的画笔 myPaint = new Paint(); myPaint.setAntiAlias(true); //设置是否使用抗锯齿功能,会消耗较大资源,绘制图形速度会变慢。 myPaint.setDither(true);//设定是否使用图像抖动处理,会使绘制出来的图片颜色更加平滑和饱满,图像更加清晰 myPaint.setColor(myResources.getColor(R.color.purple_dark)); myPaint.setStyle(Paint.Style.STROKE); myPaint.setStrokeJoin(Paint.Join.ROUND); //设置绘制时个图形的结合方式,如平滑效果等,MITER为锐角,ROUND为圆弧,BEVEL结合处为直线 myPaint.setStrokeCap(Paint.Cap.ROUND);//设置画笔为圆形样式 还有个方形 ract样式 myPaint.setStrokeWidth(12); myPath = new Path(); mBitmapPaint = new Paint(Paint.DITHER_FLAG); //防抖?? } @Override protected void onSizeChanged(int w, int h, int oldw, int oldh) { super.onSizeChanged(w, h, oldw, oldh); mWidth = w; mHeight = h; myBitmap = Bitmap.createBitmap(w, h, Bitmap.Config.ARGB_8888); myCanvas = new Canvas(myBitmap); } @Override public boolean onTouchEvent(MotionEvent event) { float x = event.getX(); float y = event.getY(); switch (event.getAction()) { case MotionEvent.ACTION_DOWN: touch_start(x, y); invalidate(); break; case MotionEvent.ACTION_MOVE: touch_move(x, y); invalidate(); break; case MotionEvent.ACTION_UP: touch_up(); invalidate(); break; } return true; } @Override protected void onDraw(Canvas canvas) { super.onDraw(canvas); // 背景颜色 // canvas.drawColor(getResources().getColor(R.color.blue_dark)); //Bitmap:图片对象,left:偏移左边的位置,top: 偏移顶部的位置 //drawBitmap(Bitmap bitmap, float left, float top, Paint paint) // 如果不调用这个方法,绘制结束后画布将清空 canvas.drawBitmap(myBitmap, 0, 0, mBitmapPaint); // 绘制路径 canvas.drawPath(myPath, myPaint); } private void touch_start(float x, float y) { myPath.reset(); myPath.moveTo(x, y); mX = x; mY = y; } private void touch_move(float x, float y) { float dx = Math.abs(x - mX); float dy = Math.abs(y - mY); if (dx >= TOUCH_TOLERANCE || dy >= TOUCH_TOLERANCE) { myPath.quadTo(mX, mY, (x + mX) / 2, (y + mY) / 2); //用于绘制圆滑曲线,即贝塞尔曲线。 mX = x; mY = y; } } private void touch_up() { myPath.lineTo(mX, mY); // commit the path to our offscreen // 如果少了这一句,笔触抬起时myPath重置,那么绘制的线将消失 myCanvas.drawPath(myPath, myPaint); // kill this so we don't double draw myPath.reset(); } /** * 清除整个图像 */ public void clear() { // 清除方法1:重新生成位图 // myBitmap = Bitmap // .createBitmap(mWidth, mHeight, Bitmap.Config.ARGB_8888); // myCanvas = new Canvas(myBitmap); // 清除方法2:将位图清除为白色 myBitmap.eraseColor(myResources.getColor(R.color.white)); // 两种清除方法都必须加上后面这两步: // 路径重置 myPath.reset(); // 刷新绘制 invalidate(); } }
activity/DrawPaintActivity.java
public class DrawPaintActivity extends Activity { @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_draw_paint); final MyPaintView myPaintView = (MyPaintView)findViewById(R.id.paintView); findViewById(R.id.btn_clear).setOnClickListener(new View.OnClickListener() { @Override public void onClick(View view) { myPaintView.clear(); } }); } }
布局文件
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" tools:context="com.example.administrator.test.DrawPaintActivity"> <view.MyPaintView android:layout_width="fill_parent" android:layout_height="fill_parent" android:id="@+id/paintView"/> <Button android:layout_width="wrap_content" android:layout_height="wrap_content" android:id="@+id/btn_clear" android:text="Clear"/> </RelativeLayout>效果:
2.直接在画布(Canvas)上绘制。
package com.example.administrator.test; import android.app.Activity; import android.graphics.Bitmap; import android.graphics.Canvas; import android.graphics.Color; import android.graphics.Paint; import android.graphics.Path; import android.graphics.RectF; import android.os.Bundle; import android.view.ViewGroup; import android.widget.ImageView; import android.widget.LinearLayout; public class DrawActivity extends Activity { @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); Bitmap bitmap = Bitmap.createBitmap(getWindowManager().getDefaultDisplay().getWidth(), getWindowManager().getDefaultDisplay().getHeight(), Bitmap.Config.ARGB_8888); Canvas canvas = new Canvas(bitmap); //画布 Paint paint = new Paint();//画笔 paint.setAlpha(100); //取值范围为0~255,数值越小越透明 /** * 风格: paint.setStyle * STROKE 仅绘形状的轮廓 * FILL 仅填充形状 * FILL_AND_STROKE 填充并绘制形状的轮廓 */ //1:画一个点 // paint.setStyle(Style.STROKE);不涉及封闭图形,不写此属性ok~ paint.setStrokeWidth(10); //设置线宽 paint.setColor(Color.RED); canvas.drawPoint(400, 201, paint); //2,画一条线 // paint.setStyle(Style.STROKE);不涉及封闭图形,不写此属性ok~ paint.setStrokeWidth(10); canvas.drawLine(50, 50, 100, 400, paint); //4个参数分别为起点的xy坐标,终点的xy坐标 //3,画一个矩形 paint.setStyle(Paint.Style.STROKE); paint.setStrokeWidth(10); paint.setColor(Color.BLUE); canvas.drawRect(50, 500, 400, 700, paint);//距离左边,上边,右边和下边的位置距离坐标。 //4,画一个椭圆 paint.setStyle(Paint.Style.FILL); paint.setStrokeWidth(10); paint.setColor(Color.GREEN); RectF oval = new RectF(50, 500, 400, 700) ;//这4个参数和矩形一样,相当于矩形里面画了一个椭圆 canvas.drawOval(oval, paint); //5,画一个圆 paint.setStyle(Paint.Style.FILL_AND_STROKE); paint.setStrokeWidth(10); paint.setColor(Color.YELLOW); canvas.drawCircle(550, 600, 100, paint);//参数表示圆心的xy坐标,半经 //6,路径:通过路径Path对象 paint.setStyle(Paint.Style.STROKE); paint.setStrokeWidth(10); Path path = new Path(); path.moveTo(0, 1000);//起始点 path.lineTo(100, 800); path.lineTo(200, 1000); path.lineTo(300, 800); path.lineTo(400, 1000); path.lineTo(500, 800); path.lineTo(600, 1000); path.lineTo(700, 800); canvas.drawPath(path, paint); ImageView imageView = new ImageView(this); ViewGroup.LayoutParams p = new ViewGroup.LayoutParams(LinearLayout.LayoutParams.FILL_PARENT,LinearLayout.LayoutParams.FILL_PARENT); imageView.setLayoutParams(p); imageView.setImageBitmap(bitmap); setContentView(imageView); } }