Androidで、WindowsアプリのTreeViewコントロールのようなViewは無いの?
一応あるみたいです。
その名も、ExpandableListView。
「ExpandableListView」でGoogleで検索したら、一番親の階層に子供があって、その子供には子供がいないという2階層の構造でいいのであれば、サンプルコードを紹介しているページがいくつかありました。
でも私は、自分で作っているAndroidアプリで、複数の階層になっているTreeViewを実装したい・・・。
しかも、階層は不特定の場合もある。
果たして、ExpandableListViewで実現できるのか!?
ExpandableListViewは、ListViewと同じく、行のレイアウトを定義できます。
これで更に子供にExpandableListViewを持たせればいいのかな?と考えましたが、気が遠くなりそう・・・。
しかも、Androidは画面が小さいので、そんな複数階層のTreeViewは、使い勝手はいいのか?
ExpandableListViewは、ネット上にも情報は少なく、APIドキュメントを読んでもよくわからず・・・。
という事で今回は、ExpandableListViewを使わず、Spinnerを使って代用してみました。
なので、この記事をご覧頂いてる皆さんのご期待に沿える内容にはなっていない可能性が高いです・・・。
ExpandableListViewは、もっと勉強して、使える!と思ったら紹介します・・・。
私は自分で作っていたAndroidアプリで、4階層のTreeViewと、不特定階層のTreeViewを作りたいと思っていました。
4階層のTreeViewは以下のような画面で代用しました。
あらかじめ、階層数を決めているので、その分、Spinnerを4つ配置。
画面の初期表示時に、全階層分のデータ(親子関係や文言)を取ってくる。
(私の作ったアプリの場合はHTTP通信で。)
それぞれの要素に対して、以下の情報を持たせる。
自身のID
親ID
階層の深さ
表示する文字列
Spinnerは、選択肢が変わったことを感知するためのListenerをセットできます。
これを使って、Spinnerの選択肢が変わったらその子のSpinnerを初期化する、という処理をさせる。
個人的には充分、これでOKでした。
画面にすると以下のような感じです。
楽天Webサービスの楽天トラベルAPIを使った地域選択画面です。
親の区分の選択肢が変更されたら、子階層(もし孫、ひ孫があれば、その子たちも。)の選択肢を更新する、という処理を入れています。
スポンサーリンク
不特定階層のTreeViewは以下のような感じで代用しました。
不特定なので、最初から全階層分のデータを取得するのは、どんなアプリであっても現実的ではないでしょう。
どれだけデータがあるのかわからないのですから。
(ある程度わかっているなら、上の方法でいいかなと。)
というわけで、Spinnerを一つだけ置くActivityを使いまわす、という感じにしました。
あとは、子階層を表示するボタンと、親階層を表示するボタンを置きます。
子階層が押されたら、今表示している内容をスタックへ保存しておき、子階層を取得して表示する。
親階層が押されたら、スタックから取り出して表示する。
Javaには、今回初めて使いましたがStackというクラスがあり、こいつが個人的にはかなり便利でした。
画面にすると以下のような感じです。
楽天Webサービスの楽天市場APIを使った商品ジャンル選択画面です。
かなりオリジナルの作りでして、、、コードを載せるのは恥ずかしいので、やめておきます。
TreeViewの代用のひとつのアイデア、として紹介しました。
Tree構造のSpinnerの作成で躓いてしまっています。
ホームページを読ませて頂いたので実装方法のイメージは
つかめたのですが、うまく作成に漕ぎ付けていません。
大変不躾なお願いで申し訳ないのですが、
Spinnerは、選択肢が変わったことを感知するためのListenerをセットできます。
これを使って、Spinnerの選択肢が変わったらその子のSpinnerを初期化する、と
いう処理をさせる。
と言うこ所の実装方法が分かりません。
実現したいのは、Spinnerを選択後、下階層のSpinnerのlist内容が変わるのを実装したいです。正しくこちらに乗っている住所選択のようなTree構造です。
親階層の選択によって、子階層の内容がインクリメントされるようにしたいのです。listの内容は同じなのですが、最後に番号が付与されていて親が選択していると子の同じ値の番号がインクリメントされるようにしたいのですが実装出来ません。
アドバイス等頂けましたらよろしくお願いします。
雷帝さん
回答になっていなければすみません。
1.Spinnerに、選択肢が変わったことを感知するためのListenerをセット
これは以下のように実装します。
————————————————————————————————
Spinner s = (Spinner)findViewById(R.id.spinner01);
s.setOnItemSelectedListener(this);
————————————————————————————————
setOnItemSelectedListener()に与えている引数thisは、Activityを継承させているクラスという想定です。
そのクラスには、以下のインタフェースを実装させます。
android.widget.AdapterView.OnItemSelectedListener
このインタフェースの以下のメソッドを実装します。
public void onItemSelected(AdapterView arg0, View view, int arg2,long arg3)
このメソッドは、Spinnerの選択肢が選ばれたときにコールされるメソッドになります。
例えば以下のように実装します。
————————————————————————————————
public void onItemSelected(AdapterView arg0, View view, int arg2,
long arg3) {
if(arg0.getId() == R.id.spinner01){
//初期化等の処理を行う。
}
}
————————————————————————————————
上記のように、第一引数で、どのSpinnerが確定されたのかを判断する事が出来ます。
===================================================
2.Spinnerの初期化の方法
これも一例ですが、以下のように行えます。
——————————————————————————————————————————
private void setSpinner(Spinner spinner,String[] arr){
ArrayAdapter adapter =
new ArrayAdapter(this, android.R.layout.simple_spinner_item, arr);
adapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
spinner.setAdapter(adapter);
}
——————————————————————————————————————————
このメソッドの仕様は、
第一引数:初期化を行いたいSpinner
第二引数:選択肢のString型配列
です。
貴方が行いたい処理にもよるかと思いますので、上記が使い物になるのか、なんとも言えませんが、、、
もし、回答に不明な点、もしくは何か御座いましたらまたご連絡下さい。
ありがとうございます。
イメージが掴めました。
やってみます。
ありがとうございました。