前回の記事では、動的なレイアウトフィールドを追加するのに、簡単にするために固定のテキストフィールドを一つだけ追加していきました。
また追加の対象となるアイテムは、そのレイアウトを記載したXMLファイルに記述しておくのでした。そうすることで、街頭するXMLファイルの内容を変更するだけで、追加するレイアウトフィールドを複雑にすることもできるようになります。
しかしフィールドを動的に追加したときに考慮する必要があるのが、IDの問題です。
レイアウトXMLにはIDを固定でしか指定できません。しかし動的に追加したフィールドから値を個別に取得し、データベースに格納したいというケースもあり得ます。
各々のフィールドから値を取得するには、通常そのフィールドのIDを使用しますので、IDについても動的に割り振っておく必要があります。
IDの分離を考慮せずにフィールドを追加するとどうなるでしょうか。前回使用したsub.xmlの内容に、EditTextを追加して検証してみます。
前回のsub.xmlをこのように変更します。TextViewとEditTextを含み、EditTextのIDをet_Subとしています。
<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="horizontal"> <TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="title" android:textSize="32dp" /> <EditText android:id="@+id/et_Sub" android:layout_width="wrap_content" android:layout_height="wrap_content" android:textSize="32dp"/> </LinearLayout>
“追加”ボタンを押下してEditTextに値を書き込み、また”追加”ボタンを押す、という動作を3回繰り返しました。画面はこのようになります。
画面上はそれぞれ異なる値を入力したのですが、Logcatに表示されている値は次のように同じものしか表示されません。
IDのコントロールなしには適切に値を取得することはできないのです。
これを解決するため、画面上のEditTextにIDを付与します。このためにはsetIdメソッドを使用します。但しsetIdメソッドの引数はint型のみです。付与するIDはint型でコントロールする必要があります。
一例として、OnClickメソッドにてIDを連番で付与してみます。
private class SampleListener implements View.OnClickListener { private int index = 1; // 付与するIDの連番を追加 @Override public void onClick(View view) { View subView = inflater.inflate(R.layout.sub, null); rootView.addView(subView, rootView.getChildCount() - 1); EditText et = (EditText) ((LinearLayout)subView).getChildAt(1); // sub.xmlの子要素を辿ってEditTextを指定 et.setId(index); // EditTextにIDを付与 if (index > 1) { EditText et2 = findViewById(index - 1); // 追加したフィールドの1つ前のフィールド値を取得する Log.i("AddViewDinamically", et2.getText().toString()); // 取得した値を表示 } index++; // 連番をインクリメント } }
この処理を追加した後、先ほどと同様に、”追加”ボタンを押下してEditTextに値を書き込み、また”追加”ボタンを押す、という動作を3回繰り返すと・・・
今度は各フィールドが取得できました。動的に付与したIDを使用することで、各々の値が正しく取れていることが分かります。