Android叠加双RecyclerView ScaleGestureDetector AnimatorSet动态放大缩小,Kotlin(1)

Android叠加双RecyclerView ScaleGestureDetector AnimatorSet动态放大缩小,Kotlin(1)

XML 复制代码
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout 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=".MainActivity">


    <androidx.recyclerview.widget.RecyclerView
        android:id="@+id/rv2"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:background="@android:color/holo_red_light" />

    <androidx.recyclerview.widget.RecyclerView
        android:id="@+id/rv1"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:background="@null" />

    <com.tran.myapp.MyTouchView
        android:id="@+id/touch_view"
        android:layout_width="match_parent"
        android:layout_height="match_parent" />
</RelativeLayout>
Kotlin 复制代码
import android.animation.Animator
import android.animation.AnimatorSet
import android.animation.ObjectAnimator
import android.content.Context
import android.util.AttributeSet
import android.util.Log
import android.view.MotionEvent
import android.view.ScaleGestureDetector
import androidx.recyclerview.widget.RecyclerView


class MyTouchView : androidx.appcompat.widget.AppCompatImageView {
    private var mContext: Context? = null

    private var mRV1: RecyclerView? = null
    private var mRV2: RecyclerView? = null

    private var mScaleGestureDetector: ScaleGestureDetector? = null

    //缩放因子
    private var mScaleFactor = 1.0f
    private var mIsScaling = false

    private val BIG = 0
    private val SMALL = 1
    private var mGridStatus = BIG

    constructor(ctx: Context, attributeSet: AttributeSet) : super(ctx, attributeSet) {
        mContext = ctx

        mScaleGestureDetector = ScaleGestureDetector(mContext!!, object : ScaleGestureDetector.SimpleOnScaleGestureListener() {
            override fun onScaleBegin(detector: ScaleGestureDetector): Boolean {
                return super.onScaleBegin(detector)
            }

            override fun onScale(detector: ScaleGestureDetector): Boolean {
                mScaleFactor = detector.scaleFactor
                Log.d(MainActivity.TAG, "onScale scaleFactor=${detector.scaleFactor}")
                return super.onScale(detector)
            }
        })
    }

    fun bindRV(rv1: RecyclerView, rv2: RecyclerView) {
        mRV1 = rv1
        mRV2 = rv2
    }

    override fun onTouchEvent(event: MotionEvent?): Boolean {
        var bRet = false
        val pointerId = event?.getPointerId(event.actionIndex)

        if (pointerId!! > 0) {
            this.postDelayed({
                mScaleGestureDetector?.onTouchEvent(event!!)
            }, 10)

            if (mScaleFactor < 1f) {
                if (!mIsScaling && mGridStatus != SMALL) {
                    mIsScaling = true
                    Log.d(MainActivity.TAG, "to small mScaleFactor=$mScaleFactor")

                    val animatorSet = AnimatorSet()
                    animatorSet.addListener(object : Animator.AnimatorListener {
                        override fun onAnimationStart(animation: Animator) {

                        }

                        override fun onAnimationEnd(animation: Animator) {
                            mIsScaling = false
                            mScaleFactor = 1f
                            mGridStatus = SMALL
                        }

                        override fun onAnimationCancel(animation: Animator) {
                            mIsScaling = false
                            mScaleFactor = 1f
                            mGridStatus = SMALL
                        }

                        override fun onAnimationRepeat(animation: Animator) {

                        }
                    })


                    val x1 = ObjectAnimator.ofFloat(mRV1, "scaleX", 1f, 0.01f).apply {
                        duration = 2000
                    }

                    val y1 = ObjectAnimator.ofFloat(mRV1, "scaleY", 1f, 0.01f).apply {
                        duration = 2000
                    }

                    val a1 = ObjectAnimator.ofFloat(mRV1, "alpha", 1f, 0f).apply {
                        duration = 2000
                    }

                    val x2 = ObjectAnimator.ofFloat(mRV2, "scaleX", 0.01f, 1f).apply {
                        duration = 2000
                    }

                    val y2 = ObjectAnimator.ofFloat(mRV2, "scaleY", 0.01f, 1f).apply {
                        duration = 2000
                    }

                    val a2 = ObjectAnimator.ofFloat(mRV2, "alpha", 0f, 1f).apply {
                        duration = 2000

                    }

                    animatorSet.playTogether(x1, y1, a1, x2, y2, a2)
                    animatorSet.start()
                }
            } else if (mScaleFactor > 1f && mGridStatus != BIG) {
                if (!mIsScaling) {
                    Log.d(MainActivity.TAG, "to big mScaleFactor=$mScaleFactor")
                    mIsScaling = true

                    val animatorSet = AnimatorSet()
                    animatorSet.addListener(object : Animator.AnimatorListener {
                        override fun onAnimationStart(animation: Animator) {

                        }

                        override fun onAnimationEnd(animation: Animator) {
                            mIsScaling = false
                            mScaleFactor = 1f
                            mGridStatus = BIG
                        }

                        override fun onAnimationCancel(animation: Animator) {
                            mIsScaling = false
                            mScaleFactor = 1f
                            mGridStatus = BIG
                        }

                        override fun onAnimationRepeat(animation: Animator) {

                        }
                    })


                    val x1 = ObjectAnimator.ofFloat(mRV1, "scaleX", 0.01f, 1f).apply {
                        duration = 2000
                    }

                    val y1 = ObjectAnimator.ofFloat(mRV1, "scaleY", 0.01f, 1f).apply {
                        duration = 2000
                    }

                    val a1 = ObjectAnimator.ofFloat(mRV1, "alpha", 0f, 1f).apply {
                        duration = 2000
                    }


                    val x2 = ObjectAnimator.ofFloat(mRV2, "scaleX", 1f, 0.01f).apply {
                        duration = 2000
                    }

                    val y2 = ObjectAnimator.ofFloat(mRV2, "scaleY", 1f, 0.01f).apply {
                        duration = 2000
                    }

                    val a2 = ObjectAnimator.ofFloat(mRV2, "alpha", 1f, 0f).apply {
                        duration = 2000
                    }

                    animatorSet.playTogether(x1, y1, a1, x2, y2, a2)
                    animatorSet.start()
                }
            }

            bRet = true
        } else {
            bRet = false
        }

        return bRet
    }
}

Android ScaleGestureDetector检测双指缩放Bitmap基于Matrix动画移动到双指捏合中心点ImageView区域中心,Kotlin-CSDN博客文章浏览阅读474次,点赞5次,收藏11次。需要注意的,因为在xml布局里面特别设置了ImageView的高度为wrap_content,手指在屏幕触点的位置是放大镜里面放大图片后准确圆心位置,但是,如果ImageView设置成match_parent,则因为ImageView里面的Bitmap被缩放(此处Bitmap其实小于ImageView,被拉伸了),拉伸后的Bitmap水平方向坐标与ImageView一直重合,但竖直方向,Bitmap坐标与ImageView不一致,会造成一种现象,手指触点放大镜放大后,水平方向是正确的,但竖直方向有偏移量。https://blog.csdn.net/zhangphil/article/details/135705931

相关推荐
潘潘潘1 天前
Android多线程机制简介
android
CYRUS_STUDIO1 天前
利用 Linux 信号机制(SIGTRAP)实现 Android 下的反调试
android·安全·逆向
CYRUS_STUDIO1 天前
Android 反调试攻防实战:多重检测手段解析与内核级绕过方案
android·操作系统·逆向
黄林晴1 天前
如何判断手机是否是纯血鸿蒙系统
android
火柴就是我1 天前
flutter 之真手势冲突处理
android·flutter
法的空间1 天前
Flutter JsonToDart 支持 JsonSchema
android·flutter·ios
循环不息优化不止1 天前
深入解析安卓 Handle 机制
android
恋猫de小郭1 天前
Android 将强制应用使用主题图标,你怎么看?
android·前端·flutter
jctech1 天前
这才是2025年的插件化!ComboLite 2.0:为Compose开发者带来极致“爽”感
android·开源
用户2018792831671 天前
为何Handler的postDelayed不适合精准定时任务?
android