小问题,记录下~
Android4.0以后开始推荐使用DialogFragment代替Dialog。Android的官方文档中给了两个示例:
- 一个
Basic Dialog
示例了如何自定义窗口内容——重写
onCreateView
方法。 - 一个
Alert Dialog
示例了如何自定义弹窗的正负按钮——重写
onCreateDialog
方法。
好的,那么问题来了
在实际应用中经常是需要既自定义窗口内容、又需要自定义按钮的。
这时候如果我们按图索骥,把DialogFragment的onCreateView和onCreateDialog方法都重写的话,会发现——Bong!异常~ 诸如“AndroidRuntimeException: requestFeature() must be called before adding content”的就出现了。
这个异常出现的原因可以看:stackoverflow的这个问题中Freerider的答案以及下面评论。
摘抄一下:“ You can override both (in fact the DialogFragment says so), the problem comes when you try to inflate the view after having already creating the dialog view. You can still do other things in onCreateView, like use the savedInstanceState, without causing
the exception.”
然后是解决方案:
既然两个方法不能同时重写,所以就选择一个进行重写:
重写onCreateDialog方法,参照官方示例即可以自定义按钮,然后对其作修改,使之能自定义view——在AlertDialog.Builder进行create()
创建dialog之前,使用AlertDialog.Builder的setView(view)
方法,其中view是自定view。
来感受一下区别~
这是Google给的示例:
@Override public Dialog onCreateDialog(Bundle savedInstanceState) { int title = getArguments().getInt("title"); return new AlertDialog.Builder(getActivity()) .setIcon(R.drawable.alert_dialog_icon) .setTitle(title) .setPositiveButton(R.string.alert_dialog_ok, 。。。) .setNegativeButton(R.string.alert_dialog_cancel, 。。。) .create(); }
这是修改之后的:
@Override public Dialog onCreateDialog(Bundle savedInstanceState) { //inflater在前面构造函数中实例化 View v = inflater.inflate(R.layout.dialog,null); imageGridView = (GridView) v.findViewById(R.id.gridViewImage); //自定义view,bla~bla~ AlertDialog.Builder builder = new AlertDialog.Builder(getActivity()); return builder.setView(v) .setIcon(android.R.drawable.ic_dialog_alert) .setTitle(title) .setCancelable(false) .setPositiveButton(R.string.alert_dialog_ok, 。。。) .setNegativeButton(R.string.alert_dialog_cancel, 。。。) .create(); }
Also at: http://www.barryzhang.com/archives/396