当前位置:   article > 正文

自定义View之Shader-很简单的一个类_android 自定义view实现边缘虚化

android 自定义view实现边缘虚化

资料

https://blog.csdn.net/aigestudio/article/details/41799811

Shader子类

在这里插入图片描述

BitmapShader

构造方法

    /**
     * Call this to create a new shader that will draw with a bitmap.
     *
     * @param bitmap The bitmap to use inside the shader
     * @param tileX The tiling mode for x to draw the bitmap in.
     * @param tileY The tiling mode for y to draw the bitmap in.
     */
    public BitmapShader(@NonNull Bitmap bitmap, @NonNull TileMode tileX, @NonNull TileMode tileY) {
        this(bitmap, tileX.nativeInt, tileY.nativeInt);
    }
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10

设置BitmapShader之前
在这里插入图片描述

设置BitmapShader之后
在这里插入图片描述

private fun drawBitmapShaderView(canvas: Canvas) {
    val paint = Paint(Paint.ANTI_ALIAS_FLAG or Paint.DITHER_FLAG)
        .apply {
            this.color = Color.RED
            this.strokeWidth = 5F
        }
    val bitmap = BitmapFactory.decodeResource(resources, R.mipmap.ic_launcher_round)
    //paint.setShader(BitmapShader(bitmap, Shader.TileMode.CLAMP, Shader.TileMode.CLAMP))
    canvas.drawColor(Color.BLACK)
    // 绘制矩形'
    val width = 300F;
    val height = 170F
    var left = 0F;
    var top = 20F;
    var right = left + width;
    var bottom = top + height
    canvas.drawRect(left, top, right, bottom, paint)
    val tiles = arrayListOf<Shader.TileMode>(
        Shader.TileMode.CLAMP,
        Shader.TileMode.MIRROR,
        Shader.TileMode.REPEAT
    )
    fun getStringText(tileMode: Shader.TileMode): String {
        return when (tileMode) {
            Shader.TileMode.CLAMP -> "Shader.TileMode.CLAMP"
            Shader.TileMode.MIRROR -> "Shader.TileMode.MIRROR"
            Shader.TileMode.REPEAT -> "Shader.TileMode.REPEAT"
            else -> ""
        }
    }
    // Shader.TileMode.CLAMP
    for (tileX in tiles) {
        for (tileY in tiles) {
            left = left.plus(30F)
            top = top.plus(height + 10)
            right = left.plus(width)
            bottom = top + height
            paint.shader = BitmapShader(bitmap, tileX, tileY)
            paint.color = Color.BLUE
            canvas.drawRect(left, top, right, bottom, paint)
            paint.color = Color.YELLOW
            canvas.drawLine(0F, top, 1000F, top, paint)
            paint.color = Color.RED
            canvas.drawLine(0F, bottom, 1000F, bottom, paint)
            //绘制文字
            paint.color =Color.GREEN
            paint.textSize = 38F
            paint.shader = null
            canvas.drawText("${getStringText(tileX)}\n${getStringText(tileY)}", 0F, bottom, paint)
        }
    }
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • mPaint.setShader(new BitmapShader(bitmap, Shader.TileMode.MIRROR, Shader.TileMode.MIRROR));
    上下左右的镜像

在这里插入图片描述

  • mPaint.setShader(new BitmapShader(bitmap, Shader.TileMode.REPEAT, Shader.TileMode.REPEAT));
    REPEAT 是重复的意思, MIRROR就是镜像的意思
    在这里插入图片描述

  • mPaint.setShader(new BitmapShader(bitmap, Shader.TileMode.CLAMP, Shader.TileMode.MIRROR));

在这里插入图片描述
大家可以看到图像分为两部分左边呢Y轴镜像了,而右边像是被拉伸了一样怪怪的!其实CLAMP的意思就是边缘拉伸的意思,比如上图中左边Y轴镜像了,而右边会紧挨着左边将图像边缘上的第一个像素沿X轴复制!

在这里插入图片描述

var posX = 0F
var posY = 0F
override fun onTouchEvent(event: MotionEvent?): Boolean {
    if (event?.action == MotionEvent.ACTION_MOVE) {
        posX = event.x
        posY = event.y
        invalidate()
    }
    return true
}
private fun drawBrickView(canvas: Canvas) {
    // 圆边
    val mStrokePaint = Paint(Paint.ANTI_ALIAS_FLAG or Paint.DITHER_FLAG)
        .apply {
            this.color = Color.BLACK
            this.style = Paint.Style.STROKE
            this.strokeWidth = 5F
        }
    val mFillPaint = Paint()
    val decodeResource = BitmapFactory.decodeResource(resources, R.mipmap.ic_launcher)
    mFillPaint.shader =
        BitmapShader(decodeResource, Shader.TileMode.REPEAT, Shader.TileMode.REPEAT)
    //设置画笔背景色
    canvas.drawColor(Color.DKGRAY)
    //绘制圆和描边
    canvas.drawCircle(posX, posY, 200F, mFillPaint)
    canvas.drawCircle(posX, posY, 200F, mStrokePaint)
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28

LinearGradient

线性渐变

mPaint.setShader(new LinearGradient(left, top, right, bottom, Color.RED, Color.YELLOW, Shader.TileMode.REPEAT));

LinearGradient(float x0, float y0, float x1, float y1, int color0, int color1, Shader.TileMode tile)
/*
参数虽多其实很好理解x0和y0表示渐变的起点坐标而x1和y1则表示渐变的终点坐标,这两点都是相对于屏幕坐标系而言的,而color0和color1则表示起点的颜色和终点的颜色,这些即便是213也能懂 - - ……Shader.TileMode上面我们给的是REPEAT重复但是并没有任何效果,这时因为我们渐变的起点和终点都落在了图形的两端,整个渐变shader已经填充了图形所以不起作用,如果我们改改,把终点坐标变一下:
*/

mPaint.setShader(new LinearGradient(left, top, right - RECT_SIZE, bottom - RECT_SIZE, Color.RED, Color.YELLOW, Shader.TileMode.REPEAT));

LinearGradient(float x0, float y0, float x1, float y1, int[] colors, float[] positions, Shader.TileMode tile)

mPaint.setShader(new LinearGradient(left, top, right, bottom, new int[] { Color.RED, Color.YELLOW, Color.GREEN, Color.CYAN, Color.BLUE }, new float[] { 0, 0.1F, 0.5F, 0.7F, 0.8F }, Shader.TileMode.MIRROR));

mPaint.setShader(new LinearGradient(left, top, right, bottom, new int[] { Color.RED, Color.YELLOW, Color.GREEN, Color.CYAN, Color.BLUE }, null, Shader.TileMode.MIRROR));
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14

在这里插入图片描述

private fun drawReflectView(canvas: Canvas) {
        val mSrcBitmap = BitmapFactory.decodeResource(resources, R.mipmap.ic_launcher)

        //实例化一个矩阵
        val matrix = Matrix().apply {
            this.setScale(1F, -1F)
        }

        //生成倒影图
        val mRefBitmap =
            Bitmap.createBitmap(mSrcBitmap, 0, 0, mSrcBitmap.width, mSrcBitmap.height, matrix, true)
        val x = canvas.width.div(2) - mSrcBitmap.width.div(2)
        val y = canvas.height.div(2) - mSrcBitmap.height.div(2)

        val mPain = Paint()
        mPain.shader = LinearGradient(
            x.toFloat()
            , (y + mSrcBitmap.height).toFloat()
            , x.toFloat()
            , (y + mSrcBitmap.height + mSrcBitmap.height / 4).toFloat()
            , 0xAA000000.toInt()
            , Color.TRANSPARENT
            , Shader.TileMode.CLAMP
        )
        val mXfermode = PorterDuffXfermode(PorterDuff.Mode.DST_IN)

        canvas.drawColor(Color.BLACK)
        canvas.drawBitmap(mSrcBitmap, x.toFloat(), y.toFloat(), null)

        val saveLayer = canvas.saveLayer(
            x.toFloat()
            , (y + mSrcBitmap.getHeight()).toFloat()
            , (x + mRefBitmap.getWidth()).toFloat()
            , (y + mSrcBitmap.getHeight() * 2).toFloat()
            , null
            , Canvas.ALL_SAVE_FLAG
        )

        canvas.drawBitmap(
            mRefBitmap
            , x.toFloat()
            , (y + mSrcBitmap.height).toFloat()
            , null
        )

        mPain.setXfermode(mXfermode)

        canvas.drawRect(
            x.toFloat()
            , (y + mSrcBitmap.height).toFloat()
            , (x + mRefBitmap.width).toFloat()
            , (y + mSrcBitmap.height * 2).toFloat()
            , mPain
        )

        mPain.setXfermode(null)

        canvas.restoreToCount(saveLayer)
    }
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59

SweepGradient

SweepGradient(float cx, float cy, int color0, int color1)

mPaint.setShader(new SweepGradient(screenX, screenY, Color.RED, Color.YELLOW));

SweepGradient(float cx, float cy, int[] colors, float[] positions)

mPaint.setShader(new SweepGradient(screenX, screenY, new int[] { Color.GREEN, Color.WHITE, Color.GREEN }, null));
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7

在这里插入图片描述

RadialGradient

RadialGradient (float centerX, float centerY, float radius, int centerColor, int edgeColor, Shader.TileMode tileMode)

RadialGradient (float centerX, float centerY, float radius, int centerColor, int edgeColor, Shader.TileMode tileMode)
  • 1
  • 2
  • 3

原图
在这里插入图片描述

修改后的

在这里插入图片描述

private fun DreamEffectView(canvas: Canvas) {
    //获取位图
    val mBitmap = BitmapFactory.decodeResource(resources, R.drawable.beatuful)
    //实例化混合模式
    val mXfermode = PorterDuffXfermode(PorterDuff.Mode.SCREEN)
    val x = (canvas.width - mBitmap.width).div(2).toFloat()
    val y = (canvas.height - mBitmap.height).div(2).toFloat()
    //实例化画笔
    val mBitmapPaint = Paint(Paint.ANTI_ALIAS_FLAG)
    //去饱和、提亮、色相矫正
    mBitmapPaint.colorFilter = ColorMatrixColorFilter(floatArrayOf(0.8587F, 0.2940F, -0.0927F, 0F, 6.79F, 0.0821F, 0.9145F, 0.0634F, 0F, 6.79F, 0.2019F, 0.1097F, 0.7483F, 0F, 6.79F, 0F, 0F, 0F, 1F, 0F))
    canvas.drawColor(Color.BLACK)
    //新建图层
    val saveLayer = canvas.saveLayer(
        x,
        y,
        x + mBitmap.width,
        y + mBitmap.height,
        null,
        Canvas.ALL_SAVE_FLAG
    )
    //绘制混合颜色
    canvas.drawColor(0xcc1c093e.toInt())
    //设置混合模式
    mBitmapPaint.xfermode = mXfermode
    //绘制位图
    canvas.drawBitmap(mBitmap, x, y, mBitmapPaint)
    //环元混合模式
    mBitmapPaint.xfermode  = null
    //还原画布
    canvas.restoreToCount(saveLayer)
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32

使用RadialGradient

在这里插入图片描述

private fun DreamEffectViewRadialGradient(canvas: Canvas) {
    //获取位图
    val mBitmap = BitmapFactory.decodeResource(resources, R.drawable.beatuful)
    //实例化混合模式
    val mXfermode = PorterDuffXfermode(PorterDuff.Mode.SCREEN)
    val x = (canvas.width - mBitmap.width).div(2).toFloat()
    val y = (canvas.height - mBitmap.height).div(2).toFloat()
    //实例化画笔
    val mBitmapPaint = Paint(Paint.ANTI_ALIAS_FLAG)
    //去饱和、提亮、色相矫正
    mBitmapPaint.colorFilter = ColorMatrixColorFilter(floatArrayOf(0.8587F, 0.2940F, -0.0927F, 0F, 6.79F, 0.0821F, 0.9145F, 0.0634F, 0F, 6.79F, 0.2019F, 0.1097F, 0.7483F, 0F, 6.79F, 0F, 0F, 0F, 1F, 0F))
    //s实例化Shadaer图形的画笔
    val mShaderPaint = Paint();
    //设置径向渐变,渐变中心当然是图标的中心,也是屏幕中心,渐变的半径我们直接拿图片的高度但是稍微小一点
    //中心颜色为透明而边缘颜色为黑色
    mShaderPaint.shader = RadialGradient(
        canvas.width.div(2).toFloat()
        , canvas.height.div(2).toFloat()
        , mBitmap.height.times(7).div(8).toFloat()
        , Color.TRANSPARENT
        , Color.BLACK
        , Shader.TileMode.CLAMP
    )
    canvas.drawColor(Color.BLACK)
    //新建图层
    val saveLayer = canvas.saveLayer(
        x,
        y,
        x + mBitmap.width,
        y + mBitmap.height,
        null,
        Canvas.ALL_SAVE_FLAG
    )
    //绘制混合颜色
    canvas.drawColor(0xcc1c093e.toInt())
    //设置混合模式
    mBitmapPaint.xfermode = mXfermode
    //绘制位图
    canvas.drawBitmap(mBitmap, x, y, mBitmapPaint)
    //环元混合模式
    mBitmapPaint.xfermode = null
    //还原画布
    canvas.restoreToCount(saveLayer)
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44

ComposeShader

ComposeShader (Shader shaderA, Shader shaderB, Xfermode mode)
ComposeShader (Shader shaderA, Shader shaderB, PorterDuff.Mode mode)
  • 1
  • 2

在这里插入图片描述
在这里插入图片描述

在这里插入图片描述

public class DreamEffectView extends View {
	private Paint mBitmapPaint, mShaderPaint;// 位图画笔和Shader图形的画笔
	private Bitmap mBitmap, darkCornerBitmap;// 源图的Bitmap和我们自己画的暗角Bitmap
	private PorterDuffXfermode mXfermode;// 图形混合模式
	private int x, y;// 位图起点坐标
	private int screenW, screenH;// 屏幕宽高
 
	public DreamEffectView(Context context, AttributeSet attrs) {
		super(context, attrs);
 
		// 初始化资源
		initRes(context);
 
		// 初始化画笔
		initPaint();
	}
 
	/**
	 * 初始化资源
	 * 
	 * @param context
	 *            丢你螺母
	 */
	private void initRes(Context context) {
		// 获取位图
		mBitmap = BitmapFactory.decodeResource(context.getResources(), R.drawable.gril);
 
		// 实例化混合模式
		mXfermode = new PorterDuffXfermode(PorterDuff.Mode.SCREEN);
 
		screenW = MeasureUtil.getScreenSize((Activity) context)[0];
		screenH = MeasureUtil.getScreenSize((Activity) context)[1];
 
		x = screenW / 2 - mBitmap.getWidth() / 2;
		y = screenH / 2 - mBitmap.getHeight() / 2;
	}
 
	/**
	 * 初始化画笔
	 */
	private void initPaint() {
		// 实例化画笔
		mBitmapPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
 
		// 去饱和、提亮、色相矫正
		mBitmapPaint.setColorFilter(new ColorMatrixColorFilter(new float[] { 0.8587F, 0.2940F, -0.0927F, 0, 6.79F, 0.0821F, 0.9145F, 0.0634F, 0, 6.79F, 0.2019F, 0.1097F, 0.7483F, 0, 6.79F, 0, 0, 0, 1, 0 }));
 
		// 实例化Shader图形的画笔
		mShaderPaint = new Paint();
 
		// 根据我们源图的大小生成暗角Bitmap
		darkCornerBitmap = Bitmap.createBitmap(mBitmap.getWidth(), mBitmap.getHeight(), Bitmap.Config.ARGB_8888);
 
		// 将该暗角Bitmap注入Canvas
		Canvas canvas = new Canvas(darkCornerBitmap);
 
		// 计算径向渐变半径
		float radiu = canvas.getHeight() * (2F / 3F);
 
		// 实例化径向渐变
		RadialGradient radialGradient = new RadialGradient(canvas.getWidth() / 2F, canvas.getHeight() / 2F, radiu, new int[] { 0, 0, 0xAA000000 }, new float[] { 0F, 0.7F, 1.0F }, Shader.TileMode.CLAMP);
 
		// 实例化一个矩阵
		Matrix matrix = new Matrix();
 
		// 设置矩阵的缩放
		matrix.setScale(canvas.getWidth() / (radiu * 2F), 1.0F);
 
		// 设置矩阵的预平移
		matrix.preTranslate(((radiu * 2F) - canvas.getWidth()) / 2F, 0);
 
		// 将该矩阵注入径向渐变
		radialGradient.setLocalMatrix(matrix);
 
		// 设置画笔Shader
		mShaderPaint.setShader(radialGradient);
 
		// 绘制矩形
		canvas.drawRect(0, 0, canvas.getWidth(), canvas.getHeight(), mShaderPaint);
	}
 
	@Override
	protected void onDraw(Canvas canvas) {
		canvas.drawColor(Color.BLACK);
 
		// 新建图层
		int sc = canvas.saveLayer(x, y, x + mBitmap.getWidth(), y + mBitmap.getHeight(), null, Canvas.ALL_SAVE_FLAG);
 
		// 绘制混合颜色
		canvas.drawColor(0xcc1c093e);
 
		// 设置混合模式
		mBitmapPaint.setXfermode(mXfermode);
 
		// 绘制位图
		canvas.drawBitmap(mBitmap, x, y, mBitmapPaint);
 
		// 还原混合模式
		mBitmapPaint.setXfermode(null);
 
		// 还原画布
		canvas.restoreToCount(sc);
 
		// 绘制我们画好的径向渐变图
		canvas.drawBitmap(darkCornerBitmap, x, y, null);
	}
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68
  • 69
  • 70
  • 71
  • 72
  • 73
  • 74
  • 75
  • 76
  • 77
  • 78
  • 79
  • 80
  • 81
  • 82
  • 83
  • 84
  • 85
  • 86
  • 87
  • 88
  • 89
  • 90
  • 91
  • 92
  • 93
  • 94
  • 95
  • 96
  • 97
  • 98
  • 99
  • 100
  • 101
  • 102
  • 103
  • 104
  • 105
  • 106
  • 107

matrix的

在这里插入图片描述

    <com.example.customview.MatrixImageView
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:scaleType="matrix"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintLeft_toLeftOf="parent"
        app:layout_constraintRight_toRightOf="parent"
        app:layout_constraintTop_toTopOf="parent" />
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
public class MatrixImageView extends androidx.appcompat.widget.AppCompatImageView {
    private static final int MODE_NONE = 0x00123;// 默认的触摸模式
    private static final int MODE_DRAG = 0x00321;// 拖拽模式
    private static final int MODE_ZOOM = 0x00132;// 缩放or旋转模式

    private int mode;// 当前的触摸模式

    private float preMove = 1F;// 上一次手指移动的距离
    private float saveRotate = 0F;// 保存了的角度值
    private float rotate = 0F;// 旋转的角度

    private float[] preEventCoor;// 上一次各触摸点的坐标集合

    private PointF start, mid;// 起点、中点对象
    private Matrix currentMatrix, savedMatrix;// 当前和保存了的Matrix对象
    private Context mContext;// Fuck……

    public MatrixImageView(Context context, AttributeSet attrs) {
        super(context, attrs);
        this.mContext = context;

        // 初始化
        init();
    }

    /**
     * 初始化
     */
    private void init() {
        /*
         * 实例化对象
         */
        currentMatrix = new Matrix();
        savedMatrix = new Matrix();
        start = new PointF();
        mid = new PointF();

        // 模式初始化
        mode = MODE_NONE;

        /*
         * 设置图片资源
         */
        Bitmap bitmap = BitmapFactory.decodeResource(getResources(), R.drawable.background);
        bitmap = Bitmap.createScaledBitmap(bitmap, 1000, 1000, true);
        setImageBitmap(bitmap);
    }

    @Override
    public boolean onTouchEvent(MotionEvent event) {
        switch (event.getAction() & MotionEvent.ACTION_MASK) {
            case MotionEvent.ACTION_DOWN:// 单点接触屏幕时
                savedMatrix.set(currentMatrix);
                start.set(event.getX(), event.getY());
                mode = MODE_DRAG;
                preEventCoor = null;
                break;
            case MotionEvent.ACTION_POINTER_DOWN:// 第二个点接触屏幕时
                preMove = calSpacing(event);
                if (preMove > 10F) {
                    savedMatrix.set(currentMatrix);
                    calMidPoint(mid, event);
                    mode = MODE_ZOOM;
                }
                preEventCoor = new float[4];
                preEventCoor[0] = event.getX(0);
                preEventCoor[1] = event.getX(1);
                preEventCoor[2] = event.getY(0);
                preEventCoor[3] = event.getY(1);
                saveRotate = calRotation(event);
                break;
            case MotionEvent.ACTION_UP:// 单点离开屏幕时
            case MotionEvent.ACTION_POINTER_UP:// 第二个点离开屏幕时
                mode = MODE_NONE;
                preEventCoor = null;
                break;
            case MotionEvent.ACTION_MOVE:// 触摸点移动时
                /*
                 * 单点触控拖拽平移
                 */
                if (mode == MODE_DRAG) {
                    currentMatrix.set(savedMatrix);
                    float dx = event.getX() - start.x;
                    float dy = event.getY() - start.y;
                    currentMatrix.postTranslate(dx, dy);
                }
                /*
                 * 两点触控拖放旋转
                 */
                else if (mode == MODE_ZOOM && event.getPointerCount() == 2) {
                    float currentMove = calSpacing(event);
                    currentMatrix.set(savedMatrix);
                    /*
                     * 指尖移动距离大于10F缩放
                     */
                    if (currentMove > 10F) {
                        float scale = currentMove / preMove;
                        currentMatrix.postScale(scale, scale, mid.x, mid.y);
                    }
                    /*
                     * 保持两点时旋转
                     */
                    if (preEventCoor != null) {
                        rotate = calRotation(event);
                        float r = rotate - saveRotate;
                        currentMatrix.postRotate(r, getMeasuredWidth() / 2, getMeasuredHeight() / 2);
                    }
                }
                break;
        }

        setImageMatrix(currentMatrix);
        return true;
    }

    /**
     * 计算两个触摸点间的距离
     */
    private float calSpacing(MotionEvent event) {
        float x = event.getX(0) - event.getX(1);
        float y = event.getY(0) - event.getY(1);
        return (float) Math.sqrt(x * x + y * y);
    }

    /**
     * 计算两个触摸点的中点坐标
     */
    private void calMidPoint(PointF point, MotionEvent event) {
        float x = event.getX(0) + event.getX(1);
        float y = event.getY(0) + event.getY(1);
        point.set(x / 2, y / 2);
    }

    /**
     * 计算旋转角度
     *
     * @return 角度值
     */
    private float calRotation(MotionEvent event) {
        double deltaX = (event.getX(0) - event.getX(1));
        double deltaY = (event.getY(0) - event.getY(1));
        double radius = Math.atan2(deltaY, deltaX);
        return (float) Math.toDegrees(radius);
    }
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68
  • 69
  • 70
  • 71
  • 72
  • 73
  • 74
  • 75
  • 76
  • 77
  • 78
  • 79
  • 80
  • 81
  • 82
  • 83
  • 84
  • 85
  • 86
  • 87
  • 88
  • 89
  • 90
  • 91
  • 92
  • 93
  • 94
  • 95
  • 96
  • 97
  • 98
  • 99
  • 100
  • 101
  • 102
  • 103
  • 104
  • 105
  • 106
  • 107
  • 108
  • 109
  • 110
  • 111
  • 112
  • 113
  • 114
  • 115
  • 116
  • 117
  • 118
  • 119
  • 120
  • 121
  • 122
  • 123
  • 124
  • 125
  • 126
  • 127
  • 128
  • 129
  • 130
  • 131
  • 132
  • 133
  • 134
  • 135
  • 136
  • 137
  • 138
  • 139
  • 140
  • 141
  • 142
  • 143
  • 144
  • 145
声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/2023面试高手/article/detail/376302
推荐阅读
相关标签
  

闽ICP备14008679号