一个旋转layout布局文件
2015-06-22 13:14
417 查看
package com.github.rongi.rotate_layout.layout; import android.content.Context; import android.content.res.TypedArray; import android.graphics.Canvas; import android.graphics.Matrix; import android.graphics.Rect; import android.graphics.RectF; import android.util.AttributeSet; import android.view.MotionEvent; import android.view.View; import android.view.ViewGroup; import android.view.ViewParent; import com.github.rongi.rotate_layout.example.R; public class RotateLayout extends ViewGroup { public static class LayoutParams extends ViewGroup.LayoutParams { public int angle; public LayoutParams(Context context, AttributeSet attrs) { super(context, attrs); final TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.RotateLayout_Layout); angle = a.getInt(R.styleable.RotateLayout_Layout_layout_angle, 0); } public LayoutParams(ViewGroup.LayoutParams layoutParams) { super(layoutParams); } } public RotateLayout(Context context) { this(context, null); } public RotateLayout(Context context, AttributeSet attrs) { super(context, attrs); setWillNotDraw(false); } public View getView() { return getChildAt(0); } @Override protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { final View view = getView(); if (view != null) { final LayoutParams layoutParams = (LayoutParams) view .getLayoutParams(); if (angle != layoutParams.angle) { angle = layoutParams.angle; angleChanged = true; } if (Math.abs(angle % 180) == 90) { measureChild(view, heightMeasureSpec, widthMeasureSpec); setMeasuredDimension( resolveSize(view.getMeasuredHeight(), widthMeasureSpec), resolveSize(view.getMeasuredWidth(), heightMeasureSpec)); } else { measureChild(view, widthMeasureSpec, heightMeasureSpec); setMeasuredDimension( resolveSize(view.getMeasuredWidth(), widthMeasureSpec), resolveSize(view.getMeasuredHeight(), heightMeasureSpec)); } } else { super.onMeasure(widthMeasureSpec, heightMeasureSpec); } } @Override protected void onLayout(boolean changed, int l, int t, int r, int b) { if (angleChanged || changed) { final RectF layoutRect = tempRectF1; final RectF layoutRectRotated = tempRectF2; layoutRect.set(0, 0, r - l, b - t); rotateMatrix.setRotate(angle, layoutRect.centerX(), layoutRect.centerY()); rotateMatrix.mapRect(layoutRectRotated, layoutRect); layoutRectRotated.round(viewRectRotated); angleChanged = false; } final View view = getView(); if (view != null) { view.layout(viewRectRotated.left, viewRectRotated.top, viewRectRotated.right, viewRectRotated.bottom); } } @Override protected void dispatchDraw(Canvas canvas) { canvas.save(); canvas.rotate(-angle, getWidth() / 2f, getHeight() / 2f); super.dispatchDraw(canvas); canvas.restore(); } @Override public ViewParent invalidateChildInParent(int[] location, Rect dirty) { invalidate(); return super.invalidateChildInParent(location, dirty); } @Override public boolean dispatchTouchEvent(MotionEvent event) { viewTouchPoint[0] = event.getX(); viewTouchPoint[1] = event.getY(); rotateMatrix.mapPoints(childTouchPoint, viewTouchPoint); event.setLocation(childTouchPoint[0], childTouchPoint[1]); boolean result = super.dispatchTouchEvent(event); event.setLocation(viewTouchPoint[0], viewTouchPoint[1]); return result; } @Override public ViewGroup.LayoutParams generateLayoutParams(AttributeSet attrs) { return new RotateLayout.LayoutParams(getContext(), attrs); } @Override protected boolean checkLayoutParams(ViewGroup.LayoutParams layoutParams) { return layoutParams instanceof RotateLayout.LayoutParams; } @Override protected ViewGroup.LayoutParams generateLayoutParams( ViewGroup.LayoutParams layoutParams) { return new RotateLayout.LayoutParams(layoutParams); } private int angle; private final Matrix rotateMatrix = new Matrix(); private final Rect viewRectRotated = new Rect(); private final RectF tempRectF1 = new RectF(); private final RectF tempRectF2 = new RectF(); private final float[] viewTouchPoint = new float[2]; private final float[] childTouchPoint = new float[2]; private boolean angleChanged = true; }
实现方案:
旋转,重新layout实现重新布局,传递消息时将x y坐标转换,达到目的。
完整工程:
https://github.com/luxiaoming/rotate-layout
![](https://github.com/rongi/rotate-layout/raw/master/docs/screenshot2.png)
相关文章推荐
- 内部类访问的外部变量需要使用final修饰解释原因
- 【麦可网】Cocos2d-X跨平台游戏开发学习笔记---第十五课:Cocos2D-X事件处理1-7
- javascript
- ASP.NET MVC5--添加验证
- 软件工程的一些基本概念总结(北邮版本)
- sgu278:Fuel(线性规划)
- java枚举小结
- Bootstrap 基本用法(续)
- 软件工程的一些基本概念总结(北邮版本)
- 日语学习之沪江N3基础 20150622 -3
- 异或在算法中的应用
- iOS:由URL成员UIImage
- JAVA抽象类和接口的深入探讨
- 双线性差值(由于分析sift源码 )
- Android学习笔记之—采用Pull解析XML文件
- PowerShell获得剪贴板上的数据
- python中if __name__ == '__main__':
- C++中模板声明与实现的分离问题
- sublime text 2的注册码
- iOS开发之旅--揭秘Runtime机制