旋转视图层次90度
我正在研究FrameLayout的子类,它应该旋转所有的孩子90度。 我这样做是为了克服Android 2.1及以下版本中的风景相机限制,通过将活动放在横向上,但将相机覆盖放入此框架布局覆盖图中,使其看起来像是人像( 这是如何Layar是这样做的 )为了完成这个,我正在调整Jeff Sharkey的代码来旋转视图。 我的问题是,我可以旋转Framelayout,但我不能调整它来匹配新的尺寸。 所以在我的g1上,而不是320×480的横向480×320照相机视图的纵向视图,我得到一个320×320框在中间显示我的肖像视图与两边砍掉。
这是我的代码到目前为止:
public class RotateLayout extends FrameLayout { private Matrix mForward = new Matrix(); private Matrix mReverse = new Matrix(); private float[] mTemp = new float[2]; public RotateLayout(Context context) { super(context); } public RotateLayout(Context context, AttributeSet attrs) { super(context, attrs); } /* (non-Javadoc) * @see android.widget.FrameLayout#onMeasure(int, int) */ @Override protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { super.onMeasure(widthMeasureSpec, heightMeasureSpec); //This didn't work: //super.onMeasure(heightMeasureSpec, widthMeasureSpec); } /* (non-Javadoc) * @see android.widget.FrameLayout#onSizeChanged(int, int, int, int) */ @Override protected void onSizeChanged(int w, int h, int oldw, int oldh) { super.onSizeChanged(w, h, oldw, oldh); } @Override protected void dispatchDraw(Canvas canvas) { canvas.rotate(270, getWidth()/2, getHeight()/2); //This code will stretch the canvas to accommodate the new screen size. This is not what I want. //float scaleX=(float)getHeight()/getWidth(); //float scaleY=(float)getWidth()/getHeight(); //canvas.scale(scaleX, scaleY, getWidth()/2, getHeight()/2); mForward = canvas.getMatrix(); mForward.invert(mReverse); canvas.save(); canvas.setMatrix(mForward); //This is the matrix we need to use for proper positioning of touch events super.dispatchDraw(canvas); canvas.restore(); } @Override public boolean dispatchTouchEvent(MotionEvent event) { final float[] temp = mTemp; temp[0] = event.getX(); temp[1] = event.getY(); mReverse.mapPoints(temp); event.setLocation(temp[0], temp[1]); return super.dispatchTouchEvent(event); } }
我已经尝试覆盖OnMeasure
切换视图的X和Y维度,但一直没有能够得到这个工作。 任何帮助,您可以提供非常感谢。
我有同样的问题,并设法解决它。 我不用手动旋转每个视图或布局,而是使用了一个LayoutAnimationController。
首先,在/ res / anim / called rotation.xml中放置一个文件
<?xml version="1.0" encoding="utf-8"?> <rotate xmlns:android="http://schemas.android.com/apk/res/android" android:fromDegrees="0" android:toDegrees="-90" android:pivotX="50%" android:pivotY="50%" android:duration="0" android:fillAfter="true"> </rotate>
然后,在你的活动的onCreate,做
@Override public void onCreate(Bundle icicle) { super.onCreate(icicle); setContentView(R.layout.myscreen); Animation rotateAnim = AnimationUtils.loadAnimation(this, R.anim.rotation); LayoutAnimationController animController = new LayoutAnimationController(rotateAnim, 0); FrameLayout layout = (FrameLayout)findViewById(R.id.MyScreen_ContentLayout); layout.setLayoutAnimation(animController); }
如果要旋转位于相机预览视图(SurfaceHolder)之上的元素,只需在SurfaceHolder上方放置一个FrameLayout,将所有元素放置在该FrameLayout中,然后调用布局“MyScreen_ContentLayout”。 完成。
希望帮助别人,花了我相当长的时间把所有的东西放在一起。
使用API级别11和更高版本,您可以使用方法setRotation(degreesFloat);
以编程方式更改视图的旋转,或者您可以使用XML属性android:rotation=""
在XML中对其进行更改。 还有一些方法/属性只能改变视图旋转的X或Y值: Android Docs – View(setRotation) 。
所以现在只要你使用API级别11或更高,你应该能够将旋转应用到包装布局节点。 但是,您可能还需要更改顶层布局的尺寸以匹配旋转后所需的尺寸。 也就是说,如果您有一个尺寸为800×1280的纵向视图,您必须将它们更改为1280×800,以便在旋转到横向后排列它们。
使用这个库你可以旋转整个视图层次https://github.com/rongi/rotate-layout
喜欢这个
一般来说,这对我来说是一种工作。
private void init() { setRotation(90f); } public YourViewOrViewGroup(final Context context) { super(context); init(); } ... (all the View/ViewGroup constructors) ... @Override protected void onLayout(final boolean changed, final int l, final int t, final int r, final int b) { super.onLayout(changed, l, t, r, b); final int width = getWidth(); final int height = getHeight(); final int offset = Math.abs(width - height) / 2; setTranslationX(-offset); setTranslationY(offset); } @Override protected void onMeasure(final int widthMeasureSpec, final int heightMeasureSpec) { super.onMeasure(heightMeasureSpec, widthMeasureSpec); }
你想要做的是交换宽度与高度,然后把X和Y偏移,以便旋转后的视图成为全屏。
以上是一个“风景”旋转的版本。 要实现一个倒转的景观只适用于270度的旋转。 您可以修改代码片段中的代码,也可以以更通用的方式应用外部旋转
final YourViewOrViewGroup layout = inflater.inflate(...); if (currentOrientation.isInverted()) { layout.setRotation(layout.getRotation + 180f); }
通过这种方式,您可以在xml定义中embedded旋转的View / ViewGroup,并在屏幕方向更改时对“port”和“land”版本进行充气,但是这似乎超出了本主题。
编辑:实际上延迟偏移设置要好得多,直到至less一个布局过去。 这是因为在我的情况下,在第一次onMeasure()之后,将会绘制视图(在设置偏移之前)。 最终,它可能会被视为一个小问题,因为视图/布局一开始就不会被绘制在最终的范围内。 (更新了片段)
我想你在onMeasure中忘了一行。
@Override protected synchronized void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { super.onMeasure(heightMeasureSpec, widthMeasureSpec); setMeasuredDimension(getMeasuredHeight(), getMeasuredWidth()); }
从垂直seekbar代码采取在这里: 我怎样才能得到一个工作垂直SeekBar在Android?
您可能需要调整getMeasuredHeight()以使其成为屏幕的正确大小。
尝试closures您的视图根的子剪辑:在您的RotateLayout的父级上调用setClipChildren(false)
,并在您的RotateLayout的onMeasure方法中放置这些行:
super.onMeasure(heightMeasureSpec, widthMeasureSpec); setMeasuredDimension(getMeasuredHeight(), getMeasuredWidth());
我的问题和你基本上是一样的,而且我还没有testing过我的解决scheme – 我明天就做,并告诉它是否工作正常。