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?.
我有一个自定义 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?.