Android实现ImageView图片双击放大及缩小
作者:BetterLaterThanNever 时间:2022-04-07 10:34:06
本文实例介绍了Android实现ImageView图片双击放大及缩小的相关技巧,分享给大家供大家参考,具体内容如下
public class DoubleScaleImageView extends ImageView implements OnTouchListener, OnGlobalLayoutListener {
private boolean isFirst = false;
private float doubleScale;// 双击放大的值
private Matrix mScaleMatrix;
private float defaultScale;// 默认的缩放值
private int mLastPinterCount;// 记录上一次多点触控的数量
private float mLastX;
private float mLastY;
private int mTouchSlop;
private boolean isCanDrag;
private boolean isCheckLeft;
private boolean isCheckTop;
private GestureDetector mGestureDetector;
public DoubleScaleImageView(Context context) {
this(context, null);
}
public DoubleScaleImageView(Context context, AttributeSet attrs) {
this(context, attrs, 0);
}
@SuppressLint("ClickableViewAccessibility")
public DoubleScaleImageView(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
mScaleMatrix = new Matrix();
setScaleType(ScaleType.MATRIX);
setOnTouchListener(this);
// getScaledTouchSlop是一个距离,表示滑动的时候,手的移动要大于这个距离才开始移动控件。如果小于这个距离就不触发移动控件
mTouchSlop = ViewConfiguration.get(context).getScaledTouchSlop();
mGestureDetector = new GestureDetector(context, new GestureDetector.SimpleOnGestureListener() {
@Override
public boolean onDoubleTap(MotionEvent e) {
float x = e.getX();
float y = e.getY();
if (getScale() < doubleScale) {
mScaleMatrix.postScale(doubleScale / getScale(), doubleScale / getScale(), x, y);// 放大
}
else {
mScaleMatrix.postScale(defaultScale / getScale(), defaultScale / getScale(), x, y);// 缩小
}
setImageMatrix(mScaleMatrix);
return super.onDoubleTap(e);
}
});
}
@Override
protected void onAttachedToWindow() {// view附加到窗体上时调用该方法
super.onAttachedToWindow();
getViewTreeObserver().addOnGlobalLayoutListener(this);
}
@SuppressWarnings("deprecation")
@Override
protected void onDetachedFromWindow() {// 将视图从窗体上分离的时候调用该方法。
super.onDetachedFromWindow();
getViewTreeObserver().removeGlobalOnLayoutListener(this);
}
@Override
public void onGlobalLayout() {// 在这个方法中获取ImageView加载完成后的图片
if (!isFirst) {
// 获取控件的宽度和高度
int width = getWidth();
int height = getHeight();
// 得到我们的图片以及图片的宽度及高度
Drawable drawable = getDrawable();
if (drawable == null) { return; }
int imageWidth = drawable.getIntrinsicWidth();// 图片的宽度
int imageHeight = drawable.getIntrinsicHeight();// 图片的高度
float scale = 1.0f;
// 如果图片宽度大于控件宽度,但是图片高度小于控件 高度,我们要缩小图片
if (imageWidth > width && imageHeight < height) {
scale = width * 1.0f / imageWidth;
}
// 如果图片宽度小于控件宽度,但是图片高度大于控件 高度,我们要缩小图片
if (imageWidth < width && imageHeight > height) {
scale = height * 1.0f / imageHeight;
}
// 如果图片的宽度都 大于或小于控件宽度,我们则要对图片进行对应缩放,保证图片占满控件
if ((imageWidth > width && imageHeight > height) || (imageWidth < width && imageHeight < height)) {
scale = Math.min(width * 1.0f / imageWidth, height * 1.0f / imageHeight);
}
// 初始化对应的缩放值
defaultScale = scale;
doubleScale = defaultScale * 2;
// 图片缩放后,将图片要移动到控件中心
int dx = width / 2 - imageWidth / 2;
int dy = height / 2 - imageHeight / 2;
mScaleMatrix.postTranslate(dx, dy);
mScaleMatrix.postScale(defaultScale, defaultScale, width / 2, height / 2);
setImageMatrix(mScaleMatrix);
isFirst = true;
}
}
@SuppressLint("ClickableViewAccessibility")
@Override
public boolean onTouch(View v, MotionEvent event) {
if (mGestureDetector.onTouchEvent(event)) { return true; }
float x = 0;
float y = 0;
int pointerCount = event.getPointerCount();// 获取放在屏幕上的手指数量
for (int i = 0; i < pointerCount; i++) {
x += event.getX(i);
y += event.getY(i);
}
x /= pointerCount;
y /= pointerCount;
if (mLastPinterCount != pointerCount) {
isCanDrag = false;
mLastX = x;
mLastY = y;
}
mLastPinterCount = pointerCount;
switch (event.getAction()) {
case MotionEvent.ACTION_MOVE:
float dx = x - mLastX;
float dy = y - mLastY;
isCanDrag = isMove(dx, dy);
if (isCanDrag) {
RectF rectf = getMatrixRectf();
if (null != getDrawable()) {
isCheckLeft = isCheckTop = true;
if (rectf.width() < getWidth()) {// 如果图片宽度小于控件宽度(屏幕宽度)不允许横向移动
dx = 0;
isCheckLeft = false;
}
if (rectf.height() < getHeight()) {// 如果图片高度小于控件高度(屏幕高度)不允许纵向移动
dy = 0;
isCheckTop = false;
}
mScaleMatrix.postTranslate(dx, dy);
checkTranslateWithBorder();
setImageMatrix(mScaleMatrix);
}
}
mLastX = x;
mLastY = y;
break;
case MotionEvent.ACTION_UP:
case MotionEvent.ACTION_CANCEL:
mLastPinterCount = 0;
break;
}
return true;
}
/**
* 移动图片时进行边界检查
* @description:
* @date 2016-1-8 下午4:02:24
*/
private void checkTranslateWithBorder() {
RectF rectf = getMatrixRectf();
float delX = 0;
float delY = 0;
int width = getWidth();
int height = getHeight();
if (rectf.top > 0 && isCheckTop) {
delY = -rectf.top;
}
if (rectf.bottom < height && isCheckTop) {
delY = height - rectf.bottom;
}
if (rectf.left > 0 && isCheckLeft) {
delX = -rectf.left;
}
if (rectf.right < width && isCheckLeft) {
delX = width - rectf.right;
}
mScaleMatrix.postTranslate(delX, delY);
}
// 判断是否有移动
private boolean isMove(float x, float y) {
return Math.sqrt(x * x + y * y) > mTouchSlop;
}
/**
* 获取图片的位置
* @description:
* @date 2016-1-8 上午9:02:10
*/
private RectF getMatrixRectf() {
Matrix matrix = mScaleMatrix;
RectF recft = new RectF();
if (getDrawable() != null) {
recft.set(0, 0, getDrawable().getIntrinsicWidth(), getDrawable().getIntrinsicHeight());
matrix.mapRect(recft);
}
return recft;
}
// 获取当前图片的缩放值
private float getScale() {
float values[] = new float[9];
mScaleMatrix.getValues(values);
return values[Matrix.MSCALE_X];
}
}
标签:Android,ImageView,图片放大,图片缩小
0
投稿
猜你喜欢
java实现学籍管理系统
2023-04-03 00:32:19
详解Java如何在Array和List之间进行转换
2023-05-27 07:37:27
Unity实现场景加载功能
2021-09-15 12:27:45
Token登陆验证机制的原理及实现
2022-07-08 03:28:19
Spring Boot用户注册验证的实现全过程记录
2023-01-03 01:58:34
C# 解决datagridview控件显示大量数据拖拉卡顿问题
2022-03-21 12:52:24
mybatis-plus的批量新增/批量更新以及问题
2022-10-28 04:44:16
java 中Map详解及实例代码
2023-06-06 01:27:37
C#线程同步的几种方法总结
2022-01-31 19:49:06
SpringBoot+SpringCache实现两级缓存(Redis+Caffeine)
2023-10-02 05:20:58
Java 中 hashCode() 与 equals() 的关系(面试)
2023-08-29 18:03:57
jdk线程池的实现
2023-07-05 18:44:35
idea推送项目到gitee中的创建方法
2021-08-19 11:27:14
MultipartFile中transferTo(File file)的路径问题及解决
2023-11-12 00:07:08
基于Spring Mvc实现的Excel文件上传下载示例
2022-01-22 02:02:56
C#正则表达式分解和转换IP地址实例(C#正则表达式大全 c#正则表达式语法)
2023-07-17 07:11:25
Servlet 过滤器详细介绍
2021-10-21 13:51:57
Android实现多点触控功能
2021-10-18 08:39:33
如何将Object类转换为实体类
2021-11-05 04:45:11
java数据结构与算法数组模拟队列示例详解
2021-07-23 16:50:24