如何强制旋转对话框片段



如果活动屏幕方向被锁定,如何旋转对话片段90度或180度?

活动声明在manifest:

<activity
   ...
   android:screenOritentation="landscape" />
对话框

片段:

public class MyFragment extends DialogFragment{
   // stuff
}

我已经旋转了对话框的布局使用NineOldAndroid库。如果我旋转到180度,它就像我预期的那样工作,但是如果我旋转到90度,布局就不完全可见了。

我正在尝试旋转整个对话框(不仅仅是布局),包括按钮,标题,一切,但我不知道如何做到这一点

你可以尝试在DialogFragment的onStart()和onStop()方法上使用ActivityInfo的一些标志。

例如,对于DialogFragment,你可以在onStart()方法上固定一些方向:

@Override
public void onStart()
{
    super.onStart();
    // lock screen;
    DisplayTools.Orientation orientation = DisplayTools.getDisplatOrientation(getActivity());
        getActivity().setRequestedOrientation(orientation == DisplayTools.Orientation.LANDSCAPE
                ? ActivityInfo.SCREEN_ORIENTATION_SENSOR_LANDSCAPE
                : ActivityInfo.SCREEN_ORIENTATION_SENSOR_PORTRAIT);
}

并在onStop()方法上恢复方向:

@Override
public void onStop()
{
    super.onStop();
    // unlock screen;
    getActivity().setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED);
}

(在你的特殊情况下,你必须使用ActivityInfo。SCREEN_ORIENTATION_SENSOR_LANDSCAPE代替ActivityInfo。SCREEN_ORIENTATION_UNSPECIFIED at onStop() method)

,

public class DisplayTools
{
    static public Point getDisplaySize(Context context)
    {
        WindowManager wm = (WindowManager) context.getSystemService(Context.WINDOW_SERVICE);
        Display display = wm.getDefaultDisplay();
        Point size = new Point();
        display.getSize(size);
        return size;
    }
    static public Orientation getDisplatOrientation(Activity activity)
    {
        if (activity != null)
        {
            int orientation = activity.getResources().getConfiguration().orientation;
            if (orientation == Configuration.ORIENTATION_LANDSCAPE)
            {
                return Orientation.LANDSCAPE;
            }
            if (orientation == Configuration.ORIENTATION_PORTRAIT)
            {
                return Orientation.PORTRAIT;
            }
            if (orientation == Configuration.ORIENTATION_UNDEFINED)
            {
                return Orientation.UNDEFINED;
            }
        }
        return Orientation.UNKNOWN;
    }
    public static enum Orientation
    {
        UNKNOWN(-1),
        UNDEFINED(0),
        PORTRAIT(1),
        LANDSCAPE(2);
        private int tag;
        Orientation(int i)
        {
            this.tag = i;
        }
    }
}

我希望你明白大意!

解决方案是根据当前方向为对话框膨胀一个特定的布局。在我的应用程序中,活动被锁定为横向,但是,如果我将设备转为纵向,我将显示一个特定的布局,而无需重新创建活动。

注意:它不能与已经打开的对话框一起工作。当设备旋转时,对话框不旋转。它只在对话框创建时旋转。

你活动:

public class ActivityMain extends Activity
{
    private boolean isPortrait = false;
    private boolean isFlip = false;
    private OrientationEventListener orientationEventListener;
    @Override
    protected void onCreate(Bundle bundle)
    {
        // stuff
        setUpOrientationListener();
    }
    // Register device to detected orientation change
    private void setUpOrientationListener()
    {
            orientationEventListener = new OrientationEventListener(this, SensorManager.SENSOR_DELAY_NORMAL)
            {
                @Override
                public void onOrientationChanged(int orientation)
                {
                    // Device is in portrait
                    if (orientation > 320 || orientation < 45)
                    {
                        if (!isPortrait)
                            onPortraitRotation();
                    }
                    else // Device is flipped
                    if (orientation > 45 && orientation < 145)
                    {
                        if (!isFlip)
                            onFlipRotation();
                    }
                    else // Device is in landscape
                    {
                        if (isPortrait)
                            onLandscapeRotation();
                    }
                }
            };
            // If device is capable for detecting orientation register listener
            if (orientationEventListener.canDetectOrientation())
                orientationEventListener.enable();
        }
    private void onPortraitRotation()
    {
        isPortrait = true;
        isFlip = false;
    }
    private void onFlipRotation()
    {
        isFlip = true;
        isPortrait = false;
    }
    private void onLandscapeRotation()
    {
        isPortrait = false;
        isFlip = false;
    }
    // Creates your custom dialog
    private void showCustomDialog()
    {
        MyDialog dialog = new MyDialog(ActivityMain.this, isPortrait, isFlipped);
        dialog.show();
    }
}

现在我们知道了设备的方向,现在创建对话框。

注意使用DialogFragment与静态构造函数:http://developer.android.com/reference/android/app/DialogFragment.html(然而,我使用简单的Dialog进行演示)

public class MyDialog extends Dialog
{
    private boolean isPortrait;
    private boolean isFlipped;
    public MyDialog(Context context, boolean isPortrait, boolean isFlipped)
    {
        super(context);
        this.isPortrait = isPortrait;
        this.isFlipped = isFlipped;
    }
    @Override
    protected void onCreate(Bundle bundle)
    {
        super.onCreate(savedInstanceState);
        getWindow().requestFeature(Window.FEATURE_NO_TITLE);
        // Device is in landscape mode
        if (!isPortrait && !isFlipped)
            setContentView(R.layout.dialog_landscape);
        else
        if (isPortrait && !isFlipped) // Device is in portrait
            setContentView(R.layout.dialog_vertical);
        else // Device is flipped
        {
            setContentView(R.layout.dialog_landscape);
            // Rotate the entire root layout
            View layout = findViewById(R.id.rlContainer);
            ObjectAnimator.ofFloat(layout, "rotation", 180).setDuration(0).start();
        }
    }
}

旋转使用nindeoldandroid库

注:此解决方案适用于:横向,纵向和翻转横向。要显示翻转的纵向,必须在方向检测侦听器中计算方向。

注2:不要使用系统按钮!它们附加到附加到父(活动)锁定方向的对话框上。使用布局内置按钮视图

我认为cosic的解决方案是最好的,以及这个Activity配置:

android:configChanges="orientation|screenSize"

…然后在你的活动,你可以实现onConfigurationChanged(),要么忽略更改或做一些自定义。

最新更新