我希望平板电脑能够显示肖像和景观(sw600dp或更大),但手机仅限于肖像。我找不到任何有条件地选择方向的方法。有什么建议吗?


当前回答

以下是接受的答案,我正在添加解决方案的kotlin文件,希望它能帮助到某人

将这个bool资源放在res/values中,作为bools.xml或其他文件(文件名在这里不重要):

<?xml version="1.0" encoding="utf-8"?>
<resources>
    <bool name="portrait_only">true</bool>
</resources>

把这个放在res/values-sw600dp和res/values-sw600dp-land中:

<?xml version="1.0" encoding="utf-8"?>
<resources>
    <bool name="portrait_only">false</bool>
</resources>

然后,将其添加到您的活动或碎片的以下行中

class MyActivity : Activity() {

    @SuppressLint("SourceLockedOrientationActivity")
    override fun onCreate(savedInstanceState: Bundle?) {
        if (resources.getBoolean(R.bool.portrait_only)) {
            requestedOrientation = ActivityInfo.SCREEN_ORIENTATION_PORTRAIT
        }
        super.onCreate(savedInstanceState)
    }

    @SuppressLint("SourceLockedOrientationActivity")
    override fun onConfigurationChanged(newConfig: Configuration) {
        if (resources.getBoolean(R.bool.portrait_only)) {
            requestedOrientation = ActivityInfo.SCREEN_ORIENTATION_PORTRAIT
        }
        super.onConfigurationChanged(newConfig)
    }
}

其他回答

你应该在你的manifest中声明你的屏幕朝向,值为'nosensor':

方向的确定不需要参考物理方向传感器。传感器被忽略,所以显示器不会根据用户移动设备的方式旋转。

然后旋转将是“自然的”设备行为(手机:纵向/平板电脑:横向)。

优点是你可以混合每个活动的不同旋转,例如,如果你有一个显示数据库记录的活动,那么你可以将这个活动的方向设置为“fullUser”,而其他活动则使用“nosensor”。"fullUser"活动将根据用户选择旋转(启用旋转:使用传感器,否则使用用户偏好)。

<activity android:name=".scanner.ScannerPropertiesActivity" 
android:configChanges="keyboardHidden|orientation|screenSize"
android:label="@string/title_activity_scanner_properties"
android:screenOrientation="${screenOrientation}"/>

${screenOrientation}是一个manifest占位符,所以我可以很容易地切换所有的活动,我希望测试之间的所有取向行为使用这个:

//module's build.gradle
defaultConfig {
//...
    manifestPlaceholders = [applicationName:appName,screenOrientation:'nosensor']
//...
}

如果你需要更复杂的功能(例如:只允许平板电脑屏幕旋转,并将手机方向固定为竖屏),那么你应该使用locked:

android: screenOrientation = "锁定" 我注意到,如果你强迫方向为纵向,而传感器发送的手机是在横向旋转,你的活动将开始在横向,然后旋转到纵向一旦你的代码被执行,几乎任何其他方向。 锁定保持以前的旋转,所以你可能已经锁定在纵向从你的上一个活动。那么你必须知道什么时候一个设备是平板电脑或手机:为了做到这一点,我建议你使用这个:

//normal tablet_detection file content:
<?xml version="1.0" encoding="utf-8"?>
<resources>
    <item name="isTablet" type="bool">false</item>
</resources>
//sw600dp tablet_detection file content:
<?xml version="1.0" encoding="utf-8"?>
<resources>
    <item name="isTablet" type="bool">true</item>
</resources>
//Now in your code you can detect if it's a tablet or not by calling following function in your Activity's **onCreate** and apply screen orientation by code:
protected  void updateScreenOrientation(){
boolean isTablet =context.getResources().getBoolean(R.bool.isTablet);
//And select the orientation you wish to set:
int defaultOrientation=isTablet? ActivityInfo.SCREEN_ORIENTATION_FULL_USER:ActivityInfo.SCREEN_ORIENTATION_PORTRAIT;
        if(getRequestedOrientation()== ActivityInfo.SCREEN_ORIENTATION_LOCKED) {
            //Apply this only on Activities where you set the orientation to 'locked' in the manifest
            this.setRequestedOrientation(defaultOrientation);
        }
}

我在toMainActivity.java文件中添加了这个代码部分。它对我的案子起作用了。

 @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            handleOrientationConfiguration();
        }

        private void handleOrientationConfiguration() {

            if (isTablet()) {
                setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE);
            } else {
                setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT);
            }
        }

        private boolean isTablet() {
            Configuration configuration = this.getContext().getResources()
                    .getConfiguration();/*from   www .j ava  2  s. c  o  m*/
            return (configuration.screenLayout & Configuration.SCREENLAYOUT_SIZE_MASK) >= Configuration.SCREENLAYOUT_SIZE_LARGE;
        }

建议的方法是不锁定任何窗口维度的方向,但您可以通过遵循这里的指南来实现。

在步骤中,要做的第一件事是解锁舱单上的方向

<activity
    android:name=".MyActivity"
    android:screenOrientation="fullUser">

接下来,你可以使用Jetpack窗口管理器来确定应用程序在屏幕上有多少空间:

/** Determines whether the device has a compact screen. **/
fun compactScreen(): Boolean {
    val screenMetrics = WindowMetricsCalculator
                        .getOrCreate()
                        .computeMaximumWindowMetrics(this)
    val shortSide = min(screenMetrics.bounds.width(),
                        screenMetrics.bounds.height())
    return shortSide / resources.displayMetrics.density < 600
}

最后,当空间变小时,锁定方向,通常在手机上:

override fun onCreate(savedInstanceState: Bundle?) {
    super.onCreate(savedInstanceState)
    requestedOrientation = if (compactScreen())
        ActivityInfo.SCREEN_ORIENTATION_PORTRAIT else
        ActivityInfo.SCREEN_ORIENTATION_FULL_USER
    ...
}

我知道这是个老问题。为了让你的应用程序总是在纵向模式下运行,即使方向可能会被交换(例如在平板电脑上),我设计了这个功能,用于将设备设置在正确的方向上,而不需要知道设备上的纵向和横向功能是如何组织的。

   private void initActivityScreenOrientPortrait()
    {
        // Avoid screen rotations (use the manifests android:screenOrientation setting)
        // Set this to nosensor or potrait

        // Set window fullscreen
        this.activity.getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN, WindowManager.LayoutParams.FLAG_FULLSCREEN);

        DisplayMetrics metrics = new DisplayMetrics();
        this.activity.getWindowManager().getDefaultDisplay().getMetrics(metrics);

         // Test if it is VISUAL in portrait mode by simply checking it's size
        boolean bIsVisualPortrait = ( metrics.heightPixels >= metrics.widthPixels ); 

        if( !bIsVisualPortrait )
        { 
            // Swap the orientation to match the VISUAL portrait mode
            if( this.activity.getResources().getConfiguration().orientation == Configuration.ORIENTATION_PORTRAIT )
             { this.activity.setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE); }
            else { this.activity.setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT ); }
        }
        else { this.activity.setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_NOSENSOR); }

    }

效果好极了!

注意: 改变这种情况。活动由您的活动或添加到主活动,并删除此。活动;-)

如果你想做相反的事情,你必须将代码更改为横向(但我认为这是很清楚的)。

在清单文件中添加以下代码:

android:screenOrientation="fullSensor"

在layout-land文件夹下创建XML文件