简体   繁体   English

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

[英]Android 8.1 screen orientation issue: flipping to landscape a portrait screen

I have all activities in portrait mode except the one that I use to play a video that is always landscape. 我以纵向模式进行所有活动,除了我用来播放始终为风景的视频的活动。 I found that on Android 8.1 every time I open the video activity and close it the previous activity go to landscape even it's set to "portrait" on the manifest. 我发现在Android 8.1上每次打开视频活动并关闭它之前的活动都会转到横向,即使它在清单上设置为“纵向”。

  1. Sometimes goes to portrait then to landscape and stay on landscape. 有时候去画像然后去景观并留在风景中。
  2. Sometimes goes to portrait then to landscape and finally portrait again. 有时去肖像然后去景观,最后再画像。

This is only happening when a go back from a activity that it's landscape. 这只发生在从景观活动回来的时候。

There is anyone who is experiencing this? 有人在体验这个吗?

Thanks. 谢谢。

EDIT 编辑

I report the bug on Google: https://issuetracker.google.com/issues/69168442 我在Google上报告了该错误: https//issuetracker.google.com/issues/69168442

EDIT 2 编辑2

It seems fixed on Android 9 它似乎在Android 9上修复

Just came across this problem in my own app. 刚刚在我自己的应用程序中遇到了这个问题。

The solution that works for me is as follows: 适合我的解决方案如下:

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

The above code should go in the activity that is in landscape mode (ie the second activity, and the one you press the back button from) 上面的代码应该进入横向模式的活动(即第二个活动,以及按下后退按钮的活动)

I would like to point out that this solution was not my own, and I have taken it from the #20 post at the following link (which is also noted in the OP): 我想指出这个解决方案不是我自己的,我从以下链接的#20帖子中获取了它(也在OP中注明):

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

I just thought it might be easier for people to access if they don't have to search another page for it. 我只是觉得如果人们不必搜索其他页面就可以更容易访问。

This fixed the issue. 这解决了这个问题。

Override the onBackPressed() method of Landscape activity and set orientation to Portrait . 覆盖Landscape活动onBackPressed()方法并将方向设置为Portrait

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

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

If u have DialogTheme like theme=Theme.AppCompat.Light.Dialog in your manifesto, remove the set orientation tag for that Dialog activity from manifesto , It will take the Orientation from the previous activity and put setorientation tag for remaing activites 如果您在宣言中有类似theme = Theme.AppCompat.Light.Dialog的DialogTheme,请从manifesto中删除该Dialog活动的set orientation标记,它将从上一个活动中获取Orientation并将setorientation标记用于重新激活活动

and for below Versions place this on oncreate 对于以下版本,请将其放在oncreate上

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

and set theme for application Theme.AppCompat.Light.DarkActionBar no need to add theme to activities 并为应用程序设置主题Theme.AppCompat.Light.DarkActionBar无需向活动添加主题

If you need to support orientation changes on the parent activtiy consider using the current orientation in onPause() of your landscape activity. 如果您需要支持父级活动的方向更改,请考虑使用横向活动的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);
  }
}

This answer is based on TheTestSpecimen s one. 这个答案基于TheTestSpecimen的答案。

from Narmi 's answer: 来自Narmi的回答:

When you will back to Activity A from Activity B and if you know the screen's orientation of the Activity A, so set the screen orientation into the ondestroy of Activity B. 当您从活动B返回活动A并且如果您知道活动A的屏幕方向时,请将屏幕方向设置为活动B的ondestroy。

you have to detect if activity is destroying from configuration change, so add field isConfigurationChanged = false , then on onSaveInstanceState method turn it to true and on onDestroy method add this: 您必须检测活动是否正在破坏配置更改,因此添加字段isConfigurationChanged = false ,然后在onSaveInstanceState方法上将其转为true并在onDestroy方法上添加以下内容:

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

on the onCreate method of each activity insert this line 在每个活动的onCreate方法中插入此行

this.setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE);

for the landscape and 对于景观和

this.setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT);

for the portrait ones 对于肖像

I had such problem and been trying all of above use cases. 我有这样的问题,并尝试了以上所有用例。 Most of them work, but there is one case you should know: 他们中的大多数都有效,但有一个案例你应该知道:

The final reason was the using of fragments inside an activity content layout in case of Android 8 . 最后的原因是在Android 8的情况下在活动内容布局中使用片段 For example: The activity launches in Landscape mode, but the fragment shows you the Portrait layout. 例如:活动以横向模式启动,但片段显示纵向布局。

Try to avoid fragments. 尽量避免碎片。

To fix this issue: 要解决此问题:

When you will back to Activity A from Activity B and if you know the screen's orientation of the Activity A, so set the screen orientation into the ondestroy of Activity B. 当您从活动B返回活动A并且如果您知道活动A的屏幕方向时,请将屏幕方向设置为活动B的ondestroy。

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

The next workaround may help you to solve the issue. 下一个解决方法可以帮助您解决问题。

You must extend all your activities using the one in the code. 您必须使用代码中的活动扩展所有活动。 It takes care of setting and restoring the correct orientations whenever the onPause / onResume methods are called. 无论何时调用onPause / onResume方法,它都会负责设置和恢复正确的方向。

The workaround will work for any type of orientation defined in the manifest activity tags. 解决方法适用于清单活动标记中定义的任何类型的方向。

For my own purposes I extend this class from ComponentActivity , so you may want to change this to extend from Activity , ActivityCompat , or whatever type of activity you are using in your code. 出于我自己的目的,我从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);
        }
    }
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM