Android自定义画线(模拟指针)
今天和大家分享一下自定义画线功能,效果其实和安卓里开发者模式下的“指针位置”功能类似的,大概就是一个空白的界面,随着手指移动不断画线,话不多说,码上~
创建空白的Activity、画笔画布
display = ScreenUtils.getDisplay(this);
//创建bitmap,宽 高,图片的参数
bitmap = Bitmap.createBitmap(display.getWidth(), display.getHeight() + 50, Bitmap.Config.ARGB_8888);
//创建画笔和画板
paint = new Paint();
paint.setColor(Color.GREEN);
canvas = new Canvas(bitmap);
//在bitmap上作画
canvas.drawBitmap(bitmap, new Matrix(), paint);
监听屏幕事件
这里我们实现两个效果,第一个是只画一条线,第二个是可以多点画线
//方法一:单点画线
public boolean onTouchEvent(MotionEvent event) {
switch (event.getAction()) {
case MotionEvent.ACTION_DOWN:
x = event.getX();
y = event.getY();
break;
case MotionEvent.ACTION_MOVE:
move_x = event.getX();
down_Y = event.getY();
canvas.drawLine(x, y, move_x, down_Y, paint);
x = move_x;
y = down_Y;
imageView.setImageBitmap(bitmap);
break;
case MotionEvent.ACTION_UP:
break;
}
return true;
}
上面就是单点画线的核心代码,记录按下的坐标,开始画线,然后在记录移动后的坐标并通过imageView显示即可,ACTION_MOVE是不断触发的。
多点画线
重点依然是onTouchEvent,和单点不一样的是,想要实现多点画线,我们需要监听ACTION_POINTER_DOWN和ACTION_MASK事件,下面贴上完整代码
package com.app.activity.set.manager;
import android.graphics.Bitmap;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Matrix;
import android.graphics.Paint;
import android.view.Display;
import android.view.MotionEvent;
import android.widget.ImageView;
import com.app.R;
import com.app.activity.BaseActivity;
import com.app.util.L;
import com.app.util.ScreenUtils;
import butterknife.BindView;
public class ScreenTestActivity extends BaseActivity {
@BindView(R.id.imageView)
ImageView imageView;
private Paint paint;
private Canvas canvas;
float x = 0;
float y = 0;
float x1 = 0;
float y1 = 0;
float move_x = 0;
float down_Y = 0;
private Bitmap bitmap;
private float[] mStartXs = new float[10];
private float[] mStartYs = new float[10];
private float[] mEndXs = new float[10];
private float[] mEndYs = new float[10];
private Display display;
@Override
protected int onCreateViewId() {
return R.layout.activity_screen_test;
}
@Override
protected void initView() {
display = ScreenUtils.getDisplay(this);
//创建bitmap,宽 高,图片的参数
bitmap = Bitmap.createBitmap(display.getWidth(), display.getHeight() + 50, Bitmap.Config.ARGB_8888);
//创建画笔和画板
paint = new Paint();
paint.setColor(Color.GREEN);
//方法一:单点画线
//canvas = new Canvas(bitmap);
//在bitmap上作画
//canvas.drawBitmap(bitmap, new Matrix(), paint);
}
@Override
protected void setListener() {
}
//方法二:多点画线
public boolean onTouchEvent(MotionEvent event) {
switch (event.getAction() & MotionEvent.ACTION_MASK) {
case MotionEvent.ACTION_DOWN:
resetBitmap(event); //每次开始画线重置之前的线
downDrawPoint(event); //开始按下时画点
//记录每次第一个手指按下的坐标,用做双击退出Activity
x = event.getX();
y = event.getY();
if (x != 0 && x1 != 0 && Math.abs(x - x1) < 10 && Math.abs(y - y1) < 10) {
finish();
}
break;
case MotionEvent.ACTION_POINTER_DOWN:
//当屏幕上已经有一个点被按住,此时再按下其他点时触发
downDrawPoint(event);
break;
case MotionEvent.ACTION_MOVE:
try {
for (int i = 0; i < event.getPointerCount(); i++) {
int pointerId = event.getPointerId(i);
mEndXs[pointerId] = event.getX(i);//获取手指移动的x坐标
mEndYs[pointerId] = event.getY(i);//获取手指移动的y坐标
canvas.drawLine(mStartXs[pointerId], mStartYs[pointerId], mEndXs[pointerId], mEndYs[pointerId], paint);//在画布上画线
mStartXs[pointerId] = mEndXs[pointerId]; //将移动后的坐标作为起点
mStartYs[pointerId] = mEndYs[pointerId];
}
//显示画线
imageView.setImageBitmap(bitmap);
} catch (Exception e) {
e.printStackTrace();
}
break;
case MotionEvent.ACTION_UP:
//记录每次第一个手指按下的坐标,用做双击退出Activity
x1 = event.getX();
y1 = event.getY();
break;
}
return true;
}
private void resetBitmap(MotionEvent event) {
bitmap = Bitmap.createBitmap(display.getWidth(), display.getHeight() + 50, Bitmap.Config.ARGB_8888);
canvas = new Canvas(bitmap);
canvas.drawBitmap(bitmap, new Matrix(), paint);
}
private void downDrawPoint(MotionEvent event) {
try {
for (int i = 0; i < event.getPointerCount(); i++) {
mStartXs[i] = event.getX(i);
mStartYs[i] = event.getY(i);
//canvas.drawPoint(mStartXs[i], mStartYs[i], paint);
canvas.drawRect(mStartXs[i] - 3, mStartYs[i] - 3, mStartXs[i] + 3, mStartYs[i] + 3, paint);
}
} catch (Exception e) {
e.printStackTrace();
}
}
}
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
tools:context=".activity.set.manager.ScreenTestActivity">
<ImageView
android:id="@+id/imageView"
android:layout_width="match_parent"
android:layout_height="match_parent" />
</LinearLayout>
BaseActivity是我封装的类,onCreateViewId和initView大家应该知道是啥吧,event.getPointerCount()返回触控点的个数,getPointerId是触控点的标记,上面我不再initView()中创建画布和bitmap,而是使用resetBitmap(event)创建是为了每次画线都可以消除之前的画线,如果需要保留之前的画线,可以注销resetBitmap(event)然后在initView()创建画布和bitmap即可。
实现的方法有很多种,我觉得这是其中比较简单的一种吧,整体来说这个功能还是比较简单的,欢迎留言交流哦~