FragmentActivity
显示一个对话框DialogFragment
- 没有标题的对话TabHost
- 对话框顶部的标签ViewPager
与FragmentPagerAdapter
- 可切换,内容已连接到标签ViewPager
的{{1}}之一,这意味着相同的按钮应保留在底部对话框,无论Fragment
显示Fragment
是什么。
ViewPager
IllegalStateException: Fragment does not have a view
包用于必要的类android.support.v4
而非getChildFragmentManager()
getSupportedFragmentManager()
类中,Fragment
假设要显示这些类,再加上ViewPager
类。DialogFragment
中,我首先尝试覆盖DialogFragment
,然后onCreateView
,然后同时覆盖onCreateDialog
。所有这些我都要跑,但意外的结果。
onCreateView
:无法到达AlertDialog.Builder
创建所需的按钮,而Dialog的结果非常棒。onCreateDialog
:上面显示的错误消息。我仍然认为这种方法与我想达到的目标一样接近。onCreateView
和onCreateDialog
:在onCreateView
中夸大了对话框布局,并将对话框按钮添加到AlertDialog.Builder
中的onCreateDialog
。这显示了对话框,但AlertDialog.Builder
中添加的按钮不可见。另外,点击EditText
字段时键盘没有显示。
大多数来自 Tutorial to implement the use of TabHost in Android 2.2 + ViewPager and Fragments 。 ActivityFragment
的代码改为DialogFragment
。但是,我使用此答案 https://stackoverflow.com/a/18167273/2375978 的源代码中的修改后的ViewPager替换了它。这是为了wrap_content
高度。
我相信,我的项目中的错误代码采用DialogFragment
的{{1}}方法。
onCreateDialog
@Override
public Dialog onCreateDialog(Bundle savedInstanceState) {
AlertDialog.Builder builder = new AlertDialog.Builder(getActivity(), AlertDialog.THEME_HOLO_DARK);
LayoutInflater inflater = getActivity().getLayoutInflater();
view = inflater.inflate(R.layout.dialog_test, null);
addActionButtons(builder, view);
builder.setView(view);
mViewPager = (WrapContentHeightViewPager) view.findViewById(R.id.viewpager);
initialiseTabHost();
List<Fragment> fragments = getFragments();
pageAdapter = new DialogPageAdapter(getChildFragmentManager(), fragments);
mViewPager.setAdapter(pageAdapter);
mViewPager.setOnPageChangeListener(this);
Dialog dialog = builder.create();
dialog.requestWindowFeature(Window.FEATURE_NO_TITLE);
dialog.getWindow().setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_ADJUST_RESIZE);
dialog.show();
return dialog;
}
答案 0 :(得分:35)
我想我刚遇到同样的问题并通过查看DialogFragment的来源了解了一些事情。
看起来即使重写onCreateDialog(...)是创建自定义对话框的有效方法,它也会导致DialogFragment具有空视图,就像错误消息所示。在大多数情况下这很好 - DialogFragment不需要View来显示对话框,但如果你想进一步嵌套片段(就像你那样),这将不会飞。
考虑到你想要与AlertDialog.Builder交互,我真的找不到完美的解决方案,但你有几个选择:
答案 1 :(得分:20)
使用
onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState)
而不是onCreateDialog(Bundle savedInstanceState)。不要创建警报对话框,使用方法提供的inflater,并构建视图。它对我有用。
祝你好运!
答案 2 :(得分:2)
感谢@Tommy Visic编写了一个非常好的描述,它起作用了。
发布适合我的代码。
我已从Dialog
方法infact删除onCreateDialog
方法中移除了onCreateDialog
建筑代码,以及我在Dialog's
自定义视图中实施的对话视图在View
方法中将其作为onCreateView
包含在内,所有内容都开始有效。
@Nullable
@Override
public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.login_sigup_screen, null, false);
bind = ButterKnife.bind(this, view);
initViewPager();
return view;
}
这个实现面临的另一个问题是:
当Activity
有Toolbar/ActionBar
时,它也会显示在DialogFragment
中,以避免要做的是:
实施onViewCreated
的{{1}}方法并添加以下代码
Fragment
这将从Dialog dialog = getDialog();
dialog.getWindow().requestFeature(Window.FEATURE_NO_TITLE);
float dimAmount = 0.6f;
dialog.getWindow().setDimAmount(dimAmount);
移除Toolbar
,DialogFragment
将按原样显示。
干杯
谢谢@Tommy
此致 宙斯
答案 3 :(得分:1)
如果实现onCreateDialog
以使用AlertDialog
,则在访问IllegalStateException: Fragment does not have a view
或类似的东西时会碰到getChildFragmentManager
。
要解决此问题,请同时实现onCreateDialog
和onCreateView
,其中onCreateView
返回以onCreateDialog
夸大的视图。
class LocationPickerDialog : DialogFragment() {
lateinit var customView: View
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? {
return customView
}
override fun onCreateDialog(savedInstanceState: Bundle?): Dialog {
Log.d(TAG, "onCreateDialog")
// StackOverflowError
// customView = layoutInflater.inflate(R.layout.dialog_location_picker, null)
customView = activity!!.layoutInflater.inflate(R.layout.dialog_location_picker, null)
val builder = AlertDialog.Builder(context!!)
.setView(customView)
.setPositiveButton(android.R.string.ok) { _, _ ->
// do something
}
.setNegativeButton(android.R.string.cancel) { _, _ ->
// do something
}
val dialog = builder.create()
return dialog
}
override fun onActivityCreated(savedInstanceState: Bundle?) {
// if onCreateView doesn't return a view
// java.lang.IllegalStateException: Fragment does not have a view
mapFragment = childFragmentManager.findFragmentByTag("map") as SupportMapFragment?
}
}