android 图片 上下左右滑动,能放大放小

本文介绍了一个Android自定义组件ZoomImageView,实现了图片上下左右滑动及放大缩小的功能。通过ScaleGestureDetector检测缩放手势,GestureDetector处理滑动和双击事件,结合Matrix矩阵变换实现图片的平移和缩放。同时,代码中包含双击放大、缩小的逻辑以及防止多次双击的处理。
package com.crpcg.domain_hchain.view;

import android.annotation.SuppressLint;
import android.content.Context;
import android.graphics.Matrix;
import android.graphics.RectF;
import android.graphics.drawable.Drawable;
import android.os.Build;
import android.util.AttributeSet;
import android.util.Log;
import android.view.GestureDetector;
import android.view.MotionEvent;
import android.view.ScaleGestureDetector;
import android.view.ScaleGestureDetector.OnScaleGestureListener;
import android.view.View;
import android.view.View.OnTouchListener;
import android.view.ViewConfiguration;
import android.view.ViewTreeObserver;
import android.widget.ImageView;

/**
 *
 */
public class ZoomImageView extends ImageView implements ViewTreeObserver.OnGlobalLayoutListener,
      ScaleGestureDetector.OnScaleGestureListener,View.OnTouchListener

{
   @SuppressWarnings("unused")
   private static final String TAG = "ZoomImageView";

   /**
    * 最大放大倍数
    */
   public static final float mMaxScale = 4.0f;

   /**
    * 默认缩放
    */
   private float mInitScale = 1.0f;
   /**
    * 双击放大比例
    */
   private float mMidScale=2.0f;

   /**
    * 检测缩放手势 多点触控手势识别 独立的类不是GestureDetector的子类
    */
   ScaleGestureDetector mScaleGestureDetector = null;//检测缩放的手势
   /**
    *检测类似长按啊 轻按啊 拖动 快速滑动 双击啊等等 OnTouch方法虽然也可以
    * 但是对于一些复杂的手势需求自己去通过轨迹时间等等判断很复杂,因此我们采用系统
    * 提供的手势类进行处理
    */
   private GestureDetector mGestureDetector;
   /**
    * 如果正在缩放中就不向下执行,防止多次双击
    */
   private boolean mIsAutoScaling;
   /**
    * Matrix的对图像的处理
    * Translate 平移变换
    * Rotate 旋转变换
    * Scale 缩放变换
    * Skew 错切变换
    */
   Matrix mScaleMatrix = new Matrix();

   /**
    * 处理矩阵的9个值
    */
   float[] mMartixValue = new float[9];

   public ZoomImageView(Context context) {
      this(context, null);
   }

   public ZoomImageView(Context context, AttributeSet attrs) {
      this(context, attrs, 0);
   }

   public ZoomImageView(Context context, AttributeSet attrs, int defStyleAttr) {
      super(context, attrs, defStyleAttr);
      setScaleType(ScaleType.MATRIX);
      mScaleGestureDetector = new ScaleGestureDetector(context, this);
      this.setOnTouchListener(this); //缩放的捕获要建立在setOnTouchListener      //符合滑动的距离 它获得的是触发移动事件的最短距离,如果小于这个距离就不触发移动控件,
      //viewpager就是用这个距离来判断用户是否翻页
      mTouchSlop = ViewConfiguration.get(context).getScaledTouchSlop();
      //监听双击事件 SimpleOnGestureListenerOnGestureListener接口实现类,
      //使用这个复写需要的方法就可以不用复写所有的方法
      mGestureDetector = new GestureDetector(context,
            new   GestureDetector.SimpleOnGestureListener() {
               @Override
               public boolean onDoubleTap(MotionEvent e) {
                  //如果正在缩放中就不向下执行,防止多次双击
                  if (mIsAutoScaling) {
                     return true;
                  }
                  //缩放的中心点
                  float x = e.getX();
                  float y = e.getY();
                  //如果当前缩放值小于这个临界值 则进行放大
                  if (getScale() < mMidScale) {
                     mIsAutoScaling = true;
                     //view中的方法 已x,y为坐标点放大到mMidScale 延时10ms
                     postDelayed(new AutoScaleRunble(mMidScale, x, y), 16);
                  } else {
                     
Android 应用中实现整个界面的放大并支持上下左右滑动,同时保持界面元素的点击事件正常工作,可以通过结合 `ScaleGestureDetector` 和 `ScrollView`(或 `HorizontalScrollView`)来实现。此外,还需要对布局的父容器进行缩放操作,通常使用 `View.setScaleX()` 和 `View.setScaleY()` 方法。 以下是一个实现思路和关键代码示例: ### 使用 `ScaleGestureDetector` 实现缩放 首先,创建一个自定义的 `ViewGroup`(例如 `FrameLayout`),并为其添加 `ScaleGestureDetector` 来检测用户的缩放手势。 ```java public class ScalableLayout extends FrameLayout { private ScaleGestureDetector scaleGestureDetector; private float scaleFactor = 1.0f; public ScalableLayout(Context context) { this(context, null); } public ScalableLayout(Context context, AttributeSet attrs) { this(context, attrs, 0); } public ScalableLayout(Context context, AttributeSet attrs, int defStyleAttr) { super(context, attrs, defStyleAttr); scaleGestureDetector = new ScaleGestureDetector(context, new ScaleListener()); } @Override public boolean onTouchEvent(MotionEvent event) { scaleGestureDetector.onTouchEvent(event); return true; } private class ScaleListener extends ScaleGestureDetector.SimpleOnScaleGestureListener { @Override public boolean onScale(ScaleGestureDetector detector) { scaleFactor *= detector.getScaleFactor(); // 防止缩放因子过小或过大 scaleFactor = Math.max(0.5f, Math.min(scaleFactor, 5.0f)); setScaleX(scaleFactor); setScaleY(scaleFactor); return true; } } } ``` ### 嵌套 `ScrollView` 和 `HorizontalScrollView` 实现滑动 为了支持上下左右滑动,可以将 `ScalableLayout` 嵌套在 `HorizontalScrollView` 和 `ScrollView` 中。注意,`ScrollView` 只支持垂直滑动,而 `HorizontalScrollView` 支持水平滑动。两者结合可以实现全方向滑动。 ```xml <ScrollView android:layout_width="match_parent" android:layout_height="match_parent"> <HorizontalScrollView android:layout_width="wrap_content" android:layout_height="wrap_content"> <!-- 自定义可缩放布局 --> <com.example.ScalableLayout android:id="@+id/scalableLayout" android:layout_width="wrap_content" android:layout_height="wrap_content"> <!-- 界面内容 --> <LinearLayout android:orientation="vertical" android:layout_width="wrap_content" android:layout_height="wrap_content"> <!-- 添加可点击的子元素 --> <Button android:text="Click Me" android:layout_width="wrap_content" android:layout_height="wrap_content"/> </LinearLayout> </com.example.ScalableLayout> </HorizontalScrollView> </ScrollView> ``` ### 保持点击事件正常工作 当对父容器进行缩放时,需要注意 `View` 的点击事件是否受到影响。由于 `ScaleGestureDetector` 仅影响父容器的缩放,而子元素的布局位置会自动调整,因此点击事件仍然可以正常触发。 此外,如果发现点击事件失效,可以尝试重写 `onInterceptTouchEvent()` 方法以确保事件能够正确传递到子元素。 ### 总结 通过 `ScaleGestureDetector` 实现缩放功能,并结合 `ScrollView` 和 `HorizontalScrollView` 实现滑动功能,可以实现在 Android 应用中对整个界面进行缩放并支持上下左右滑动的效果。同时,由于子元素的布局位置会随父容器缩放而调整,点击事件仍然可以正常工作。
评论 2
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值