Android 对话框问题:添加内容之前必须调用requestFeature()

Android 对话框问题:添加内容之前必须调用requestFeature(),android,dialog,Android,Dialog,我正在创建一个包含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

我正在创建一个包含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()的
行中。我应该怎么做才能摆脱这个问题?

在创建对话框之前,您需要设置自定义视图。如果您使用的是
AlertDialog
为您提供的默认正面和负面按钮,则还需要使用
setView(View)
而不是
setContentView()

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();

还要确保没有返回已显示的对话框。例如,
ProgressDialog
有一个方便的静态方法,它接受一些参数并返回一个
ProgressDialog
。结果表明,您无法使用该方法并返回结果
ProgressDialog
,因为当操作系统尝试显示它时(并且已经显示),它将抛出相同的异常


也要注意:上面的行为在Android emulator上是有经验的,但它实际上没有引发异常,在我的Droid难以置信运行2.2上运行得很好。

我也有类似的问题。但我的对话框是要为IME显示的。当我切换到Dialog而不是AlertDialog,并省略了create时,该程序对我有效

解决此问题的确切方法:

requestFeature(int)
Window
的一种方法。您必须导入此类(
android.view.Window

您必须获得AlertDialog.Builder对象的窗口。然后调用
requestFeature(int)
。输入参数是窗口的常数


keyBuilder.getWindow().requestFeature(Window.FEATURE\u ACTION\u BAR)

大约一年前我遇到过这个问题,并用一种奇怪的代码修复了它。同样,我正在开发的一个应用程序中有一个片段,应该可以在手机上正常显示,但在平板电脑上的对话中显示。我是这样解决的:

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()
            ;
    }
}

这使我可以将片段添加为任何普通片段(在布局中),但也可以将其显示为一个对话框,在该对话框中它可以自动运行。

适用于那些在使用
DialogFragment
时遇到此问题的人

在我的例子中,发生这种情况是因为我错误地扩展了
DialogFragment
类。我在
onCreateView()
上返回了一个视图,在
onCreateDialog()
上也返回了一个自定义对话框。文件规定:

您可能有一个UI设计,希望在其中添加一部分UI 在某些情况下显示为对话框,但显示为全屏或 在其他设备中嵌入片段(可能取决于设备 是大屏幕还是小屏幕)。DialogFragment类提供了 您可以使用这种灵活性,因为它仍然可以作为可嵌入的 碎片

但是,不能使用AlertDialog.Builder或其他对话框对象 在这种情况下构建对话框。如果你想让DialogFragment 可嵌入,必须在布局中定义对话框的UI,然后加载 onCreateView()回调中的布局


通过在
onCreateDialog()
上不创建任何内容(仅返回超类实现)解决了此问题。

如果尝试在
onCreate()
之前使用
findViewById()
访问任何视图项,也会发生这种情况,在我的情况下,我是这样做的:

 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
    }}

我的应用程序中有一个警报对话框,它在android API 23上给了我这个android运行时异常

原来这个问题是进口的。我在导入中将
android.app.AlertDialog
更改为
androidx.appcompat.app.AlertDialog
,问题得到了解决


这适用于使用AndroidX工件的项目。考虑使用支持版本<代码> Android .Buff.V7.App.AdvtReals如果您不使用ANDROIDX。

< P>我在使用<强>对话片段< /强>

时也有此错误信息。 在
onCreateDialog(Bundle savedInstanceState)
中,我更改了返回的对话框,我的问题就解决了

android.appAlertDialog

androidx.appcompat.app.AlertDialog


(或者如果你还没有迁移到AndroidX,那么
android.support.v7.app.AlertDialog

最好添加一条注释,这样其他人就可以很容易地找出不同之处,而无需比较代码。你说得对,伙计。。。我现在没有时间。你介意把答案编辑得更精确些吗?谢谢!您使用“…您需要使用setView(View)而不是setContentView()…”:)@Cristian保存了我的一天当以这种方式使用时,它不会显示正按钮和负按钮。有什么想法吗?