2011-01-11 77 views
13

我正在创建一个包含EditText的自定义对话框,以便我可以从用户那里获取文本数据:对话问题:在添加内容之前必须调用requestFeature()

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

但是我总是得到这个例外: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) 

... 

。我应该怎么做才能摆脱这个?

回答

34

您需要在创建对话框之前设置自定义视图。如果您使用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(); 
+2

这将是很好的添加评论,让别人可以很容易地找出不同的做法,而不必比较代码。 – codinguser

+0

你是对的......我现在没时间了。你介意编辑答案,使其更加精确吗? – Cristian

+3

谢谢!你用“...你需要使用setView(View)而不是setContentView()...”来保存我的一天...“:) –

4

还要确保你没有返回已经显示的对话框。例如,ProgressDialog有一个方便的静态方法show(),它需要一些参数并返回ProgressDialog。事实证明,你不能使用该方法并返回结果ProgressDialog,因为当操作系统试图显示它(并且它已经显示)时,它会抛出同样的异常。

小心,太:上述行为是经历了Android模拟器,但它实际上没有抛出异常,只是正常工作在我的Droid难以置信运行2.2。

2

我也有类似的问题。但我的对话框将显示为IME。当我切换到对话框而不是AlertDialog,并省略了创建,该程序为我工作。

-3

来解决这个问题的确切方式:

requestFeature(int)Window的方法。你必须导入这个类(android.view.Window)。

而且你必须得到AlertDialog.Builder对象的窗口。然后致电requestFeature(int)。输入参数是Window的一个常量。

keyBuilder.getWindow().requestFeature(Window.FEATURE_ACTION_BAR);

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

对于那些谁使用DialogFragment时专门有这个问题。

对我来说,这是发生了,因为我没有正确扩展DialogFragment类。我正在返回onCreateView()的视图,并且还返回onCreateDialog()上的自定义对话框。该文件指出:

您可能必须要在其中一块UI到 的出现在某些情况下一个对话框中的用户界面设计,但在其他人(全屏幕或 嵌入式片段或许取决于设备 是大屏幕还是小屏幕)。 DialogFragment类为您提供了这种灵活性,因为它仍然可以作为可嵌入的 片段。

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

通过在onCreateDialog()(仅返回超类实现)上不创建任何东西来解决问题。

相关问题