57

除了用于播放始终为横向的视频的活动外,我的所有活动都处于纵向模式。我发现在 Android 8.1 上,每次我打开视频活动并关闭它时,即使它在清单上设置为“纵向”,上一个活动也会进入横向。

  1. 有时会先画肖像,然后再画风景,然后再画风景。
  2. 有时先是肖像,然后是风景,最后是肖像。

这仅在从一个活动返回时才会发生。

有没有人正在经历这种情况?

谢谢。

编辑

我在 Google 上报告了这个错误:https ://issuetracker.google.com/issues/69168442

编辑 2

它似乎在 Android 9 上已修复

4

10 回答 10

16

刚刚在我自己的应用程序中遇到了这个问题。

适合我的解决方案如下:

onCreate(){
   setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_SENSOR_LANDSCAPE);
}

onPause(){ 
  if (android.os.Build.VERSION.SDK_INT >= 27) {
         setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_SENSOR_PORTRAIT);
  }
}

onResume(){
  if (android.os.Build.VERSION.SDK_INT >= 27) {
         setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_SENSOR_LANDSCAPE);
  }
}

上面的代码应该进入处于横向模式的活动中(即第二个活动,以及您按下后退按钮的活动)

我想指出这个解决方案不是我自己的,我是从以下链接的#20 帖子中获取的(在 OP 中也有说明):

https://issuetracker.google.com/issues/69168442

我只是认为如果人们不必搜索另一个页面来访问它可能会更容易。

于 2018-03-15T19:34:53.873 回答
10

这解决了这个问题。

覆盖Landscape 活动的onBackPressed()方法并将方向设置为Portrait

@Override
public void onBackPressed() {
    super.onBackPressed();
    setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT);
}
于 2018-08-14T11:29:08.297 回答
3

如果您的宣言中有像 theme=Theme.AppCompat.Light.Dialog 这样的 DialogTheme,请从 manifesto 中删除该 Dialog 活动的设置方向标签,它将采用上一个活动的方向并为剩余活动放置 setorientation 标签

对于以下版本,请将其放在 oncreate

if (android.os.Build.VERSION.SDK_INT < Build.VERSION_CODES.O) {
            setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT);
  }

并为应用程序 Theme.AppCompat.Light.DarkActionBar 设置主题无需为活动添加主题

于 2018-06-21T12:52:01.160 回答
1

在以前的活动中使用intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP | Intent.FLAG_ACTIVITY_NEW_TASK)解决了我的问题。

于 2018-04-20T06:10:54.030 回答
1

来自Narmi的回答:

当你从 Activity B 回到 Activity A 时,如果你知道 Activity A 的屏幕方向,那么将屏幕方向设置为 Activity B 的 ondestroy。

您必须检测活动是否因配置更改而破坏,因此添加字段isConfigurationChanged = false,然后在onSaveInstanceState方法上将其转为true并在onDestroy方法上添加以下内容:

@Override
protected void onDestroy() {
    if(!isConfigurationChanged)
        setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT);
    super.onDestroy();
}
于 2019-09-11T09:44:49.990 回答
1

如果您需要支持父活动的方向更改,请考虑在横向活动的 onPause() 中使用当前方向。

onCreate(){
   super.onCreate();
   setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_SENSOR_LANDSCAPE);
}

onPause(){ 
  super.onPause();
  if (android.os.Build.VERSION.SDK_INT >= 27) {
         setRequestedOrientation(getResources().getConfiguration().orientation);
  }
}

onResume(){
  super.onResume();
  if (android.os.Build.VERSION.SDK_INT >= 27) {
         setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_SENSOR_LANDSCAPE);
  }
}

该答案基于TheTestSpecimen的答案。

于 2019-05-17T06:45:17.940 回答
0

下一个解决方法可能会帮助您解决问题。

您必须使用代码中的活动扩展所有活动。每当调用 onPause / onResume 方法时,它都会负责设置和恢复正确的方向。

该解决方法适用于清单活动标记中定义的任何类型的方向。

出于我自己的目的,我从ComponentActivity扩展了此类,因此您可能希望将其更改为从ActivityActivityCompat或您在代码中使用的任何类型的活动中扩展。

public abstract class AbsBaseActivity extends ComponentActivity
{
    private int currentActivityOrientation   = ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED;
    private int parentActivityOrientation = ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED;

    @CallSuper
    @Override
    protected void onCreate(@Nullable final Bundle savedInstanceState)
    {
        super.onCreate(savedInstanceState);

        this.cacheOrientations();
    }

    private void cacheOrientations()
    {
        if (this.currentActivityOrientation == ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED)
        {
            final Intent parentIntent = this.getParentActivityIntent();

            if (parentIntent != null)
            {
                final ComponentName parentComponentName = parentIntent.getComponent();

                if (parentComponentName != null)
                {
                    this.currentActivityOrientation = this.getConfiguredOrientation(this.getComponentName());
                    this.parentActivityOrientation = this.getConfiguredOrientation(parentComponentName);
                }
            }
        }
    }

    private int getConfiguredOrientation(@NonNull final ComponentName source)
    {
        try
        {
            final PackageManager packageManager = this.getPackageManager();
            final ActivityInfo   activityInfo   = packageManager.getActivityInfo(source, 0);
            return activityInfo.screenOrientation;
        }
        catch (PackageManager.NameNotFoundException e)
        {
            e.printStackTrace();
        }

        return ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED;
    }

    @CallSuper
    @Override
    protected void onPause()
    {
        if (this.parentActivityOrientation != ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED)
        {
            this.setRequestedOrientation(this.parentActivityOrientation);
        }

        super.onPause();
    }

    @CallSuper
    @Override
    protected void onResume()
    {
        super.onResume();

        if (this.currentActivityOrientation != ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED)
        {
            this.setRequestedOrientation(this.currentActivityOrientation);
        }
    }
}
于 2019-02-20T18:54:22.627 回答
0

要解决此问题:

当你从 Activity B 回到 Activity A 时,如果你知道 Activity A 的屏幕方向,那么将屏幕方向设置为 Activity B 的 ondestroy。

@Override
protected void onDestroy() {
    setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT);
    super.onDestroy();
}
于 2018-12-03T16:17:54.597 回答
0

我遇到了这样的问题,并且一直在尝试上述所有用例。它们中的大多数都有效,但是您应该知道一种情况:

最后一个原因是在Android 8的情况下在活动内容布局中使用片段。例如:活动以横向模式启动,但片段显示纵向布局。

尽量避免碎片。

于 2018-11-06T15:27:52.880 回答
0

在每个活动的 onCreate 方法上插入这一行

this.setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE);

对于景观和

this.setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT);

对于肖像的

于 2017-11-10T17:37:17.907 回答