博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
Android百日程序:绘画程序-画手指路径
阅读量:5965 次
发布时间:2019-06-19

本文共 4505 字,大约阅读时间需要 15 分钟。

本程序实如今一个画布中,用手指绘图的效果。

须要使用的知识:

1 Canvas 画布,动态保存更新当前画面

2 Path 记录并画出手接触屏幕经过的路径

如以下效果图:

仅仅须要依照默认设置新建一个项目,然后在输入java代码:

package com.example.sugestures;import android.app.Activity;import android.content.Context;import android.graphics.Bitmap;import android.graphics.Canvas;import android.graphics.Color;import android.graphics.Paint;import android.graphics.Path;import android.os.Bundle;import android.util.Log;import android.view.MotionEvent;import android.view.View;import android.view.View.OnTouchListener;public class MainActivity extends Activity {	DrawingView dv;	private Paint mPaint;	@Override	protected void onCreate(Bundle savedInstanceState) {		super.onCreate(savedInstanceState);		dv = new DrawingView(this);		dv.setOnTouchListener(new OnTouchListener() {			@Override			public boolean onTouch(View arg0, MotionEvent arg1) {				// TODO Auto-generated method stub				return false;			}		});		setContentView(dv);		mPaint = new Paint();		mPaint.setAntiAlias(true);		mPaint.setDither(true);		mPaint.setColor(Color.GREEN);		mPaint.setStyle(Paint.Style.STROKE);		mPaint.setStrokeJoin(Paint.Join.ROUND);		mPaint.setStrokeCap(Paint.Cap.ROUND);		mPaint.setStrokeWidth(12);				Log.d("onCreate", "onCreateActivityMain=========================");	}	public class DrawingView extends View {		public int width;		public int height;		private Bitmap mBitmap;		private Canvas mCanvas;		private Path mPath;		private Paint mBitmapPaint;		Context context;		private Paint circlePaint;		private Path circlePath;		public DrawingView(Context c) {			super(c);			context = c;			mPath = new Path();			mBitmapPaint = new Paint(Paint.DITHER_FLAG);			mBitmapPaint.setColor(Color.BLUE);			circlePaint = new Paint();			circlePath = new Path();			circlePaint.setAntiAlias(true);			circlePaint.setColor(Color.RED);			circlePaint.setStyle(Paint.Style.STROKE);			circlePaint.setStrokeJoin(Paint.Join.MITER);			circlePaint.setStrokeWidth(4f);						Log.d("DrawingView", "DrawingView=========================");		}		@Override		protected void onSizeChanged(int w, int h, int oldw, int oldh) {			super.onSizeChanged(w, h, oldw, oldh);			mBitmap = Bitmap.createBitmap(w, h, Bitmap.Config.ARGB_8888);			mCanvas = new Canvas(mBitmap);						Log.d("OnSizeChanged", "OnSizeChanged=========================");		}		@Override		protected void onDraw(Canvas canvas) {			super.onDraw(canvas);			canvas.drawBitmap(mBitmap, 0, 0, mBitmapPaint);			canvas.drawPath(mPath, mPaint);			canvas.drawPath(circlePath, circlePaint);						Log.d("onDraw", "onDraw================================");		}		private float mX, mY;		private static final float TOUCH_TOLERANCE = 4;		private void touch_start(float x, float y) {			mPath.reset();			mPath.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) {				mPath.quadTo(mX, mY, (x + mX) / 2, (y + mY) / 2);				//mPath.quadTo(mX, mY, x, y);				mX = x;				mY = y;				circlePath.reset();				circlePath.addCircle(mX, mY, 30, Path.Direction.CW);			}		}		private void touch_up() {			mPath.lineTo(mX, mY);			circlePath.reset();			// commit the path to our offscreen			mCanvas.drawPath(mPath, mPaint);			// kill this so we don't double draw			mPath.reset();		}		@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;		}	}}

主要知识点:

DrawingView类是扩展了View类的,这样能够重载当中的onTouchEvent函数,然后跟踪当前的Touch事件。这里主要是三个事件:

1 ACTION_DOWN:点击開始

2 ACTION_MOVE:点击屏幕之后,移动事件

3 ACTION_UP: 松开点击事件

分别使用touch_start, touch_move和touch_up三个函数处理这三个事件

主要是Path.quadTo这个函数画手指经过的路径。这里是使用二次方程的贝塞尔曲线画路径的。

而使用lineTo就是直接画直线了。

故此使用quadTo效果会更好点。

而moveTo就是设置開始点了,这就是为什么touch_start使用的是moveTo。

这里为了优化,添加了一个TOUCH_TOLERANCE,仅仅有移动超过这个值才会更新路径,事实上能够不做这个推断的。

Path.reset()是清除路径作用;

新建Canvas的时候传入一个Bitmap对象,是让Canvas使用这个Bitmap保存暂时数据,能够在invalid的时候又一次绘制这个Bitmap画面。假设没有Bitmap。画的路径会立即消失的。

使用Lod.d()记录一下各个函数的调用情况。能够得知在程序启动的时候,onResize是在onDraw之前调用的。

绘图的时候onDraw调用十分频繁,须要不断更新Path路径的。

和使用MFC等框架做的绘图程序,事实上没什么两样,当中的逻辑思路基本一样的。

最后不要忙了使用Canvas的drawPath函数把当前绘制的路径加到Bitmap中,否则也无法把当前路径暂时保存。

參考:http://stackoverflow.com/questions/16650419/draw-in-canvas-by-finger-android

这是最简单的一个绘图程序了,却是非常多程序,尤其是游戏程序的基础。还有非常多其它功能以后慢慢加上去。

你可能感兴趣的文章
IDE---Python IDE之Eric5在window下的安装
查看>>
python---LineReceiver实现记录服务器
查看>>
Mybatis调用Oracle中的存储过程和function
查看>>
telnet :No route to host
查看>>
基本安装lnmp环境
查看>>
yum源资料汇总
查看>>
7、MTC与MTV,http请求介绍
查看>>
logstash消费阿里云kafka消息
查看>>
第四节课作业
查看>>
EasyUI Calendar 日历
查看>>
Oracle 索引
查看>>
数据库复习
查看>>
unix 环境高级编程
查看>>
为数据库建立索引
查看>>
第二周作业-软件工作量的估计
查看>>
我的wordpress插件总结
查看>>
MAXIMO 快速查找实现
查看>>
Oracle——条件控制语句
查看>>
[Linux][Redis][05]Benchmark
查看>>
第一次作业-准备篇
查看>>