2

在我的 android 应用程序中,我想在列表中显示项目。为此,我正在使用 listView。因为列表项由文本(名称)和编辑文本(数量)组成,所以我使用自定义 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;
    }
}

如您所见,我使用 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)的新手,我没有发现我的错。你有什么主意吗?为什么会有这么多 textchanged 事件?它是如何工作的?我是否错误地使用了 listView?提前致谢。

4

1 回答 1

0

我认为你的问题在这里。

item.quantity = Integer.parseInt(s.toString());

item 变量可能不是您想要的。请参阅这篇文章:Android SimpleAdapter 错误的数据项与列表行相关联,它描述了 getView 不能被调用一次并且视图可以被重用。您在此处通过设置名称和值成功地实现了它:

holder.name.setText (item.name);
holder.quantity.setText (String.valueOf(item.quantity));

但不是使用 EditText。将标签设置为您的编辑视图,或以其他方式检索项目以更正它。

希望它会有所帮助。

于 2013-01-02T09:32:21.680 回答