关于android.util.AndroidRuntimeException: requestFeature() must be called before adding content
的问题有很多。但是所提出的解决方案都没有对我有用。
我有自定义DialogFragment
@Override
public Dialog onCreateDialog(Bundle savedInstanceState) {
return new AlertDialog.Builder(getActivity()).create();
}
@Override
public final View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
return inflater.inflate(R.layout.notification_dialog, null);
}
@Override
public void onViewCreated(View view, Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState);
//setting up dialog
}
我这样表现出来
newDialogInstance().show(activity.getFragmentManager(), "tag-dialog-fragment");
每次我得到:
android.util.AndroidRuntimeException: requestFeature() must be called before adding content
at com.android.internal.policy.impl.PhoneWindow.requestFeature(PhoneWindow.java:226)
at com.android.internal.app.AlertController.installContent(AlertController.java:234)
at android.app.AlertDialog.onCreate(AlertDialog.java:337)
at android.app.Dialog.dispatchOnCreate(Dialog.java:355)
at android.app.Dialog.show(Dialog.java:260)
at android.app.DialogFragment.onStart(DialogFragment.java:490)
at android.app.Fragment.performStart(Fragment.java:1719)
有人可以解释一下这里发生了什么吗?
答案 0 :(得分:3)
这是一个迟到的答案,但也许可以帮助某人,问题来自于您试图从onCreateDialog
和onCreateView
充气对话这一事实。为避免这种情况,您可以避免使用onCreateView
并在onCreateDialog
中扩充您的布局。
你会得到这个:
@Override
public Dialog onCreateDialog(Bundle savedInstanceState) {
// Get the layout inflater
LayoutInflater inflater = getActivity().getLayoutInflater();
View layout = inflater.inflate(R.layout.notification_dialog, null);
/** Add modifications on your layout if needed */
AlertDialog.Builder builder = new AlertDialog.Builder(getActivity());
// Add your custom layout to the builder
builder.setView(layout);
return builder.create();
}
然后只需删除onCreateView
或使用它来执行其他操作,例如使用savedInstanceState
,如其他答案中所述:https://stackoverflow.com/a/15602648/2206688
您还可以查看文档示例: http://developer.android.com/guide/topics/ui/dialogs.html#CustomLayout
答案 1 :(得分:3)
另一个迟到的答案我把它的一部分作为评论写了但也许它对其他人也很有用。
正如Yoann已经写过的,问题是View被创建了两次,在对话框中,它创建了自己的窗口,导致了问题。官方文档(http://developer.android.com/reference/android/app/DialogFragment.html#AlertDialog)使得似乎可以同时覆盖onCreateView
和onCreateDialog
并显示可以嵌入或使用的自定义布局AlertDialog样式:< / p>
而不是(或除此之外)实施 onCreateView(LayoutInflater,ViewGroup,Bundle)生成视图 对话框内的层次结构,你可以实现onCreateDialog(Bundle) 创建自己的自定义Dialog对象。
这对于创建AlertDialog,[...]
非常有用
可以覆盖这两种方法,但不能与AlertDialog.Builder结合使用。
到目前为止,对我有用的是:
public class CustomDialogFragment extends DialogFragment {
@NonNull
@Override
public Dialog onCreateDialog(Bundle savedInstanceState) {
if (isInLayout())
return super.onCreateDialog(savedInstanceState);
AlertDialog.Builder builder = new AlertDialog.Builder(getActivity())
.setView(R.layout.my_custom_layout)
.setTitle(R.string.my_title)
.setPositiveButton(R.string.ok, new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
// TODO implement
}
});
return builder.create();
}
@Nullable
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
if (!isInLayout())
return super.onCreateView(inflater, container, savedInstanceState);
View v = inflater.inflate(R.layout.my_custom_layout, container);
return v;
}
}
我使用isInLayout()
来决定是调用超级方法还是使用自定义实现。
编辑:此示例使用支持库类:http://developer.android.com/reference/android/support/v7/app/AlertDialog.Builder.html#setView(int)
答案 2 :(得分:-8)
像这样使用:
@Override
public Dialog onCreateDialog(Bundle savedInstanceState) {
AlertDialog.Builder builder = new AlertDialog.Builder(getActivity());
View view = getActivity().getLayoutInflater().inflate(R.layout.notification_dialog, null);
builder.setView(view);
return builder;
}