前回の記事では、動的なレイアウトフィールドを追加するのに、簡単にするために固定のテキストフィールドを一つだけ追加していきました。
また追加の対象となるアイテムは、そのレイアウトを記載した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を使用することで、各々の値が正しく取れていることが分かります。

