强制“人像”定向模式


298

我试图对我的应用程序强制使用“人像”模式,因为我的应用程序绝对不是针对“风景”模式设计的。

阅读一些论坛后,我在清单文件中添加了以下几行:

<application 
  android:debuggable="true"
  android:icon="@drawable/icon" 
  android:label="@string/app_name"
  android:screenOrientation="portrait">

但这不适用于我的设备(HTC Desire)。它从“肖像”或“风景”切换,而忽略清单文件中的行。

在更多论坛上阅读后,我尝试将其添加到清单文件中:

<application 
  android:debuggable="true"
  android:icon="@drawable/icon" 
  android:label="@string/app_name"
  android:configChanges="orientation"       
  android:screenOrientation="portrait">

而这个功能在我的活动课中:

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

但同样,没有运气。

Answers:


531

不要将方向应用于application元素,而是应将属性应用于activity元素,并且还必须configChanges按照以下说明进行设置。

例:

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

这将应用在清单文件中AndroidManifest.xml


26
configChanges是做什么用的?
Dror 2012年

71
@ Orchestrator,configChanges表示配置更改由活动本身处理。没有它,如果方向发生变化,该活动将重新启动。您可能会问,如果您已指定方向为“人像”,它将如何改变?如果您启动另一个改变方向的活动,它可能会改变,然后新活动退出,使您返回到活动中。例如,Samsung Galaxy S3上的默认图像捕获意图会在某些方向上做到这一点。
Gordon McCreight 2013年

2
@GordonMcCreight,您能用一个真实的例子来解释一下吗?“您可能会问,如果您指定了方向为“人像”,它将如何改变?如果您启动了另一个改变方向的活动,它可能会改变。新活动退出,返回到您的活动中。”
Tushar Pandey

3
当然,@ TusharPandey。如果我没记错的话,引起我们悲伤的一个地方是我们的活动在三星Galaxy S3上启动了默认图像捕获意图。基本上,我们只是想拍照并得到结果。但是,当相机意图恢复时,它会导致方向改变,从而消除了我们活动中的状态,因为我们认为我们不需要对此进行保护(假设我们的整个应用仅处于“人像”方向)。我如何(以及有限地)无法理解Galaxy S3的操作方式和原因。
Gordon McCreight

8
为什么包含“ keyboardHidden”?
gonzobrains

24

注意

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

被添加到清单文件中-在其中定义活动。


13

我认为android:screenOrientation="portrait"可以用于个人活动。因此,请在<activity>标记中使用该属性,例如:

<activity android:name=".<Activity Name>"
    android:label="@string/app_name" 
    android:screenOrientation="portrait">
   ...         
</activity>

13

如果您有很多像我这样的活动,则在您的应用程序中,或者如果您不想在清单中输入每个活动标签的代码,则可以执行此操作。

在您的Application Base类中,您将获得生命周期回调

因此,基本上,在此处触发在Application Class中创建on create时,每个活动所发生的是代码..

public class MyApplication extends Application{

@Override
    public void onCreate() {
        super.onCreate();  

  registerActivityLifecycleCallbacks(new ActivityLifecycleCallbacks() {
            @Override
            public void onActivityCreated(Activity activity, Bundle bundle) {
                activity.setRequestedOrientation(
                        ActivityInfo.SCREEN_ORIENTATION_PORTRAIT);


// for each activity this function is called and so it is set to portrait mode


            }

            @Override
            public void onActivityStarted(Activity activity) {

            }

            @Override
            public void onActivityResumed(Activity activity) {

            }

            @Override
            public void onActivityPaused(Activity activity) {

            }

            @Override
            public void onActivityStopped(Activity activity) {

            }

            @Override
            public void onActivitySaveInstanceState(Activity activity, Bundle bundle) {

            }

            @Override
            public void onActivityDestroyed(Activity activity) {

            }
        });
}

我希望这有帮助。


1
高效答案!这应该是正确的答案,尤其是对于那些正在开发严重依赖大量Activity的复杂应用的用户。
2

10

设置力为人像或风景模式,分别添加线条。

导入以下行:

import android.content.pm.ActivityInfo;

在正上方的行下方添加 setContentView(R.layout.activity_main);

对于肖像

setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT);//Set Portrait

对于景观

setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE);//Set Landscape

这肯定会工作。


1
这在某些设备上无法在Android 9上运行-即使您仅使用PORTRAIT,屏幕旋转过渡也会在短时间内可见
Igor Wojda

能否请您指定您已经面临这样的,如果可能的设备信息
PARTH帕特尔

4

根据Android的文档,您还应该经常包括screenSize一个可能的配置更改。

android:configChanges="orientation|screenSize"

如果您的应用程序的目标API级别为13或更高(如minSdkVersion和targetSdkVersion属性所声明),则还应声明“ screenSize”配置,因为当设备在纵向和横向之间切换时,它也会更改。

另外,如果你所有的包括价值keyboardHidden在你的例子,你不应该那么也可以考虑localemccfontScalekeyboard和其他人?..


3

我的AndroidManifest.xml中有这行

<activity 
    android:configChanges="orientation|keyboardHidden|keyboard|screenSize|locale"
    android:label="@string/app_name" android:name="Project Name"
    android:theme="@android:style/Theme.Black.NoTitleBar">

我改为(刚刚添加android:screenOrientation="portrait"

<activity 
    android:configChanges="orientation|keyboardHidden|keyboard|screenSize|locale"
    android:label="@string/app_name" android:name="Project Name"
    android:screenOrientation="portrait"
    android:theme="@android:style/Theme.Black.NoTitleBar">

这为我解决了问题。


2

补充一点:我最近更新了一个应用程序,以前的应用程序可以在横向和纵向模式下工作,并且我希望更新后的版本可以在纵向模式下工作,所以我添加了

android:screenOrientation="portrait"

到相应的活动,并且在我测试更新时它崩溃了。然后我加了

android:configChanges="orientation|keyboardHidden"

也是如此,并且有效。


1
如果这不是问题的答案,则可以添加它,因为评论会有所帮助。
JPReddy 2014年

检查是否已将其添加到活动中,而不是针对应用程序阻止
Waran-

1

我认为您想增加android:configChanges="orientation|keyboardHidden"自己的活动?否则,该活动将在config-change时重新启动。然后onConfigurationChanged将不会调用onCreate


1

如果您希望在版本debugrelease版本中支持不同的方向,请这样编写(请参阅https://developer.android.com/studio/build/gradle-tips#share-properties-with-the-manifest)。

build.gradle您的app文件夹的写:

android {
    ...
    buildTypes {
        debug {
            applicationIdSuffix '.debug'
            minifyEnabled false
            proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
            // Creates a placeholder property to use in the manifest.
            manifestPlaceholders = [orientation: "fullSensor"]
        }
        release {
            debuggable true
            minifyEnabled false
            proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
            // Creates a placeholder property to use in the manifest.
            manifestPlaceholders = [orientation: "portrait"]
        }
    }
}

然后,AndroidManifest您可以在任何情况下使用此变量“ orientation” Activity

<activity
    android:name=".LoginActivity"
    android:screenOrientation="${orientation}" />

你可以加 android:configChanges

manifestPlaceholders = [configChanges: "", orientation: "fullSensor"]在调试和manifestPlaceholders = [configChanges: "keyboardHidden|orientation|screenSize", orientation: "portrait"]发布中,

<activity
    android:name=".LoginActivity"
    android:configChanges="${configChanges}"
    android:screenOrientation="${orientation}" />

-8

简短的答案:不要这样做。

重新设计您的应用程序,使其可以在纵向和横向模式下运行。没有像这样的用户界面不能同时在纵向和横向模式下工作;仅懒惰或缺乏想象力的开发人员。

原因很简单。您希望您的应用程序能够在尽可能多的不同设备上吸引尽可能多的受众。通过强制特定的屏幕方向,可以阻止(正常地)在不支持该屏幕方向的设备上运行您的应用,并且使希望使用其他方向的潜在客户感到沮丧和疏远。

示例:您将应用程序设计为强制纵向模式。客户在主要用于横向模式的2合1设备上下载了该应用程序。
后果1:您的应用程序无法使用,或者客户被迫取消设备的固定位置,旋转设备,并以不熟悉或不舒服的方式使用设备。
结果2:客户对您应用程序的非直观设计感到沮丧,并找到了替代方案或完全放弃了该应用程序。

我现在正在使用一个应用程序来应对这个问题,作为消费者和开发人员,我讨厌它。我的应用程式既实用又实用,它所提供的功能也很棒,我绝对讨厌该应用程序,因为它迫使我使用与我使用设备的其他方式相反的方向。

您不希望客户讨厌您的应用程序。


我知道这并不能直接回答问题,因此我想为好奇的人更详细地解释它。

开发人员倾向于真正擅长编写代码,并且在设计方面确实很糟糕。这个问题虽然听起来像是一个代码问题,而问问者当然感觉像是一个代码问题,但它实际上是一个设计问题。

问题确实是“我应该在应用程序中锁定屏幕方向吗?” 询问者选择将UI设计为仅在纵向模式下才能正常工作并看起来不错。我怀疑这是为了节省开发时间,或者因为该应用程序的工作流程特别有利于人像布局(手机游戏常见)。但是这些原因忽略了促使适当设计的所有重要因素。

  1. 客户参与度-您希望客户感到被应用吸引,而不是被应用淘汰。在打开您的应用程序之前,该应用程序应能从您的客户所做的任何事情顺利过渡。(这就是大多数平台具有一致的设计原则的原因,因此,大多数应用虽然不一定必须相似,但看起来或多或少都是相似的。)

  2. 客户响应-您希望客户对您的应用做出积极反应。他们应该喜欢使用它。即使它是一个工作的薪资应用程序,对于他们来说打开它并计时也应该是一种乐趣。该应用程序应该节省您的客户时间并减少对替代方案的沮丧。(惹恼用户的应用会对您的应用产生反感,而对您的品牌则反感。)

  3. 客户转换-您希望客户能够快速轻松地从浏览转换为交互。这是任何应用程序将印象转换为收入的最终目标。(从业务角度来看,无法产生收入的应用会浪费您的构建时间。)

UI设计不当会降低客户参与度和响应速度,最终导致收入降低。在以移动为中心的世界中(尤其是在纵向/横向显示模式方面),这解释了为什么响应式网页设计如此重要。2013年11月,加拿大沃尔玛在其网站上引入了响应式设计,客户转换率提高了20%奥尼尔服装实施自适应设计,并使用iOS设备的客户收入增长了101.25%591.42%的用户在使用Android设备

开发人员还倾向于专心于实现特定的解决方案(例如锁定显示方向),并且该站点上的大多数开发人员都非常乐于帮助实现该解决方案,而不必怀疑这是否是最好的解决方案。解决问题。

锁定屏幕方向等同于实现do-while循环的UI设计。你真的确定要那样做,或是否有更好的选择吗?

不要强迫您的应用进入单一显示模式。投入额外的时间和精力使它响应。


2
我了解并同意您认为UI设计不良。但这并不能改变您可能需要这样做的事实,尽管如此,框架通常应该具有这些功能。您永远不会知道未来的应用程序会是什么样,需要做什么,因此这个问题仍然有效。
Z. Khullah '17

1
你没看错 我认为我的答案部分是由于我对一些不必要的应用程序感到沮丧而感到沮丧,而这完全破坏了体验。我要说的是,锁定显示模式的合法案例数量非常少(并且仍然可行且可取,只是不在预算之内)。这使我想到其他问题。随着编程变得如此简单,许多业余开发人员正在编写应用程序,因为他们知道代码,却没有学习如何进行UI或设计,甚至没有学习基本的最佳实践(安装在\ AppData-EWWWW中的Java应用程序)。
托马斯

1
我正在构建一个VR应用程序。眼镜的方向必须是横向的,才能发挥魔力。那是一个UI的示例,该UI不能被设计为既可以纵向又可以横向使用。游戏可能还必须强制某种方向。我敢打赌,这里有大量合法案件。
拉拉斯诺夫

1
虽然存在StackExchange来回答特定问题,但应该编写答案以使其尽可能普遍地适用,以便这些答案对其他人有用。开发不仅仅只是编写代码,而且世界上有那么多垃圾应用程序的原因在于,因为有这么多开发人员忘记了或从未学习过这一重要原理。我个人要补充一点,如果您在手机上进行虚拟现实,那就意味着虚拟现实做错了-但是成本将对虚拟现实的需求推到了永远不支持虚拟现实的平台上。
托马斯(Thomas)

1
我不同意这个答案,但是它是在回答一个没有被问到的问题。
bmovement '19
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.