android 屏幕的放大缩小实现

                       ios中 UIScrollView能很好的实现放大缩小功能,在anroid这里,scrollview并不能很好的支持放大缩小,而对于简单的图片放大,缩小,android可以使用
ZoomControls

控件来实现一些简单图片放大缩小,移动,,,,当然,直接使用webview来加载图片也是能很好实现图片放大缩小功能的。

                     不过简单的只是图片放大,缩小,并不能满足我们的需要,在实际应用中,我们经常需要的是整个布局的放大缩小,移动,而且布局中的子view也应该随着同时放大,缩小,,,子控件相对于父容器的位置不应该变化,同时一些点击事件等也不应该被覆盖。

                  对于实现整个布局的放大缩小,我们一般的思路是

1 捕捉手势,拿到x和y的偏移

2 更据偏移的数据,来放大x,y,同时所以子控件也随着放大同样倍数。

3 移动的话就简单一些,直接使用view的移动动画,同时移动就行。

实际编程中,为了更好支持早期的版本,所以,我们需要在项目中引入nineoldandroids。2.4.0jar包,然后自定义一个布局类

package com.test.myvideo.SuoMudeio;

import android.content.Context;
import android.support.v4.widget.ViewDragHelper;
import android.util.AttributeSet;
import android.view.MotionEvent;
import android.view.ScaleGestureDetector;
import android.view.View;
import android.widget.FrameLayout;

import com.nineoldandroids.view.ViewHelper;

/**
 * _oo0oo_
 * o8888888o
 * 88" . "88
 * (| -_- |)
 * 0\  =  /0
 * ___/`---'\___
 * .' \\|     |// '.
 * / \\|||  :  |||// \
 * / _||||| --|||||- \
 * |   | \\\  -  /// |   |
 * | \_|  ''\---/''  |_/ |
 * \  .-\__  '-'  ___/-. /
 * ___'. .'  /--.--\  `. .'___
 * ."" '<  `.___\_<|>_/___.' >' "".
 * | | :  `- \`.;`\ _ /`;.`/ - ` : | |
 * \  \ `_.   \_ __\ /__ _/   .-` /  /
 * =====`-.____`.___ \_____/___.-`___.-'=====
 * `=---='
 * 佛祖保佑        永无BUG
 * 佛曰:
 * 程序园里程序天,程序天里程序员;
 * 程序猿人写程序,又拿程序换肉钱。
 * 肉饱继续桌前坐,饱暖还是桌前眠;
 * 半迷半醒日复日,码上码下年复年。
 * 但愿叱咤互联世,不愿搬砖码当前;
 * 诸葛周瑜算世事,我来算出得加钱。
 * 别人笑我忒直男,我笑自己太像猿;
 * 但见成都府国内,处处地地程序员。
 * Created by 水东流 on 2018/2/26 0026.
 */

public class PowerFullLayout extends FrameLayout {

    // 屏幕宽高
    private int screenHeight;
    private int screenWidth;
    private ViewDragHelper mDragHelper;
    private long lastMultiTouchTime;// 记录多点触控缩放后的时间
    private int originalWidth;// view宽度
    private int originalHeight;// view高度
    private ScaleGestureDetector mScaleGestureDetector = null;
    // private View view;
    private int downX;// 手指按下的x坐标值
    private int downY;// 手指按下的y坐标值
    private int left;// view的左坐标值
    private int top;// view的上坐标值
    private int right;// view的右坐标值
    private int bottom;// view的下坐标值
    private int newHeight;
    private int newWidth;

    public  boolean isScale = false;
    private float scale;
    private float preScale = 1;// 默认前一次缩放比例为1

    public PowerFullLayout(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        init(context);
    }

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

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

    private void init(Context context) {
        mDragHelper = ViewDragHelper.create(this, callback);
        mScaleGestureDetector = new ScaleGestureDetector(context,
                new ScaleGestureListener());

    }

    @Override
    protected void onSizeChanged(int w, int h, int oldw, int oldh) {
        super.onSizeChanged(w, h, oldw, oldh);
        screenWidth = getMeasuredWidth();
        screenHeight = getMeasuredHeight();
    }

    @Override
    public boolean onInterceptTouchEvent(MotionEvent ev) {
        super.onInterceptTouchEvent(ev);

        return isScale;
    }


    private boolean needToHandle=true;
    @Override
    public boolean onTouchEvent(MotionEvent event) {

        int pointerCount = event.getPointerCount(); // 获得多少点
        if (pointerCount > 1) {// 多点触控,
            switch (event.getAction()) {
                case MotionEvent.ACTION_DOWN:
                    needToHandle=true;
                    break;
                case MotionEvent.ACTION_MOVE:

                    break;
                case MotionEvent.ACTION_POINTER_2_UP://第二个手指抬起的时候
                    needToHandle=true;
                    break;

                default:
                    break;
            }
            return mScaleGestureDetector.onTouchEvent(event);//mScaleGestureDetector处理触摸事件
        } else {
            long currentTimeMillis = System.currentTimeMillis();
            if (currentTimeMillis - lastMultiTouchTime > 200&&needToHandle) {
//                  多点触控全部手指抬起后要等待200毫秒才能执行单指触控的操作,避免多点触控后出现颤抖的情况
                try {
                    mDragHelper.processTouchEvent(event);
                } catch (Exception e) {
                    e.printStackTrace();
                }
                return true;
            }
//            }
        }
        return false;
    }

    private ViewDragHelper.Callback callback = new ViewDragHelper.Callback() {
        /**
         * 用于判断是否捕获当前child的触摸事件
         *
         * @param child
         *            当前触摸的子view
         * @param pointerId
         * @return true就捕获并解析;false不捕获
         */
        @Override
        public boolean tryCaptureView(View child, int pointerId) {
            if (preScale > 1){
                return true;
            }
            return false;
        }

        /**
         * 控制水平方向上的位置
         */
        @Override
        public int clampViewPositionHorizontal(View child, int left, int dx) {

            if (left < (screenWidth - screenWidth * preScale) / 2)
                left = (int) (screenWidth - screenWidth * preScale) / 2;// 限制mainView可向左移动到的位置
            if (left > (screenWidth * preScale - screenWidth) / 2)
                left = (int) (screenWidth * preScale - screenWidth) / 2;// 限制mainView可向右移动到的位置
            return left;
        }

        public int clampViewPositionVertical(View child, int top, int dy) {

            if (top < (screenHeight - screenHeight * preScale) / 2) {
                top = (int) (screenHeight - screenHeight * preScale) / 2;// 限制mainView可向上移动到的位置
            }
            if (top > (screenHeight * preScale - screenHeight) / 2) {
                top = (int) (screenHeight * preScale - screenHeight) / 2;// 限制mainView可向上移动到的位置
            }
            return top;
        }

    };

    public class ScaleGestureListener implements
            ScaleGestureDetector.OnScaleGestureListener {

        @Override
        public boolean onScale(ScaleGestureDetector detector) {

            float previousSpan = detector.getPreviousSpan();// 前一次双指间距
            float currentSpan = detector.getCurrentSpan();// 本次双指间距
            if (currentSpan < previousSpan) {
                // 缩小
                scale = preScale - (previousSpan - currentSpan) / 1000;
            } else {
                // 放大
                scale = preScale + (currentSpan - previousSpan) / 1000;
            }
            // 缩放view
            if (scale > 0.5) {
                ViewHelper.setScaleX(PowerFullLayout.this, scale);// x方向上缩放
                ViewHelper.setScaleY(PowerFullLayout.this, scale);// y方向上缩放
            }
            return false;
        }

        @Override
        public boolean onScaleBegin(ScaleGestureDetector detector) {
            // 一定要返回true才会进入onScale()这个函数
            return true;
        }

        @Override
        public void onScaleEnd(ScaleGestureDetector detector) {
            preScale = scale;// 记录本次缩放比例
            lastMultiTouchTime = System.currentTimeMillis();// 记录双指缩放后的时间
        }
    }


}

xml中的实际情况
<?xml version="1.0" encoding="utf-8"?>
<com.test.myvideo.SuoMudeio.PowerFullLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:id="@+id/activity_shuofang"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context="com.test.myvideo.ShuofangActivity">

    <FrameLayout
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:background="@drawable/aa">

        <ImageButton
            android:id="@+id/imageButton2"
            android:layout_width="50dp"
            android:layout_height="50dp"
            android:src="@drawable/icon_app" />

        <TextView
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_marginLeft="50dp"
            android:layout_marginTop="50dp"
            android:background="@color/colorAccent"
            android:onClick="dian"
            android:text="测试2,我"
            android:textSize="20dp" />

        <TextView
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_marginLeft="250dp"
            android:layout_marginTop="100dp"
            android:background="@color/colorAccent"
            android:onClick="diantwo"
            android:text="测试2,我"
            android:textSize="20dp" />

        <TextView
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_marginLeft="150dp"
            android:layout_marginTop="150dp"
            android:background="@color/colorAccent"
            android:onClick="dianthree"
            android:text="测试2,我"
            android:textSize="20dp" />
    </FrameLayout>
</com.test.myvideo.SuoMudeio.PowerFullLayout>
如上,即可简单的实现anroid的缩放和放大。。。不过采用此种方式,,在布局中缩小,放大,实际使用没有ios的 UIScrollView流畅



 



  • 2
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值