<em>Mac</em>Book项目 2009年学校开始实施<em>Mac</em>Book项目,所有师生配备一本<em>Mac</em>Book,并同步更新了校园无线网络。学校每周进行电脑技术更新,每月发送技术支持资料,极大改变了教学及学习方式。因此2011
2021-06-01 09:32:01
本文範例為大家分享了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); } }
以上就是本文的全部內容,希望對大家的學習有所幫助,也希望大家多多支援it145.com。
相關文章
<em>Mac</em>Book项目 2009年学校开始实施<em>Mac</em>Book项目,所有师生配备一本<em>Mac</em>Book,并同步更新了校园无线网络。学校每周进行电脑技术更新,每月发送技术支持资料,极大改变了教学及学习方式。因此2011
2021-06-01 09:32:01
综合看Anker超能充系列的性价比很高,并且与不仅和iPhone12/苹果<em>Mac</em>Book很配,而且适合多设备充电需求的日常使用或差旅场景,不管是安卓还是Switch同样也能用得上它,希望这次分享能给准备购入充电器的小伙伴们有所
2021-06-01 09:31:42
除了L4WUDU与吴亦凡已经多次共事,成为了明面上的厂牌成员,吴亦凡还曾带领20XXCLUB全队参加2020年的一场音乐节,这也是20XXCLUB首次全员合照,王嗣尧Turbo、陈彦希Regi、<em>Mac</em> Ova Seas、林渝植等人全部出场。然而让
2021-06-01 09:31:34
目前应用IPFS的机构:1 谷歌<em>浏览器</em>支持IPFS分布式协议 2 万维网 (历史档案博物馆)数据库 3 火狐<em>浏览器</em>支持 IPFS分布式协议 4 EOS 等数字货币数据存储 5 美国国会图书馆,历史资料永久保存在 IPFS 6 加
2021-06-01 09:31:24
开拓者的车机是兼容苹果和<em>安卓</em>,虽然我不怎么用,但确实兼顾了我家人的很多需求:副驾的门板还配有解锁开关,有的时候老婆开车,下车的时候偶尔会忘记解锁,我在副驾驶可以自己开门:第二排设计很好,不仅配置了一个很大的
2021-06-01 09:30:48
不仅是<em>安卓</em>手机,苹果手机的降价力度也是前所未有了,iPhone12也“跳水价”了,发布价是6799元,如今已经跌至5308元,降价幅度超过1400元,最新定价确认了。iPhone12是苹果首款5G手机,同时也是全球首款5nm芯片的智能机,它
2021-06-01 09:30:45