您的位置:首页 > 其它

缩放系列(三):一个可以手势缩放、拖拽、旋转的layout

2016-09-04 20:15 281 查看
弄了一个下午,终于搞出来了,PowerfulLayout

下面是一个功能强大的改造的例子:

可以实现以下需求:

1.两个手指进行缩放布局

2.所有子控件也随着缩放,

3.子控件该有的功能不能丢失(像button有可被点击的功能,缩放后不能丢失该功能)

相对上个例子,多了一个功能---

4.拖拽(平移)layout

 运行效果图:http://pan.baidu.com/s/1geIoG8r


图片太大就不贴出来了。

 

布局文件test.xml、超级简单的

<?xml version="1.0" encoding="utf-8"?>
<com.example.testbitmapscale.PowerfulLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical" >

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

<ImageButton
android:id="@+id/imageButton2"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:src="@drawable/selector_button1" />
</FrameLayout>

</com.example.testbitmapscale.PowerfulLayout>


java代码:

MainActivity也是超级简单
public class MainActivity extends ActionBarActivity {

private View view;

@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
// setContentView(R.layout.test);
view = View.inflate(this, R.layout.test, null);
setContentView(view);

}

//    @Override
//    public boolean onTouchEvent(MotionEvent event) {
//        if (event.getPointerCount() > 1) {
//            // 多点触控
//            // 返回给ScaleGestureDetector来处理
//            return mScaleGestureDetector.onTouchEvent(event);
//        } else {
//            // 单点触控
//            switch (event.getAction()) {
//            case MotionEvent.ACTION_DOWN:
//                downX = (int) event.getX();
//                downY = (int) event.getY();
//                newHeight = view.getLayoutParams().height;
//                newWidth = view.getLayoutParams().width;
////                 int widthMeasureSpec =
////                 View.MeasureSpec.makeMeasureSpec(2000,View.MeasureSpec.AT_MOST);
////
////                 int heightMeasureSpec
////                 =View.MeasureSpec.makeMeasureSpec(2000,View.MeasureSpec.AT_MOST);
////
////                 view.measure(widthMeasureSpec,heightMeasureSpec);
////
////                 newHeight = view.getMeasuredHeight();
////
////                 newWidth = view.getMeasuredWidth();
//                break;
//            case MotionEvent.ACTION_MOVE:
//                long currentTimeMillis = System.currentTimeMillis();
//                if (currentTimeMillis - lastMultiTouchTime > 200) {
//                    // 双指触控后要等待200毫秒才能执行单指触控的操作,避免双指触控后出现颤抖的情况
//                    int moveX = (int) event.getX();// 移动手指的时候手指的x
//                    int moveY = (int) event.getY();// 移动手指的时候手指的y
//                    int deltaX = (int) (moveX - downX);
//                    int deltaY = (int) (moveY - downY);
//                    int newLeft = left + deltaX;// view的新left
//                    int newTop = top + deltaY;// view的新top
//                    int newRight = right + deltaX;// view的新right
//                    int newBottom = bottom + deltaY;// view的新bottom
////                    int newWidth = (int) (preScale * originalWidth);
////                    int newHeight = (int) (preScale * originalHeight);
////                    if (deltaX>(newWidth-originalHeight)/2||deltaY>(newHeight-originalHeight)/2) {
////                        return false;
////                    }
//                    // int newWidth = view.getWidth();
//                    // int newHeight = view.getHeight();
//                    System.out.println("newWidth:" + newWidth + "newHeight:"
//                            + newHeight);
////                    System.out.println(preScale);
//                    if (newLeft < originalWidth - newWidth) {
//                        newLeft = originalWidth - newWidth;
//                        newRight = newLeft + newWidth;
//                    }
//                    // if (newTop < originalHeight - newHeight){
//                    // newTop = originalHeight - newHeight;
//                    // newBottom= newTop+newHeight;
//                    // }
//                    // if(newRight>originalWidth){
//                    // newRight=originalWidth;
//                    // newLeft=newRight-newWidth;
//                    // }
//                    // if(newBottom>originalHeight){
//                    // newBottom=originalHeight;
//                    // newTop=newBottom-newHeight;
//                    // }
//                    view.layout(newLeft, newTop, newRight, newBottom);// 重新摆放view的位置
//                } else {
//                    return false;
//                }
//
//                break;
//            case MotionEvent.ACTION_UP:
//                // 更新位置信息
//                left = view.getLeft();
//                top = view.getTop();
//                right = view.getRight();
//                bottom = view.getBottom();
//                break;
//
//            default:
//                break;
//            }
//            return true;// 代表消费了事件
//        }
//    }

}

PowerfulLayout.java:

package com.example.testbitmapscale;

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;

public class PowerfulLayout 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;

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

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

public PowerfulLayout(Context context, AttributeSet attrs) {
super(context, attrs);
init(context);
}

public PowerfulLayout(Context context) {
super(context);
init(context);
}

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

// view.post(new Runnable() {
//
// @Override
// public void run() {
// left = view.getLeft();
// top = view.getTop();
// right = view.getRight();
// bottom = view.getBottom();
// originalWidth = view.getWidth();
// originalHeight = view.getHeight();
// }
// });
}

@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);
boolean b = mDragHelper.shouldInterceptTouchEvent(ev);// 由mDragHelper决定是否拦截事件,并传递给onTouchEvent
return b;
}

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=false;
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-detector.getScaleFactor()/3;
scale = preScale - (previousSpan - currentSpan) / 1000;
} else {
// 放大
// scale = preScale+detector.getScaleFactor()/3;
scale = preScale + (currentSpan - previousSpan) / 1000;
}
// 缩放view
if (scale > 0.5) {
ViewHelper.setScaleX(PowerfulLayout.this, scale);// x方向上缩放
ViewHelper.setScaleY(PowerfulLayout.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();// 记录双指缩放后的时间
}
}

}


旋转效果跟缩放效果的用法类似的,一个用的是RotateGestureDetector 一个用的是ScaleGustureDetector都是手势检测器,在这就不写了。
可以手势缩放、拖拽、旋转的layout应用场景,例子:qq侧滑菜单。侧滑的时候菜单中所有子控件跟随父控件从小变大,不过它不支持双指缩放,只是单指操作。链接:http://blog.csdn.net/qq_30948129/article/details/52282451

源码地址:https://github.com/Jszgw/ScaleLayout3
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: 
相关文章推荐