1

我想顯示一個自定義AlertDialog。我在主LinearLayout中有一個LinearLayout,它包含幾個按鈕。按鈕只能顯示在某些時候,所以我試圖將佈局設置爲GONE。然而,這會在下面指出的線上拋出一個NPE。有任何想法嗎?NPE在自定義AlertDialog中設置嵌套LinearLayout的可見性嗎?

@Override 
    protected Dialog onCreateDialog(int id) { 
     switch (id) {  
     //case 0 removed for purposes of space 
     case 1: 
      LayoutInflater layoutInflater = (LayoutInflater)getApplicationContext().getSystemService(Context.LAYOUT_INFLATER_SERVICE); 
     View view=layoutInflater.inflate(R.layout.ingamepopup,null); 

     if(getPrefs.getBoolean("custom button checked"+gameNum, false)){ 
      customButtonLayout.setVisibility(View.VISIBLE); 

      cb1.setText(Float.toString(getPrefs.getFloat("button 1 value"+gameNum,1))); 
      cb2.setText(Float.toString(getPrefs.getFloat("button 2 value"+gameNum,5))); 
      cb3.setText(Float.toString(getPrefs.getFloat("button 3 value"+gameNum,10))); 
     } else 
      customButtonLayout.setVisibility(View.GONE); //Line 172 

     scoreChangeDialog = new AlertDialog.Builder(this) 
     .setTitle("Score change") 
     .setView(view) 
     .create(); 

     return scoreChangeDialog; 
     } 
     return null; 
    } 

customButtonLayout在的onCreate()中所定義:

customButtonLayout = (LinearLayout) findViewById(R.id.llCustomButtonsScoreChange); 

而定義在R:

public static final int llCustomButtonsScoreChange=0x7f070015; 

而logcat的:

 08-14 13:56:07.192: E/AndroidRuntime(10020): FATAL EXCEPTION: main 
08-14 13:56:07.192: E/AndroidRuntime(10020): java.lang.NullPointerException 
08-14 13:56:07.192: E/AndroidRuntime(10020): at com.webs.pratia.scorekeeper.InGame.onCreateDialog(InGame.java:172) 
08-14 13:56:07.192: E/AndroidRuntime(10020): at android.app.Activity.onCreateDialog(Activity.java:2472) 
08-14 13:56:07.192: E/AndroidRuntime(10020): at android.app.Activity.createDialog(Activity.java:881) 
08-14 13:56:07.192: E/AndroidRuntime(10020): at android.app.Activity.showDialog(Activity.java:2547) 
08-14 13:56:07.192: E/AndroidRuntime(10020): at android.app.Activity.showDialog(Activity.java:2514) 
08-14 13:56:07.192: E/AndroidRuntime(10020): at com.webs.pratia.scorekeeper.InGame.onListItemClick(InGame.java:121) 
08-14 13:56:07.192: E/AndroidRuntime(10020): at android.app.ListActivity$2.onItemClick(ListActivity.java:321) 
08-14 13:56:07.192: E/AndroidRuntime(10020): at android.widget.AdapterView.performItemClick(AdapterView.java:289) 
08-14 13:56:07.192: E/AndroidRuntime(10020): at android.widget.ListView.performItemClick(ListView.java:3688) 
08-14 13:56:07.192: E/AndroidRuntime(10020): at android.widget.AbsListView$PerformClick.run(AbsListView.java:1873) 
08-14 13:56:07.192: E/AndroidRuntime(10020): at android.os.Handler.handleCallback(Handler.java:587) 
08-14 13:56:07.192: E/AndroidRuntime(10020): at android.os.Handler.dispatchMessage(Handler.java:92) 
08-14 13:56:07.192: E/AndroidRuntime(10020): at android.os.Looper.loop(Looper.java:123) 
08-14 13:56:07.192: E/AndroidRuntime(10020): at android.app.ActivityThread.main(ActivityThread.java:4627) 
08-14 13:56:07.192: E/AndroidRuntime(10020): at java.lang.reflect.Method.invokeNative(Native Method) 
08-14 13:56:07.192: E/AndroidRuntime(10020): at java.lang.reflect.Method.invoke(Method.java:521) 
08-14 13:56:07.192: E/AndroidRuntime(10020): at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:858) 
08-14 13:56:07.192: E/AndroidRuntime(10020): at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:616) 
08-14 13:56:07.192: E/AndroidRuntime(10020): at dalvik.system.NativeStart.main(Native Method) 

編輯

經過一些更多的測試後,似乎在ingamepopup.xml中定義的所有變量都返回null(如cb1,cb2,cb3)。 ingamepopup.xml不是該活動的主要xml。 setContentView(ingame.xml)和嘗試訪問來自ingamepopup.xml的視圖(inflater充氣)之間是否存在一些衝突?

+3

+1不錯的風格問一個問題!並檢查您設置爲contentview的佈局xml文件,並檢查customButtonLayout的ID。 – 2012-08-14 17:42:21

+1

這是在'setContentView'之前調用的嗎?因爲'llCustomButtons'可能是一個ID,但它在被引用時返回一個'null'對象。 – Eric 2012-08-14 17:48:26

+0

我的問題以前是誤導性的。我嘗試設置爲不可見的LL不在contentview設置的xml中,但是它位於AlertDialog的XML中。 – rphello101 2012-08-14 20:40:51

回答

0

終於找到了問題。因爲我試圖從AlertDialog的視圖中引用對象(正確的術語?),所以我引用了我充氣的視圖:view.findViewById(...)。通過說明findViewById(...),程序試圖從加載到主要活動的視圖中查找ID。新代碼看起來像:

LayoutInflater layoutInflater = (LayoutInflater)getApplicationContext().getSystemService(Context.LAYOUT_INFLATER_SERVICE); 
      View view=layoutInflater.inflate(R.layout.ingamepopup,null); //This is the view that has to be referenced. 

      mainLayout = (LinearLayout) view.findViewById(R.id.llScoreChange); 
//notice view.findViewById(...) 
      customButtonLayout = (LinearLayout) view.findViewById(R.id.llCustomButtonsScoreChange); 
      plus = (ImageButton) view.findViewById(R.id.ibPlusPU); 
      minus = (ImageButton) view.findViewById(R.id.ibMinusPU); 
      cancel = (ImageButton) view.findViewById(R.id.ibCancelPU); 
      cb1 = (Button) view.findViewById(R.id.bCustom1PU); 
      cb2 = (Button) view.findViewById(R.id.bCustom2PU); 
      cb3 = (Button) view.findViewById(R.id.bCustom3PU); 
      score = (EditText) view.findViewById(R.id.etScoreChange); 

      if(getPrefs.getBoolean("custom button checked"+gameNum, false)){ 
       customButtonLayout.setVisibility(View.VISIBLE); 

       cb1.setText(Float.toString(getPrefs.getFloat("button 1 value"+gameNum,1))); 
       cb2.setText(Float.toString(getPrefs.getFloat("button 2 value"+gameNum,5))); 
       cb3.setText(Float.toString(getPrefs.getFloat("button 3 value"+gameNum,10))); 
      } else{ 
       customButtonLayout.setVisibility(View.GONE); 
      } 

      scoreChangeDialog = new AlertDialog.Builder(this) 
      .setTitle("Score change") 
      .setView(view) 
      .create(); 

      return scoreChangeDialog; 
     } 
0

此行中的NPE表示customButtonLayout爲null。由於View是一個類,因此不能爲空。看起來你知道這一點。現在如果customButtonLayout爲空,則可能有不同的原因。

  1. 創建尚未被調用。當您嘗試隱藏視圖時,我認爲它已經顯示過。如果是這樣,它不是一個選項。
  2. findViewById沒有找到視圖。同樣的邏輯適用。
  3. 最後一個選項是某人在初始化後將其設置爲null。這個很明顯,你可能已經分析過了。
  4. 此調用在一個實例上完成,而另一個已經初始化。也許customButtonLayout是在超類中定義的,並且您認爲它是每個子類型實例上的相同變量。只有當它是一個靜態成員時纔是如此。
+0

#2本質上是這個問題。 findViewId確實找到了一個視圖,它只是找到_wrong_視圖。 – rphello101 2012-08-16 04:27:24