Android教程網
  1. 首頁
  2. Android 技術
  3. Android 手機
  4. Android 系統教程
  5. Android 游戲
 Android教程網 >> Android技術 >> 關於Android編程 >> Android開發之自定義Dialog二次打開報錯問題解決

Android開發之自定義Dialog二次打開報錯問題解決

編輯:關於Android編程

之前自定義了一個AlertDialog對話框,第一次點擊時正常,但第二次調用時會出現錯誤:java.lang.IllegalStateException: The specified child already has a parent. You must call removeView() on the child's parent first.

關於這個錯誤糾結了我好久,在網上百度了也不少,但感覺解決效果都達不到自己想要的效果。網上的解釋說是一個子視圖指定了多個父視圖。由此可以推斷出,在第二次點擊按鈕彈出對話框時,子視圖與第一次點擊時的子視圖是同一個對象,而父視圖已經不再是同一個對象了。但感覺說的雲裡霧裡的,經過我研究之後,發現了我認為的很好的解決方法,想分享給大家交流一下。

代碼如下所示:

builder = new AlertDialog.Builder(MainActivity.this);
				builder.setView(null);
			  
				builder.setView(dialogview);
				
				builder.setTitle("記賬");
				builder.setPositiveButton("確定", new OnClickListener() {

					@Override
					public void onClick(DialogInterface dialog, int which) {
						// TODO Auto-generated method stub
						MySQLiteOpenHelper helper = new MySQLiteOpenHelper(
								MainActivity.this);
						SQLiteDatabase database = helper.getWritableDatabase();
						ContentValues values = new ContentValues();
						values.put("sum", editText.getText().toString());
						values.put(
								"project",
								spinner.getItemAtPosition(
										(int) spinner.getSelectedItemId())
										.toString());

						if (checkBox.isChecked()) {
							values.put("category", "收入");
						}
						if (checkBox2.isChecked()) {
							values.put("category", "支出");
						}
						TextView textView = (TextView) view
								.findViewById(R.id.textView1);
						values.put("date", textView.getText().toString());
						database.update("budget", values, "date=?",
								new String[] { textView.getText().toString() });
						dialogview=null;
                        if(dialogview==null){
                        	dialogview = getLayoutInflater().inflate(R.layout.add_dialog, null);
                        	editText = (EditText) dialogview.findViewById(R.id.editText1);
                    		spinner = (Spinner) dialogview.findViewById(R.id.spinner1);
                    		checkBox = (CheckBox) dialogview.findViewById(R.id.checkBox1);
                    		checkBox2 = (CheckBox) dialogview.findViewById(R.id.checkBox2);
                    		clock = (DigitalClock) dialogview.findViewById(R.id.digitalClock2);
						  flag=true;
  					  }
						loaderManager.getLoader(1001).onContentChanged();// 若狀態改變,觸發這個方法
                    
					}
				});
				builder.setNegativeButton("取消", new OnClickListener() {

					@Override
					public void onClick(DialogInterface dialog, int which) {
						// TODO Auto-generated method stub
						dialogview=null;
						if(dialogview==null){
                        	dialogview = getLayoutInflater().inflate(R.layout.add_dialog, null);
                        	editText = (EditText) dialogview.findViewById(R.id.editText1);
                    		spinner = (Spinner) dialogview.findViewById(R.id.spinner1);
                    		checkBox = (CheckBox) dialogview.findViewById(R.id.checkBox1);
                    		checkBox2 = (CheckBox) dialogview.findViewById(R.id.checkBox2);
                    		clock = (DigitalClock) dialogview.findViewById(R.id.digitalClock2);
						  flag=true;
  					  } 
					}
				});
				builder.create().show();
               
			}
		});

我自定義了一個dialog,裡頭包含checkbox控件和spinner控件,我想根據checkbox空間的勾選情況動態spinner的內容,因此我將其定義為了全局變量,以此就造成了我上述所說的問題。

網友建議呢自定義的view不應該設置為全局變量,應該設置為局部變量,Alert.builder創建一次,view通過getLayoutInflater獲取一次就不會有二次點擊對話框的問題,但這樣就影響了我程序的效果。

根據我自己的不斷探索,發現報錯的原因時,因為我的view設置的為全局變量,在第一次創建對話框的時候,已經綁定了一個builder(也就是上次所說的Parent對象),所以在第二次點擊對話框的時候,再次綁定builder的時候,新的builder就不會接收我們自定義的view,因為它認為你已經綁定過了,此時就算你將之前的builder在對話框消受的同時銷毀掉也是沒用的,因為我們的view仍然會有綁定的過往記錄。

那麼該如何解決呢,我的解決方法是每次對話框完成任務消失時,就將view置為null,重新動態獲取一次布局,其實也就是為了實現近似於局部變量的效果,但要注意自定義布局的控件也要隨之findViewByid一遍,要不然你在第二次點擊對話框時候是無法對該控件影響的。

  1. 上一頁:
  2. 下一頁:
熱門文章
閱讀排行版
Copyright © Android教程網 All Rights Reserved