私の Android アプリケーションでは、項目をリストに表示したいと考えています。このために、listView を使用しています。リスト項目はテキスト (名前) と editText (数量) で構成されているため、カスタム ArraryAdapter を使用しています。ユーザーが数量を変更できるようにしたいので、私は editText を使用しています。ユーザーが編集を停止したときに、新しい値を保存したいので、editTexts に onTextChanged イベントを追加しました。
アイテムのクラスを作成しました(リストに表示しています)。とてもシンプルで、名前と数量のみです。
public class Foo {
final String name;
int quantity;
public Foo (String name, int quantity) {
this.name = name;
this.quantity = quantity;
}
// for debug message
@Override
public String toString () {
return "name: " + this.name+ " quantity: " + this.quantity;
}
}
メイン アクティビティの onCreate メソッドで、Foo 要素のリストを作成し、独自の Adapter を使用してそれらをリストに追加します。
public class MainActivity extends Activity {
ListView list;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
list = (ListView) findViewById (R.id.list);
List<Foo> elements = new ArrayList<Foo> ();
elements.add(new Foo ("foo", 1));
elements.add(new Foo ("bar", 2));
elements.add(new Foo ("baz", 3));
elements.add(new Foo ("foo2", 4));
elements.add(new Foo ("bar2", 5));
elements.add(new Foo ("baz2", 6));
FooAdapter adapter = new FooAdapter (this, R.layout.foo_elements, elements);
//where foo_elements contains a horizontal LinearLayout and in it
//there's a TextView and an EditText
list.setAdapter(adapter);
}
したがって、私のアダプターは次のとおりです (ここでホルダー パターンを見つけました: http://www.vogella.com/articles/AndroidListView/article.html#adapterperformance_hoder ):
public class FooAdapter extends ArrayAdapter<Foo> {
Context context;
int layoutResourceId;
List<Foo> elements;
public FooAdapter (Context context, int layoutResourceId, List<Foo> elements) {
super (context, layoutResourceId, elements);
this.context = context;
this.layoutResourceId = layoutResourceId;
this.elements = elements;
}
@Override
public View getView(int position, View convertView, ViewGroup parent) {
View row = convertView;
Holder holder = null;
final Foo item = elements.get(position);
if (row == null) {
LayoutInflater inflater = ((Activity)context).getLayoutInflater ();
row = inflater.inflate(layoutResourceId, parent, false);
holder = new Holder ();
holder.name = (TextView) row.findViewById (R.id.name);
holder.quantity = (EditText) row.findViewById(R.id.quantity);
holder.quantity.addTextChangedListener(new TextWatcher() {
@Override
public void onTextChanged(CharSequence s, int start, int before, int count) {
// TODO Auto-generated method stub
}
@Override
public void beforeTextChanged(CharSequence s, int start, int count, int after) {
// TODO Auto-generated method stub
}
@Override
public void afterTextChanged(Editable s) {
Log.d("textchanged", "text has changed");
Log.d ("new text", s.toString());
item.quantity = Integer.parseInt(s.toString());
}
});
row.setTag(holder);
}
else {
holder = (Holder) row.getTag();
}
holder.name.setText (item.name);
holder.quantity.setText (String.valueOf(item.quantity));
return row;
}
class Holder {
TextView name;
EditText quantity;
}
}
ご覧のとおり、textchanged イベントをリッスンするために TextWatcher を使用し、afterTextChanged 関数で新しい数量を Foo オブジェクトに設定したいと考えています。
そこで何が起こっているかを確認するためにいくつかのデバッグ メッセージを入れ、Foo オブジェクトを印刷するボタンを追加しました。アプリケーションを起動した後の出力は次のとおりです。
textchanged text has changed
new text 1
textchanged text has changed
new text 2
textchanged text has changed
new text 3
textchanged text has changed
new text 4
textchanged text has changed
new text 5
textchanged text has changed
new text 6
textchanged text has changed
new text 6
textchanged text has changed
new text 2
textchanged text has changed
new text 3
textchanged text has changed
new text 4
textchanged text has changed
new text 5
textchanged text has changed
new text 6
したがって、プログラムを起動した後の数量は次のとおりです。
name: foo quantity: 6 //instead of name: foo quantity: 1
name: bar quantity: 2
name: baz quantity: 3
name: foo2 quantity: 4
name: bar2 quantity: 5
name: baz2 quantity: 6
最後の要素を変更すると、最初の要素も変更されます。
name: foo quantity: 62 //instead of name: foo quantity: 1
name: bar quantity: 2
name: baz quantity: 3
name: foo2 quantity: 4
name: bar2 quantity: 5
name: baz2 quantity: 62
私は Android (Java でさえも) を初めて使いましたが、自分のせいではありませんでした。何か考えはありますか?そして、なぜこれほど多くのテキスト変更イベントが発生するのでしょうか? それはどのように機能しますか?listView の使い方は間違っていますか? 前もって感謝します。