如何在 Android 上禁用方向更改?

问题描述 投票:0回答:14

我有一个应用程序,我只想在纵向模式下使用,所以我定义了 清单 XML 中的 android:screenOrientation="portrait"。这适用于 HTC Magic 手机(也可以防止其他手机上的方向改变)。

但是当我打开硬件 QWERTY 键盘(不是虚拟键盘)时,HTC G1 手机出现问题。我的活动保持纵向模式,但它似乎重新启动并失去了所有状态。 HTC Hero 版本不会发生这种情况。

我的应用程序很大,所以我不希望它在打开键盘时重新启动并丢失所有状态。我怎样才能防止这种情况发生?

android android-activity android-orientation
14个回答
331
投票

2013 年 4 月更新:不要这样做。 2009 年我第一次回答这个问题时,这不是一个好主意,现在也确实不是一个好主意。原因见hackbod的这个回答:

避免在 android 中使用异步任务重新加载活动

android:configChanges="keyboardHidden|orientation"
添加到您的 AndroidManifest.xml。这告诉系统您将自己处理哪些配置更改 - 在这种情况下什么都不做。

<activity android:name="MainActivity"
     android:screenOrientation="portrait"
     android:configChanges="keyboardHidden|orientation">

有关详细信息,请参阅开发人员参考configChanges

但是,您的申请可能会随时中断,例如通过电话,所以你真的应该添加代码来保存应用程序暂停时的状态。

更新: 从Android 3.2开始,您还需要添加“screenSize”:

<activity
    android:name="MainActivity"
    android:screenOrientation="portrait"
    android:configChanges="keyboardHidden|orientation|screenSize">

来自开发人员指南自己处理配置更改

注意:从 Android 3.2(API 级别 13)开始,“屏幕尺寸” 当设备在纵向和横向之间切换时也会发生变化 方向。因此,如果你想防止运行时由于 为 API 级别 13 或更高级别开发时方向发生变化(如 由 minSdkVersion 和 targetSdkVersion 属性声明),你 除了“orientation”之外,还必须包含“screenSize”值 价值。也就是说,你必须声明

android:configChanges="orientation|screenSize"
。但是,如果您的 应用程序目标 API 级别 12 或更低,那么你的活动总是 自行处理此配置更改(此配置更改 不会重新启动您的活动,即使在 Android 3.2 或 更高的设备)。


99
投票

您需要将 AndroidManifest.xml 修改为 Intrications(以前称为 Ashton),并确保活动按您希望的方式处理 onConfigurationChanged 事件。它应该是这样的:

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

41
投票

我一直发现你两者都需要

android:screenOrientation="nosensor" android:configChanges="keyboardHidden|orientation"

23
投票

如前所述,将您的活动(在清单文件中)的

android:configChanges
设置为
keyboardHidden|orientation
然后:

1)覆盖

onConfigurationChanged()

@Override
public void onConfigurationChanged(Configuration newConfig) {
    super.onConfigurationChanged(newConfig);
    //here you can handle orientation change
}

2) 将此行添加到您的活动的

onCreate()

setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE);

这比向

onConfigurationChanged
添加相同的行更好,因为您的应用程序将转为纵向模式然后返回横向(它只会发生一次,但很烦人)。

您还可以为您的活动设置

android:screenOrientation="nosensor"
(在清单中)。 但是 使用这种方式你根本无法处理方向变化。


21
投票

用这个..

    android:screenOrientation="portrait"

14
投票

在您的活动的 OnCreate 方法中使用此代码:

    @Override
public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    this.setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT);

现在您的方向将设置为纵向并且永远不会改变。


10
投票

在 AndroidManifest.xml 文件中,为每个要锁定的活动添加最后

screenOrientation
行:

android:label="@string/app_name"
android:name=".Login"
android:screenOrientation="portrait" >

android:screenOrientation="landscape".


8
投票

在你的androidmanifest.xml文件中:

   <activity android:name="MainActivity" android:configChanges="keyboardHidden|orientation">

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

7
投票

要通过代码锁定屏幕,您必须使用屏幕的实际旋转(0、90、180、270)并且您必须知道它的自然位置,在智能手机中自然位置将是纵向,而在平板电脑中,它将是风景。

这是代码(锁定和解锁方法),它已经在一些设备(智能手机和平板电脑)上进行了测试并且效果很好。

public static void lockScreenOrientation(Activity activity)
{   
    WindowManager windowManager =  (WindowManager) activity.getSystemService(Context.WINDOW_SERVICE);   
    Configuration configuration = activity.getResources().getConfiguration();   
    int rotation = windowManager.getDefaultDisplay().getRotation(); 

    // Search for the natural position of the device    
    if(configuration.orientation == Configuration.ORIENTATION_LANDSCAPE &&  
       (rotation == Surface.ROTATION_0 || rotation == Surface.ROTATION_180) ||  
       configuration.orientation == Configuration.ORIENTATION_PORTRAIT &&   
       (rotation == Surface.ROTATION_90 || rotation == Surface.ROTATION_270))   
    {   
        // Natural position is Landscape    
        switch (rotation)   
        {   
            case Surface.ROTATION_0:    
                activity.setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE);    
                break;      
            case Surface.ROTATION_90:   
                activity.setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_REVERSE_PORTRAIT); 
            break;      
            case Surface.ROTATION_180: 
                activity.setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_REVERSE_LANDSCAPE); 
                break;          
            case Surface.ROTATION_270: 
                activity.setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT); 
                break;
        }
    }
    else
    {
        // Natural position is Portrait
        switch (rotation) 
        {
            case Surface.ROTATION_0: 
                activity.setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT); 
            break;   
            case Surface.ROTATION_90: 
                activity.setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE); 
            break;   
            case Surface.ROTATION_180: 
                activity.setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_REVERSE_PORTRAIT); 
                break;          
            case Surface.ROTATION_270: 
                activity.setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_REVERSE_LANDSCAPE); 
                break;
        }
    }
}

public static void unlockScreenOrientation(Activity activity)
{
    activity.setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED);
}

1
投票

添加

android:configChanges="keyboardHidden|orientation|screenSize" 

你的清单。


1
投票

在 Visual Studio Xamarin 中:

  1. 添加:

using Android.Content.PM;
给你活动命名空间列表。

  1. 添加:

[Activity(ScreenOrientation = Android.Content.PM.ScreenOrientation.Portrait)]

作为你班级的一个属性,像这样:

[Activity(ScreenOrientation = ScreenOrientation.Portrait)]
public class MainActivity : Activity
{...}

1
投票

如果您只想为应用程序中的所有活动设置纵向模式,则可以在应用程序类中像下面这样简单地使用。

class YourApplicationName : Application() {

override fun onCreate() {
    super.onCreate()

    registerActivityLifecycleCallbacks(object : ActivityLifecycleCallbacks {

        override fun onActivityCreated(activity: Activity, savedInstanceState: Bundle?) {
            activity.requestedOrientation = ActivityInfo.SCREEN_ORIENTATION_PORTRAIT
        }

        override fun onActivityStarted(activity: Activity) {

        }

        override fun onActivityResumed(activity: Activity) {

        }

        override fun onActivityPaused(activity: Activity) {

        }

        override fun onActivityStopped(activity: Activity) {

        }

        override fun onActivitySaveInstanceState(activity: Activity, outState: Bundle) {

        }

        override fun onActivityDestroyed(activity: Activity) {

        }

    })

}

}


0
投票

请注意,这些方法现在似乎都不起作用!

Android Studio1中,一种简单的方法是添加

android:screenOrientation="nosensor"
.

这有效地锁定了屏幕方向。


0
投票

旧的解决方案:

@SuppressLint("SourceLockedOrientationActivity")
fun Activity?.lockScreenOrientation() {
    this ?: return

    val display: Display = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) {
        display
    } else {
        @Suppress("DEPRECATION")
        windowManager.defaultDisplay
    } ?: return

    val width: Int = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) {
        window.windowManager.currentWindowMetrics.bounds.width()
    } else {
        @Suppress("DEPRECATION")
        display.width
    }
    val height: Int = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) {
        window.windowManager.currentWindowMetrics.bounds.height()
    } else {
        @Suppress("DEPRECATION")
        display.height
    }

    when (display.rotation) {
        // 0
        Surface.ROTATION_0 -> {
            requestedOrientation = if (height > width) {
                ActivityInfo.SCREEN_ORIENTATION_PORTRAIT
            } else {
                ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE
            }
        }
        // 1
        Surface.ROTATION_90 -> {
            requestedOrientation = if (width > height) {
                ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE
            } else {
                ActivityInfo.SCREEN_ORIENTATION_REVERSE_PORTRAIT
            }
        }
        // 2
        Surface.ROTATION_180 -> {
            requestedOrientation = if (height > width) {
                ActivityInfo.SCREEN_ORIENTATION_REVERSE_PORTRAIT
            } else {
                ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE
            }
        }
        // 3
        Surface.ROTATION_270 -> {
            requestedOrientation = if (width > height) {
                ActivityInfo.SCREEN_ORIENTATION_REVERSE_LANDSCAPE
            } else {
                ActivityInfo.SCREEN_ORIENTATION_PORTRAIT
            }
        }
    }
}

新的解决方案:

fun Activity?.lockScreenOrientation() {
    this ?: return
    requestedOrientation = ActivityInfo.SCREEN_ORIENTATION_LOCKED
}

解锁方案:

fun Activity?.unlockScreenOrientation() {
    this ?: return
    requestedOrientation = ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED
}
© www.soinside.com 2019 - 2024. All rights reserved.