2012-02-06 9 views
9

私はこのエラーについて質問する何十もの質問があることを知っていますが、提案された解決策のどれも私の問題には当てはまりません。ここでAndroid - 指定した子にはすでに親があります。最初に子供の親のremoveView()を呼び出す必要があります

は私のログです:ここで

java.lang.IllegalStateException: The specified child already has a parent. You must call removeView() on the child's parent first. 
    at android.view.ViewGroup.addViewInner(ViewGroup.java:1976) 
    at android.view.ViewGroup.addView(ViewGroup.java:1871) 
    at android.view.ViewGroup.addView(ViewGroup.java:1851) 
    at com.android.internal.app.AlertController.setupView(AlertController.java:365) 
    at com.android.internal.app.AlertController.installContent(AlertController.java:206) 
    at android.app.AlertDialog.onCreate(AlertDialog.java:251) 
    at android.app.Dialog.dispatchOnCreate(Dialog.java:307) 
    at android.app.Dialog.show(Dialog.java:225) 
    at com.company.MyApp.MyActivity$7.onItemClick(MyActivity.java:240) 
    at android.widget.AdapterView.performItemClick(AdapterView.java:284) 
    at android.widget.ListView.performItemClick(ListView.java:3513) 
    at android.widget.AbsListView$PerformClick.run(AbsListView.java:1812) 
    at android.os.Handler.handleCallback(Handler.java:587) 
    at android.os.Handler.dispatchMessage(Handler.java:92) 
    at android.os.Looper.loop(Looper.java:130) 
    at android.app.ActivityThread.main(ActivityThread.java:3683) 
    at java.lang.reflect.Method.invokeNative(Native Method) 
    at java.lang.reflect.Method.invoke(Method.java:507) 
    at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:839) 
    at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:597) 
    at dalvik.system.NativeStart.main(Native Method) 

はMyActivity.javaのonCreate(です)。ダイアログビルダが表示され、いくつかの値が与えられていることがわかります。特定のボタンが私の活動にクリックされたときにmyDialogLayoutmyDialogBuilderどちらも、プライベートクラスのメンバーである

@Override 
public void onCreate(Bundle savedInstanceState) 
{ 
    // ... a bunch of init code... 

    // Create a dialog builder 
    myDialogLayout = getLayoutInflater().inflate(R.layout.leaving, null); 
    myDialogBuilder = new AlertDialog.Builder(this) 
     .setTitle("My Title") 
     .setView(myDialogLayout) 
     .setNegativeButton("Cancel", new DialogInterface.OnClickListener() 
     { 
      public void onClick(DialogInterface dialog, int which) {} 
     }); 

    // ... more code ... 
} 

その後、myDialogBuilderは少しカスタマイズされて、その後、ダイアログが作成され、示されています。 myDialogは、プライベートクラス変数/メンバです:

// Builder customized a bit 
myDialogBuilder 
    .setMessage("custom message here"); 

// Dialog created from Builder 
myDialog = myDialogBuilder.create(); 

// Dialog shown 
myDialog.show(); // <---- MyActivity.java Line: 240 

だから、私の問題に、私は私のボタンをクリックすると、ダイアログが正常に作成されます。しかし、ダイアログのキャンセルを押してからもう一度ボタンを押すと、ログにエラーが表示されます。何らかの理由で、このアクティビティで私のmyDialogダイアログを再利用したくありません。これはクラスメンバーなので、onClickハンドラからアクセスできます。 myDialogは毎回myDialogBuilder.create()によって最初から作成されているため、ボタンをクリックするたびに新しいダイアログが表示されます。

誰でも問題が分かっていますか?キャンセルボタンが押されても差をつけなかったとき、私はmyDialog.dismiss()に追加しようとしました。

また、私のmyDialogBuilderでは、カスタムXMLレイアウトがDialogのビューに使用されていることがわかります。エラーメッセージによると、それは私がremoveView()を使用して、ダイアログ内でビューを使用しないようにしたいと思ったようです。しかし、myDialogBuilder.removeView()は有効な方法ではありません。

答えて

17

myDialogLayoutです。そうであれば、初めてダイアログを表示したときからすでに親があり、次にmyDialogLayoutの親にしようとする第2のダイアログを作成します。ダイアログを開くたびにmyDialogLayoutという新しいインスタンスを作成してみてください。

+2

これが鍵です。'myDialogLayout'をクラスメンバ変数から削除し、代わりに' onClick'ハンドラメソッドに対してローカルにしました。それは毎回膨らんだ新しいレイアウトです。ありがとう! –

3

これは、onCreateDialog()onPrepareDialog()メソッドの使用が推奨される理由の主な例です。

ボタンを押すたびにmyDialogをインスタンス化すると、以前に作成されたダイアログオブジェクト(古い親)から新しいダイアログにビューをアタッチしようとしています。

インスタンス化、表示、および却下されたダイアログは、単に再表示するだけで、完全に再作成する必要はありません。

myDialogがクラスメンバーであると仮定して、myDialogが最初にnullかどうかを確認してください。 nullでない場合は、完全にインスタンス化するのではなく、再度表示します。

EDIT - ここでは、onPrepareDialog()とonCreateDialog()を使用して、私が意味するものの例です。作成時にダイアログが作成され、表示されるたびに準備が整えられ、findViewByIdとテキストがクリアされてEditTextリファレンスが取得されます。ここでは仮定しています。DIALOG_TESTは整数の定数で、layout/dialog_test.xmlにはidがedittextのEditTextビューがあります。

@Override 
protected void onPrepareDialog(int id, Dialog dialog) { 

    switch(id){ 

    case DIALOG_TEST: 

     EditText mEditText = (EditText) dialog.findViewById(R.id.edittext); 
     mEditText.setText(""); 
     break; 
    } 

} 

@Override 
protected Dialog onCreateDialog(int id) { 

    AlertDialog.Builder builder = new AlertDialog.Builder(this); 

    switch(id){ 

    case DIALOG_TEST: 

     LinearLayout layout = (LinearLayout) ((LayoutInflater) getSystemService(Context.LAYOUT_INFLATER_SERVICE)).inflate(R.layout.dialog_test, null); 

     builder.setTitle("Enter Something").setView(layout); 
     return builder.create(); 
    } 
} 
+0

ダイアログはメッセージ(とそのほかの側面)が毎回異なるため、作成する必要があります。 –

+0

ダイアログにはfindViewByIdメソッドがあります。これを使用してビューへの参照を取得し、それらを更新する必要があります。 – Maximus

+0

ええ、私はそれを認識しています。私はまた、毎回ポジティブボタンの 'onClick'動作を変更しています。上記の元の記事でこれを言及しなかったので、例を単純化することができます。 –

関連する問題

 関連する問題