我的github

>>继承自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);
  }
}

 

posted on 2016-07-08 10:05  XiaoNiuFeiTian  阅读(615)  评论(0编辑  收藏  举报