我正在创建一个包含EditText的自定义对话框,以便我可以从用户那里获取文本数据:
final EditText newKey = (EditText) findViewById(R.id.dialog_result);
AlertDialog.Builder keyBuilder = new AlertDialog.Builder(StegDroid.this);
keyBuilder
.setCancelable(false)
.setPositiveButton("Try Again", new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int id) {
Log.v("Dialog","New Key: "+newKey.getText().toString());
}
})
.setNegativeButton("Cancel", new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int id) {
dialog.cancel();
}
});
AlertDialog dialog = keyBuilder.create();
dialog.setTitle("Decryption Failed");
dialog.setContentView(R.layout.decrypt_failed_dialog);
dialog.show();
但是我总是得到这个例外:
01-11 18:49:00.507: ERROR/AndroidRuntime(3461): android.util.AndroidRuntimeException: requestFeature() must be called before adding content
01-11 18:49:00.507: ERROR/AndroidRuntime(3461): at com.android.internal.policy.impl.PhoneWindow.requestFeature(PhoneWindow.java:181)
01-11 18:49:00.507: ERROR/AndroidRuntime(3461): at com.android.internal.app.AlertController.installContent(AlertController.java:199)
01-11 18:49:00.507: ERROR/AndroidRuntime(3461): at android.app.AlertDialog.onCreate(AlertDialog.java:251)
...
在dialog.show()
行。我应该怎么做才能摆脱这个?
答案 0 :(得分:37)
您需要在创建对话框之前设置自定义视图。如果您使用setView(View)
为您提供的默认正面和负面按钮,则还需要使用setContentView()
而不是AlertDialog
。
final EditText newKey = (EditText) findViewById(R.id.dialog_result);
AlertDialog.Builder keyBuilder = new AlertDialog.Builder(StegDroid.this);
keyBuilder
.setCancelable(false)
.setPositiveButton("Try Again", new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int id) {
Log.v("Dialog","New Key: "+newKey.getText().toString());
}
})
.setNegativeButton("Cancel", new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int id) {
dialog.cancel();
}
});
keyBuilder.setTitle("Decryption Failed");
keyBuilder.setView(getLayoutInflater().inflate(R.layout.decrypt_failed_dialog, null));
AlertDialog dialog = keyBuilder.create();
dialog.show();
答案 1 :(得分:4)
还要确保您没有返回已经显示的对话框。例如,ProgressDialog
有一个方便的静态方法show()
,它接受一些参数并返回ProgressDialog
。事实证明你不能使用那个方法并返回结果ProgressDialog
,因为当操作系统试图显示它(并且它已经显示)时,它将抛出同样的异常。
请注意:上述行为在Android模拟器上有所体现,但它实际上没有引发异常并且在我的Droid Incredible运行2.2上运行得很好。
答案 2 :(得分:4)
我大约一年前遇到过这种情况并使用奇怪的代码修复了它。同样,我正在处理的应用程序有一个片段,应该在手机上正常显示,但在平板电脑上的对话框中。我这样解决了:
public class MyDialogFragment extends DialogFragment {
private View mLayout;
private ViewGroup mContainer;
@Nullable
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
mContainer = container;
if (getShowsDialog()) {
// one could return null here, or be nice and call super()
return super.onCreateView(inflater, container, savedInstanceState);
}
return getLayout(inflater, container);
}
private View getLayout(LayoutInflater inflater, ViewGroup container) {
mLayout = inflater.inflate(R.layout.my_layout, container, false);
return mLayout;
}
@Override
public Dialog onCreateDialog(Bundle savedInstanceState) {
return new AlertDialog.Builder(getContext())
.setPositiveButton(R.string.ok, null)
.setNegativeButton(R.string.cancel, null)
.setNeutralButton(R.string.filter_clear_selection, null)
.setView(getLayout(LayoutInflater.from(getContext()), mContainer))
.create()
;
}
}
这允许我将我的片段添加为任何正常片段(在布局中),但也将其显示为自动运行的对话框。
答案 3 :(得分:3)
对于那些在使用DialogFragment
时特别遇到此问题的人。
就我而言,发生这种情况是因为我错误地扩展了DialogFragment
类。我在onCreateView()
上返回了一个视图,并在onCreateDialog()
上返回了一个自定义对话框。文档说明:
您可能在UI设计中需要一部分UI 在某些情况下显示为对话框,但作为全屏或 在其他人中嵌入片段(可能取决于设备 是一个大屏幕或小屏幕)。 DialogFragment类提供 你有这种灵活性,因为它仍然可以表现为嵌入式 片段。
但是,您不能使用AlertDialog.Builder或其他Dialog对象 在这种情况下构建对话框。如果你想要DialogFragment 可嵌入,您必须在布局中定义对话框的UI,然后加载 onCreateView()回调中的布局。
通过不在onCreateDialog()
上创建任何内容来解决问题(仅返回超类实现)。
答案 4 :(得分:2)
我有类似的问题。但我的对话框将显示给IME。当我切换到Dialog而不是AlertDialog,并省略了创建时,该程序为我工作。
答案 5 :(得分:1)
如果您尝试在findViewById()
之前使用onCreate()
访问任何视图项,也会发生这种情况,在我的情况下,我这样做了:
private class ShareViaDialog extends Dialog {
private ImageView mainSmallIcon = findViewById(R.id.mainSmallIcon); //this is wrong
@Override
protected void onCreate(Bundle savedInstanceState) {
requestWindowFeature(Window.FEATURE_NO_TITLE);
super.onCreate(savedInstanceState);
}}
所以避免此错误的正确方法是:
private class ShareViaDialog extends Dialog {
private ImageView mainSmallIcon;
@Override
protected void onCreate(Bundle savedInstanceState) {
requestWindowFeature(Window.FEATURE_NO_TITLE);
super.onCreate(savedInstanceState);
mainSmallIcon = findViewById(R.id.mainSmallIcon); //should be here
}}
答案 6 :(得分:0)
我的应用程序中有一个“警告”对话框,它曾经给我提供了Android API 23上的这个Android运行时异常。
原来,这个问题与导入有关。我在导入中将android.app.AlertDialog
更改为androidx.appcompat.app.AlertDialog
,问题已解决。
这适用于使用AndroidX Artifacts的项目。如果您未使用AndroidX,请考虑使用支持版本android.support.v7.app.AlertDialog
。
答案 7 :(得分:0)
使用 DialogFragment 时,我也收到此错误消息。
在onCreateDialog(Bundle savedInstanceState)
中,我更改了返回的对话框时,我的问题得到解决
来自
android.appAlertDialog
到
androidx.appcompat.app.AlertDialog
(或者,如果您尚未迁移到AndroidX,则android.support.v7.app.AlertDialog
)
答案 8 :(得分:-3)
解决此问题的确切方法:
requestFeature(int)
是Window
的一种方法。您必须导入此类(android.view.Window
)。
你必须得到AlertDialog.Builder对象的Window。然后拨打requestFeature(int)
。输入参数是Window的常量。
keyBuilder.getWindow().requestFeature(Window.FEATURE_ACTION_BAR);