1. 程式人生 > >android 螢幕的放大縮小實現

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