Android实现手写板功能

 更新时间:2022年06月29日 15:23:20   作者:伏辄  
这篇文章主要为大家详细介绍了Android实现手写板功能,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
(福利推荐:【腾讯云】服务器最新限时优惠活动,云服务器1核2G仅99元/年、2核4G仅768元/3年,立即抢购>>>:9i0i.cn/qcloud

(福利推荐:你还在原价购买阿里云服务器?现在阿里云0.8折限时抢购活动来啦!4核8G企业云服务器仅2998元/3年,立即抢购>>>:9i0i.cn/aliyun

本文实例为大家分享了Android实现手写板功能的具体代码,供大家参考,具体内容如下

自定义个一个手写板的重点:

笔画为一次down-move-up的集合

撤销笔画并非一次path的动作撤销 应该也是一次down-move -up的撤销

为了更好的笔画需要使用贝塞尔曲线来完成

效果如下:

截图中清楚 的意思是清除 !

具体代码如下:

package com.kyli.base.view;

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.util.AttributeSet;
import android.view.MotionEvent;
import android.view.View;

import androidx.annotation.Nullable;

import java.util.ArrayList;
import java.util.List;

/**
?* 绘制画板
?*/
public class SignBoradView extends View {
? ? /*4个像素点*/
? ? private int beierThreshold = 4;
? ? private float x = 0;
? ? private float y = 0;
? ? /*画笔*/
? ? private Paint mPaint;
? ? /*宽度*/
? ? private int strokeWidth = 10;

? ? /*yanbse*/
? ? private int color = Color.BLACK;

? ? /*当前笔画*/
? ? private Path path;

? ? private int state = State.CLEAR;

? ? private interface State {
? ? ? ? /*画板可以使用了*/
? ? ? ? int START = 0;

? ? ? ? /*停止使用画板*/
? ? ? ? int STOP = 1;
? ? ? ? /*清空画板*/
? ? ? ? int CLEAR = 2;
? ? }

? ? private List<EveryPenPath> everyPenPaths = new ArrayList<>();

? ? /*每一个笔画*/
? ? private static class EveryPenPath {
? ? ? ? public Path path;
? ? }

? ? public SignBoradView(Context context) {
? ? ? ? super(context);
? ? }

? ? public SignBoradView(Context context, @Nullable AttributeSet attrs) {
? ? ? ? super(context, attrs);
? ? }

? ? public SignBoradView(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
? ? ? ? super(context, attrs, defStyleAttr);
? ? }

? ? private void initPaint() {
? ? ? ? if (mPaint == null) {
? ? ? ? ? ? mPaint = new Paint();
? ? ? ? ? ? mPaint.setStrokeWidth(strokeWidth);
? ? ? ? ? ? mPaint.setColor(color);
? ? ? ? ? ? mPaint.setStyle(Paint.Style.STROKE);
? ? ? ? ? ? mPaint.setAntiAlias(true);
? ? ? ? ? ? mPaint.setFlags(Paint.ANTI_ALIAS_FLAG);
? ? ? ? }
? ? }

? ? public void start() {
? ? ? ? state = State.START;
? ? ? ? initPaint();

? ? }

? ? /*停止使用*/
? ? public void stop() {
? ? ? ? state = State.STOP;
? ? }

? ? /*清空画板*/
? ? public void clear() {
? ? ? ? state = State.CLEAR;
? ? ? ? for (int i = everyPenPaths.size() - 1; i >= 0; i--) {
? ? ? ? ? ? EveryPenPath everyPenPath = everyPenPaths.get(i);
? ? ? ? ? ? everyPenPath.path.reset();
? ? ? ? ? ? everyPenPath.path.close();
? ? ? ? ? ? everyPenPath.path = null;

? ? ? ? }
? ? ? ? everyPenPaths.clear();
? ? ? ? invalidate();

? ? }


? ? public void back() {
? ? ? ? int count = everyPenPaths.size();
? ? ? ? if (count < 1)
? ? ? ? ? ? return;
? ? ? ? EveryPenPath everyPenPath = everyPenPaths.get(count - 1);
? ? ? ? everyPenPath.path.reset();
? ? ? ? everyPenPath.path.close();
? ? ? ? everyPenPath.path = null;
? ? ? ? everyPenPaths.remove(count - 1);
? ? ? ? invalidate();
? ? }


? ? @Override
? ? protected void onDraw(Canvas canvas) {
? ? ? ? super.onDraw(canvas);
? ? ? ? if (state == State.START) {

? ? ? ? ? ? /*先绘制完整笔画*/
? ? ? ? ? ? for (EveryPenPath e : everyPenPaths) {
? ? ? ? ? ? ? ? canvas.drawPath(e.path, mPaint);
? ? ? ? ? ? }
? ? ? ? ? ? //当前进行中的 ?path!=null
? ? ? ? ? ? if (path != null) {
? ? ? ? ? ? ? ? canvas.drawPath(path, mPaint);
? ? ? ? ? ? }

? ? ? ? }

? ? }


? ? @Override
? ? public boolean onTouchEvent(MotionEvent event) {
? ? ? ? if (state == State.START) {
? ? ? ? ? ? if (event.getAction() == MotionEvent.ACTION_UP) {
? ? ? ? ? ? ? ? actionUp(event);
? ? ? ? ? ? ? ? invalidate();
? ? ? ? ? ? ? ? return true;
? ? ? ? ? ? }
? ? ? ? ? ? if (event.getAction() == MotionEvent.ACTION_MOVE) {
? ? ? ? ? ? ? ? actionMove(event);
? ? ? ? ? ? ? ? invalidate();
? ? ? ? ? ? ? ? return true;
? ? ? ? ? ? }
? ? ? ? ? ? if (event.getAction() == MotionEvent.ACTION_DOWN) {
? ? ? ? ? ? ? ? actionDown(event);
? ? ? ? ? ? ? ? invalidate();
? ? ? ? ? ? ? ? return true;
? ? ? ? ? ? }
? ? ? ? }
? ? ? ? return super.onTouchEvent(event);
? ? }


? ? private void actionUp(MotionEvent event) {
? ? ? ? actionMove(event);
? ? ? ? /*构成一个笔画*/
? ? ? ? EveryPenPath everyPenPath = new EveryPenPath();
? ? ? ? everyPenPath.path = path;
? ? ? ? everyPenPaths.add(everyPenPath);
? ? ? ? //将当前画笔置位null;
? ? ? ? path = null;

? ? }

? ? /**/
? ? private void actionMove(MotionEvent event) {
? ? ? ? /*每次移动去绘制贝塞尔曲线*/
? ? ? ? float cX = event.getX();
? ? ? ? float cY = event.getY();
? ? ? ? float dX = Math.abs(cX - x);//变化量
? ? ? ? float dY = Math.abs(cY - y);

? ? ? ? if (dX >= beierThreshold || dY >= beierThreshold) {
? ? ? ? ? ? float rX = x + (cX - x) / 2;
? ? ? ? ? ? float rY = y + (cY - y) / 2;
? ? ? ? ? ? path.quadTo(rX, rY, cX, cY);
? ? ? ? ? ? //下次的x 域y 将重新计算
? ? ? ? ? ? x = cX;
? ? ? ? ? ? y = cY;
? ? ? ? }
? ? }

? ? /*开始时*/
? ? private void actionDown(MotionEvent event) {
? ? ? ? path = new Path();
? ? ? ? x = event.getX();
? ? ? ? y = event.getY();
? ? ? ? path.moveTo(x, y);
? ? }


? ? public void setBeierThreshold(int beierThreshold) {
? ? ? ? this.beierThreshold = beierThreshold;
? ? }


? ? public void setStrokeWidth(int strokeWidth) {
? ? ? ? this.strokeWidth = strokeWidth;
? ? }


? ? public void setColor(int color) {
? ? ? ? this.color = color;
? ? }

? ? public Bitmap getResult(int bgColor) {
? ? ? ? if (everyPenPaths.size() == 0)
? ? ? ? ? ? return null;
? ? ? ? Bitmap bitmap = Bitmap.createBitmap(getWidth(), getHeight(), Bitmap.Config.ARGB_8888);
? ? ? ? Canvas canvas = new Canvas(bitmap);
? ? ? ? canvas.drawColor(bgColor);
? ? ? ? for (int i = 0; i < everyPenPaths.size(); i++) {
? ? ? ? ? ? if (mPaint == null) {
? ? ? ? ? ? ? ? initPaint();

? ? ? ? ? ? }
? ? ? ? ? ? canvas.drawPath(everyPenPaths.get(i).path, mPaint);
? ? ? ? }
? ? ? ? return bitmap;
? ? }

? ? public Bitmap getResult() {
? ? ? ? return getResult(Color.WHITE);
? ? }
}

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持程序员之家。

相关文章

最新评论

?


http://www.vxiaotou.com