Android基于Matrix绘制PaintDrawable设置BitmapShader,以手指触点为中心显示原图像圆图,Kotlin(2)

Android基于Matrix绘制PaintDrawable设置BitmapShader,以手指触点为中心显示原图像圆图,Kotlin(2)

在 https://zhangphil.blog.csdn.net/article/details/135374279 基础上,增加一个功能,当手指在上面的图片上滑动时候,显示滑动轨迹:

Kotlin 复制代码
import android.content.Context
import android.graphics.Bitmap
import android.graphics.BitmapShader
import android.graphics.Canvas
import android.graphics.Color
import android.graphics.Matrix
import android.graphics.Paint
import android.graphics.Path
import android.graphics.Shader.TileMode
import android.graphics.drawable.BitmapDrawable
import android.graphics.drawable.PaintDrawable
import android.os.Bundle
import android.util.AttributeSet
import android.util.Log
import android.view.MotionEvent
import android.widget.ImageView
import androidx.appcompat.app.AppCompatActivity
import androidx.appcompat.widget.AppCompatImageView


class MainActivity : AppCompatActivity() {
    private var iv: MyImageView? = null

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)
        iv = findViewById(R.id.iv)

        val r = findViewById<ImageView>(R.id.result)
        iv?.setTestImageView(r)
    }
}

class MyImageView : AppCompatImageView {
    private var mCurX = 0
    private var mCurY = 0

    private val mPath = Path()
    private val mPathPaint = Paint()

    private var mNewBmp: Bitmap? = null
    private var mSrcBmp: Bitmap? = null
    private var mIsDraw = false
    private val mRadius = 300f

    private var mDrawable: PaintDrawable? = null

    private var testIV: ImageView? = null

    constructor(ctx: Context, attrs: AttributeSet) : super(ctx, attrs) {
        mSrcBmp = (drawable as BitmapDrawable).bitmap

        mPathPaint.style = Paint.Style.STROKE
        mPathPaint.strokeWidth = 15f
        mPathPaint.isAntiAlias = true
        mPathPaint.color = Color.RED
    }

    fun setTestImageView(iv: ImageView?) {
        testIV = iv
    }

    override fun onTouchEvent(event: MotionEvent): Boolean {
        mCurX = event.x.toInt()
        mCurY = event.y.toInt()

        when (event.action) {
            MotionEvent.ACTION_DOWN -> {
                Log.d("fly", "开始绘制")

                mPath.moveTo(event.x, event.y)

                mIsDraw = true
            }

            MotionEvent.ACTION_MOVE -> {
                mPath.lineTo(event.x, event.y)
            }

            MotionEvent.ACTION_UP, MotionEvent.ACTION_CANCEL -> {
                Log.d("fly", "不需绘制")
                mIsDraw = false

                //抬手后,清除手指轨迹。
                myClear()
            }
        }

        invalidate()

        return true
    }

    private fun myClear() {
        //清除历史轨迹。
        mPath.reset()
    }

    override fun onDraw(canvas: Canvas) {
        super.onDraw(canvas)

        if (mIsDraw) {
            myDraw()

            canvas.drawPath(mPath, mPathPaint)
        }
    }

    private fun myDraw() {
        val shader = BitmapShader(Bitmap.createScaledBitmap(mSrcBmp!!, this.width, this.height, true), TileMode.DECAL, TileMode.DECAL)
        mDrawable = PaintDrawable(Color.DKGRAY)
        mDrawable!!.setCornerRadius(mRadius / 2) //圆角矩形,如果不除2即是圆形框图。
        mDrawable!!.paint.shader = shader
        mDrawable!!.setBounds(0, 0, (mRadius * 2).toInt(), (mRadius * 2).toInt())

        mNewBmp = Bitmap.createBitmap(this.width, this.height, Bitmap.Config.ARGB_8888)
        val c = Canvas(mNewBmp!!)
        c.drawColor(Color.LTGRAY) //画满底色。


        val matrix = Matrix()
        matrix.setTranslate(-mCurX + mRadius, -mCurY + mRadius)
        mDrawable!!.paint.shader.setLocalMatrix(matrix)

        mDrawable!!.draw(c)


        testIV?.setImageBitmap(mNewBmp)
    }
}
XML 复制代码
<?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:background="@android:color/darker_gray"
    android:orientation="vertical"
    tools:context=".MainActivity">

    <com.pkg.MyImageView
        android:id="@+id/iv"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:adjustViewBounds="true"
        android:background="@drawable/ic_launcher_background"
        android:scaleType="fitCenter"
        android:src="@mipmap/mypic" />

    <ImageView
        android:id="@+id/result"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginTop="20dp"
        android:background="@drawable/ic_launcher_background"
        android:src="@drawable/ic_launcher_foreground" />

</LinearLayout>

https://zhangphil.blog.csdn.net/article/details/135374279https://zhangphil.blog.csdn.net/article/details/135374279

相关推荐
道尔柯南9 小时前
C++ string 类详解:从常用接口到深拷贝,彻底掌握字符串处理
android·java·c++
唐诺10 小时前
5、Android JNI 动态注册中的“签名“详解
android·jni
zhaoshuzhaoshu13 小时前
Android 系统启动与调试中的日志抓取方式全解析
android
雨声不在14 小时前
android 动画掉帧
android
在多学一点15 小时前
MYSQL第二次作业
android·数据库·mysql
骑着蜗牛撵大象32715 小时前
MySQL 8.0 迁移后 SQL 变慢:执行计划里 3 类被忽略的成本差异
android·数据库·sql·mysql·优化器·执行计划
我叫张土豆16 小时前
Android 14+ 模拟器抓包实录:把 Burp CA 装成系统 CA,让 targetSdk≥34 的 App 乖乖解密
android
Nerd(BUG版)17 小时前
KMP学习day4--Kotlin空安全与泛型
学习·安全·kotlin
booboosui19 小时前
Android 悬浮窗藏不住自己:一个标志位与 140 毫秒
android
传奇开心果19 小时前
【Flutter踩坑排雷】第5课:扩展方法冲突坑|同名扩展引发编译歧义,故障规避手段
android·flutter