TransWikia.com

alert dialogの中にrealmで取得した情報をsimple_list_item_2で表示

スタック・オーバーフロー Asked by Hojun on August 24, 2020

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

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

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

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

How to set both lines of a ListView using simple_list_item_2? – Stack Overflow
ダイアログにListView表示 – Qiita

以下がコードです。

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();
}

One Answer

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

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

// レイアウトの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("登録しようとしている言葉と同じ言葉が見つかりました。")
        ...

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

Answered by kakajika on August 24, 2020

Add your own answers!

Ask a Question

Get help from others!

© 2024 TransWikia.com. All rights reserved. Sites we Love: PCI Database, UKBizDB, Menu Kuliner, Sharing RPP