Android開發之自訂Dialog二次開啟報錯問題解決

來源:互聯網
上載者:User

標籤:android   dialog   自訂   全域變數   局部變數   

                 之前自訂了一個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() {@Overridepublic void onClick(DialogInterface dialog, int which) {// TODO Auto-generated method stubMySQLiteOpenHelper 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() {@Overridepublic void onClick(DialogInterface dialog, int which) {// TODO Auto-generated method stubdialogview=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一遍,要不然你在第二次點擊對話方塊時候是無法對該控制項影響的。

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.