>>继承自View

>>使用Canvas绘图

每次View组件上的图形状态数据发生了改变,都应该通知View组件重写调用onDraw(Canvas canvas)方法重绘该组件。通知View重绘可调用invalidate(在UI线程中)或postInvalidate(在非UI线程中)。

采用双缓冲实现绘图板。表现上看起来是随用户在触摸屏上自由地画曲线,实际上依然利用的是Canvas的drawLine方法画直线。借助于Android提供的Path类,可以非常方便地实现这种效果。

需要指出的是,如果程序每次都只是从上次拖动事件的发生点绘一条直线到本次拖动事件的发生点,那么用户前面绘制的就会丢失。为了保留用户之前绘制的内容,程序要借助于“双缓冲”技术。

所谓双缓冲技术其实很简单:当程序需要在指定View上进行绘制时,程序并不直接绘制到该View组件上,而是先绘制到一个内存中的Bitmap图片(这就是缓冲)上,等到内存中的Bitmap绘制好之后,再一次性地将Bitmap绘制到View组件上。

该程序需要一个自定义View,该View的代码如下。

public class DrawView extends View {
float preX;
float preY;
private Path path;
//记住所有的Path,允许返回1步
private Path paths[] = new Path[1];
public Paint paint = null;
final int VIEW_WIDTH = 320;
final int VIEW_HEIGHT = 480;
//定义一个内存中的图片,该图片将作为缓冲区
Bitmap cacheBitmap = null;
//定义cacheBitmap上的Canvas对象
Canvas cacheCanvas = null; public DrawView(Context context, AttributeSet set)
{
super(context, set);
//创建一个与该View相同大小的缓存区
cacheBitmap = Bitmap.createBitmap(VIEW_WIDTH, VIEW_HEIGHT, Config.ARGB_8888);
cacheCanvas = new Canvas();
path = new Path();
//设置cacheCanvas将会绘制到内存中的cacheBitmap上
cacheCanvas.setBitmap(cacheBitmap);
//设置画笔的颜色
paint = new Paint(Paint.DITHER_FLAG);
paint.setColor(Color.RED);
//设置画笔风格
paint.setStyle(Paint.Style.STROKE);
paint.setStrokeWidth(1);
//反锯齿
paint.setAntiAlias(true);
paint.setDither(true);
}
@Override
public boolean onTouchEvent(MotionEvent event)
{
//获取拖动事件的发生位置
float x = event.getX();
float y = event.getY();
switch(event.getAction())
{
case MotionEvent.ACTION_DOWN:
path.moveTo(x, y);
preX = x;
preY = y;
break;
case MotionEvent.ACTION_MOVE:
path.quadTo(preX, preY, x, y);
preX = x;
preY = y;
break;
case MotionEvent.ACTION_UP:
cacheCanvas.drawPath(path, paint);
paths[0] = path;
path.reset();
break;
}
invalidate();
//返回true表明处理方法已经处理该事件
return true;
}
@Override
public void onDraw(Canvas canvas)
{
Paint bmpPaint = new Paint();
//将cacheBitmap绘制到该View组件上
canvas.drawBitmap(cacheBitmap, 0, 0, bmpPaint);
//沿着path绘制
canvas.drawPath(path, paint);
}
}

Android绘图板的开发的更多相关文章

  1. Android应用安全开发之浅谈加密算法的坑

      <Android应用安全开发之浅谈加密算法的坑> 作者:阿里移动安全@伊樵,@舟海 阿里聚安全,一站式解决应用开发安全问题     Android开发中,难免会遇到需要加解密一些数据内 ...

  2. [转]Android样式的开发:shape篇

    转载自Keegan小钢原文链接:http://keeganlee.me/post/android/20150830 Android样式的开发:shape篇Android样式的开发:selector篇A ...

  3. Android之NDK开发(转)

    Android之NDK开发 一.NDK产生的背景 Android平台从诞生起,就已经支持C.C++开发.众所周知,Android的SDK基于Java实现,这意味着基于Android SDK进行开发的第 ...

  4. Android移动APP开发笔记——最新版Cordova 5.3.1(PhoneGap)搭建开发环境

    引言 简单介绍一下Cordova的来历,Cordova的前身叫PhoneGap,自被Adobe收购后交由Apache管理,并将其核心功能开源改名为Cordova.它能让你使用HTML5轻松调用本地AP ...

  5. 提供给Android和iOS开发人员的UWP移植向导

    (此文章同时发表在本人微信公众号"dotNET每日精华文章",欢迎右边二维码来关注.) 题记:前几天微软发布了一个针对Android和iOS开发人员理解Windows Apps概念 ...

  6. Android插件化开发

    客户端开发给人的印象往往是小巧,快速奔跑.但随着产品的发展,目前产生了大量的门户型客户端.功能模块持续集成,开发人员迅速增长.不同的开发小组开发不同的功能模块,甚至还有其他客户端集成进入.能做到功能模 ...

  7. (译)cocos2d-x跨android&ios平台开发入门教程

    免责申明(必读!):本博客提供的所有教程的翻译原稿均来自于互联网,仅供学习交流之用,切勿进行商业传播.同时,转载时不要移除本申明.如产生任何纠纷,均与本博客所有人.发表该翻译稿之人无任何关系.谢谢合作 ...

  8. Android之NDK开发

    转自:http://www.cnblogs.com/devinzhang/archive/2012/02/29/2373729.html 一.NDK产生的背景 Android平台从诞生起,就已经支持C ...

  9. [原]零基础学习在Android进行SDL开发系列文章

    [原]零基础学习SDL开发之移植SDL2.0到Android [原]零基础学习SDL开发之在Android使用SDL2.0显示BMP图 [原]零基础学习SDL开发之在Android使用SDL2.0显示 ...

随机推荐

  1. 迷你MVVM框架 avalonjs 学习教程19、avalon历史回顾

    avalon最早发布于2012.09.15,当时还只是mass Framework的一个模块,当时为了解决视图与JS代码的分耦,参考knockout开发出来. 它的依赖收集机制,视图扫描,绑定的命名d ...

  2. 利用 setInterval 确定用户的动作是否停止

    最近遇到一个问题,对于某一个持续的动作,希望能够知晓用户何时停止这个动作, 比如说 我们通过注册onresize事件,去监听浏览器窗口变化的事件,在这个事件里面,我们可能要执行大量的计算去确定窗口变化 ...

  3. 实现spring IOC的常见二种方法 setter注入与构造器注入

    案例: beans.xml配置 <?xml version="1.0" encoding="UTF-8"?><beansxmlns=" ...

  4. sql语句执行的时间

    统计mysql里每条SQL语句执行的时间 收藏 CrazyHarry 发表于 2年前 阅读 3785 收藏 8 点赞 3 评论 3 Google.Github 双重认证前端课程,独家硅谷内容,每周直播 ...

  5. Mysql 多个字段查找重复数

    delete FROM `test_table` WHERE id in (SELECT id,concat(user_id,user_id2) as __fFROM `test_table` whe ...

  6. JAVA——遍历

    关于遍历,发现了个坑. 详见如下: package com.fxl.test; import java.util.ArrayList; import java.util.Iterator; impor ...

  7. 88. Merge Sorted Array 后插

    合并两个排序的整数数组A和B变成一个新的数组.给出A=[1,2,3,4],B=[2,4,5,6],返回 [1,2,2,3,4,4,5,6] 假设A具有足够的空间(A数组的大小大于或等于m+n)去添加B ...

  8. swift 官方文档

    swift 官方文档 https://swift.org/blog/

  9. Python学习day5作业

    目录 Python学习day5作业 ATM和购物商城 1. 程序说明 2. 基本流程图 3. 程序测试帐号 4. 程序结构: 5. 程序测试 title: Python学习day5作业 tags: p ...

  10. js无刷新提交表单

    $("#form1").attr("target", "frameFile"); $("#form1").submit( ...