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流畅