Android是一种基于Linux的自由及开放源代码的操作系统,主要使用于移动设备,如智能手机和平板电脑,由Google公司和开放手机联盟领导及开发。尚未有统一中文名称,中国大陆地区较多人使用“安卓”或“安致”。
这篇文章主要介绍了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];
- }
- }
来源: http://www.phperz.com/article/17/0915/349010.html