Android:旋转整个布局

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/21355784/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-20 04:24:44  来源:igfitidea点击:

Android: Rotate whole layout

androidandroid-layoutrotation

提问by boulaycote

I need to be able to rotate whole layouts on the fly (on the click of a button).

我需要能够即时旋转整个布局(单击按钮)。

I am able to rotate the layouts using, eg. layout.setRotation(270.0f). The problem is, after the rotation, the layout heightand widthare not matching its parent's.

我可以使用例如旋转布局。layout.setRotation(270.0f). 问题是,旋转后,布局heightwidth不匹配其父级的.

I have tried inverting heightand widthlike so,

我试过反转heightwidth就像这样,

RelativeLayout layout = (RelativeLayout)findViewById(R.id.rootLayout);
LayoutParams layoutParams = layout.getLayoutParams();
int height = layout.getHeight();
int width = layout.getWidth();
layoutParams.height = width;
layoutParams.width = height;

Which does nothing at all.

什么都不做。

I am working with sdk 14.

我正在与sdk 14.

The first image below is the app as it starts. The second one, after a rotation. I wish to fill the black "space". Any help would be appreciated.

下面的第一张图片是启动时的应用程序。第二个,轮换之后。我想填补黑色的“空间”。任何帮助,将不胜感激。

The images below show only a button in the layout. However, in reality, the layout are a lot more complex. What I am trying to achieve is "faking" a landscape view.

下图仅显示布局中的一个按钮。然而,实际上,布局要复杂得多。我想要实现的是“伪造”景观视图。

When startingAfter rotation

启动时旋转后

Edit:Changed images and added descriptions.

编辑:更改图像并添加说明。

回答by yoah

Not sure why this is useful, but it's a nice puzzle. Here is something that works for me:

不知道为什么这很有用,但这是一个很好的谜题。这是对我有用的东西:

On rotate click, do this:

在旋转单击时,执行以下操作:

RelativeLayout mainLayout = (RelativeLayout) findViewById(R.id.main);
int w = mainLayout.getWidth();
int h = mainLayout.getHeight();

mainLayout.setRotation(270.0f);
mainLayout.setTranslationX((w - h) / 2);
mainLayout.setTranslationY((h - w) / 2);

ViewGroup.LayoutParams lp = (ViewGroup.LayoutParams) mainLayout.getLayoutParams();
lp.height = w;
lp.width = h;
mainLayout.requestLayout();

And the layout:

和布局:

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:id="@+id/main"
    android:layout_height="match_parent"
    android:background="#ffcc88"
    tools:context=".TestRotateActivity" >

    <Button 
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="Test"
        android:layout_alignParentTop="true"
        android:layout_alignParentLeft="true"
        />

    <Button 
        android:id="@+id/rotate"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="Rotate"
        android:layout_centerInParent="true"
        />

</RelativeLayout>

回答by Sagar Shah

Try this code:

试试这个代码:

btnRotate.setOnClickListener(new OnClickListener()
{
    @SuppressLint("NewApi")
    @Override
    public void onClick(View v) 
    {
        int orientation = getResources().getConfiguration().orientation;
        switch(orientation)
        {
            case Configuration.ORIENTATION_LANDSCAPE:
                llparent.setRotation(270.0f);
                RelativeLayout.LayoutParams layoutParams_LandsScape =
                    new RelativeLayout.LayoutParams(
                        rlRoot.getHeight(), rlRoot.getWidth()); 
                layoutParams_LandsScape.setMargins(
                    rlRoot.getTop(), rlRoot.getRight(),
                    rlRoot.getBottom(), rlRoot.getLeft());
                layoutParams_LandsScape.addRule(RelativeLayout.CENTER_IN_PARENT);
                llparent.setLayoutParams(layoutParams_LandsScape);  
                break;
            case Configuration.ORIENTATION_PORTRAIT:
                llparent.setRotation(270.0f);
                RelativeLayout.LayoutParams layoutParams_Portrait =
                    new RelativeLayout.LayoutParams(
                        rlRoot.getHeight(), rlRoot.getWidth()); 
                layoutParams_Portrait.setMargins(
                    0, 0, rlRoot.getBottom(), rlRoot.getLeft());    
                layoutParams_Portrait.addRule(RelativeLayout.CENTER_IN_PARENT);
                llparent.setLayoutParams(layoutParams_Portrait);
                break;
            }
        }
    });
}

And XML:

和 XML:

<RelativeLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".RotateAnim">

    <RelativeLayout
        android:id="@+id/rlroot"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:background="#090">

        <LinearLayout
            android:id="@+id/llParent"
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:background="#900"
            android:gravity="center"
            android:orientation="vertical">

            <Button
                android:id="@+id/button1"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:layout_gravity="center"
                android:gravity="center"
                android:text="Button"/>
        </LinearLayout>
    </RelativeLayout>
</RelativeLayout>

回答by Joyal

Simple and tricky way to make screen orientation along the button click.. with an example..

沿着按钮点击屏幕方向的简单而棘手的方法..举个例子..

Here,I'm using the sharedPreference(Im setting an boolean value based on orientation )

在这里,我使用的是 sharedPreference(我根据方向设置了一个布尔值)

Method for button onClick.

按钮 onClick 的方法。

public void rotate(View v) {
    edt = prefs.edit();

    if (!prefs.getBoolean("screen_protrait", true)) {
        edt.putBoolean("screen_protrait", true);
        setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT);
    } else {
        edt.putBoolean("screen_protrait", false);
        setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE);
    }
    edt.commit();
}

In xml, set an onClick method for rotate button

在xml中,设置旋转按钮的onClick方法

       <Button
   android:id="@+id/bt_rotate"
   android:layout_width="wrap_content"
   android:layout_height="wrap_content"
   android:layout_centerInParent="true"
   android:onClick="rotate"
   android:text="Rotate" />

Last one, is in onCreate of Activity you want to set the Prefernce from Application..as

最后一个,是在 Activity 的 onCreate 中,您要从 Application..as 设置 Prefernce

  prefs = PreferenceManager.getDefaultSharedPreferences(getApplicationContext());

Keep coding.. You can achieve your goal...Let me know,if it's working with your scenario.

继续编码......你可以实现你的目标......让我知道,如果它适用于你的场景。

回答by Takhion

If you want to literally rotate the screen, you can force a screen orientation. Otherwise there's no easy way to do what you are trying to do as View.setRotation(float)will always render the Viewin its "real" bounds and thenrotate it! What I suggest is careful consideration of what elements of the layout should be rotated and then to rotate those specifically.

如果你想从字面上旋转屏幕,你可以强制屏幕方向。否则没有简单的方法来做你想做的事情,因为它View.setRotation(float)总是View在它的“真实”边界内渲染然后旋转它!我的建议是仔细考虑应该旋转布局的哪些元素,然后专门旋转这些元素。

The only true "automatic" way of achieving it would be to create a custom layout that essentially measures, layouts and draws children rotated... Honestly I would only go there if I really, reallyneeded to and it's probably more trouble than it's worth!

实现它的唯一真正“自动”方式是创建一个自定义布局,该布局基本上可以测量、布局和绘制旋转的儿童......老实说,我只会在我真的、真的需要时去那里,而且这可能比它的价值更麻烦!

回答by Rajan

i'll suggest you rotate only button rather than rotating the whole layout like

我建议你只旋转按钮而不是像旋转整个布局一样

btn_rotate.setOnClickListener(new OnClickListener() {

@Override
public void onClick(View v) 
{
    rotation = AnimationUtils.loadAnimation(MainActivity.this, R.anim.rotate);
    rotation.setFillAfter(true);
    btn_rotate.startAnimation(rotation);
}
});

rotate.xml

旋转文件

<set>
    <rotate
          xmlns:android="http://schemas.android.com/apk/res/android"
          android:duration="0"
          android:fromDegrees="270"
          android:pivotX="50%"
          android:pivotY="50%"
          android:startOffset="0"
          android:toDegrees="270" />
</set>

回答by rexxar

    // get root layout from activity's XML
    LinearLayout mParentLayout = (LinearLayout) findViewById(R.id.activity_main);

    // get screen size from DisplayMetrics if you need to rotate before the screen is shown
    DisplayMetrics displayMetrics = new DisplayMetrics();
    getWindowManager().getDefaultDisplay().getMetrics(displayMetrics);

    int height = displayMetrics.heightPixels;
    int width = displayMetrics.widthPixels;

    // if you are rotating after the view was shown
    // acquire width and height from the layout's parent's LayoutParams

    // calculate offset to move the view into correct position
    int offset = (width - height) / 2;

    // rotate the layout
    FrameLayout.LayoutParams lp = new FrameLayout.LayoutParams(height, width);
    mParentLayout.setLayoutParams(lp);
    // 90° clockwise
    mParentLayout.setRotation(90.0f);
    mParentLayout.setTranslationX(offset);
    mParentLayout.setTranslationY(-offset);

It may look like the suggested answer, but this displays how to get dimensions from DisplayMetrics and the calculating the offset for the translation is a little different because that's the only way it worked properly.

它可能看起来像建议的答案,但这显示了如何从 DisplayMetrics 获取尺寸,并且计算平移的偏移量有点不同,因为这是它正常工作的唯一方法。

回答by Andybhai

Try this code:
(RelativeLayoutOuterFrame) it is the name of your layout.which you want to rotate.

试试这个代码:
(RelativeLayoutOuterFrame) 它是你想要旋转的布局的名称。

Actually, we are not rotate the layout.we just change height an width value.

实际上,我们不是旋转布局。我们只是改变高度和宽度值。

    int w = RelativeLayoutOuterFrame.getWidth();
    int h = RelativeLayoutOuterFrame.getHeight();
    ViewGroup.LayoutParams lp = (ViewGroup.LayoutParams) RelativeLayoutOuterFrame.getLayoutParams();
    lp.height = w;
    lp.width = h;
    RelativeLayoutOuterFrame.setGravity(RelativeLayout.CENTER_IN_PARENT);
    RelativeLayoutOuterFrame.setGravity(RelativeLayout.CENTER_HORIZONTAL);
    RelativeLayoutOuterFrame.requestLayout();

回答by Alex

try set your layout params to match_parent after rotation:

尝试在旋转后将您的布局参数设置为 match_parent:

layout.setRotation(270.0f)

and then

进而

RelativeLayout layout = (RelativeLayout) findViewById(R.id.rootLayout);     
layout.setLayoutParams(new LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT));

EDIT: get the parentView View parent = layout.getParent();and set the width and height of the parent view to your layout as you need - in width to height and vice versa.

编辑:获取 parentViewView parent = layout.getParent();并根据需要将父视图的宽度和高度设置为您的布局 - 宽度到高度,反之亦然。

回答by albert2702

Android: alternate layout xml for landscape mode

Android:横向模式的备用布局 xml

As I can remember, you should define a new layout for the horizontal view. I think this link can help you

我记得,您应该为水平视图定义一个新布局。我认为这个链接可以帮助你