将视图层次结构旋转90度

QRo*_*hlf 35 animation android android-widget android-layout

我正在研究FrameLayout的子类,它应该将其所有子项旋转90度.我这样做是为了克服Android 2.1及以下版本中仅限风景的相机限制,让活动处于风景中,但将我的相机叠加放入此framelayout叠加层,使其看起来像是肖像(这就是如何Layar做到了)为了做到这一点,我正在调整Jeff Sharkey的代码来旋转视图.我的问题是我可以旋转Framelayout,但我不能调整它以匹配新的尺寸.所以在我的g1上,而不是在景观中480x320相机视图上的320x480纵向视图,我在中间看到一个320x320的盒子,显示我的纵向视图,两侧被切掉.

到目前为止,这是我的代码:

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);
    }
}
Run Code Online (Sandbox Code Playgroud)

我已经尝试重写OnMeasure切换视图的X和Y维度,但是无法使其工作.非常感谢您提供的任何帮助.

Geo*_*org 39

我有同样的问题,并设法解决它.我没有手动旋转每个视图或布局,而是使用了LayoutAnimationController.

首先,将文件放在/ res/anim /中,名为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>
Run Code Online (Sandbox Code Playgroud)

然后,在您的Activity的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);
 }
Run Code Online (Sandbox Code Playgroud)

如果要旋转位于相机预览视图(SurfaceHolder)上方的元素,只需将FrameLayout放在SurfaceHolder上方,将所有元素放在FrameLayout中并调用Layout"MyScreen_ContentLayout".完成.

希望帮助别人,让我花了很长时间才把所有东西都放在一起.


Ale*_*oss 7

使用API​​级别11及更高版本,您可以使用该方法setRotation(degreesFloat);以编程方式更改视图的旋转,或者您可以使用XML属性在XML android:rotation=""中更改它.还有用于仅更改视图旋转的X或Y值的方法/属性:Android Docs - View(setRotation).

因此,现在只要您使用API​​级别11或更高级别,您就应该能够将旋转应用于包装器布局节点.但是,您可能还需要更改顶级布局的尺寸以匹配旋转后所需的尺寸.即如果你有一个尺寸为800x1280的纵向视图,你必须将它们更改为1280x800,以便在旋转到横向后排成一行.