質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

ただいまの
回答率

88.64%

Xamarin - ExpandableListViewのリスト追加

解決済

回答 1

投稿 編集

  • 評価
  • クリップ 0
  • VIEW 1,382

sezaki_H

score 39

XamarinのExpandableListViewの親リストを後から追加し更新させたいのですが、どのように書けばいいのでしょうか?
追加する親リストの名前はダイアログで入力させています。

                notebutton.Click += (_, __) =>
                {
                    var layout = new LinearLayout(this) { Orientation = Orientation.Vertical };
                    layout.SetGravity(GravityFlags.Left);
                    var notename = new EditText(this);
                    layout.AddView(new TextView(this) { Text = "ノート名" });
                    layout.AddView(notename);

                    var dlg = new AlertDialog.Builder(this);
                    dlg.SetTitle("ノートの名前を入力してください。");
                    dlg.SetView(layout); //<=作成したビューを指定

                    dlg.SetPositiveButton("OK", (s, a) => Toast.MakeText(this, notename.Text, ToastLength.Short).Show());
                    dlg.Create().Show();

                    //リスト追加、更新
                    groupElement.Add(notename.Text);
                    groupList.Add(groupElement);
                    adapter.NotifyDataSetChanged();

                };

全体コード

using Android.App;
using Android.Widget;
using Android.OS;
using System.Collections.Generic;
using Android.Content;
using PCLStorage;
using Android.Runtime;
using Temo1.Resources.layout;
using Android.Views;
using static Android.Resource;

namespace Temo1
{
    [Activity(Label = "Temo1", MainLauncher = true)]
    public class MainActivity : Activity
    {
        protected override void OnCreate(Bundle savedInstanceState)
        {
            base.OnCreate(savedInstanceState);

            // Set our view from the "main" layout resource
            SetContentView(Resource.Layout.Main);



            Button memobutton = FindViewById<Button>(Resource.Id.button1);
            Button notebutton = FindViewById<Button>(Resource.Id.notebutton);
            ExpandableListView memolist = FindViewById<ExpandableListView>(Resource.Id.expandableListView1);

            string[] filename = new string[100];
            int n;
            var localFolder = FileSystem.Current.LocalStorage;
            var files = localFolder.GetFilesAsync().Result;


            //親リストgroupList子リストchildList
            List<IDictionary<string, object>> groupList = new List<IDictionary<string, object>>();
            List<IList<IDictionary<string, object>>> childList = new List<IList<IDictionary<string, object>>>();

            //デフォルトのグループ"全て"
            JavaDictionary<string, object> groupElement = new JavaDictionary<string, object>();
            groupElement.Add("GROUP_TITLE", "ALL");
            groupList.Add(groupElement);





            //子リスト用の文字列(ファイル名)を配列に用意
            n = 0;
            foreach (var file in files)
            {
                var fn = file.Name;
                fn = fn.Remove(fn.Length - 4);//拡張子を表示しないように末尾を削除
                filename[n] = fn;//配列にファイル名を格納
                n++;
            }


            JavaList<IDictionary<string, object>> childElements = new JavaList<IDictionary<string, object>>();
            for (int j = 0; j <= n - 1; j++)
            {
                JavaDictionary<string, object> child = new JavaDictionary<string, object>();
                child.Add("CHILD_TITLE", filename[j]);
                childElements.Add(child);
            }
            childList.Add(childElements);

            SimpleExpandableListAdapter adapter = new SimpleExpandableListAdapter(
                                          this,
                                          groupList,
                                          Android.Resource.Layout.SimpleExpandableListItem1,
                                          new string[] { "GROUPE_TITLE" },
                                          new int[] { Android.Resource.Id.Text1 },
                                          childList,
                                          Android.Resource.Layout.SimpleExpandableListItem2,
                                          new string[] { "CHILD_TITLE" },
                                          new int[] { Android.Resource.Id.Text2 }
                                          );
            memolist.SetAdapter(adapter);


            //親リスト追加

            //リスト名入力ダイアログ
            notebutton.Click += (_, __) =>
            {
                var layout = new LinearLayout(this) { Orientation = Orientation.Vertical };
                layout.SetGravity(GravityFlags.Left);
                var notename = new EditText(this);
                notename.SetMaxLines(1);
                layout.AddView(new TextView(this) { Text = "ノート名" });
                layout.AddView(notename);

                var dlg = new AlertDialog.Builder(this);
                dlg.SetTitle("ノートの名前を入力してください。");
                dlg.SetView(layout); //<=作成したビューを指定

                dlg.SetPositiveButton("OK", (s, a) =>
                {
                    Toast.MakeText(this, notename.Text, ToastLength.Short).Show();

                    if (!string.IsNullOrEmpty(notename.Text))
                    {
                        var newGroupElement = new JavaDictionary<string, object>();
                        newGroupElement.Add("GROUPE_LIST", notename.Text);
                        groupList.Add(newGroupElement);
                        adapter.NotifyDataSetChanged();
                    }
                    else
                    {
                        // 未入力エラー
                    }
                });
                dlg.Create().Show();


                };


            //メモ作成画面へ遷移
            memobutton.Click += (_, __) =>

            {

                var intent = new Intent(this, typeof(memocreate));

                StartActivity(intent);


            };


            //リストアイテムがクリックされたらテキスト編集に遷移
            memolist.ChildClick+= async (sender, e) =>
            {
                var parent = (ExpandableListView)e.Parent;
                var packedPosition = parent.GetExpandableListPosition(e.ChildPosition);

                var groupPosition = ExpandableListView.GetPackedPositionGroup(packedPosition);
                var childPosition = ExpandableListView.GetPackedPositionChild(packedPosition);
                var type = ExpandableListView.GetPackedPositionType(packedPosition);
                if (type == PackedPositionType.Child)
                {
                    var item = (IDictionary<string, object>)parent.ExpandableListAdapter.GetChild(groupPosition, childPosition+1);
                    var clickfile = item["CHILD_TITLE"].ToString();

                    //そのファイルのテキストを取得
                    IFolder rootFolder = FileSystem.Current.LocalStorage;
                    IFile file = await rootFolder.GetFileAsync(clickfile + ".txt");
                    string saveddata = await file.ReadAllTextAsync();

                    var intent = new Intent(this, typeof(memoedit));
                    intent.PutExtra("clickfile", clickfile); 
                    intent.PutExtra("Data", saveddata);


                    StartActivity(intent);

                }
            };



                //長押しされたアイテムを削除
                memolist.ItemLongClick += async (sender, e) =>
            {
                var parent = (ExpandableListView)e.Parent;
                var packedPosition = parent.GetExpandableListPosition(e.Position);

                var groupPosition = ExpandableListView.GetPackedPositionGroup(packedPosition);
                var childPosition = ExpandableListView.GetPackedPositionChild(packedPosition);
                var type = ExpandableListView.GetPackedPositionType(packedPosition);
                if (type == PackedPositionType.Child)
                {
                    var item = (IDictionary<string, object>)parent.ExpandableListAdapter.GetChild(groupPosition, childPosition);
                    var deletefile = item["CHILD_TITLE"].ToString();


                    //adapterから削除し更新
                    childList[groupPosition].Remove(item);
                    adapter.NotifyDataSetChanged();

                    //元ファイル削除
                    IFolder rootFolder = FileSystem.Current.LocalStorage;
                    IFile file = await rootFolder.GetFileAsync(deletefile + ".txt");

                    await file.DeleteAsync();
                }


            };




















        }
    }
}
  • 気になる質問をクリップする

    クリップした質問は、後からいつでもマイページで確認できます。

    またクリップした質問に回答があった際、通知やメールを受け取ることができます。

    クリップを取り消します

  • 良い質問の評価を上げる

    以下のような質問は評価を上げましょう

    • 質問内容が明確
    • 自分も答えを知りたい
    • 質問者以外のユーザにも役立つ

    評価が高い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。

    質問の評価を上げたことを取り消します

  • 評価を下げられる数の上限に達しました

    評価を下げることができません

    • 1日5回まで評価を下げられます
    • 1日に1ユーザに対して2回まで評価を下げられます

    質問の評価を下げる

    teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。

    • プログラミングに関係のない質問
    • やってほしいことだけを記載した丸投げの質問
    • 問題・課題が含まれていない質問
    • 意図的に内容が抹消された質問
    • 過去に投稿した質問と同じ内容の質問
    • 広告と受け取られるような投稿

    評価が下がると、TOPページの「アクティブ」「注目」タブのフィードに表示されにくくなります。

    質問の評価を下げたことを取り消します

    この機能は開放されていません

    評価を下げる条件を満たしてません

    評価を下げる理由を選択してください

    詳細な説明はこちら

    上記に当てはまらず、質問内容が明確になっていない質問には「情報の追加・修正依頼」機能からコメントをしてください。

    質問の評価を下げる機能の利用条件

    この機能を利用するためには、以下の事項を行う必要があります。

質問への追記・修正、ベストアンサー選択の依頼

  • 退会済みユーザー

    退会済みユーザー

    2018/10/22 12:33

    xamarinは日本語のリソースに乏しいので、英語で調べるとよいかもです。

    キャンセル

回答 1

checkベストアンサー

+1

groupListに追加しても表示が変わらないのであれば、groupListの型がJavaListになっていないのではないでしょうか?
また、groupListに追加するgroupElementは新しくオブジェクトを作成しなければいけません。

dlg.SetPositiveButton("OK", (s, a) => 
{
    Toast.MakeText(this, notename.Text, ToastLength.Short).Show();

    if (!string.IsNullOrEmpty(notename.Text))
    {
        var newGroupElement = new JavaDictionary<string, object>();
        newGroupElement.Add("GROUPE_TITLE", notename.Text);
        groupList.Add(newGroupElement);
        adapter.NotifyDataSetChanged();
    }
    else
    {
        // 未入力エラー
    }
});

あと、ダイアログで入力した値を使うのであれば、この処理は、SetPositiveButtonhandler内でやるべきです。


リストデータの保存は、OnSaveInstanceStatePutSerializableで行い、OnCreateで、GetSerializableで取得します。

    public class MainActivity : Activity
    {
        private JavaList<IDictionary<string, object>> groupList;
        private JavaList<IList<IDictionary<string, object>>> childList;

        protected override void OnCreate(Bundle savedInstanceState)
        {
            base.OnCreate(savedInstanceState);

            // Set our view from the "main" layout resource
            SetContentView(Resource.Layout.Main);

            ...

            if (savedInstanceState != null)
            {
                groupList = savedInstanceState.GetSerializable(nameof(groupList)).JavaCast<JavaList<IDictionary<string, object>>>();
                childList = savedInstanceState.GetSerializable(nameof(childList)).JavaCast<JavaList<IList<IDictionary<string, object>>>>();
            }
            else
            {
                groupList = new JavaList<IDictionary<string, object>>();
                childList = new JavaList<IList<IDictionary<string, object>>>();

                ...
            }

            SimpleExpandableListAdapter adapter = new SimpleExpandableListAdapter(
                                          this,
                                          groupList,
                                          Android.Resource.Layout.SimpleExpandableListItem1,
                                          new string[] { "GROUPE_TITLE" },
                                          new int[] { Android.Resource.Id.Text1 },
                                          childList,
                                          Android.Resource.Layout.SimpleExpandableListItem2,
                                          new string[] { "CHILD_TITLE" },
                                          new int[] { Android.Resource.Id.Text2 }
                                          );
            memolist.SetAdapter(adapter);

            ...
        }

        protected override void OnSaveInstanceState(Bundle outState)
        {
            base.OnSaveInstanceState(outState);

            outState.PutSerializable(nameof(groupList), groupList.JavaCast<ISerializable>());
            outState.PutSerializable(nameof(childList), childList.JavaCast<ISerializable>());
        }
    }

投稿

編集

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2018/11/07 11:20

    調べてみました。なるほど、初期値で再生成されてるということですかね?
    OnResumeを使用すればよいのでしょうか?

    キャンセル

  • 2018/11/07 13:25 編集

    再生成されているのであれば、上記のやり方で大丈夫なはずです。それでダメというならば、再生成されている訳ではないということになるのですが、それであっていますか?
    MainActivityが消えない限り、何もしないでリストが初期化されるとは考えづらいです。
    もしかして、戻るのではなくMainActivityに再度遷移していたりしていませんか?それだと初期化されて当然です。

    キャンセル

  • 2018/11/07 13:38

    おっしゃる通り再遷移していました(汗)。
    すいません、ありがとうございます。お騒がせしました。

    キャンセル

15分調べてもわからないことは、teratailで質問しよう!

  • ただいまの回答率 88.64%
  • 質問をまとめることで、思考を整理して素早く解決
  • テンプレート機能で、簡単に質問をまとめられる

関連した質問

同じタグがついた質問を見る