在我的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;
}
}
在main活动的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;
}
}
正如您所看到的,我使用TextWatcher来监听textchanged事件,而在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?提前谢谢。
答案 0 :(得分:0)
我认为你的问题在这里。
item.quantity = Integer.parseInt(s.toString());
项变量可能不是你想要的那样。看到这篇文章:Android SimpleAdapter wrong data-item gets associated with a list row它描述了getView不能被调用一次,并且可以重用视图。您可以通过设置名称和值来成功实现它:
holder.name.setText (item.name);
holder.quantity.setText (String.valueOf(item.quantity));
但不是EditText。将标记设置为编辑视图,或以其他方式检索项目以进行更正。
希望它会有所帮助。