如何将项目动态添加到 ListView 的自定义适配器
How to add items dynamically to a custom adapter for 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
字段和您的 activity 的 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);
现在您的适配器和 activity 将引用不同的列表,因此 this.lfs.clear()
不会意外清除您传递给它的列表。
我为 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
字段和您的 activity 的 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);
现在您的适配器和 activity 将引用不同的列表,因此 this.lfs.clear()
不会意外清除您传递给它的列表。