Android 屏幕旋转时如何改变DialogFragment的布局

How to change the layout of DialogFragment when the screen is rotated in Android

我有一个自定义 DialogFragment,其中包含两个 DatePicker 小部件(从和到,使用 layout/custom_date_picker)。

我需要在屏幕旋转到横向时更改 dialogFragment 的布局(使用 layout-land/custom_date_picker)。

Activity的配置是:

<activity
        android:name=".activities.MainActivity"
        android:configChanges="orientation|keyboardHidden|screenSize"
        android:launchMode="singleTop"/>

实现的DialogFragment来源是:

public class DatePickerDialog extends DialogFragment
{

public static final String START_SEARCH_DATE = "startSearchDate";
public static final String END_SEARCH_DATE = "endSearchDate";
private CustomDatePicker dpStartDate;
private CustomDatePicker dpEndDate;
private AlertDialog d;

public interface DatePickerDialogListener
{
    void onFinishDatePickDialog(String fromDate, String toDate);
}

public DatePickerDialog()
{
}

// Use this instance of the interface to deliver action events
DatePickerDialogListener mListener;

// Override the Fragment.onAttach() method to instantiate the DatePickerDialogListener
@Override
public void onAttach(Activity activity)
{
    super.onAttach(activity);
    // Verify that the host activity implements the callback interface
    try
    {
        // Instantiate the NoticeDialogListener so we can send events to the host
        mListener = (DatePickerDialogListener) activity;
    } catch (ClassCastException e)
    {
        // The activity doesn't implement the interface, throw exception
        throw new ClassCastException(activity.toString() + " must implement DatePickerDialogListener");
    }
}

public static DatePickerDialog newInstance(String startSearchDate, String endSearchDate)
{
    DatePickerDialog frag = new DatePickerDialog();
    Bundle args = new Bundle();
    args.putString(START_SEARCH_DATE, startSearchDate);
    args.putString(END_SEARCH_DATE, endSearchDate);
    frag.setArguments(args);
    return frag;
}

@NonNull
@Override
public Dialog onCreateDialog(Bundle savedInstanceState)
{
    View customView = getActivity().getLayoutInflater().inflate(R.layout.custom_date_picker, null);
    // Define your date pickers
    dpStartDate = (CustomDatePicker) customView.findViewById(R.id.dpStartDate);
    dpEndDate = (CustomDatePicker) customView.findViewById(R.id.dpEndDate);

    String startSearchDate = getArguments().getString(START_SEARCH_DATE);
    String endSearchDate = getArguments().getString(END_SEARCH_DATE);

    dpStartDate.updateDate(startSearchDate);
    dpEndDate.updateDate(endSearchDate);

    d = new AlertDialog.Builder(getActivity())
            .setView(customView)
            .setTitle(getString(R.string.datepicker_hint))
            .setPositiveButton(getString(R.string.ok), new DialogInterface.OnClickListener()
            {
                @Override
                public void onClick(DialogInterface dialog, int which)
                {

                }
            }) //Set to null. We override the onclick
            .setNegativeButton(getString(R.string.cancel), null)
            .create();
    d.show();
    d.getButton(AlertDialog.BUTTON_POSITIVE).setOnClickListener(new View.OnClickListener()
    {
        @Override
        public void onClick(View v)
        {

            boolean b = DateUtils.largerThanEndDate(dpStartDate, dpEndDate);
            if (b)
            {
                ToastUtils.showShortText(getActivity(), getString(R.string.date_error));
            } else
            {
                mListener.onFinishDatePickDialog(dpStartDate.getDate(), dpEndDate.getDate());
                dismiss();
            }
        }
    });
    return d;
}
}

谁能指导我如何做到这一点?提前致谢。

编辑: 这是我调用 DialogFragment:

的代码
public void showDatePicker()
{
    startSearchDate = dateModel.getStartDate();
    endSearchDate = dateModel.getEndDate();
    datePickerDialog = (DatePickerDialog)fragmentManager.findFragmentByTag(DATE_PICKER_DIALOG);

    if (alertDialog == null)
    {
        alertDialog = DatePickerDialog.newInstance(startSearchDate, endSearchDate);
        alertDialog.show(fragmentManager, DATE_PICKER_DIALOG);
    }

}

我想您可以考虑在 onCreate() 中使用 if 子句,如下所示:

int rotation = getWindowManager().getDefaultDisplay().getRotation();

然后

switch(rotation){
    case Surface.ROTATION_0: 
    case Surface.ROTATION_180:
        // show portrait

    case Surface.ROTATION_90: 
    case Surface.ROTATION_270:
        // show landscape
}

对于纵向模式,堆叠显示两个对话框。对于横向模式,并排显示它们。

编辑:

逐点回答:

  • 旋转phone时,必然会重新创建Activity。 这意味着 onCreate() 将在轮换时调用 。因此,旋转 state 可以在 onCreate() 中确定,如上所示。在这种情况下,使 rotation 成为 class 成员字段,以便可以在整个 class.
  • 中访问它
  • 确实,正如您正确指出的那样,对话框可以从 onConfigurationChanged()onCreate() 本身显示。为此,以及如何保存实例状态,请参阅附件链接。

参考文献:

1. How to properly retain a DialogFragment through rotation?.

2. Why won't Fragment retain state when screen is rotated?.