2011-12-31 179 views
1

我试图通过扩展AlertDialog类来构建自定义AlertDialog
和往常一样,我在onCreate()方法中设置对话框。或者,我想这样做:自定义AlertDialog无法初始化onCreate()

@Override 
protected void onCreate(Bundle savedInstanceState) { 
    super.onCreate(savedInstanceState); 

    this.setTitle("Some title"); 
    this.setButton(BUTTON_POSITIVE, "Click me", (DialogInterface.OnClickListener)null); 

    final FrameLayout custom = (FrameLayout) this 
      .findViewById(android.R.id.custom); 

    custom.addView(this.getLayoutInflater().inflate(R.layout.mydlg, null), 
      LayoutParams.MATCH_PARENT, LayoutParams.WRAP_CONTENT); 

} 

现在,当涉及到显示该对话框的一个实例,没有所示。 当前Activity淡出并失去焦点,但不显示对话框的单个像素。按返回带来Activity回到前台,这表明对我来说,实际上对话框是显示,但只是一个完全空的。

但是,当我创建一个AlertDialog并使用(例如)dlg.setButton(BUTTON_POSITIVE, "Click me", (DialogInterface.OnClickListener)null); 时,对话框将显示相应的按钮。
即使当我使用与上面相同的代码在其构造函数中设置自定义对话框时,一切似乎都可以正常工作。

现在,这怎么可能?为什么我似乎无法在其onCreate()方法中初始化我的对话框?这是不是你应该初始化任何 GUI元素的方式?我错过了什么?

编辑

请注意,东西是“显示”,淡出活动,并从中取焦点。只是它看起来完全是空的/看不见的。

这里的另一种尝试:把我的对话框的构造函数时

this.setTitle("Some title"); 
    this.setButton(BUTTON_POSITIVE, "Click me", (DialogInterface.OnClickListener)null); 

    final View v = this.getLayoutInflater().inflate(R.layout.mydlg, null); 

    this.setView(v); 

这些精确的线条工作。
这些确切的行不要工作时,把我的对话框的onCreate()

这是怎么回事?

一般情况下,我不应该在onCreate()吗? - 如果我在构造函数中进行上面的初始化,我会面临麻烦吗? (无论如何,这对我来说似乎并不太干净。)

+0

你找到任何解决方案,专门做这种方式?我面临同样的问题。 – 2015-03-11 04:23:13

+0

在下面的评论中,TheTerribleSwiftTomato指出,“派生AlertDialog并在其构造函数中定制它而不是onCreate()方法”应该是一个好的做事方式。这就是我最终使用的。 – JimmyB 2015-03-19 13:52:04

+0

嗨Hanno,我尝试在onCreate中设置自定义对话框,其结果与您的相同,活动失去焦点并没有显示任何内容。但是当我在构造函数中放入相同的代码时,android.R.id.custom的framelayout返回null。因此,你可以发布工作代码,以便我可以验证我出错的地方。谢谢。 – 2015-03-20 03:48:39

回答

2

您需要拨打show()方法才能看到内容。

+0

毫无疑问:) – JimmyB 2011-12-31 12:38:19

+1

我没有意识到视图不会膨胀直到调用show(),并且因此我的findViewById()将总是返回null,因为我还没有调用show()。 – Keith 2012-05-16 19:26:37

1

您应该考虑使用AlertDialog.Builder而不是AlertDialog的子类本身。它允许你在你的例子中做所有你需要的东西(按顺序:setTitle(),setPositiveButton()和setView())。不要忘了在最后调用create()来获得对话。

另外,检查您的onCreateDialog()和onPrepareDialog()活动方法是否正确实现。如果你根本没有实现它们(一个非托管对话框),不管怎样,都要考虑这样做,特别是如果你的应用允许改变方向。你可能知道这一点,但这里是一个教程:

http://developer.android.com/guide/topics/ui/dialogs.html

也DialogFragments是实现这一点更简单的方法,但你需要一个新的API版本或兼容性包:

http://developer.android.com/reference/android/app/DialogFragment

最后一个问题 - 你在哪里打电话show()在你的活动? onResume()应该没问题,onCreate()没有那么多。

+0

使用Builder可以工作,例如AlertDialog实例,然后从“外部”进行设置。 Activity的方法似乎也没问题:按预期方式显示用于测试的简单AlertDialog。 Dialogs的文档对这个问题没有什么可说的。我想将我的对话框的功能封装在一个专门的类中。扩展AlertDialog将是自然的方式。但为什么我不能在onCreate中设置? – JimmyB 2011-12-31 12:50:16

+0

我尝试从我的活动中按钮的* onClickListener *中显示对话框。应该很好。 – JimmyB 2011-12-31 13:07:32

+1

我仍然不鼓励,除非你有真正的通用功能。但是,如果你这样做,看起来AlertDialog的子类化和定制它的标准方式是在它的**构造函数**而不是onCreate()方法中执行。例如,这就是DatePickerDialog的实现方式。 – 2011-12-31 17:05:48

1

对不起,我迟到了派对:)

您对警报对话框有不同的要求。

我做它的方式是创建警告对话框之前,自定义视图:

// This is the activity that is the background of the AlertDialog 
public class Main extends Activity { 

    public static final int DIALOG_CONFIG = 1; 
    @Override 
    public void onCreate(Bundle savedInstanceState) { 
     super.onCreate(savedInstanceState); 
     requestWindowFeature(Window.FEATURE_NO_TITLE); 

     setContentView(R.layout.emptybackground); 
    } 

    @Override 
    protected void onStart() { 
     super.onStart(); 

     // Open the alert dialog on openning the Activity 
     showDialog(Main.DIALOG_CONFIG); 
    } 

    protected Dialog onCreateDialog(int id) { 
     LayoutInflater factory = LayoutInflater.from(this); 
     switch (id) { 
     case DIALOG_CONFIG: 
      // Here, we load the existing view R.layout.config 
      configView = factory.inflate(R.layout.config, null); 
      configDialog = new AlertDialog.Builder(this) 
       .setTitle("Configuration") 
       .setView(configView) 
       .create(); 

      // Using configView, you can do whatever you want with the view. Here, we add value to a spinner. 
      Spinner spinner = (Spinner)configView.findViewById(R.id.config_select_conn); 
      ArrayAdapter<String> adapter = new ArrayAdapter<String>(this, android.R.layout.simple_spinner_item); 
      adapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item); 
      adapter.add("TCP"); 
      adapter.add("Bluetooth"); 
      spinner.setAdapter(adapter); 

      return configPrinter; 
     } 
     return null; 
    } 
}