自定义viewAndroid自定义View

自定义view基础 简单画图板的实现

2019-07-11  本文已影响6人  总会颠沛流离

废话少说 直接上效果 图

效果图

image.png
绘制的逻辑

这个相信大家都不陌生,很多手机都会自带一个给用户涂鸦的画图板,这里我们就来写个简单的 例子,首先我们分析下,实现这个东东的一些逻辑:

Q1:这个画板放在哪里?

答:View里,我们自定义一个View,在onDraw()里完成绘制,另外View还有个onTouchEvent的方法, 我们可以在获取用户的手势操作!

Q2.需要准备些什么?

答:一只画笔(Paint),一块画布(Canvas),一个路径(Path)记录用户绘制路线; 另外划线的时候,每次都是从上次拖动时间的发生点到本次拖动时间的发生点!那么之前绘制的 就会丢失,为了保存之前绘制的内容,我们可以引入所谓的"双缓冲"技术: 其实就是每次不是直接绘制到Canvas上,而是先绘制到Bitmap上,等Bitmap上的绘制完了, 再一次性地绘制到View上而已!

Q3.具体的实现流程?

答:初始化画笔,设置颜色等等一些参数;在View的onMeasure()方法中创建一个View大小的Bitmap, 同时创建一个Canvas;onTouchEvent中获得X,Y坐标,做绘制连线,最后invalidate()重绘,即调用 onDraw方法将bitmap的东东画到Canvas上!

代码:
  package com.example.guide;

  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.util.AttributeSet;
  import android.view.MotionEvent;
  import android.view.View;

  ;

  /**
 * Created by Android Studio.
 * User: 薛志辉
 * Date: 2019/7/11
 * Describe: recharge
 */
 public class MyView extends View {


private Path path;
private Paint paint;
private Canvas canvas;
private Bitmap bitmap;


private int mLastX;
private int mLastY;
public MyView(Context context) {
    super(context);
}

public MyView(Context context,  AttributeSet attrs) {
    super(context, attrs);
    init();
}

private void init() {
    path = new Path();
    paint = new Paint();
    paint.setColor(Color.GREEN);
    paint.setAntiAlias(true);
    paint.setDither(true);
    paint.setStyle(Paint.Style.STROKE);
    paint.setStrokeJoin(Paint.Join.ROUND);//结合处为圆角
    paint.setStrokeCap(Paint.Cap.ROUND);//设置转弯处为圆角
    paint.setStrokeWidth(20);//设置画笔的宽度
}

@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
    super.onMeasure(widthMeasureSpec, heightMeasureSpec);
    int measuredHeight = getMeasuredHeight();
    int measuredWidth = getMeasuredWidth();
   //以src为原图,创建新的图像,指定新图像的高宽以及是否变。
    bitmap = Bitmap.createBitmap(measuredWidth, measuredHeight, Bitmap.Config.ARGB_8888);
    canvas = new Canvas(bitmap);


}

@Override
protected void onDraw(Canvas canvas) {
    super.onDraw(canvas);
       drawPath();
       canvas.drawBitmap(bitmap,0,0,null);
}
public void drawPath(){
    canvas.drawPath(path,paint);
}

@Override
public boolean onTouchEvent(MotionEvent event) {
    int action = event.getAction();
    int x = (int) event.getX();
    int y = (int) event.getY();
    switch (action) {
        case MotionEvent.ACTION_DOWN:
          mLastX=x;
          mLastY=y;
          //移动起点  移动下一次操作的起点位置
          path.moveTo(mLastX,mLastY);
          break;
        case MotionEvent.ACTION_MOVE:
            //该方法返回x的绝对值
            int dx = Math.abs(x - mLastX);
            int dy = Math.abs(y - mLastY);
            if (dx>3 ||dy>3) {
                //连接直线  添加上一个点到当前点之间的直线到Path
                path.lineTo(x,y);
            }
            mLastY=y;
            mLastX=x;


            break;
    }
    //刷新界面
    invalidate();
    return true;
}
 }
上一篇下一篇

猜你喜欢

热点阅读