3

我有一个ListView小部件(位于其他UI元素下方),它是Activity的一部分,它不延伸ListActivity。我正在尝试编写一个基本功能,在单击Button时向ListView添加额外项目。该数据来自EditText。我定义了Adapter,ArrayAdapter在我的情况下,ListViewonCreate()中,并且使用setListAdapter()设置适配器为ListView。但是,当我尝试向ListView添加一个额外项目时,两个项目被添加到一个项目(一个项目及其副本)的位置。关于下面的更多细节。Android - ArrayAdapter复制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。增加(数据);

单个项目添加到预计的行为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为字符串的ArrayList,使得被包括在ListView的项尽管没有调用adapter.add(Object)`。

Q1。这是为什么发生? Q2302。作为扩展,这是否意味着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 in android to create simple listview

Why can't one add/remove items from an ArrayAdapter?

Duplicated entries in ListView

任何方向或在此的说明将是非常理解的。也非常感谢你的时间。

+0

什么是代码中的“b”? – VM4

+0

b是一个字符串ArrayList,用于存放我想要在屏幕上呈现的数据。这也包括在问题中。 – user1841702

+0

从您的代码中删除这两行代码ArrayAdapter adapter =(ArrayAdapter)listView.getAdapter(); adapter.add((String)data);. –

回答

2

看起来你已经找到了答案。通过将ArrayList提供给ArrayAdapter,您可以有效地将两者结合在一起。为了更新数据,您只需在ArrayList中添加一个新元素即可。

.add()方法只是一个捷径。它所做的只是将提供的元素添加到ArrayList中。您可以以任何方式添加元素,只是不要这样做。

那么notifyDataSetChanged()又有什么意义呢?仅仅因为你更新了ArrayList并不意味着ListView知道有新数据。因此,新数据可能存在,但该视图可能不会自行刷新。拨打notifyDataSetChanged()会通知ListView查找新数据并重新绘制,以便用户看到更改。


从Android文档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()

+0

非常感谢你。我也意识到,如果绑定到适配器的数据超出了范围,或者如果没有直接访问数据的方法,请从另一个类中进行说明,然后使用ArrayAdapter的add(),addAll()或clear()方法操纵该数据源。此外,ArrayList和ArrayAdapter的方法名称和签名完全相同,从而使您的答案更加重要。 – user1841702

0

在您的适配器,检验是否认为是空的,如果是,从你的布局分配适当的意见后,如果,设置值。

@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;

现在我滚动我的列表,它完美的工作!