如何强制旋转对话框片段?

时间:2014-07-04 17:33:05

标签: android dialog rotation

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

在manifest中声明

活动

<activity
   ...
   android:screenOritentation="landscape" />

对话片段:

public class MyFragment extends DialogFragment{
   // stuff
}

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

我正在尝试旋转整个对话框(不仅是布局),包含按钮,标题,所有内容,但我无法弄清楚如何去做。

3 个答案:

答案 0 :(得分:3)

您可以尝试在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);
}

(这使用来自ActivityInfo的标志)

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

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

(在您的特定情况下,您必须在onStop()方法中使用ActivityInfo.SCREEN_ORIENTATION_SENSOR_LANDSCAPE而不是ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED)

哪里

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

我希望你理解主意!

答案 1 :(得分:1)

解决方案是按当前方向为对话框扩展特定布局。在我的应用中,活动被锁定为横向,但是,如果我将设备设置为纵向,我将显示特定的布局而不重新创建活动。

注意:它不适用于已打开的对话框。旋转设备时,不会旋转对话框。它仅在对话框创建时旋转。

您的活动:

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

轮换使用NindeOldAndroids库。

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

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

答案 2 :(得分:0)

我认为cosic's solution是最好的,以及此活动配置:

android:configChanges="orientation|screenSize"

...然后在您的活动中,您可以实施onConfigurationChanged(),并忽略更改或执行自定义操作。