📅  最后修改于: 2023-12-03 15:07:51.878000             🧑  作者: Mango
在Android开发中,有时需要让用户对界面进行放大或缩小操作。下面我们将介绍如何在Android中实现这个功能。
ScaleGestureDetector
类是Android提供的一个手势识别工具,它可以识别用户的缩放手势,并提供缩放比例。
在布局文件中添加需要缩放的控件,代码片段如下:
<ImageView
android:id="@+id/imageView"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:src="@drawable/image" />
在Activity中获取该控件,并声明ScaleGestureDetector
类的对象和相关变量:
private lateinit var mScaleGestureDetector: ScaleGestureDetector
private var mScaleFactor = 1.0f
private var mMinScaleFactor = 0.1f
private var mMaxScaleFactor = 10.0f
private val mOnScaleGestureListener = object : ScaleGestureDetector.SimpleOnScaleGestureListener() {
override fun onScale(detector: ScaleGestureDetector): Boolean {
mScaleFactor *= detector.scaleFactor
// 限制缩放范围
mScaleFactor = Math.max(mMinScaleFactor, Math.min(mScaleFactor, mMaxScaleFactor))
imageView.scaleX = mScaleFactor
imageView.scaleY = mScaleFactor
return true
}
}
在onCreate
方法中为ScaleGestureDetector
类对象赋值:
mScaleGestureDetector = ScaleGestureDetector(this, mOnScaleGestureListener)
在onTouchEvent
方法中调用ScaleGestureDetector
类的onTouchEvent
方法,以响应缩放手势:
override fun onTouchEvent(event: MotionEvent): Boolean {
mScaleGestureDetector.onTouchEvent(event)
return true
}
private lateinit var mScaleGestureDetector: ScaleGestureDetector
private var mScaleFactor = 1.0f
private var mMinScaleFactor = 0.1f
private var mMaxScaleFactor = 10.0f
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
val imageView = findViewById<ImageView>(R.id.imageView)
mScaleGestureDetector = ScaleGestureDetector(this, mOnScaleGestureListener)
}
private val mOnScaleGestureListener = object : ScaleGestureDetector.SimpleOnScaleGestureListener() {
override fun onScale(detector: ScaleGestureDetector): Boolean {
mScaleFactor *= detector.scaleFactor
mScaleFactor = Math.max(mMinScaleFactor, Math.min(mScaleFactor, mMaxScaleFactor))
imageView.scaleX = mScaleFactor
imageView.scaleY = mScaleFactor
return true
}
}
override fun onTouchEvent(event: MotionEvent): Boolean {
mScaleGestureDetector.onTouchEvent(event)
return true
}
另一种实现放大和缩小效果的方法是使用Matrix
类,该类允许你在运行时对控件的样式和内容进行转换。
在布局文件中添加需要缩放的控件,代码片段如下:
<ImageView
android:id="@+id/imageView"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:src="@drawable/image" />
在Activity中获取该控件,并声明Matrix
类的对象:
private lateinit var mImageView: ImageView
private val mMatrix = Matrix()
在onCreate
方法中为ImageView
类对象赋值:
mImageView = findViewById(R.id.imageView)
在onTouchEvent
方法中对手势进行处理,代码片段如下:
val pointerCount = event.pointerCount
val action = event.actionMasked
when (action) {
MotionEvent.ACTION_DOWN, MotionEvent.ACTION_POINTER_DOWN -> {
if (pointerCount == 2) {
// 设置缩放基准点
mMatrix.setTranslate(event.getX(0), event.getY(0))
}
}
MotionEvent.ACTION_MOVE -> {
if (pointerCount == 2) {
// 修改缩放比例
val distance = distance(event.getX(0), event.getY(0), event.getX(1), event.getY(1))
val scaleFactor = distance / mBaseDistance
mMatrix.setScale(mBaseScale * scaleFactor, mBaseScale * scaleFactor)
}
}
MotionEvent.ACTION_POINTER_UP -> {
if (pointerCount == 2) {
// 保存当前缩放比例
mBaseScale = mMatrix.currentScale
}
}
}
// 更新ImageView的Matrix
mImageView.imageMatrix = mMatrix
最后,还需定义和实现计算两个手指之间距离的方法:
private fun distance(x1: Float, y1: Float, x2: Float, y2: Float): Float {
val x = x1 - x2
val y = y1 - y2
return Math.sqrt(x * x + y * y.toDouble()).toFloat()
}
private lateinit var mImageView: ImageView
private val mMatrix = Matrix()
private var mBaseDistance = 0f
private var mBaseScale = 1f
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
mImageView = findViewById(R.id.imageView)
}
override fun onTouchEvent(event: MotionEvent): Boolean {
val pointerCount = event.pointerCount
val action = event.actionMasked
when (action) {
MotionEvent.ACTION_DOWN, MotionEvent.ACTION_POINTER_DOWN -> {
if (pointerCount == 2) {
// 设置缩放基准点
mMatrix.setTranslate(event.getX(0), event.getY(0))
}
}
MotionEvent.ACTION_MOVE -> {
if (pointerCount == 2) {
// 修改缩放比例
val distance = distance(event.getX(0), event.getY(0), event.getX(1), event.getY(1))
val scaleFactor = distance / mBaseDistance
mMatrix.setScale(mBaseScale * scaleFactor, mBaseScale * scaleFactor)
}
}
MotionEvent.ACTION_POINTER_UP -> {
if (pointerCount == 2) {
// 保存当前缩放比例
mBaseScale = mMatrix.currentScale
}
}
}
// 更新ImageView的Matrix
mImageView.imageMatrix = mMatrix
return true
}
private fun distance(x1: Float, y1: Float, x2: Float, y2: Float): Float {
val x = x1 - x2
val y = y1 - y2
return Math.sqrt(x * x + y * y.toDouble()).toFloat()
}
以上就是两种实现放大和缩小效果的方法。你可以根据自己的需求选择其中一种方法来实现。