参考博客:https://www.cnblogs.com/hao-dotnet/p/3269149.html
代码很简单,参考博客中有些错误已改正。

step1:新建ViewPoint类

该类用于存放点坐标,就是手指接触ImageView并移动时的坐标

package com.example.handwritingimageview;public class ViewPoint {    float x;    float y;}

step2:新建Line类

顾名思义,该类存放点的集合,即一条线

//表示一条线public class Line {    ArrayList<ViewPoint> points = new ArrayList<>();}

step3:编写HandWritingImageView类

该类继承AppCompatImageView,先重写父类构造器,再重写onTouchEvent和onDraw方法,在onTouchEvent方法中多次使用了 invalidate()这个方法,这个方法是用来触发onDraw方方法进行画图。

package com.example.handwritingimageview;import android.content.Context;import android.graphics.Canvas;import android.graphics.Paint;import android.util.AttributeSet;import android.util.Log;import android.view.MotionEvent;import android.widget.ImageView;import androidx.appcompat.widget.AppCompatImageView;import androidx.core.widget.ImageViewCompat;import java.util.ArrayList;public class HandWritingImageView extends AppCompatImageView {    private Paint paint = new Paint();    //当前正在画的线    private Line current = new Line();    public HandWritingImageView(Context context) {        super(context);    }    public HandWritingImageView(Context context, AttributeSet attrs) {        super(context, attrs);    }    public HandWritingImageView(Context context, AttributeSet attrs, int defStyleAttr) {        super(context, attrs, defStyleAttr);    }    //画过的所有线    private ArrayList<Line> lines = new ArrayList<Line>();    @Override    public boolean onTouchEvent(MotionEvent event) {        //获取坐标        float clickX = event.getX();        float clickY = event.getY();        if (event.getAction() == MotionEvent.ACTION_DOWN) {            //刷新屏幕            invalidate();            return true;        }else if (event.getAction() == MotionEvent.ACTION_MOVE){            ViewPoint point = new ViewPoint();            point.x = clickX;            point.y = clickY;            Log.d("444", "clickX: "+clickX);            Log.d("444", "clickY: "+clickY);            //在移动时添加所有经过的点            current.points.add(point);            Log.d("222", "current.points.size(): "+current.points.size());            invalidate();            return true;        }else if (event.getAction() == MotionEvent.ACTION_UP){            //添加画过的线            lines.add(current);            Log.d("222", "lines.size(): "+lines.size());            current = new Line();            invalidate();        }        return super.onTouchEvent(event);    }    @Override    protected void onDraw(Canvas canvas) {        super.onDraw(canvas);        //画出之前所有的线        for (int i = 0; i < lines.size(); i++)        {            drawLine(canvas, lines.get(i));        }        //画出当前的线        drawLine(canvas, current);    }    private void drawLine(Canvas canvas, Line line)    {        for(int i = 0; i < line.points.size()-1; i++){            float x = line.points.get(i).x;            float y = line.points.get(i).y;            float nextX = line.points.get(i+1).x;            float nextY = line.points.get(i+1).y;            canvas.drawLine(x,y,nextX,nextY,paint);        }    }}

step4:编写xml

<?xml version="1.0" encoding="utf-8"?><LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"    android:layout_width="match_parent"    android:layout_height="match_parent">    <com.example.handwritingimageview.HandWritingImageView        android:id="@+id/im_view"        android:layout_width="match_parent"        android:layout_height="match_parent" />LinearLayout>

效果图

更多相关文章

  1. Android(安卓)Wear开发 - 数据通讯 - 第一节 : 连接数据层
  2. Android中home键和back键区别实例分析
  3. 安卓开发中Android消息机制详解
  4. Android(安卓)UI开发第三十篇――使用Fragment构建灵活的桌面
  5. 坐标地址互找
  6. Unity与Android对比学习之生命周期方法
  7. Unity导出Android在高通骁龙800以上CPU概率性崩溃解决方法研究
  8. Android中AsyncTask的入门使用学习指南
  9. Android使用Service实现简单音乐播放实例

随机推荐

  1. 【Android】关于android:divider 的用法
  2. android常用颜色
  3. android 的button
  4. Binder子系统之调试分析(三)
  5. android加分割线
  6. Android使用贝塞尔曲线画心形
  7. Android(安卓)解决WebView支持WebGL的兼
  8. Android系列之Android 命令行手动编译打
  9. Android shell命令大全
  10. Android软键盘弹出,界面整体上移的问题