android 画布画笔,安卓画笔笔锋的实现探索(一)

本篇文章已授权微信公众号 guolin_blog (郭霖)独家发布

20181207日更新博客,写这篇文章的时候,我对简书的写作技巧还不熟悉,现在更新下说明

写在前面的话:我就一直纠结啊,这种可以啊,没毛病啊,老铁,我就一直做啊做,实现的效果,就是一直Move事件中的笔的宽度都是一样的,是不是崩溃啊,的确很崩溃,最后我在想,能不能拿到按压值MotionEvent.getPressure();但是最后通过一查,这个方法的返回值是这样决定的:感应出用户的手指压力,当然具体的级别由驱动和物理硬件决定的,我一直用手写,这个值永远不变,奔溃,又一次崩溃,最后在研究一个opengl写的Demo的时候,我发现了一个真理:那就是,我要画多长,是用户手指决定的,但是它的Move事件中接受到的点的数量是和这个距离没有相对应的关系,啊哈哈,对不对,我接受了这个多点,但是我要画很长的线,是不是我的线就细了,但Move中的接受到的点数量一样,我画的距离短了,是不是线就粗了,这就是这个Demo的原理,顿时豁然开朗,春暖花开!

不逼逼,看效果,感觉我的书法还阔以,哈哈!!

设置笔宽度为60,效果如下

6746d68ef2c3

微信图片_20170910184918.png

6746d68ef2c3

image.png

这个效果明显一点,哈哈,是不是很有大师的写字风格

6746d68ef2c3

微信图片_20170902142924.jpg

实现这个效果,大体用了40个小时,熬了3天夜,我未来的女朋友给我作证,看了无数的文档,在git上有个哥们用opengGl3.0实现比我这个更牛逼的效果,但是发现在低端手机上会报错,原因是不支持openGL3.0,导致Apk装入失败,1.0的api有看不懂,你说我能怎么办,我也很绝望啊!同时感觉opengl更加节手机性能,but我错了,在低端手机上使用opengl简直就是噩梦,卡的一逼,算了不提了,此功能的实现还是基于安卓的Paint,通过事件去绘制路径。

1.创建DrawPenView类继承View

6746d68ef2c3

image.png

初始化笔,笔锋的效果,我个人尝试了使用三个笔,每次绘制的时候,三个笔一起绘制,根据手指的滑动速率的快慢去使其中的某个笔不用绘制,但是这个效果稀烂,所以view的还是用一只笔即可,

mPaint = new Paint();

mPaint.setColor(Color.parseColor("#FF4081"));

mPaint.setStrokeWidth(14);

mPaint.setStyle(Paint.Style.STROKE);

mPaint.setStrokeCap(Paint.Cap.ROUND);//结束的笔画为圆心

mPaint.setStrokeJoin(Paint.Join.ROUND);//连接处元

mPaint.setAlpha(0xFF);

mPaint.setAntiAlias(true);

mPaint.setStrokeMiter(1.0f);

初始化bitmap,和画布,画布在这里主要是生成一张bitmap的

private void initParameter(Context context) {

mContext = context;

DisplayMetrics dm = new DisplayMetrics();

((Activity) mContext).getWindowManager().getDefaultDisplay().getMetrics(dm);

mBitmap = Bitmap.createBitmap(dm.widthPixels, dm.heightPixels, Bitmap.Config.ARGB_8888);

//笔的控制类

mVisualStrokePen=new VisualStrokePen(mContext);

initPaint(mContext);

initCanvas();

}

private void initCanvas() {

mCanvas = new Canvas(mBitmap);

//设置画布的颜色的问题

mCanvas.drawColor(Color.TRANSPARENT);

}

重写onDraw()方法:由于项目需要,在这里我仅仅提供了两个方法:清除画布和绘制。扩展的功能有:返回上一步的绘制步骤,设置画笔的属性,mark笔,毛笔,钢笔,圆珠笔,铅笔等一切的控制都在这里进行

@Override

protected void onDraw(Canvas canvas) {

canvas.drawBitmap(mBitmap, 0, 0, mPaint);

switch (mCanvasCode) {

case CANVAS_NORMAL:

mVisualStrokePen.draw(canvas);

break;

case CANVAS_RESET:

reset();

break;

default:

Log.e(TAG, "onDraw" + Integer.toString(mCanvasCode));

break;

}

super.onDraw(canvas);

}

2.认识MotionEvent对象

当用户触摸屏幕时,将创建一个MontionEvent对象。MotionEvent包含了关于发生触摸的位置和时间的信息,以及触摸事件的其他细节。

/**

event.getAction() //获取触控动作比如ACTION_DOWN

event.getPointerCount(); //获取触控点的数量,比如2则可能是两个手指同时按压屏幕

event.getPointerId(nID); //对于每个触控的点的细节,我们可以通过一个循环执行getPointerId方法获取索引

event.getX(nID); //获取第nID个触控点的x位置,记录的第一个点为getX,getY

event.getY(nID); //获取第nID个点触控的y位置

event.getPressure(nID); //LCD可以感应出用户的手指压力,当然具体的级别由驱动和物理硬件决定的

event.getDownTime() //按下开始时间

event.getEventTime() // 事件结束时间

event.getEventTime()-event.getDownTime()); //总共按下时花费时间

* @param event

* @return

*/

@Override

public boolean onTouchEvent(MotionEvent event) {

//测试过程中,当使用到event的时候,产生了没有收到事件的问题,所以在这里需要obtian的一下

MotionEvent event2 = MotionEvent.obtain(event);

switch (event2.getActionMasked()) {

case MotionEvent.ACTION_DOWN:

setCanvasCode(CANVAS_NORMAL);

mVisualStrokePen.onDown(mVisualStrokePen.createMotionElement(event2));

break;

case MotionEvent.ACTION_MOVE:

mVisualStrokePen.onMove(mVisualStrokePen.createMotionElement(event2));

break;

case MotionEvent.ACTION_UP:

long time = System.currentTimeMillis();</

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值