在android中的自定义listView中的editText上的afterTextChanged事件

时间:2013-01-02 09:18:04

标签: android android-listview

在我的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?提前谢谢。

1 个答案:

答案 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。将标记设置为编辑视图,或以其他方式检索项目以进行更正。

希望它会有所帮助。