首页 > 解决方案 > 如何将项目动态添加到 ListView 的自定义适配器

问题描述

我为 ListView 制作了适配器。如果我在创建适配器并将其链接到 listView 之前填充元素数组,则会显示元素。但是如果我在单击按钮时使用 updateItems() 方法添加项目,则什么也不会发生。适配器代码:

public class ListAdapter extends ArrayAdapter<Lf> {
private LayoutInflater inflater;
private int layout;
private List<Lf> lfs;

public ListAdapter(Context context, int resource, List<Lf> lfs) {
    super(context, resource, lfs);
    this.lfs = lfs;
    this.layout = resource;
    this.inflater = LayoutInflater.from(context);
}
public View getView(int position, View convertView, ViewGroup parent) {
    ViewHolder viewHolder;
    if(convertView==null){
        convertView = inflater.inflate(this.layout, parent, false);
        viewHolder = new ViewHolder(convertView);
        convertView.setTag(viewHolder);
    }
    else{
        viewHolder = (ViewHolder) convertView.getTag();
    }
    Lf lf = lfs.get(position);

    viewHolder.name.setText(lf.getLf());
    viewHolder.freq.setText((int)lf.getFreq() + "");

    return convertView;
}

public void updateItems(List<Lf> lfs) {
    this.lfs.clear();
    this.lfs.addAll(lfs);
    this.notifyDataSetChanged();
}

private class ViewHolder {
    final TextView name, freq;
    ViewHolder(View view){
        name = (TextView) view.findViewById(R.id.text_item_1);
        freq = (TextView) view.findViewById(R.id.text_item_2);
    }
}
}

MainActivity 代码:

public class MainActivity extends AppCompatActivity {
    EditText editText1;
    ListView listView;
    ListAdapter adapter;
    List<Lf> elements = new ArrayList<>();

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        editText1 = (EditText) findViewById(R.id.edit_text);
        listView = (ListView) findViewById(R.id.fragment_list);
        // Working... Elements print on screen
        for(int i = 0; i < 10; i++) {
            Lf temp = new Lf();
            temp.setLf("mean");
            temp.setFreq(100);
            elements.add(temp);
        }

        adapter = new ListAdapter(this, R.layout.list_item, elements);
        listView.setAdapter(adapter);

    }


    public void activity_button(View view) {
        adapter.updateItems(elements);
    }
}

如果我单击该按钮,屏幕上的现有项目将被清除,而不是添加新项目。但在调试中,我看到元素通常传递给 ListAdapter。

标签: javaandroidlistviewandroid-arrayadapter

解决方案


问题是您的适配器的lfs字段和您的活动的elements字段都引用同一个List实例。发生这种情况是因为您传递elementsListAdapter构造函数,然后简单地赋值this.lfs = lfs

所以让我们看看当你传递elementsupdateItems()...时会发生什么

public void updateItems(List<Lf> lfs) {
    this.lfs.clear(); // this.lfs and the input lfs are the same list, so this clears both
    this.lfs.addAll(lfs); // input lfs is now empty, so addAll() does nothing
    this.notifyDataSetChanged();
}

最好的办法可能是在适配器的构造函数中创建列表的副本。

this.lfs = new ArrayList<>(lfs);

现在您的适配器和活动将引用不同的列表,因此this.lfs.clear()不会意外清除您传递给它的列表。


推荐阅读