一个旋转layout布局文件
发布日期:2021-06-29 15:24:18 浏览次数:3 分类:技术文章

本文共 4206 字,大约阅读时间需要 14 分钟。

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://codegg.blog.csdn.net/article/details/46592865 如侵犯您的版权,请留言回复原文章的地址,我们会给您删除此文章,给您带来不便请您谅解!

上一篇:欢迎使用CSDN-markdown编辑器
下一篇:Android支持RTL(从右向左)语言

发表评论

最新留言

很好
[***.229.124.182]2024年04月11日 16时02分35秒