Android 在指定 requestedOrientation 时检测设备方向

标签 android android-layout android-orientation

我正在构建一个视频流应用程序。它具有 Youtube 风格的布局,纵向布局在顶部显示视频,在底部显示其他内容列表。该应用可以通过旋转设备或单击按钮以横屏方式全屏显示视频。

现在,如果我将手机旋转为横向,然后将其旋转回纵向,布局将按预期返回纵向。相反,如果我点击按钮强制进入纵向模式,将设备横向旋转以观看视频,然后将其旋转回纵向,则布局仍然停留在横向。

我在 list 中的 Activity :

    <activity
        android:name="MyActivity"
        android:configChanges="keyboardHidden|orientation|screenSize|smallestScreenSize|screenLayout"
        android:label="@string/app_name"
        android:launchMode="singleTask" />

我的按钮点击:

mChangeOrientButton.setOnClickListener((OnClickListener)(new OnClickListener() {
    public final void onClick(View it) {
        if (getResources().getConfiguration().orientation == Configuration.ORIENTATION_PORTRAIT) {
            setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE);
        } else if(getResources().getConfiguration().orientation == Configuration.ORIENTATION_LANDSCAPE){
            setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT);
        } else {
            setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED);
        }
    }
}));

我的 onConfigurationChanged 方法(我注意到如果我点击按钮然后旋转手机,只要 requestedOrientation 保持设置为不同于 UNSPECIFIED 的设置,就不会再调用此方法):

@Override
public void onConfigurationChanged(Configuration newConfig)
{
    super.onConfigurationChanged(newConfig);
    if (newConfig.orientation == Configuration.ORIENTATION_LANDSCAPE) {
    {
        // Set the layout for landscape mode
    } else if (newConfig.orientation == Configuration.ORIENTATION_PORTRAIT){
        // Set the layout for portrait mode        
    }
}

我尝试像这样将 requestedOrientation 重置为 UNSPECIFIED:

@Override
public void onConfigurationChanged(Configuration newConfig)
{
    super.onConfigurationChanged(newConfig);
    if (newConfig.orientation == Configuration.ORIENTATION_LANDSCAPE) {
    {
        // Set the layout for landscape mode
    } else if (newConfig.orientation == Configuration.ORIENTATION_PORTRAIT){
        // Set the layout for portrait mode        
    }
    setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED);
}

但它不起作用,因为方向被强制从纵向变为横向,然后在用户有机会将其旋转为横向之前再次设置为未指定,因此它立即再次变为纵向并且它似乎正在做什么都没有。

最佳答案

好的,我在 this other answer 中找到了解决方案.它对我不起作用,所以我稍微修改了一下:

主 Activity

import android.content.Context;
import android.hardware.Sensor;
import android.hardware.SensorEvent;
import android.hardware.SensorEventListener;
import android.hardware.SensorManager;
import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.util.Log;
import android.view.Surface;
import android.widget.ImageView;

public class MainActivity extends AppCompatActivity {

    private SensorManager mSensorManager;
    private Sensor mOrientation;

    private boolean mIsForcingOrientation = false;

    float value_0 = -10000;
    float value_1 = -10000;

    private SensorEventListener mOrientationSensorListener = new SensorEventListener() {
        int orientation = -1;

        @Override
        public void onSensorChanged(SensorEvent event) {
            int value ;
            if(value_0 == event.values[0] && value_1==event.values[1]){
                return;
            }
            if (value_0 < 0 && event.values[0] > 0){
                // Setting rotation to 270°: Landscape reverse
                value = Surface.ROTATION_270;                
            } else if (value_0 > 0 && event.values[0] < 0){
                // Setting rotation to 90°: Landscape
                value = Surface.ROTATION_90;                
            } else if (value_1 < 0 && event.values[1] > 0){
                // Setting rotation to 180°: Portrait reverse
                value = Surface.ROTATION_180;                
            } else if (value_1 > 0 && event.values[1] < 0){
                // Setting rotation to 0°: Portrait
                value = Surface.ROTATION_0                
            } else {
                value = orientation;
            }

            if (orientation != value) {
                if((requestedOrientation == ActivityInfo.SCREEN_ORIENTATION_PORTRAIT && (value == Surface.ROTATION_90 || value == Surface.ROTATION_270) ) ||
                (requestedOrientation == ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE && (value == Surface.ROTATION_0 || value == Surface.ROTATION_180) )     ){
                    isForcingOrientation = false;
                    requestedOrientation = ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED;
                }
            }

            value_0=event.values[0];
            value_1=event.values[1];
        }

        @Override
        public void onAccuracyChanged(Sensor sensor, int accuracy) {

        }
    };

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        // Get sensor manager
        mSensorManager = (SensorManager) getSystemService(Context.SENSOR_SERVICE);
        // Get the default sensor of specified type
        mOrientation = mSensorManager.getDefaultSensor(Sensor.TYPE_ACCELEROMETER);

        mChangeOrientButton.setOnClickListener((OnClickListener)(new OnClickListener() {
            public final void onClick(View it) {
                mIsForcingOrientation = true;
                if (getResources().getConfiguration().orientation == Configuration.ORIENTATION_PORTRAIT) {
                    setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE);
                } else if(getResources().getConfiguration().orientation == Configuration.ORIENTATION_LANDSCAPE){
                    setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT);
                } else {
                    setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED);
                }
            }
        }));
    }

    @Override
    protected void onResume() {
        super.onResume();
        if (mOrientation != null) {
            mSensorManager.registerListener(mOrientationSensorListener, mOrientation,
                    SensorManager.SENSOR_DELAY_GAME);
        }
    }

    @Override
    protected void onPause() {
        super.onPause();
        if (mOrientation != null) {
            mSensorManager.unregisterListener(mOrientationSensorListener);
        }
    }
}

关于Android 在指定 requestedOrientation 时检测设备方向,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/50280889/

相关文章:

android - 覆盖 NavigationView 中单个 MenuItem 的高度

android - 我如何用 setRetainInstance(true) 破坏 fragment 并将它们添加到后台堆栈?

java - 检测用户是否在启动器上

android - 将 SVG 转换为 Android Vector Drawable

java - 如何在Android约束布局中均匀分布对象?

java - 方向改变时出现 InflateException

android - 带有 ProgressDialog 的 AsyncTask 与方向更改

android - Xamarin Android 的 Hangfire 替代品?

java - 如何在 8 秒内完成 Ads_Fullscreen Activity 并在之后执行 MainActivity?

java - Android : How to get just two digit after the point in decimal value ? 不想截断值