Kotlin中改变scaleX和scaleY后如何获取图像在imageview中的位置

问题描述 投票:0回答:1

我需要在比例改变后获取ImageView内图像的位置、宽度和高度。我需要这些值来添加代码来控制滚动限制。 我见过其他使用 Matrix 机制的线程,但在我的情况下,它们并不适用,因为我的图像确实超出了 ImageView 的范围,因为比例更改是将图像缩放 2 倍和 3 倍。

我需要的是保持图像在滚动时不显示空白区域。例如,图像的左上角不能低于视图的上边框,也不能超出视图左边框的最右侧。与其他角类似,图像不能越过底部边框或右边框的最左侧等。

当我执行 pdfview.x 和 pdfview.width 等操作时,这些值给了我原始值。我可以通过数学得到宽度和高度,但不能用位置来做到这一点,因为它在滚动时会改变。

我尝试获取边界,但它也给了我原始值。

边界代码:

var bounds: RectF = getImageBounds(pdfview)

fun getImageBounds(imageView: ImageView): RectF {
    val bounds = RectF()
    val drawable = imageView.drawable
    if (drawable != null) {
        imageView.imageMatrix.mapRect(bounds, RectF(drawable.bounds))
    }
    return bounds
}

缩放代码:

val binding = ActivityMainBinding.inflate(layoutInflater)
    setContentView(binding.root)
        
pdfview = binding.pdfview
    slider = binding.slider

    slider.addOnChangeListener { slider, value, fromUser ->
        // Responds to when slider's value is changed
        pdfview.scaleX = 1 + slider.value / 100
        pdfview.scaleY = 1 + slider.value / 100
    }

PAN 代码:

var preX: Float = pdfview.x
    var preY: Float = pdfview.y
    
    pdfview.setOnTouchListener { v, event ->
        val currentX: Float
        val currentY: Float

        when (event.action) {
            MotionEvent.ACTION_DOWN -> {
                preX = event.x
                preY = event.y
            }

            MotionEvent.ACTION_MOVE -> {
                currentX = event.x
                currentY = event.y
                    pdfview.scrollBy((preX - currentX).toInt(), (preY - currentY).toInt())
                    preX = currentX
                    preY = currentY
            }

            MotionEvent.ACTION_UP -> {
                currentX = event.x
                currentY = event.y
                    pdfview.scrollBy((preX - currentX).toInt(), (preY - currentY).toInt())
            }
        }
        true
    }

布局 xml:

<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:id="@+id/myLayout"
    tools:context=".MainActivity">

<FrameLayout
        android:id="@+id/frame"
        android:layout_width="350dp"
        android:layout_height="515dp"
        android:layout_marginStart="30dp"
        android:layout_marginTop="4dp"
        android:layout_marginEnd="30dp"
        android:background="@drawable/image_border"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toBottomOf="@id/creatorButton">

        <View
            android:id="@+id/view"
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:cropToPadding="true"
            android:padding="1dp"
            android:scaleType="centerCrop" />

        <ImageView
            android:id="@+id/pdfview"
            android:layout_width="350dp"
            android:layout_height="515dp"
            android:contentDescription="@string/pdf"
            android:cropToPadding="true"
            android:padding="1dp"
            android:scaleType="centerCrop"
            app:srcCompat="@color/material_dynamic_neutral80" />

    </FrameLayout>

<LinearLayout
        android:id="@+id/linear"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:gravity="center_horizontal"
        android:orientation="vertical"
        android:visibility="invisible"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toBottomOf="@+id/frame"
        app:layout_constraintVertical_bias="0.0">

        <com.google.android.material.slider.Slider
            android:id="@+id/slider"
            android:layout_width="350dp"
            android:layout_height="wrap_content"
            android:layout_marginTop="0dp"
            android:layout_marginBottom="0dp"
            android:valueFrom="0.0"
            android:valueTo="300.0" />

    </LinearLayout>
</androidx.constraintlayout.widget.ConstraintLayout>
kotlin imageview position pan zoom-sdk
1个回答
0
投票

原来我找到了如何使用矩阵移动机制而不是滚动机制。关键是要执行正确的矩阵重绘代码。

以下为动作代码:

pdfview.setOnTouchListener { _, event -> //v, event ->
        val bounds: RectF = getImageBounds(pdfview, m)

        val currentX: Float
        val currentY: Float

        when (event.action) {
            MotionEvent.ACTION_DOWN -> {
                preX = event.x
                preY = event.y
            }

            MotionEvent.ACTION_MOVE -> {
                currentX = event.x
                currentY = event.y
                //// The function xyComp is used to control the limits of the Matrix movements 
                //// with the help of the Drawable boundaries and corner coordinates, and total size of the View. 
                //// Those values are obtain on each movement below.
                if (xyComp(
                        bounds,
                        fixbounds,
                        preX,
                        preY,
                        currentX,
                        currentY,
                        (preX - currentX),
                        (preY - currentY)
                    )
                ) {
                    //// Matrix movement. postTranslate move the Matrix in continuos mode
                    m.postTranslate(
                        -(preX - currentX),
                        -(preY - currentY)
                    )

                    //// Redraw Matrix by assigning the moved Matrix to the View, do not use invalidate method 
                    pdfview.imageMatrix = m

                    //// Get the size(top,left,bottom,right) coordinates of the Drawable/Matrix within the View
                    pbounds = getImageBounds(pdfview)
                    
                    //// Get the Matrix corner coordinates
                    val f = FloatArray(9)
                    m.getValues(f)
                    pscrollX = f[Matrix.MTRANS_X]
                    pscrollY = f[Matrix.MTRANS_Y]

                    //// With the size and corner then you can control the limits which can it move
                    preX = currentX
                    preY = currentY
                }
            }

            MotionEvent.ACTION_UP -> {
                currentX = event.x
                currentY = event.y
                if (xyComp(
                        bounds,
                        fixbounds,
                        preX,
                        preY,
                        currentX,
                        currentY,
                        (preX - currentX),
                        (preY - currentY)
                    )
                ) {
                    m.postTranslate(
                        -(preX - currentX),
                        -(preY - currentY)
                    )
                    pdfview.imageMatrix = m
                    pbounds = getImageBounds(pdfview)
                    val f = FloatArray(9)
                    m.getValues(f)

                    pscrollX = f[Matrix.MTRANS_X]
                    pscrollY = f[Matrix.MTRANS_Y]

                }
            }
        }
        if (pscrollX != scrollX) {
            switchPAN.tag = true
            switchPAN.visibility = VISIBLE
            switchCenter.visibility = GONE
        }
        true
    }
© www.soinside.com 2019 - 2024. All rights reserved.