

タイトルのようにアラートダイアログの中にsimple_list_item_2をinflateしたリストビューを表示させたいのですが、ビルダーのインスタンスにリストビューをセットし実行するとエラーメッセージが表示されます。なぜでしょうか？

[code]

    java.lang.IllegalStateException: The specified child already has a parent. 
    You must call removeView() on the child's parent first.
    
[/code]

ダイアログのカスタマイズの仕方はネット上に転がってるのですが、私の「データをrealmから読み込んでsimple_list_item_2をinlateしたリストに追加したのちにダイアログで表示」というのは見つからないので困っております。（今回はデータどうこうの話ではないと思うのですが）

なお参考にしたのは以下のサイトです。

[How to set both lines of a ListView using simple_list_item_2? - Stack
Overflow](https://stackoverflow.com/questions/11256563/how-to-set-both-lines-
of-a-listview-using-simple-list-item-2)  
[ダイアログにListView表示 - Qiita](https://qiita.com/ueno-
yuhei/items/ef6d835e143592e7a3f0)

以下がコードです。

[code]

    private void showExistingWordAlertDialog(final Word newWord, RealmResults<Word> existingWords) {
    
        // カスタムビューを設定
        LayoutInflater inflater = (LayoutInflater) this.getSystemService(LAYOUT_INFLATER_SERVICE);
        final View listLayout = inflater.inflate(
                R.layout.alert_dialog_existing_custom,
                (ViewGroup) findViewById(R.id.dialogExistingCustom));
    
        final List<Word> existingWordsList = mRealm.copyFromRealm(existingWords);
        ListView listView = listLayout.findViewById(R.id.listView2);
        ArrayAdapter adapter = new ArrayAdapter(this,
                                                     android.R.layout.simple_list_item_2,
                                                        android.R.id.text1) {
            @Override
            @NonNull
            public View getView(int position, View convertView, @NonNull ViewGroup parent) {
                View view = super.getView(position, convertView, parent);
                TextView text1 = view.findViewById(android.R.id.text1);
                TextView text2 = view.findViewById(android.R.id.text2);
                text1.setText(existingWordsList.get(position).getWord());
                text2.setText(existingWordsList.get(position).getMeaning());
    
                return view;
            }
        };
    
        listView.setAdapter(adapter);
        // アラートダイアログ を生成
        mBuilder = new AlertDialog.Builder(this);
        mBuilder.setView(listView)  //ここを加えるとエラー発生
                .setTitle("登録しようとしている言葉と同じ言葉が見つかりました。")
                .setPositiveButton("登録", new DialogInterface.OnClickListener() {
                    @Override
                    public void onClick(DialogInterface dialog, int which) {
                        mRealm.beginTransaction();
                        mRealm.copyToRealmOrUpdate(newWord);
                        mRealm.commitTransaction();
                    }
                })
                .setNegativeButton("キャンセル", null);
        mBuilder.create();
        mBuilder.show();
    }
    
[/code]


CC BY-SA 4.0
2018-05-05T05:10:06.030
43802
2020-07-21T00:43:23.263
2020-07-21T00:43:23.263
3060
27793
question
android java
alert dialogの中にrealmで取得した情報をsimple_list_item_2で表示


問題となっているのは、あるViewの子としてすでに追加されているView（`listView`）を、別のView（この場合はDialogのView）に追加しようとしていることによるエラーです。

ListViewだけを親のレイアウトから取り出して `setView`
でセットしていることに特に理由がないのであれば、以下のように親のレイアウトごとセットしてあげればよいと思います。

[code]

    // レイアウトのinflate
    LayoutInflater inflater = (LayoutInflater) this.getSystemService(LAYOUT_INFLATER_SERVICE);
    final View listLayout = inflater.inflate(R.layout.alert_dialog_existing_custom, null);
    
    ...
    
    // ListViewとAdapterの設定
    ListView listView = listLayout.findViewById(R.id.listView2);
    ArrayAdapter adapter = ...;
    listView.setAdapter(adapter);
    
    // AlertDialogを生成
    mBuilder = new AlertDialog.Builder(this);
    mBuilder.setView(listLayout)
            .setTitle("登録しようとしている言葉と同じ言葉が見つかりました。")
            ...
    
[/code]

どうしてもListViewの部分だけを取り出して使いたいのであれば、ListViewをルートの要素に持つレイアウトxmlを定義して、それをinflateするようにしてみてください。


CC BY-SA 4.0
2018-05-06T14:05:21.067
43822
2018-05-06T14:13:19.923
2018-05-06T14:13:19.923
915
915
43802
answer