【问题标题】:Freeze screen orientation冻结屏幕方向
【发布时间】:2012-04-25 05:01:02
【问题描述】:

有如下代码的CheckBox:

    CheckBox cb = (CheckBox)findViewById(R.id.freezer);
    cb.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {

        @Override
        public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
            if (isChecked) {
                setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_NOSENSOR);
            } else {
                setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_FULL_SENSOR);
            }
        }
    });

所以,当我检查它时,屏幕会旋转到默认的系统方向(我的平板电脑的横向)。

我需要冻结当前方向。如果您将设备转为纵向并切换了 CheckBox,则必须先进行设备旋转,直到取消选中 CheckBox。

Display.getRotation() 不是解决方案,因为每个设备都有自己的 Surface.ROTATION

【问题讨论】:

    标签: android screen-orientation android-screen


    【解决方案1】:

    所以,这是我的解决方案。

    private int getCurentOrientation() {
        Display d = ((WindowManager) getSystemService(WINDOW_SERVICE))
                .getDefaultDisplay();
        boolean isWide = d.getWidth() >= d.getHeight();
        switch (d.getRotation()) {
        case Surface.ROTATION_0:
            return isWide ? ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE
                    : ActivityInfo.SCREEN_ORIENTATION_PORTRAIT;
        case Surface.ROTATION_90:
            return isWide ? ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE
                    : ActivityInfo.SCREEN_ORIENTATION_REVERSE_PORTRAIT;
        case Surface.ROTATION_180:
            return isWide ? ActivityInfo.SCREEN_ORIENTATION_REVERSE_LANDSCAPE
                    : ActivityInfo.SCREEN_ORIENTATION_REVERSE_PORTRAIT;
        case Surface.ROTATION_270:
            return isWide ? ActivityInfo.SCREEN_ORIENTATION_REVERSE_LANDSCAPE
                    : ActivityInfo.SCREEN_ORIENTATION_PORTRAIT;
        }
        return -1;
    }
    
    private void lockOrientation(boolean lock) {
        if (lock) {
            setRequestedOrientation(getCurentOrientation());
        } else {
            setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_FULL_SENSOR);
        }
    }
    

    在 4 台设备(2 台智能手机和 2 台平板电脑)上,它可以正常工作。

    【讨论】:

      【解决方案2】:

      创建一个成员变量并保存当前设置状态。 短is_landscape = -1;

      oncheckedchange 监听器,您可以永久设置状态并保存。

      if (is_landscape == -1) {
          Configuration config_screen = getResources().getConfiguration();
          int orientation = config_screen.orientation;
          if (orientation == Configuration.ORIENTATION_LANDSCAPE) {
             setRequestedOrientation(Configuration.ORIENTATION_LANDSCAPE);
             is_landscape = 0;
          } else {
             setRequestedOrientation(Configuration.ORIENTATION_PORTRAIT);
             is_landscape = 1;
         }
      }
      

      问题是,每当您旋转设备时,它都会重新创建您的活动,从而使您失去状态。所以只需将您的 is_landscape 变量保存在

      @Override
      protected void onSaveInstanceState(Bundle outState) {
          oustate.putExtra("last_state", is_landscape);
          super.onSaveInstanceState(outState);
      }
      
      you can restore your position on on restore instance
      
      @Override
      protected void onRestoreInstanceState(Bundle savedInstanceState) {
          is_landscape = savedInstanceState.getShort("last_state");
          if (is_landscape == 0) {
              setRequestedOrientation(Configuration.ORIENTATION_LANDSCAPE);
          } else if (is_landscape == 1) {
              setRequestedOrientation(Configuration.ORIENTATION_PORTRAIT);
          }
          super.onRestoreInstanceState(savedInstanceState);
      }
      

      如果你不想保存和恢复实例,那么你可以使用。

      android:configChanges="orientation"

      在您的清单文件中,它不允许在更改设备方向时重新创建活动。

      希望它对你有用。

      如果你想检测反向状态也可以使用

      int state = (WindowManager)getSystemService(WINDOW_SERVICE)).getDefaultDisplay().getRotation();

      如果状态是 Surface.ROTATION_0 那么它将是纵向的 如果状态是 Surface.ROTATION_90 那么它将是横向 如果状态是 Surface.ROTATION_180 那么它将是反向纵向 如果状态是 Surface.ROTATION_270 那么它将是反向横向

      在 Surface.ROTATION_0 和 Surface.ROTATION_180 的情况下设置纵向。 在 Surface.ROTATION_90 和 Surface.ROTATION_270 的情况下设置横向。

      您还可以设置旋转而不是方向,以便您的设备处于旋转状态而不是定向状态。

      【讨论】:

      • 您的代码将在 REVERSE_LANDSCAPE 和 REVERSE_PORTRAIT 方向上失败
      • 如果它适用于横向和纵向,那么你可以让它工作我已经告诉你你只需要检测 reverse_landscape 和 reverse_portrai 模式并保存它的状态并恢复它
      • 我给你的想法是你现在可以保存你的反向状态并恢复它onrestoreinstance剩下的事情是你只需要检测reverse_landscape和reverse_portrait并保存它。
      • 正如我在下面所说的那样,Display.getRotation() 返回“屏幕从其“自然”方向旋转”,因此在不同的设备上 Surface.ROTATION_0 可以同时是 SCREEN_ORIENTATION_PORTRAIT (对于高屏幕,如智能手机)和 SCREEN_ORIENTATION_LANDSCAPE(平板电脑)。
      • ok 使用两个不同的变量,一个来保存方向,另一个来保存旋转,如果方向是横向并且旋转小于 180,那么它不是反向的,否则根据你可以尝试的反向设置。我也在尝试寻找其他方法。
      【解决方案3】:

      既然你知道如何获取当前方向,那就写

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

      【讨论】:

      • Display display = ((WindowManager) getSystemService(WINDOW_SERVICE)).getDefaultDisplay(); int orientation = display.getOrientation(); //portrait=1;景观=2;
      • @styanton 接受正确/适合您的答案。
      • Display.getRotation() 返回“屏幕从其“自然”方向的旋转”,因此在不同的设备上 Surface.ROTATION_0 可以是 SCREEN_ORIENTATION_PORTRAIT (适用于高屏幕,如智能手机)和 SCREEN_ORIENTATION_LANDSCAPE (适用于平板电脑) )。这就是为什么这个答案不正确。
      • 好吧@styanton 我建议display.getOrientation(); 而不是Display.getRotation() 这是你正在做的事情,我不推荐!!!
      • Google 文档说,如果不推荐使用 display.getOrientation(),那么它应该仅用于向后兼容。我认为display.getOrientation() 返回相同的值。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-12-20
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多