先上图:

关键是在检測到手指移动的时候用mPath.quadTo的方法,android sdk解释是:

Add a quadratic bezier from the last point, approaching control point (x1,y1), and ending at (x2,y2). If no moveTo() call has been made for this contour, the first point is automatically set to (0,0).

中文是用贝塞尔曲线链接了(x1,y1),(x2,y2)这两个点,假设没有moveTo()这种方法调用的话,第一个点默觉得(0,0)

android绘图是用Canvas的API,如画一个实心的矩形,能够用在重写一个View的onDraw():

<span style="white-space:pre">		</span>Rect rect = new Rect(100,100,500,500);
mPaint.setStrokeWidth(5); //设置画笔的粗细
mPaint.setColor(Color.RED); //设置画笔的颜色
mPaint.setStyle(Style.FILL); //填充整个图形
mPaint.setAntiAlias(true); //抗锯齿效果
canvas.drawRect(rect, mPaint);

对于检測手指的移动,我们能够用onTouchEvent来实现:

	private float mX, mY;
private float mOppositeX, mOppositeY;
private static final float TOUCH_TOLERANCE = 4; //当手指移动超过4时我们才去set Path @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);
if(isMirrorDraw) {
touch_opposite_start(x, y);
}
invalidate();
break;
case MotionEvent.ACTION_MOVE:
touch_move(x, y);
if(isMirrorDraw) {
touch_opposite_move(x, y);
}
invalidate();
break;
case MotionEvent.ACTION_UP:
touch_up();
if(isMirrorDraw) {
touch_opposite_up();
}
invalidate();
break;
}
return true;
} 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);
mX = x;
mY = y;
}
} private void touch_up() {
mPath.lineTo(mX, mY);
mCanvas.drawPath(mPath, mPaint);
mPath.reset();
} private void touch_opposite_up() {
mOppositePath.lineTo(mOppositeX, mY);
mCanvas.drawPath(mOppositePath, mOppoPaint);
mOppositePath.reset();
} private void touch_opposite_move(float x, float y) {
float oppositeX = OppositeDrawActivity.screenWidth - x; //<span style="font-family: Arial, Helvetica, sans-serif;">OppositeDrawActivity.screenWidth是屏幕宽度</span>
float dx = Math.abs(oppositeX - mOppositeX);
float dy = Math.abs(y - mY);
if (dx >= TOUCH_TOLERANCE || dy >= TOUCH_TOLERANCE) {
mOppositePath.quadTo(mOppositeX, mY, (mOppositeX + oppositeX) / 2, (y + mY) / 2);
mOppositeX = oppositeX;
mY = y;
}
} private void touch_opposite_start(float x, float y) {
mOppositePath.reset();
float oppositeX = OppositeDrawActivity.screenWidth - x;
mOppositePath.moveTo(oppositeX, y);
mOppositeX = oppositeX; }

然后重写onDraw():

@Override
protected void onDraw(Canvas canvas) {
canvas.drawColor(0xFFAAAAAA);
canvas.drawBitmap(mBitmap, 0, 0, mBitmapPaint);
canvas.drawPath(mPath, mPaint);
if(isMirrorDraw) {
canvas.drawPath(mOppositePath, mOppoPaint);
}
}

代码能够在http://download.csdn.net/detail/baidu_nod/7572549下载

创建android画笔程序的样例(有镜面效果)的更多相关文章

  1. MapGuide应用程序演示样例——你好,MapGuide!

    图 3‑4显示了基于MapGuide的Web应用程序的开发流程,整个开发流程能够分为五个阶段.图中,矩形代表任务,椭圆形被任务使用的或被任务创建的实体,箭头代表数据流. 1) 载入文件类型的数据,配置 ...

  2. 【UNIX网络编程(三)】TCP客户/server程序演示样例

    上一节给出了TCP网络编程的函数.这一节使用那些基本函数编写一个完毕的TCP客户/server程序演示样例. 该样例运行的过程例如以下: 1.客户从标准输入读入一行文本,并写给server. 2.se ...

  3. 使用Android编写录制视频小程序演示样例

    主要实现录制功能的类:Camera类和MediaRecorder类.功能描写叙述:首先进入视频录制界面,点击录像button进入录像功能界面,点击录制開始录制视频, 点击停止button,将录制的视频 ...

  4. 基于Android Fragment功能的样例

    通过近期空暇时候对Fragment的学习,尝试着写了一个小Demo,将在开发的时候能经常使用到的Fragment知识放在一起,写过了这个Demo对Android Fragment的了解更加深入了,以后 ...

  5. android一个上传图片的样例,包含怎样终止上传过程,假设在上传的时候更新进度条(一)

    先上效果图: Layout为: <? xml version="1.0" encoding="utf-8"?> <LinearLayout x ...

  6. android发送短信样例

    Android应用开发中我们经常须要发送手机短信.这对于android平台来说,是最简单只是的功能了,无需太多代码,也无需自己定义代码,仅仅须要调用android提供的消息管理类SmsManager就 ...

  7. 使用JavaScript定义一个微信小程序插件样例

    var wxTimer = new wxTimer({ beginTime: "00:00:20", complete: function () { wx.redirectTo({ ...

  8. Android之——流量管理程序演示样例

    转载请注明出处:http://blog.csdn.net/l1028386804/article/details/47680811 眼下.市面上有非常多管理手机流量的软件,能够让用户实时获取到自己手机 ...

  9. Android应用程序请求SurfaceFlinger服务创建Surface的过程分析

    文章转载至CSDN社区罗升阳的安卓之旅,原文地址:http://blog.csdn.net/luoshengyang/article/details/7884628 前面我们已经学习过Android应 ...

随机推荐

  1. HDU Wolf and Rabbit

    Description There is a hill with n holes around. The holes are signed from 0 to n-1. A rabbit must h ...

  2. 为经典版eclipse增加web and JavaEE插件

    链接地址:http://jingyan.baidu.com/article/f25ef2546cd0e2482d1b825d.html 为经典版eclipse增加web and JavaEE插件 百度 ...

  3. 监听手机晃动(摇一摇)SensorEventListener

    import android.content.Context; import android.hardware.Sensor; import android.hardware.SensorEvent; ...

  4. EasyUI - DataGrid 组建 - [ 删除,修改 ]

    效果: html代码: <div style="padding-top: 50px; width: 800px; margin: 0 auto;"> <!--使用 ...

  5. CSS中的!important属性用法

    关于CSS的运用技巧有很多, 今天主要探讨一下CSS中 !important 这个属性的用法.在CSS的使用中,遇到最多的问题就是不同浏览器之间的兼容问题. 由于IE并不严格执行W3C标准, 而又几乎 ...

  6. 史上最全的java随机数/字符串生成算法(转)

    代码如下: package com.zuidaima.core.util; import java.util.Random; public class RandomUtil { public stat ...

  7. 我在北京找工作(五):备战阿里巴巴java笔试<1>:筑基

    @@@2013年9月11日 还在北京昌平区@@@ 好几天没有往博客上贴我的面试备战笔记了,今天开始分享一下备战阿里巴巴校招的笔经,当然重点是java方向的题目~. 插一段2014年阿里巴巴校招的消息: ...

  8. 深入理解extern使用方法

    一. extern做变量声明 l  声明externkeyword的全局变量和函数可以使得它们可以跨文件被訪问. 我们一般把全部的全局变量和全局函数的实现都放在一个*.cpp文件中面,然后用一个同名的 ...

  9. 解决VTune错误.../lib64/libstdc++.so.6: version `GLIBCXX_3.4.14&#39; not found (required by ...)

    错误信息及出现情景: 在export环境变量LD_PRELOAD=$XTERN_ROOT/dync_hook/interpose.so后,再执行amplxe-gui,出现上述错误.新增的动态链接库对V ...

  10. PHP开发-上传文件

    <?php /****************************************************************************** 参数说明: $max_ ...