我有一个ListView
小部件(位于其他UI元素下方),它是不扩展ListActivity
的Activity
的一部分。我正试图编写一个基本功能,在单击Button
时向ListView
添加额外的项目。该数据来自EditText
。我在onCreate()
中为ListView
定义了Adapter
和ArrayAdapter
,并使用setListAdapter()
为ListView
设置了适配器。然而,当我试图向ListView
添加额外的项目时,两个项目被添加到一个项目的位置(一个项目及其副本)。下面是更多细节。
响应Button
点击并尝试在调用notifyDataSetChanged()
之前添加额外元素的函数如下:
public void saveButton(View view){
EditText editText = (EditText) findViewById(R.id.edit_text);
String data = editText.getText().toString();
// duplication caused by this line
b.add(data);
ArrayAdapter adapter = (ArrayAdapter) listView.getAdapter();
adapter.add((String)data);
adapter.notifyDataSetChanged();
}
当我不包含这一行时:
b.add(数据);
一个单独的项目被添加到列表中,这是adapter.add(Object)
附加一个额外的项目到列表中的预期行为。然而,更奇怪的是,当我不包括adapter.add(Object)
时,列表项仍然呈现在列表中。
public void saveButton(View view){
EditText editText = (EditText) findViewById(R.id.edit_text);
String data = editText.getText().toString();
b.add(data);
ArrayAdapter adapter = (ArrayAdapter) listView.getAdapter();
// not calling adapter.add() still includes an item in the list.
// adapter.add((String)data);
adapter.notifyDataSetChanged();
}
经过一点调试,我发现这是由于向ArrayList
添加了一个数据项,即b.add(data)
,其中b是字符串的数组列表,导致一个项目被包含在ListView
中,尽管没有调用adapter.add(Object) '。
Q1。为什么会发生这种情况?
Q2。作为扩展,这是否意味着ArrayList
是"耦合"到我的ArrayAdapter
(因为它是使用ArrayList作为参数构造的)意味着我不需要调用适配器方法,如add()或clear()来操纵我的ListView
?
这里是我的活动的完整代码以及:
public class MainActivity extends Activity {
ListView listView;
ArrayList<String> b = new ArrayList<String>();
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
b.add("Liquorice");
b.add("Dairy Milk");
b.add("Rice Crispies");
b.add("Orange-Mint");
b.add("After-Tens");
listView = (ListView) findViewById(R.id.list_view);
ArrayAdapter adapter = new ArrayAdapter<String>(getApplicationContext(),R.layout.layout_file,b);
listView.setAdapter(adapter);
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.main, menu);
return true;
}
public void saveButton(View view){
EditText editText = (EditText) findViewById(R.id.edit_text);
String data = editText.getText().toString();
b.add(data);
ArrayAdapter adapter = (ArrayAdapter) listView.getAdapter();
adapter.add((String)data);
adapter.notifyDataSetChanged();
}
}
我也看了看其他的SO帖子,但他们没有给我我正在寻找的答案。
ArrayAdapter在android中创建简单的listview
为什么不能'从ArrayAdapter添加/删除项?
ListView中重复条目
任何方向或解释这将是最感激的。也非常感谢你的时间。
看起来你已经找到答案了。通过将ArrayList
提供给ArrayAdapter
,您有效地将两者耦合在一起。为了更新数据,您所需要做的就是在ArrayList
中添加一个新元素。
.add()
方法只是一个快捷方式。它所做的只是将提供的元素添加到ArrayList
中。你可以用任意一种方式添加元素,但不要两种方式都添加。
那么notifyDataSetChanged()
的意义是什么?仅仅因为你更新了ArrayList
并不意味着ListView
知道有新的数据。因此,可能存在新数据,但视图可能不会刷新自身。调用notifyDataSetChanged()
告诉ListView
查找新数据并重新绘制自己,以便用户看到变化。
From Android documentation for ArrayAdapter.notifyDataSetChanged()
:
Notifies the attached observers that the underlying data has been changed and any View reflecting the data set should refresh itself.
http://developer.android.com/reference/android/widget/ArrayAdapter.html notifyDataSetChanged ()
在您的适配器上,验证视图是否为空,如果是,从您的布局中分配适当的视图,在if之后设置值。
@Override
public View getView(int position, View convertView, ViewGroup parent) {
ViewHolder viewHolder;
if (convertView == null) {
viewHolder = new ViewHolder();
LayoutInflater vi = (LayoutInflater) getContext().getSystemService(Context.LAYOUT_INFLATER_SERVICE);
convertView = vi.inflate(R.layout.customswipelayout, parent, false);
viewHolder.name = (TextView) convertView.findViewById(R.id.rowTextView1);
viewHolder.price = (TextView) convertView.findViewById(R.id.rowTextView2);
viewHolder.stockCount = (TextView) convertView.findViewById(R.id.rowTextView3);
convertView.setTag(viewHolder);
mItemManger.bindView(view, position);
}
/* rest of your adapter code */
}
这是我的一个例子,在我关闭if语句后,我赋值并返回视图:
viewHolder = (ViewHolder) view.getTag();
final Object object = this.list.get(position);
ImageView cmdDelete = (ImageView) view.findViewById(R.id.cmdDelete);
cmdDelete.setOnClickListener
//more personal code follows
return view;
现在我滚动我的列表,它工作得很好!