2011-12-31 180 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; 
    } 
}