Android 8.1屏幕方向问题:翻转横向纵向屏幕

时间:2017-11-10 17:29:46

标签: android android-8.1-oreo

我以纵向模式进行所有活动,但我用来播放始终为风景的视频的活动除外。我发现在Android 8.1每次打开视频活动并关闭它时,之前的活动都会转到横向,即使它已设置为" portrait"在清单上。

  1. 有时会去画像然后去景观并留在风景中。
  2. 有时会去肖像然后去风景,最后再画像。
  3. 这只发生在从它的风景活动回来的时候。

    有没有人遇到这种情况?

    感谢。

    修改

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

    编辑2

    似乎已在Android 9上修复

10 个答案:

答案 0 :(得分:14)

在我自己的应用中遇到过这个问题。

对我有用的解决方案如下:

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

我只是觉得如果人们不必搜索其他网页就可以更容易访问。

答案 1 :(得分:9)

此问题已解决。

覆盖横向活动 onBackPressed()方法,并将方向设置为纵向

@Override
public void onBackPressed() {
    super.onBackPressed();
    setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT);
}

答案 2 :(得分:4)

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

答案 3 :(得分:4)

如果您的清单中有DialogTheme,例如theme = Theme.AppCompat.Light.Dialog,请从清单中删除该Dialog活动的设置方向标签,它将采用上一个活动的Orientation 并放置setorientation标签以进行剩余的活动

及以下版本将其放在oncreate

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

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

答案 4 :(得分: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

答案 5 :(得分:1)

来自 Narmi 的答案:

  

何时从活动B返回活动A,并且您知道   活动A的屏幕方向,因此设置屏幕方向   进入活动B的毁灭。

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

@Override
protected void onDestroy() {
    if(!isConfigurationChanged)
        setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT);
    super.onDestroy();
}

答案 6 :(得分:0)

在每个活动的onCreate方法中插入此行

this.setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE);

为景观和

this.setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT);

为肖像

答案 7 :(得分:0)

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

最终的原因是在 Android 8 情况下,在活动内容布局中使用了片段。 例如:该活动以 Landscape 模式启动,但是该片段向您显示 Portrait 布局。

尝试避免碎片。

答案 8 :(得分:0)

要解决此问题:

当您从活动B返回活动A时,如果您知道活动A的屏幕方向,则将屏幕方向设置为活动B的本体。

@Override
protected void onDestroy() {
    setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT);
    super.onDestroy();
}

答案 9 :(得分:0)

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

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

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

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

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);
        }
    }
}