android 双击图片变大,缩放功能
package com.example.administrator.myapplicationphotochange; /**
* Created by Administrator on 2016/8/22.
*/
import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.Matrix;
import android.util.AttributeSet;
import android.util.FloatMath;
import android.view.MotionEvent;
import android.widget.ImageView; public class ImageControl extends ImageView {
public ImageControl(Context context) {
super(context);
// TODO Auto-generated constructor stub
} public ImageControl(Context context, AttributeSet attrs) {
super(context, attrs);
// TODO Auto-generated constructor stub
} public ImageControl(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
// TODO Auto-generated constructor stub
} // ImageView img;
Matrix imgMatrix = null; // 定义图片的变换矩阵 static final int DOUBLE_CLICK_TIME_SPACE = 300; // 双击时间间隔
static final int DOUBLE_POINT_DISTANCE = 10; // 两点放大两点间最小间距
static final int NONE = 0;
static final int DRAG = 1; // 拖动操作
static final int ZOOM = 2; // 放大缩小操作
private int mode = NONE; // 当前模式 float bigScale = 3f; // 默认放大倍数
Boolean isBig = false; // 是否是放大状态
long lastClickTime = 0; // 单击时间
float startDistance; // 多点触摸两点距离
float endDistance; // 多点触摸两点距离 float topHeight; // 状态栏高度和标题栏高度
Bitmap primaryBitmap = null; float contentW; // 屏幕内容区宽度
float contentH; // 屏幕内容区高度 float primaryW; // 原图宽度
float primaryH; // 原图高度 float scale; // 适合屏幕缩放倍数
Boolean isMoveX = true; // 是否允许在X轴拖动
Boolean isMoveY = true; // 是否允许在Y轴拖动
float startX;
float startY;
float endX;
float endY;
float subX;
float subY;
float limitX1;
float limitX2;
float limitY1;
float limitY2;
ICustomMethod mCustomMethod = null; /**
* 初始化图片
*
* @param bitmap
* 要显示的图片
* @param contentW
* 内容区域宽度
* @param contentH
* 内容区域高度
* @param topHeight
* 状态栏高度和标题栏高度之和
*/
public void imageInit(Bitmap bitmap, int contentW, int contentH,
int topHeight, ICustomMethod iCustomMethod) {
this.primaryBitmap = bitmap;
this.contentW = contentW;
this.contentH = contentH;
this.topHeight = topHeight;
mCustomMethod = iCustomMethod;
primaryW = primaryBitmap.getWidth();
primaryH = primaryBitmap.getHeight();
float scaleX = (float) contentW / primaryW;
float scaleY = (float) contentH / primaryH;
scale = scaleX < scaleY ? scaleX : scaleY;
if (scale < 1 && 1 / scale < bigScale) {
bigScale = (float) (1 / scale + 0.5);
} imgMatrix = new Matrix();
subX = (contentW - primaryW * scale) / 2;
subY = (contentH - primaryH * scale) / 2;
this.setImageBitmap(primaryBitmap);
this.setScaleType(ScaleType.MATRIX);
imgMatrix.postScale(scale, scale);
imgMatrix.postTranslate(subX, subY);
this.setImageMatrix(imgMatrix);
} /**
* 按下操作
*
* @param event
*/
public void mouseDown(MotionEvent event) {
mode = NONE;
startX = event.getRawX();
startY = event.getRawY();
if (event.getPointerCount() == 1) {
// 如果两次点击时间间隔小于一定值,则默认为双击事件
if (event.getEventTime() - lastClickTime < DOUBLE_CLICK_TIME_SPACE) {
changeSize(startX, startY);
} else if (isBig) {
mode = DRAG;
}
} lastClickTime = event.getEventTime();
} /**
* 非第一个点按下操作
*
* @param event
*/
public void mousePointDown(MotionEvent event) {
startDistance = getDistance(event);
if (startDistance > DOUBLE_POINT_DISTANCE) {
mode = ZOOM;
} else {
mode = NONE;
}
} /**
* 移动操作
*
* @param event
*/
public void mouseMove(MotionEvent event) {
if ((mode == DRAG) && (isMoveX || isMoveY)) {
float[] XY = getTranslateXY(imgMatrix);
float transX = 0;
float transY = 0;
if (isMoveX) {
endX = event.getRawX();
transX = endX - startX;
if ((XY[0] + transX) <= limitX1) {
transX = limitX1 - XY[0];
}
if ((XY[0] + transX) >= limitX2) {
transX = limitX2 - XY[0];
}
}
if (isMoveY) {
endY = event.getRawY();
transY = endY - startY;
if ((XY[1] + transY) <= limitY1) {
transY = limitY1 - XY[1];
}
if ((XY[1] + transY) >= limitY2) {
transY = limitY2 - XY[1];
}
} imgMatrix.postTranslate(transX, transY);
startX = endX;
startY = endY;
this.setImageMatrix(imgMatrix);
} else if (mode == ZOOM && event.getPointerCount() > 1) {
endDistance = getDistance(event);
float dif = endDistance - startDistance;
if (Math.abs(endDistance - startDistance) > DOUBLE_POINT_DISTANCE) {
if (isBig) {
if (dif < 0) {
changeSize(0, 0);
mode = NONE;
}
} else if (dif > 0) {
float x = event.getX(0) / 2 + event.getX(1) / 2;
float y = event.getY(0) / 2 + event.getY(1) / 2;
changeSize(x, y);
mode = NONE;
}
}
}
} /**
* 鼠标抬起事件
*/
public void mouseUp() {
mode = NONE;
} /**
* 图片放大缩小
*
* @param x
* 点击点X坐标
* @param y
* 点击点Y坐标
*/
private void changeSize(float x, float y) {
if (isBig) {
// 如果处于最大状态,则还原
imgMatrix.reset();
imgMatrix.postScale(scale, scale);
imgMatrix.postTranslate(subX, subY);
isBig = false;
} else {
imgMatrix.postScale(bigScale, bigScale); // 在原有矩阵后乘放大倍数
float transX = -((bigScale - 1) * x);
float transY = -((bigScale - 1) * (y - topHeight)); // (bigScale-1)(y-statusBarHeight-subY)+2*subY;
float currentWidth = primaryW * scale * bigScale; // 放大后图片大小
float currentHeight = primaryH * scale * bigScale;
// 如果图片放大后超出屏幕范围处理
if (currentHeight > contentH) {
limitY1 = -(currentHeight - contentH); // 平移限制
limitY2 = 0;
isMoveY = true; // 允许在Y轴上拖动
float currentSubY = bigScale * subY; // 当前平移距离
// 平移后,内容区域上部有空白处理办法
if (-transY < currentSubY) {
transY = -currentSubY;
}
// 平移后,内容区域下部有空白处理办法
if (currentSubY + transY < limitY1) {
transY = -(currentHeight + currentSubY - contentH);
}
} else {
// 如果图片放大后没有超出屏幕范围处理,则不允许拖动
isMoveY = false;
} if (currentWidth > contentW) {
limitX1 = -(currentWidth - contentW);
limitX2 = 0;
isMoveX = true;
float currentSubX = bigScale * subX;
if (-transX < currentSubX) {
transX = -currentSubX;
}
if (currentSubX + transX < limitX1) {
transX = -(currentWidth + currentSubX - contentW);
}
} else {
isMoveX = false;
} imgMatrix.postTranslate(transX, transY);
isBig = true;
} this.setImageMatrix(imgMatrix);
if (mCustomMethod != null) {
mCustomMethod.customMethod(isBig);
}
} /**
* 获取变换矩阵中X轴偏移量和Y轴偏移量
*
* @param matrix
* 变换矩阵
* @return
*/
private float[] getTranslateXY(Matrix matrix) {
float[] values = new float[9];
matrix.getValues(values);
float[] floats = new float[2];
floats[0] = values[Matrix.MTRANS_X];
floats[1] = values[Matrix.MTRANS_Y];
return floats;
} /**
* 获取两点间的距离
*
* @param event
* @return
*/
private float getDistance(MotionEvent event) {
float x = event.getX(0) - event.getX(1);
float y = event.getY(0) - event.getY(1);
return(float)Math.sqrt(x * x + y * y);
} /**
* @author Administrator 用户自定义方法
*/
public interface ICustomMethod {
public void customMethod(Boolean currentStatus);
}
}
<?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:paddingBottom="@dimen/activity_vertical_margin"
android:paddingLeft="@dimen/activity_horizontal_margin"
android:paddingRight="@dimen/activity_horizontal_margin"
android:paddingTop="@dimen/activity_vertical_margin"
tools:context="com.example.administrator.myapplicationphotochange.MainActivity"> <com.example.administrator.myapplicationphotochange.ImageControl
android:id="@+id/common_imageview_imageControl1"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:src="@mipmap/ic_launcher" /> <LinearLayout
android:id="@+id/common_imageview_llTitle"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="50dp"
android:layout_alignParentLeft="true"
android:layout_alignParentTop="true" > <TextView
android:id="@+id/common_imageview_title"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_weight="1"
android:text="报告" />
</LinearLayout> </RelativeLayout>
package com.example.administrator.myapplicationphotochange; import android.graphics.Bitmap;
import android.graphics.Rect;
import android.graphics.drawable.BitmapDrawable;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.view.MotionEvent;
import android.view.View;
import android.widget.LinearLayout;
import android.widget.TextView;
import android.widget.Toast; public class MainActivity extends AppCompatActivity { ImageControl imgControl;
LinearLayout llTitle;
TextView tvTitle;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
findView();
tvTitle.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Toast.makeText(MainActivity.this,"ssssssssss",Toast.LENGTH_LONG).show();
}
});
} public void onWindowFocusChanged(boolean hasFocus) {
super.onWindowFocusChanged(hasFocus);
init();
} private void findView() {
imgControl = (ImageControl) findViewById(R.id.common_imageview_imageControl1);
llTitle = (LinearLayout) findViewById(R.id.common_imageview_llTitle);
tvTitle = (TextView) findViewById(R.id.common_imageview_title);
} private void init() {
tvTitle.setText("图片测试");
// 这里可以为imgcontrol的图片路径动态赋值
// ............ Bitmap bmp;
if (imgControl.getDrawingCache() != null) {
bmp = Bitmap.createBitmap(imgControl.getDrawingCache());
} else {
bmp = ((BitmapDrawable) imgControl.getDrawable()).getBitmap();
}
Rect frame = new Rect();
getWindow().getDecorView().getWindowVisibleDisplayFrame(frame);
int statusBarHeight = frame.top;
int screenW = this.getWindowManager().getDefaultDisplay().getWidth();
int screenH = this.getWindowManager().getDefaultDisplay().getHeight()
- statusBarHeight;
if (bmp != null) {
imgControl.imageInit(bmp, screenW, screenH, statusBarHeight,
new ImageControl.ICustomMethod() { @Override
public void customMethod(Boolean currentStatus) {
// 当图片处于放大或缩小状态时,控制标题是否显示
if (currentStatus) {
llTitle.setVisibility(View.GONE);
} else {
llTitle.setVisibility(View.VISIBLE);
}
}
});
}
else
{
Toast.makeText(MainActivity.this, "图片加载失败,请稍候再试!", Toast.LENGTH_SHORT)
.show();
} } @Override
public boolean onTouchEvent(MotionEvent event) {
switch (event.getAction() & MotionEvent.ACTION_MASK) {
case MotionEvent.ACTION_DOWN:
imgControl.mouseDown(event);
break; /**
* 非第一个点按下
*/
case MotionEvent.ACTION_POINTER_DOWN: imgControl.mousePointDown(event); break;
case MotionEvent.ACTION_MOVE:
imgControl.mouseMove(event); break; case MotionEvent.ACTION_UP:
imgControl.mouseUp();
break; } return super.onTouchEvent(event);
}
}
android 双击图片变大,缩放功能的更多相关文章
- CSS3实现鼠标移动到图片上图片变大
CSS3实现鼠标移动到图片上图片变大(缓慢变大,有过渡效果,放大的过程是有动画过渡的,这个过渡的时间可以自定义 <!DOCTYPE html><html> <head&g ...
- 点击图片或者鼠标放上hover .图片变大. 1)可以使用css中的transition, transform 2) 预先设置一个 弹出div. 3)弹出层 alert ; 4) 浏览器的宽度document.documentElement.clientWidth || document.body.clientWidth
变大: 方法一: 利用css属性. 鼠标放上 hover放大几倍. .kecheng_02_cell_content img { /*width: 100px; height: 133px;*/ wi ...
- CSS3动画@keyframes图片变大变小颜色变化
在我做公司官网的时候也会帮着写一些游戏的静态页,今天产品要求为了突出一个按钮,他要有颜色的变化而且要变大变小,然后我就在网上搜了下呼吸灯和其他的案例,写了个小damo,看着还有些魔性嘞. html: ...
- Android imageView图片按比例缩放
android:scaleType可控制图片的缩放方式,示例代码如下: <ImageView android:id="@+id/img" android:src=" ...
- Android 让图片等比例缩放的三种方法
方法一:客户端等比例 前提条件:服务器端需要返回原始图片的“宽和高”或者“宽高缩放比例”,客户端要显示的图片的宽或者高只要其一是固定的(例如:高度为200,宽度未知,或者高度为400宽度未知) 在这种 ...
- CSS3实现鼠标移动到图片上图片变大(缓慢变大,有过渡效果,放大的过程是有动画过渡的,这个过渡的时间可以自定义)
转载自:http://blog.csdn.net/u014175572/article/details/51535768 CSS3的transform:scale()可以实现按比例放大或者缩小功能. ...
- 黑马day18 鼠标事件&图片变大
有时候我们在淘宝网或者京东商城上浏览要购买的商品的时候当把鼠标移动到图图片上的时候会发现图片放大.然后鼠标移动,图片也会跟着移动,接下来我就使用jquery来实现这样的效果: 这是图片文件夹: < ...
- 图片拖拽缩放功能:兼容Chrome、Firefox、IE8+
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&quo ...
- .net 加水印 图片变大很多 解决方法
/// 给图片加水印 中国红木网 /// </summary> /// <param name="originalImg"> ...
随机推荐
- spring boot的项目名称问题
spring boot直接执行main函数时是不需要加项目名称,但是可以在application配置文件中配置server.context-path=/*来配置项目名称: spring mvc的运行方 ...
- js 或运算
表达式a && 表达式b : 计算表达式a(也可以是函数)的运算结果, 如果为 True, 执行表达式b(或函数),并返回b的结果: 如果为 False,返回a的结果: 表达式a || ...
- WEBGL学习【十】运动模型
<!DOCTYPE HTML> <html lang="en"> <head> <title>LWEBGL6.2, Animated ...
- 在Django运行安装mysqlclient和pymysql
推荐使用douban提供的pipy国内镜像服务,如果想手动指定源,可以在pip后面跟-i 来指定源. 下载mysqlclient为例: pip install mysqlclient -i http: ...
- sessionStorage与clone方法在项目中的应用
//资料列表: //JSON.parse(jsonstr); //json格式字符串转换成json对象 //JSON.stringify(jsonobj); //json对象转换成json格式字符串 ...
- HDU2188 - 悼念512汶川大地震遇难同胞——选拔志愿者【巴什博弈】
对于四川同胞遭受的灾难,全国人民纷纷伸出援助之手,几乎每个省市都派出了大量的救援人员,这其中包括抢险救灾的武警部队,治疗和防疫的医护人员,以及进行心理疏导的心理学专家.根据要求,我校也有一个奔赴灾区救 ...
- 刷新linux硬盘存储接口
#!/bin/bash for i in /sys/class/scsi_host/*; do echo "- - -" > $i/scan; done 简写 for i i ...
- 新手学python-Day1-鸡汤,变量,编码,进制,判断
作业要求为编写一个登录接口:`输入用户名密码`认证成功后显示欢迎信息`输错三次锁定做完作业以后,使用ctrl+alt+f格式化一下,特别舒爽 1 def jilu(str): 2 zt = open( ...
- PHP面向对象(二)
7 多态 多态: 多种形态 多态分俩种: 方法重写和方法加载 7.1 方法重写 子类重写了父类的同名的方法 <?php class Person{ public function show(){ ...
- HDU2188(巴什博奕)
悼念512汶川大地震遇难同胞--选拔志愿者 Time Limit: 1000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Other ...