如何检测Android中布局的方向变化?

时间:2011-04-20 07:04:25

标签: android

我刚刚实施了方向更改功能 - 例如当布局从纵向变为横向时(反之亦然)。如何检测方向更改事件何时结束。

OrientationEventListener无效。如何获取有关布局方向更改事件的通知?

10 个答案:

答案 0 :(得分:269)

使用Activity的 onConfigurationChanged 方法。 请参阅以下代码:

@Override
public void onConfigurationChanged(Configuration newConfig) {
    super.onConfigurationChanged(newConfig);

    // Checks the orientation of the screen
    if (newConfig.orientation == Configuration.ORIENTATION_LANDSCAPE) {
        Toast.makeText(this, "landscape", Toast.LENGTH_SHORT).show();
    } else if (newConfig.orientation == Configuration.ORIENTATION_PORTRAIT){
        Toast.makeText(this, "portrait", Toast.LENGTH_SHORT).show();
    }
}

您还必须在清单文件中编辑相应的 元素,以包含 android:configChanges 请看下面的代码:

<activity android:name=".MyActivity"
          android:configChanges="orientation|keyboardHidden"
          android:label="@string/app_name">

注意:对于Android 3.2(API级别13)或更高版本,当设备在纵向和横向之间切换时,“屏幕尺寸”也会发生变化。因此,如果要在开发API级别13或更高级别时因为方向更改而阻止运行时重新启动,则必须为API级别13或更高级别声明 android:configChanges =“orientation | screenSize”。

希望这会对你有所帮助...... :)

答案 1 :(得分:12)

layout-land 文件夹中加载布局意味着您有两个单独的布局,然后您必须在setContentView方法中进行onConfigurationChanged

@Override
public void onConfigurationChanged(Configuration newConfig) {
    super.onConfigurationChanged(newConfig);

    // Checks the orientation of the screen
    if (newConfig.orientation == Configuration.ORIENTATION_LANDSCAPE) {
        setContentView(R.layout.yourxmlinlayout-land);
    } else if (newConfig.orientation == Configuration.ORIENTATION_PORTRAIT){
        setContentView(R.layout.yourxmlinlayoutfolder);
    }
}

如果只有一个布局,则无需在此方法中创建setContentView。简单地

@Override
public void onConfigurationChanged(Configuration newConfig) {
    super.onConfigurationChanged(newConfig);
}

答案 2 :(得分:12)

只想在onConfigurationChanged之后向您展示一种保存所有Bundle的方法:

在课程结束后创建新的Bundle:

public class MainActivity extends Activity {
    Bundle newBundy = new Bundle();

接下来,在“protected void onCreate”之后添加:

@Override
public void onConfigurationChanged(Configuration newConfig) {
     super.onConfigurationChanged(newConfig);
     if (newConfig.orientation == Configuration.ORIENTATION_LANDSCAPE) {
            onSaveInstanceState(newBundy);
        } else if (newConfig.orientation == Configuration.ORIENTATION_PORTRAIT) {
            onSaveInstanceState(newBundy);
        }
}

@Override
public void onSaveInstanceState(Bundle outState) {
    super.onSaveInstanceState(outState);
    outState.putBundle("newBundy", newBundy);
}

@Override
protected void onRestoreInstanceState(Bundle savedInstanceState) {
    super.onRestoreInstanceState(savedInstanceState);
    savedInstanceState.getBundle("newBundy");
}

如果你添加这个,你的所有crated类都将保存到MainActivity中。

但最好的方法是在AndroidManifest中添加:

<activity name= ".MainActivity" android:configChanges="orientation|screenSize"/>

答案 3 :(得分:4)

使用此方法

@Override
public void onConfigurationChanged(Configuration newConfig) {
    super.onConfigurationChanged(newConfig);
    if (newConfig.orientation == Configuration.ORIENTATION_PORTRAIT)
    {
        Toast.makeText(getActivity(),"PORTRAIT",Toast.LENGTH_LONG).show();
       //add your code what you want to do when screen on PORTRAIT MODE
    }
    else if (newConfig.orientation == Configuration.ORIENTATION_LANDSCAPE)
    {
        Toast.makeText(getActivity(),"LANDSCAPE",Toast.LENGTH_LONG).show();
        //add your code what you want to do when screen on LANDSCAPE MODE
   }
}

不要忘记在Androidmainfest.xml中添加它

android:configChanges="orientation|screenSize"
像这样

<activity android:name=".MainActivity"
          android:theme="@style/Theme.AppCompat.NoActionBar"
          android:configChanges="orientation|screenSize">

    </activity>

答案 4 :(得分:3)

覆盖活动的方法onConfigurationChanged

答案 5 :(得分:0)

创建OrientationEventListener类的实例并启用它。

OrientationEventListener mOrientationEventListener = new OrientationEventListener(YourActivity.this) {
    @Override
    public void onOrientationChanged(int orientation) {
        Log.d(TAG,"orientation = " + orientation);
    }
};

if (mOrientationEventListener.canDetectOrientation())
    mOrientationEventListener.enable();

答案 6 :(得分:0)

确实,如上所述,我只想提出另一个与您有关的替代方法:

android:configChanges="orientation|keyboardHidden" 

意味着我们明确声明要注入的布局。

如果要保留自动注入功能,请使用layout-land和layout文件夹。您所要做的就是将其添加到onCreate中:

    if (getResources().getConfiguration().orientation == Configuration.ORIENTATION_LANDSCAPE) {
        getSupportActionBar().hide();

    } else if (getResources().getConfiguration().orientation == Configuration.ORIENTATION_PORTRAIT) {
        getSupportActionBar().show();
    }

在这里,我们是否显示操作栏,具体取决于手机的方向

答案 7 :(得分:0)

如果接受的答案对您不起作用,请确保您未在​​清单文件中定义:

android:screenOrientation="portrait"

我的情况是

答案 8 :(得分:0)

如果这对某些较新的开发人员有用,因为上面未指定。只是非常明确:

如果使用 onConfigurationChanged ,则需要两件事:

  1. 活动类中的onConfigurationChanged方法

  2. 在清单中指定将由您的onConfigurationChanged方法

  3. 处理的配置更改

以上答案中的清单清单无疑对清单所属的特定应用正确,但不是正是您需要在清单中添加的内容。在您的活动类中触发onConfigurationChanged方法。即以下清单条目可能不适用于您的应用。

<activity name= ".MainActivity" android:configChanges="orientation|screenSize"/>

在上述清单条目中,有android:configChanges=""的各种Android操作,它们可以触发Activity生命周期中的onCreate。

这非常重要-清单中未指定的那些是触发您的onCreate的清单中指定的那些是触发您的onConfigurationChanged的那些方法

因此,您需要确定需要处理的配置更改。对于像我这样的Android百科全书挑战者,我使用了Android Studio中的快速提示弹出窗口,并添加了几乎所有可能的配置选项。列出所有这些基本上表示我将处理所有内容,由于配置,永不调用onCreate。

<activity name= ".MainActivity" android:configChanges="screenLayout|touchscreen|mnc|mcc|density|uiMode|fontScale|orientation|keyboard|layoutDirection|locale|navigation|smallestScreenSize|keyboardHidden|colorMode|screenSize"/>

现在显然我不想处理所有事情,因此我开始一次消除了上述选项。每次删除后重新构建并测试我的应用。

另一个要点:如果仅自动处理一个触发您的onCreate的配置选项(您的清单清单中未列出该选项),那么它将类似于{{1} } 不管用。您必须将所有相关内容放入清单中。

我最终得到3个最初触发onCreate的触发器,然后我在S10 +上进行了测试,但仍然可以使用onCreate,因此我不得不再次进行消除练习,并且我还需要onConfigurationChanged。因此,请在多种平台上进行测试。

|screenSize

所以我的建议是,尽管我确定有人可以对此进行戳破:

  1. 在您的Activity类中使用TOAST或LOG添加<activity name= ".MainActivity" android:configChanges="screenLayout|uiMode|orientation|screenSize"/> 方法,以便查看其工作时间。

  2. 将所有可能的配置选项添加到清单中。

  3. 通过测试您的应用来确认您的onConfigurationChanged方法是否正常。

  4. 一次从清单文件中删除每个配置选项,然后逐个测试您的应用。

  5. 在尽可能多的设备上进行测试。

  6. 请勿将上面的代码段复制/粘贴到清单文件中。 Android更新会更改列表,因此请使用弹出的Android Studio提示来确保全部获取。

我希望这可以节省一些时间。

我的onConfigurationChanged方法仅用于以下信息。在新生命周期的之后,可以在生命周期中调用onConfigurationChanged,但是之前已重新创建UI。因此,我第一个检查方向的onConfigurationChanged可以正常工作,然后第二个嵌套的if可以查看UI ImageView的可见性。

if

答案 9 :(得分:0)

以最简单的形式实现Kotilin的实现-仅在屏幕从纵向更改为横向时才触发--->如果需要设备进行翻转检测(180度),则需要输入重力传感器值

override fun onCreate(savedInstanceState: Bundle?) {
    super.onCreate(savedInstanceState)
    setContentView(R.layout.activity_main)

val rotation = windowManager.defaultDisplay.rotation

    when (rotation) {            
        0 -> Log.d(TAG,"at zero degree")
        1 -> Log.d(TAG,"at 270 degree")
        2 -> Log.d(TAG,"at 180 degree")
        3 -> Log.d(TAG,"at 90 degree")


    }
}