显示为对话框的 DialogFragment 在方向更改时调整为全屏
DialogFragment shown as Dialog resizes to full screen on orientation change
我正在实现一个包含两个 EditText
字段的对话框。根据 Material 设计规范,此类对话框应在较小的设备上全屏显示,而在大屏幕上应显示在对话框 window.
中
为了实现这一点,我遵循了 developer.android.com guide on Dialogs.
中的实现
这适用于较小的屏幕,但对于大屏幕,对话框 window 在方向更改后占据整个屏幕。
用于显示 DialogFragment
的代码(我的 AppCompatActivity
中 onOptionsItemSelected()
的一部分)
mIsLargeLayout = getResources().getBoolean(R.bool.large_layout);
FragmentManager fragmentManager = getSupportFragmentManager();
mDialog = MyDialogFragment.newInstance(mIsLargeLayout);
if (mIsLargeLayout)
{
// The device is using a large layout, so show the fragment as a dialog
mDialog.show(fragmentManager, "dialog");
}
else
{
// The device is smaller, so show the fragment fullscreen
FragmentTransaction transaction = fragmentManager.beginTransaction();
// To make it fullscreen, use the 'content' root view as the container
// for the fragment, which is always the root view for the activity
transaction.add(android.R.id.content, mDialog, "dialog")
.addToBackStack(null)
.commit();
}
对于 DialogFragment
,我首先重写 onCreateView()
来扩展我的自定义布局:
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState)
{
setStyle(DialogFragment.STYLE_NORMAL, R.style.AppTheme);
View v = inflater.inflate(R.layout.dialog_filter_audio_files,
container, false);
// code for Buttons and EditTexts here:
// set listeners etc.
return v;
}
... 然后 onCreateDialog()
使用以下语句:
Dialog dialog = super.onCreateDialog(savedInstanceState);
dialog.setCancelable(true);
dialog.getWindow().setBackgroundDrawableResource(R.color.c_background_dark);
return dialog;
我不会关闭 DialogFragment
方向更改,但在 onRestoreInstanceState()
中,我会像这样重新连接到 DialogFragment
:
mDialog = (DialogFilterAudiofiles) getSupportFragmentManager().findFragmentByTag("dialog");
虽然用户可以完成对话框,无论它看起来像什么,但我想保持对话框小 - 就像方向改变之前一样。
当然,我可以在保存到目前为止的输入后关闭 onSaveInstanceState()
中的对话框,然后在 onRestoreInstanceState()
中显示一个新对话框。
或者,如果屏幕尺寸很大,我可以使用基于 AlertDialog
和 setContentView()
的 DialogFragment
s。
还有其他方法可以修复指南中的示例代码吗?
编辑
我想尽可能接近“一种布局适合所有尺寸”的方法。
我对“onCreateView()”的实现灵感来自于但扩展了
示例代码,所以我在上面的文本中添加了相关部分。
在布局的根元素中,为较大的设备定义不填满对话框布局屏幕的尺寸。如果这不起作用,请参阅 how-to-set-a-maximum-height-with-wrap-content-in-android
终于找到问题的根源了:
setStyle(DialogFragment.STYLE_NORMAL, R.style.AppTheme);
起初工作正常:DialogFragment
创建为全屏对话框或小 window,具体取决于 mIsLargeLayout
.
的值
但是如果在更改配置后必须重新创建它,此行会导致它全屏显示。
我的预期是值 R.style.AppTheme
会让运行时查找作为应用程序主题一部分的自定义对话框样式,但实际上它只是将 DialogFragment
视为一种在配置更改后重新创建时 Activity
。
在我的例子中,删除整个语句和使用
一样有效
setStyle(DialogFragment.STYLE_NORMAL, 0);
来自documentation第二个参数:
Optional custom theme. If 0, an appropriate theme (based on the style) will be selected for you.
我正在实现一个包含两个 EditText
字段的对话框。根据 Material 设计规范,此类对话框应在较小的设备上全屏显示,而在大屏幕上应显示在对话框 window.
为了实现这一点,我遵循了 developer.android.com guide on Dialogs.
中的实现这适用于较小的屏幕,但对于大屏幕,对话框 window 在方向更改后占据整个屏幕。
用于显示 DialogFragment
的代码(我的 AppCompatActivity
中 onOptionsItemSelected()
的一部分)
mIsLargeLayout = getResources().getBoolean(R.bool.large_layout);
FragmentManager fragmentManager = getSupportFragmentManager();
mDialog = MyDialogFragment.newInstance(mIsLargeLayout);
if (mIsLargeLayout)
{
// The device is using a large layout, so show the fragment as a dialog
mDialog.show(fragmentManager, "dialog");
}
else
{
// The device is smaller, so show the fragment fullscreen
FragmentTransaction transaction = fragmentManager.beginTransaction();
// To make it fullscreen, use the 'content' root view as the container
// for the fragment, which is always the root view for the activity
transaction.add(android.R.id.content, mDialog, "dialog")
.addToBackStack(null)
.commit();
}
对于 DialogFragment
,我首先重写 onCreateView()
来扩展我的自定义布局:
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState)
{
setStyle(DialogFragment.STYLE_NORMAL, R.style.AppTheme);
View v = inflater.inflate(R.layout.dialog_filter_audio_files,
container, false);
// code for Buttons and EditTexts here:
// set listeners etc.
return v;
}
... 然后 onCreateDialog()
使用以下语句:
Dialog dialog = super.onCreateDialog(savedInstanceState);
dialog.setCancelable(true);
dialog.getWindow().setBackgroundDrawableResource(R.color.c_background_dark);
return dialog;
我不会关闭 DialogFragment
方向更改,但在 onRestoreInstanceState()
中,我会像这样重新连接到 DialogFragment
:
mDialog = (DialogFilterAudiofiles) getSupportFragmentManager().findFragmentByTag("dialog");
虽然用户可以完成对话框,无论它看起来像什么,但我想保持对话框小 - 就像方向改变之前一样。
当然,我可以在保存到目前为止的输入后关闭 onSaveInstanceState()
中的对话框,然后在 onRestoreInstanceState()
中显示一个新对话框。
或者,如果屏幕尺寸很大,我可以使用基于 AlertDialog
和 setContentView()
的 DialogFragment
s。
还有其他方法可以修复指南中的示例代码吗?
编辑 我想尽可能接近“一种布局适合所有尺寸”的方法。
我对“onCreateView()”的实现灵感来自于但扩展了 示例代码,所以我在上面的文本中添加了相关部分。
在布局的根元素中,为较大的设备定义不填满对话框布局屏幕的尺寸。如果这不起作用,请参阅 how-to-set-a-maximum-height-with-wrap-content-in-android
终于找到问题的根源了:
setStyle(DialogFragment.STYLE_NORMAL, R.style.AppTheme);
起初工作正常:DialogFragment
创建为全屏对话框或小 window,具体取决于 mIsLargeLayout
.
但是如果在更改配置后必须重新创建它,此行会导致它全屏显示。
我的预期是值 R.style.AppTheme
会让运行时查找作为应用程序主题一部分的自定义对话框样式,但实际上它只是将 DialogFragment
视为一种在配置更改后重新创建时 Activity
。
在我的例子中,删除整个语句和使用
一样有效setStyle(DialogFragment.STYLE_NORMAL, 0);
来自documentation第二个参数:
Optional custom theme. If 0, an appropriate theme (based on the style) will be selected for you.