java - 如何将项目动态添加到 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。
解决方案
问题是您的适配器的lfs
字段和您的活动的elements
字段都引用同一个List
实例。发生这种情况是因为您传递elements
给ListAdapter
构造函数,然后简单地赋值this.lfs = lfs
。
所以让我们看看当你传递elements
给updateItems()
...时会发生什么
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()
不会意外清除您传递给它的列表。
推荐阅读
- python - 使用 pandas 计算百分比并存储在 csv 文件中
- azure - 如何在 Azure Devops Pipeline 中使用 PowerShell 根据条件触发代理作业
- android - 如何解决错误,无法启动模拟器。原因:在 React native 中没有找到模拟器作为 `emulator -list-avds` 的输出?
- mysql - MySQL将时间戳转换为时区以进行搜索查询
- mysql - SQL:INNER JOIN,仅在右表中的所有行都满足条件时才返回结果
- kubernetes - 无法访问 Kubernetes 集群
- powershell - 使用 FBX2glTF 将多个 FBX 转换为 glTF
- git - 删除缓存在 git 中的大文件(文件名中有空格)
- flutter - 如何使用测试驱动程序在颤振中测试导航?
- mongodb - mongodb 服务器总是写在磁盘上