Android叠加双RecyclerView ScaleGestureDetector AnimatorSet动态放大缩小,Kotlin(1)
<?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.RecyclerViewandroid:id="@+id/rv2"android:layout_width="match_parent"android:layout_height="match_parent"android:background="@android:color/holo_red_light" /><androidx.recyclerview.widget.RecyclerViewandroid:id="@+id/rv1"android:layout_width="match_parent"android:layout_height="match_parent"android:background="@null" /><com.tran.myapp.MyTouchViewandroid:id="@+id/touch_view"android:layout_width="match_parent"android:layout_height="match_parent" />
</RelativeLayout>
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.RecyclerViewclass MyTouchView : androidx.appcompat.widget.AppCompatImageView {private var mContext: Context? = nullprivate var mRV1: RecyclerView? = nullprivate var mRV2: RecyclerView? = nullprivate var mScaleGestureDetector: ScaleGestureDetector? = null//缩放因子private var mScaleFactor = 1.0fprivate var mIsScaling = falseprivate val BIG = 0private val SMALL = 1private var mGridStatus = BIGconstructor(ctx: Context, attributeSet: AttributeSet) : super(ctx, attributeSet) {mContext = ctxmScaleGestureDetector = ScaleGestureDetector(mContext!!, object : ScaleGestureDetector.SimpleOnScaleGestureListener() {override fun onScaleBegin(detector: ScaleGestureDetector): Boolean {return super.onScaleBegin(detector)}override fun onScale(detector: ScaleGestureDetector): Boolean {mScaleFactor = detector.scaleFactorLog.d(MainActivity.TAG, "onScale scaleFactor=${detector.scaleFactor}")return super.onScale(detector)}})}fun bindRV(rv1: RecyclerView, rv2: RecyclerView) {mRV1 = rv1mRV2 = rv2}override fun onTouchEvent(event: MotionEvent?): Boolean {var bRet = falseval pointerId = event?.getPointerId(event.actionIndex)if (pointerId!! > 0) {this.postDelayed({mScaleGestureDetector?.onTouchEvent(event!!)}, 10)if (mScaleFactor < 1f) {if (!mIsScaling && mGridStatus != SMALL) {mIsScaling = trueLog.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 = falsemScaleFactor = 1fmGridStatus = SMALL}override fun onAnimationCancel(animation: Animator) {mIsScaling = falsemScaleFactor = 1fmGridStatus = 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 = trueval animatorSet = AnimatorSet()animatorSet.addListener(object : Animator.AnimatorListener {override fun onAnimationStart(animation: Animator) {}override fun onAnimationEnd(animation: Animator) {mIsScaling = falsemScaleFactor = 1fmGridStatus = BIG}override fun onAnimationCancel(animation: Animator) {mIsScaling = falsemScaleFactor = 1fmGridStatus = 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