我尝试过 Stackoverflow 系统提供的许多类似问题,但它们适用于其他场景。我不使用画布,我使用 Matrix 进行缩放和平移,但与scrollBy 和 imageview.scaleX、imageview.scaleY 结合使用。
问题是我想替换 ImageView 中的位图,但是替换后它采用与前一个位图相同的位置和缩放状态。
我尝试执行 ScrollTo(0,0) 来重置位置。尝试了translateX(0)、translateY(0)。尝试过 setX(0), setY(0)
尝试执行setImageMatrix(originalM),其中originalM是创建时的imageview.imageMatrix。尝试过 imageview.imageMatrix = Matrix()
尝试 imageview.setScaleType(ImageView.ScaleType.CENTER_CROP) 然后 imageview.setScaleType(ImageView.ScaleType.MATRIX)
为了让读者受益,这是我代码的一部分。 您会注意到我在场景后面平移和缩放矩阵,但不会使图像视图无效。我希望用户看到视图中的更改,而不是矩阵中的更改。我正在尝试在 PX 中缩放和平移矩阵(这部分无法正常工作,但超出了本问题的范围。使用此矩阵可能是问题的一部分,但我无法将其删除,因为用于代码中的另一个函数和其他主题/问题)
布局:
<FrameLayout
android:id="@+id/frame"
android:layout_width="350dp"
android:layout_height="500dp"
android:layout_marginStart="30dp"
android:layout_marginTop="2dp"
android:layout_marginEnd="30dp"
android:background="@drawable/image_border"
android:visibility="visible"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/button_layout">
<ImageView
android:id="@+id/pdfview"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:contentDescription="@string/pdf"
android:cropToPadding="true"
android:scaleType="matrix"
app:layout_constraintDimensionRatio="1:1"
app:srcCompat="@color/material_dynamic_neutral80" />
<!--android:scaleType="centerCrop"-->
</FrameLayout>
缩放:
slider.addOnChangeListener { slider, value, fromUser ->
// Responds to when slider's value is changed
tv = "Zoom Value:\n${value.format(2)}%"
zoom.text = tv
m = pdfview.imageMatrix
scaleX = 1 + value / 100
scaleY = 1 + value / 100
// Responds to when slider's value is changed
pdfview.scaleX = scaleX
pdfview.scaleY = scaleY
scrollX = pdfview.scrollX
scrollY = pdfview.scrollY
m.setScale(scaleX, scaleY, centerX, centerY)
m.postTranslate(
-(scrollX).toInt().toFloat().px,
-(scrollY).toInt().toFloat().px
)
}
扩展功能
private val Float.px: Float get() = (this * getSystem().displayMetrics.density)
潘:
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())
m.postTranslate(
-(preX - currentX).toInt().toFloat().px,
-(preY - currentY).toInt().toFloat().px
)
preX = currentX
preY = currentY
}
MotionEvent.ACTION_UP -> {
currentX = event.x
currentY = event.y
pdfview.scrollBy((preX - currentX).toInt(), (preY - currentY).toInt())
m.postTranslate(
-(preX - currentX).toInt().toFloat().px,
-(preY - currentY).toInt().toFloat().px
)
}
}
true
}
图像视图位图:
@Throws(IOException::class)
private fun openPdfFromStorage(uri: Uri) {
var FILE_NAME = getFileName(uri)//"temp${Date()}.pdf"
if (FILE_NAME == null) FILE_NAME = "temp${Date()}.pdf"
val fileCopy = File(cacheDir, FILE_NAME) //anything as the name
copyToCache(fileCopy, uri) /////////// Function not shown. Reads full file from Uri and place it in memory
// Get a page from the PDF doc by calling 'open'
val fileDescriptor = ParcelFileDescriptor.open(
fileCopy,
ParcelFileDescriptor.MODE_READ_ONLY
)
mPdfRenderer = PdfRenderer(fileDescriptor)
pdfpages = mPdfRenderer.pageCount
pdfnum = 0
val mPdfPage = mPdfRenderer.openPage(pdfnum)
val bitmap = Bitmap.createBitmap(
pdfview.width, //bmWidth,
pdfview.height, //bmHeight,
Bitmap.Config.ARGB_8888
) //Not RGB, but ARGB
mPdfPage.render(bitmap, null, null, PdfRenderer.Page.RENDER_MODE_FOR_DISPLAY)
pdfview.setImageBitmap(bitmap)
///////////
// WHEN THIS IS EXECUTED OVER A PREVIOUSLY USED IMAGEVIEW THE BITMAP IS SHOWN WITH THE SAME POSITION AND SCALE OF THE PREVIOUS BITMAP
///////////
pdfview.setScaleType(ImageView.ScaleType.CENTER_CROP)
pdfview.setScaleType(ImageView.ScaleType.MATRIX)
m = pdfview.imageMatrix
mPdfPage.close()
pbounds = getImageBounds(pdfview) //imageView.imageMatrix.mapRect(bounds, RectF(drawable.bounds))
centerX = pbounds.centerX()
centerY = pbounds.centerY()
}
一旦我发现如何正确地使用矩阵移动机制,就很简单了:
在替换图像之前,将当前图像移动到原点。 以下代码会将图像平移回原点。
val sX = scrollX //current X coord.
val sY = scrollY //current Y coord.
val pX = pscrollX //previous X coord.
val pY = pscrollY //previous Y coord.
m.postTranslate(-(pX - sX), -(pY - sY))
pdfview.imageMatrix = m
val f = FloatArray(9)
m.getValues(f)
pscrollX = f[Matrix.MTRANS_X]
pscrollY = f[Matrix.MTRANS_Y]
然后替换图像:
pdfview.imageMatrix = Matrix()
pdfview.scaleType = ImageView.ScaleType.MATRIX
pdfview.setImageBitmap(bitmap)