缩放系列(三):一个可以手势缩放、拖拽、旋转的layout
来源:互联网 发布:消失的夫妻 知乎 编辑:程序博客网 时间:2024/06/13 07:23
弄了一个下午,终于搞出来了,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
0 0
- 缩放系列(三):一个可以手势缩放、拖拽、旋转的layout
- 缩放系列(二):所有子控件也随着缩放、手势缩放、多点触控layout
- 缩放系列(一):一个很好的bitmap手势缩放demo(多点触控)
- 手势 平移 缩放 旋转
- 【IOS】扩展UIImageViewEx实现:手势移动,旋转,缩放(附带一个收缩的文字标签功能)
- 【IOS】扩展UIImageViewEx实现:手势移动,旋转,缩放(附带一个收缩的文字标签功能)
- 【IOS】扩展UIImageViewEx实现:手势移动,旋转,缩放(附带一个收缩的文字标签功能)
- 单指手势,旋转,缩放
- 手势识别--拖动,旋转,缩放
- iOS 利用平移缩放旋转手势对view实现对应的平移缩放旋转效果(一)
- android中手势操作图片的平移、缩放、旋转
- android中手势操作图片的平移、缩放、旋转
- android中手势操作图片的平移、缩放、旋转
- unity 手势控制物体旋转缩放(ar)
- touch.js 拖动、缩放、旋转 (鼠标手势)
- unity移动端操作方式(旋转、缩放手势)总结
- Unity 移动端简单手势控制(移动,旋转,缩放)
- iOS手势识别的详细使用(拖动,缩放,旋转,点击,手势依赖,自定义手势)
- 【经典算法】——KMP,深入讲解next数组的求解
- Context——Context的使用(2)
- (一)算法——冒泡排序、选择排序
- css知识点2
- Android-support-v4源码导入项目按钮无法显示
- 缩放系列(三):一个可以手势缩放、拖拽、旋转的layout
- memcache与memcached的概念、区别的相关解释
- boost库 bind实现思路简易版本(去模板化)
- 磁盘与目录的容量
- 出书之一【反射技术】
- 更改时间格式
- 共享可变性设计中存在风险以及解决方法(三)
- bzoj 4688: One-Dimensional 矩阵乘法
- kettle学习日记(1)