实例介绍
【实例简介】
【实例截图】
【核心代码】
package me.jrl.demo36; 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.graphics.PorterDuff; import android.graphics.PorterDuffXfermode; import android.util.AttributeSet; import android.view.MotionEvent; import android.view.View; import java.util.ArrayList; import java.util.List; public class DrawingBoard extends View { //画图的模式(默认是画笔) private DrawMode mDrawMode = DrawMode.PaintMode; //画笔 private Paint mPaint; //画笔颜色 private int mPaintColor = Color.RED; //画笔宽度 private int mPaintSize = dip2px(5); //橡皮擦宽度 private int mEraserSize = dip2px(36); //缓冲的位图 private Bitmap mBufferBitmap; //缓冲的画布 private Canvas mBufferCanvas; //当前控件的宽度 private int mWidth; //当前控件的高度 private int mHeight; //画布的颜色 private int mCanvasColor = Color.WHITE; //上次的位置 private float mLastX; private float mLastY; //路径 private Path mPath; //设置图形混合模式为清除 private PorterDuffXfermode mEraserMode = new PorterDuffXfermode(PorterDuff.Mode.DST_OUT); //保存的路径 private List<DrawPathInfo> savePaths; //当前的路径 private List<DrawPathInfo> currPaths; //最多保存20条路径 private int MAX_PATH = 20; public DrawingBoard(Context context) { this(context,null); } public DrawingBoard(Context context, AttributeSet attrs) { this(context, attrs,0); } public DrawingBoard(Context context, AttributeSet attrs, int defStyleAttr) { super(context, attrs, defStyleAttr); initPaint(); initPath(); } //获取屏幕像素,实现外部赋值控制控件大小 public int dip2px(float dipValue){ final float scale = this.getResources().getDisplayMetrics().density; return (int)(dipValue*scale 0.5f); } //重新测量宽高 @Override protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { super.onMeasure(widthMeasureSpec, heightMeasureSpec); mWidth = MeasureSpec.getSize(widthMeasureSpec); mHeight = MeasureSpec.getSize(heightMeasureSpec); setMeasuredDimension(mWidth,mHeight); initCanvas(); } private void initPath(){ mPath = new Path(); savePaths = new ArrayList<>(); currPaths = new ArrayList<>(); } private void initCanvas(){ //创建一个BITMAP mBufferBitmap = Bitmap.createBitmap(mWidth,mHeight, Bitmap.Config.ARGB_8888); mBufferCanvas = new Canvas(mBufferBitmap); mBufferCanvas.drawColor(mCanvasColor); } private void initPaint(){ //设置画笔抗锯齿和抖动 mPaint = new Paint(Paint.ANTI_ALIAS_FLAG|Paint.DITHER_FLAG); //设置画笔填充方式为只描边 mPaint.setStyle(Paint.Style.STROKE); //设置画笔颜色 mPaint.setColor(mPaintColor); //设置画笔宽度 mPaint.setStrokeWidth(mPaintSize); //设置圆形线帽 mPaint.setStrokeJoin(Paint.Join.ROUND); //设置线段连接处圆角 mPaint.setStrokeCap(Paint.Cap.ROUND); } @Override protected void onDraw(Canvas canvas) { super.onDraw(canvas); canvas.drawBitmap(mBufferBitmap,0,0,null); } @Override public boolean onTouchEvent(MotionEvent event) { float x = event.getX(); float y = event.getY(); switch (event.getAction()){ case MotionEvent.ACTION_DOWN: mLastX = x; mLastY = y; mPath.moveTo(mLastX,mLastY); break; case MotionEvent.ACTION_MOVE: //画出路径 mPath.quadTo(mLastX,mLastY,(mLastX x)/2,(mLastY y)/2); mBufferCanvas.drawPath(mPath,mPaint); invalidate(); mLastX = x; mLastY = y; break; case MotionEvent.ACTION_UP: //保存路径 saveDrawPaths(); mPath.reset(); break; } return true; } private void saveDrawPaths(){ if (savePaths.size() == MAX_PATH){ savePaths.remove(0); } savePaths.clear(); savePaths.addAll(currPaths); Path cachePath = new Path(mPath); Paint cachePaint = new Paint(mPaint); savePaths.add(new DrawPathInfo(cachePaint,cachePath)); currPaths.add(new DrawPathInfo(cachePaint,cachePath)); } /** * 设置画笔模式 * */ public void setMode(DrawMode mode){ if (mode != mDrawMode){ if (mode == DrawMode.EraserMode){ mPaint.setStrokeWidth(mEraserSize); mPaint.setXfermode(mEraserMode); mPaint.setColor(mCanvasColor); } else{ mPaint.setXfermode(null); mPaint.setColor(mPaintColor); mPaint.setStrokeWidth(mPaintSize); } mDrawMode = mode; } } public DrawMode getMode(){ return mDrawMode; } /** * 下一步 反撤销 * */ public void nextStep(){ if (currPaths != savePaths){ if (savePaths.size()>currPaths.size()){ currPaths.add(savePaths.get(currPaths.size())); redrawBitmap(); } } } /** * 重绘位图 * */ private void redrawBitmap(){ mBufferBitmap.eraseColor(Color.TRANSPARENT); for (int i = 0;i<currPaths.size();i ){ DrawPathInfo path = currPaths.get(i); mBufferCanvas.drawPath(path.getPath(),path.getPaint()); } invalidate(); } /** * 保存图片 * */ /** * 擦除画布 * */ public void clean(){ savePaths.clear(); currPaths.clear(); //将位图擦成透明的 mBufferBitmap.eraseColor(Color.TRANSPARENT); invalidate(); } }
好例子网口号:伸出你的我的手 — 分享!
小贴士
感谢您为本站写下的评论,您的评论对其它用户来说具有重要的参考价值,所以请认真填写。
- 类似“顶”、“沙发”之类没有营养的文字,对勤劳贡献的楼主来说是令人沮丧的反馈信息。
- 相信您也不想看到一排文字/表情墙,所以请不要反馈意义不大的重复字符,也请尽量不要纯表情的回复。
- 提问之前请再仔细看一遍楼主的说明,或许是您遗漏了。
- 请勿到处挖坑绊人、招贴广告。既占空间让人厌烦,又没人会搭理,于人于己都无利。
关于好例子网
本站旨在为广大IT学习爱好者提供一个非营利性互相学习交流分享平台。本站所有资源都可以被免费获取学习研究。本站资源来自网友分享,对搜索内容的合法性不具有预见性、识别性、控制性,仅供学习研究,请务必在下载后24小时内给予删除,不得用于其他任何用途,否则后果自负。基于互联网的特殊性,平台无法对用户传输的作品、信息、内容的权属或合法性、安全性、合规性、真实性、科学性、完整权、有效性等进行实质审查;无论平台是否已进行审查,用户均应自行承担因其传输的作品、信息、内容而可能或已经产生的侵权或权属纠纷等法律责任。本站所有资源不代表本站的观点或立场,基于网友分享,根据中国法律《信息网络传播权保护条例》第二十二与二十三条之规定,若资源存在侵权或相关问题请联系本站客服人员,点此联系我们。关于更多版权及免责申明参见 版权及免责申明
网友评论
我要评论