如何为所有活动设置固定方向

7

Android布局。我该如何在AndroidMainfest.xml文件的应用程序标签中设置所有活动的固定方向?我不想为每个活动单独设置方向。提前致谢。

5个回答

21

GoogleIO应用程序有一个ActivityHelper类。它有一个名为initialize()的静态方法,它处理每个活动发生的许多事情。然后只需要记住onCreate()方法中的1行代码,就可以处理设置该值以及每个活动所需的其他几个值。

编辑:没有导入或其他任何操作。创建一个名为ActivityHelper的类。

public class ActivityHelper {
    public static void initialize(Activity activity) {
        //Do all sorts of common task for your activities here including:

        activity.setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE);
    }
}

接着在你的所有活动中的onCreate()方法中调用ActivityHelper.initialize()。 如果你计划开发平板电脑应用程序,你可能需要考虑使用:

setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_NOSENSOR);

我在这里写了更多相关内容。

编辑:抱歉……你需要通过该活动。请参考上面的代码。


谢谢bytebender,你能告诉我如何在我的项目中使用ActivityHelper类吗?有任何示例将不胜感激。我已经按照你的链接进行了尝试,但仍然感到困惑。 - Xorsat
给我一点时间... 我今晚稍后会写出一些代码并在这里发布。 - bytebender
非常感谢您的反馈,我只是想知道,在我的项目中,我需要导入哪些文件或jar包,以及如何调用那些静态方法。期待您的回复。 - Xorsat
1
@Eugene,如果您将问题从评论中移出并创建一个新的Stack问题,那么您更有可能得到答案。 - bytebender
1
@bytebender,太棒了,伙计。我非常感谢你的帮助。 - Jay Dangar
显示剩余4条评论

5

接受的答案以及任何建议使用setRequestedOrientation的方法都远非完美,因为文档所述,在运行时调用setRequestedOrientation可能会导致活动重新启动,这会影响屏幕之间的动画等其他事情。

如果可能的话,最好在AndroidManifest.xml中设置所需的方向。 但由于依赖每个开发人员记得在添加新活动时修改清单是容易出错的,因此可以在构建期间通过编辑AndroidManifest文件来完成。

但是,这种方式编辑AndroidManifest需要注意一些注意事项:

我的要求是在发布版本中更新所有活动以具有固定方向。我在build.gradle中使用了一些代码来实现这一点,在AndroidManifest中进行简单的字符串替换(假设没有任何活动已经指定方向):

适用于Android Studio 3.0的解决方案示例(仅涉及与com.mycompany.*匹配的活动):

android.applicationVariants.all { variant ->
    variant.outputs.all { output ->
        if (output.name == "release") {
            output.processManifest.doLast {
                String manifestPath = "$manifestOutputDirectory/AndroidManifest.xml"
                def manifestContent = file(manifestPath).getText('UTF-8')
                // replacing whitespaces and newlines between `<activity>` and `android:name`, to facilitate the next step
                manifestContent = manifestContent.replaceAll("<activity\\s+\\R\\s+", "<activity ")
                // we leverage here that all activities have android:name as the first property in the XML
                manifestContent = manifestContent.replace(
                        "<activity android:name=\"com.mycompany.",
                        "<activity android:screenOrientation=\"userPortrait\" android:name=\"com.mycompany.")
                file(manifestPath).write(manifestContent, 'UTF-8')
            }
        }
    }
}

Android Studio 2.3 兼容解决方案示例 (匹配所有活动,但不匹配 <activity-alias> 条目):

android.applicationVariants.all { variant ->
    variant.outputs.each { output ->
        if (output.name == "release") {
            output.processManifest.doLast {
                def manifestOutFile = output.processManifest.manifestOutputFile
                def newFileContents = manifestOutFile.getText('UTF-8')
                        .replaceAll(/<activity(?!-)/, "<activity android:screenOrientation=\"userPortrait\" ")
                manifestOutFile.write(newFileContents, 'UTF-8')
            }
        }
    }
}

我使用userPortrait而不是portrait,因为我更喜欢给用户更多的灵活性。

如果你只有变体(调试,发布),上述内容可以直接使用。如果你还有其他版本,你可能需要进行一些微调。

根据你的需求,你可能需要删除if (output.name == "release")


2
如果您使用泛型编写项目。
并且您有类似于“BaseActivity”的内容,那么在其中的 onCreate 中,您可以编写以下代码:
例如: BaseActivity扩展AppCompatActivity,稍后您使用YourActivity扩展BaseActivity 纵向
this.setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT);

横屏模式

this.setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE);

1
泛型在哪里? - CoolMind
@CoolMind 我的意思是当你使用泛型编写项目时,你必须自己创建它们。简而言之,你创建一个类 BaseActivity 继承自 AppCompatActivity 或其他什么的,然后在所有的活动中都通过扩展 BaseActiviy 来继承它。 并且在基础活动的 onCreate 方法中编写这些行 - Jakub S.
1
然后你应该说:“如果你从BaseActivity扩展你的活动”。你的想法很好。 - CoolMind

0

我有最好的解决方案。你不需要传递任何活动作为参数之类的东西。

这是你需要做的。

创建一个类并像这样扩展你的应用程序。 实现onActivityCreated和onActivityStarted并添加设置方向的代码,以便你想要的方向。

public class OldApp extends Application {

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

        // register to be informed of activities starting up
        registerActivityLifecycleCallbacks(new ActivityLifecycleCallbacks() {

            @Override
            public void onActivityStarted(Activity activity) {
                activity.setRequestedOrientation(
                        ActivityInfo.SCREEN_ORIENTATION_PORTRAIT);
            }

            @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) {

            }

            @Override
            public void onActivityCreated(Activity activity,
                                          Bundle savedInstanceState) {
              activity.setRequestedOrientation(
                        ActivityInfo.SCREEN_ORIENTATION_PORTRAIT);
              }
        });
    }
}

接下来,在<application block>内的清单文件中添加以下内容:

android:name=".OldApp"

最终结果将会是这样的:

<application
    android:name=".OldApp"
    ...other values... >
    <activity
        android:name=".SomeActivity"></activity>
</application>

0

(Monodroid/C# 代码)

您可以创建一个抽象基类。

public abstract class ActBase : Activity
{
    protected override void OnCreate(Bundle bundle)
    {
        base.OnCreate(bundle);
        RequestedOrientation = clsUtilidades.GetScreenOrientation();
    }
 }

那么你的所有活动都必须继承这个类,而不是 Activity

类似这样

[Activity(Label = "Orders", ConfigurationChanges = ConfigChanges.Orientation | ConfigChanges.Keyboard | ConfigChanges.Mcc | ConfigChanges.Mnc)]
public class ActOrders : ActBase
{
  ....

这种方式避免在您的事件中调用ActivityHelper


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接