【问题标题】:RowAdapter deletes random rows that are added dynamically to ListView?RowAdapter 删除动态添加到 ListView 的随机行?
【发布时间】:2012-04-03 22:17:24
【问题描述】:

我正在尝试从ListView 动态添加和删除行元素。

ListView 中的每个元素都是一个LinearLayout。我可以添加和删除行,但是每当我这样做时,行的顺序都是混乱的,并且不一定要删除正确的行。我检查了每次添加一行时我的ArrayList<LinearLayout> rows 的大小都会增加,但是对getItem(position) 的调用始终为空。我认为这是导致问题的原因,但为什么将空布局添加到 rows

Edit:我将 ArrayAdapter 参数从 LinearList 更改为 Row,这是一个包含两个 EditText 字段的 getter 和 setter 的简单对象。这已经解决了 null 问题,但同样的问题仍然存在 - 随机行被删除。在下面的getView() 中,Logcat 在我的删除按钮onClick() 的每种情况下都显示position = 0。 Logcat 还显示 L​​istView 中的每个 View 都被随机分配了一个位置。

我的新适配器代码:

public class RowAdapter extends ArrayAdapter<Row>{

    private ArrayList<Row> rows;

    public RowAdapter(Context context, int textViewResourceId, ArrayList<Row> rows) {
        super(context, textViewResourceId, rows);
        this.rows = rows;
    }

    public Row getItem(int position){
        return rows.get(position);
    }

    public int getCount(){
        return rows.size();
    }

    public static class ViewHolder {
        public EditText name;
        public EditText value;
        public Button delete; 
    }

    @Override
    public View getView(int position, View convertView, ViewGroup parent) {
        View v = convertView;
        ViewHolder viewHolder;

        if(v == null){
            LayoutInflater li = (LayoutInflater)getContext().
                    getSystemService(Context.LAYOUT_INFLATER_SERVICE);
            v = li.inflate(R.layout.row, parent, false);

            viewHolder = new ViewHolder();

            viewHolder.name = (EditText)v.findViewById(R.id.editAttrName);
            viewHolder.value = (EditText)v.findViewById(R.id.editAttrValue);

            viewHolder.delete = (Button)v.findViewById(R.id.btnDelete);
            viewHolder.delete.setTag(position);
            viewHolder.delete.setOnClickListener(new AdapterView.OnClickListener() {
                @Override
                public void onClick(View v) {
                    int position = (Integer) v.getTag();
                    Log.e("RowAdapter", "position = " + position);
                    Row row = getItem(position);
                    rows.remove(row);
                    notifyDataSetChanged();
                }   
            });

            v.setTag(viewHolder);
        } else {
            viewHolder = (ViewHolder)v.getTag();
        }
        Log.e("RowAdapter", "row " + v.toString() + ", position = " + position);    
        Row row = getItem(position);

        if(row != null) {

            EditText editText1 = (EditText)v.findViewById(R.id.editAttrName);
            EditText editText2 = (EditText)v.findViewById(R.id.editAttrValue);

            String text1 = editText1.getText().toString();
            String text2 = editText2.getText().toString();
            if(viewHolder.name != null) {
                viewHolder.name.setText(text1);
            }
            if(viewHolder.value != null) {
                viewHolder.value.setText(text2);
            }

        }

        return v;
    }
}

【问题讨论】:

    标签: android listview android-linearlayout android-adapter


    【解决方案1】:

    您的问题可能是适配器旨在包含 models 列表,而不是视图列表。视图应该由您的getView() 方法生成。所以你真正想要的是创建一个代表一行的Row 类,然后你可以在getView() 中填充和填充视图。

    【讨论】:

    • 感谢您的回复!我会试一试,然后告诉你进展如何。
    • 我已经实施了您建议的更改,但我仍然遇到类似的问题。我将更新问题以反映这些变化。
    • Hmmmm... 我快速查看了您的代码,但您没有在任何地方使用新的 Row 对象。但是,您说它“包含两个 EditText 字段的 getter 和 setter”,这是错误的。同样,您不应该存储实际的 EditText,您需要存储纯字符串值。见this for a good example
    • 我在扩展视图后使用新行(如果适用)。我应该更清楚, Row 对象确实存储纯字符串文本。我尝试获取用户在视图中键入的任何字符串,然后将其存储在 Row 对象中。我要看看那个例子。感谢您迄今为止的帮助!
    【解决方案2】:

    我认为您不需要创建函数public Row getItem(int position),因为ArrayAdapter&lt;T&gt; 提供了一个名为getItemAtPosition(int position) 的内置函数。还要确保当您调用getItemAtPosition(int position) 时,活动视图是列表视图,或者您拥有列表视图的句柄,以便您可以执行view.getItemAtPosition(position),否则您将获得null

    【讨论】:

    • 感谢您的回复。我不确定这是否是我想要的,因为 getItemAtPosition() 不返回视图(在这种情况下,ListView 包含 LinearLayouts)?我认为我需要更新 ArrayList 然后通知适配器我的数据集已更改
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2012-12-21
    • 1970-01-01
    • 2015-09-26
    • 2017-04-05
    • 1970-01-01
    • 2013-04-25
    • 1970-01-01
    相关资源
    最近更新 更多