Android-ArrayAdapter复制ListView项 [英] Android - ArrayAdapter duplicates ListView items

查看:77
本文介绍了Android-ArrayAdapter复制ListView项的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个ListView小部件(位于其他UI元素下方),它是不扩展ListActivityActivity的一部分.我正在尝试编写一个基本功能,该功能可以在单击Button时将其他项目添加到ListView.此数据是从EditText获得的.我为onCreate()中的ListView定义了Adapter(在我的情况下为ArrayAdapter),并使用setListAdapter()ListView设置了适配器.但是,当我尝试向ListView添加一个额外的项目时,将两个项目替换为一个项目(一项及其重复项).有关此的更多细节,请参见下文.

I have a ListView widget (positioned below other UI elements) that is part of an Activity that does not extend ListActivity. I am trying to write a basic feature that adds extra items to the ListView upon clicking a Button. This data is obtained from an EditText. I define the Adapter, an ArrayAdapter in my case, for the ListView in onCreate() and set the adapter for the ListView using setListAdapter(). However when I try to add an extra item to the ListView two items are added in the place of one (an item and its duplicate). More detail on this below.

响应Button单击并尝试在调用notifyDataSetChanged()之前尝试添加额外元素的函数为:

The function that responds to the Button click and attempts to add an extra element before calling notifyDataSetChanged() is as:

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(data);

b.add(data);

一个单独的项目被添加到列表中,这是预期的行为,因为adapter.add(Object)将一个额外的项目添加到列表中.但是,甚至更奇怪的是,当我不包含adapter.add(Object)时,列表项仍会显示在列表中.

a single item is added to the list which is expected behaviour as adapter.add(Object) appends an extra item to the list. However even queerer, is that when I do not include adapter.add(Object) a list item is still rendered in the list.

 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)`.

After a bit of debugging I found that this is owing to the addition of a data item to the ArrayList, i.e. b.add(data) where b is an ArrayList of Strings, causes an item to be included in the ListView despite not calling adapter.add(Object)`.

Q1.为什么会这样呢?

Q1. Why is this happening ?

Q2.作为扩展,这是否意味着ArrayList被耦合"到我的ArrayAdapter(因为它是使用ArrayList作为参数构造的),这意味着我不需要调用诸如add()或clear()之类的适配器方法.操纵我的ListView?

Q2. As an extension, does this mean that the ArrayList is 'coupled' to my ArrayAdapter (as it was constructed using the ArrayList as a argument) implying that I needn't call adapter methods like add() or clear() to manipulate my ListView ?

这也是我的活动的完整代码:

Here is the full code for my Activity as well:

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帖子,但是他们没有给我我所需要的答案.

I also had a look around other SO posts, but they have not given me the answers I was looking for.

Android中的ArrayAdapter创建简单的listview

为什么一个人不能从一个ArrayAdapter?

ListView中的重复条目

任何方向或对此的解释将是最大的赞赏.也非常感谢您的宝贵时间.

Any direction or an explanation on this would be most appreciated. Also thank you very much for your time.

推荐答案

似乎您已经找到了答案.通过将ArrayList提供给ArrayAdapter,可以有效地将两者结合在一起.为了更新数据,您需要做的就是在ArrayList中添加一个新元素.

It looks like you've already tracked down the answer. By providing the ArrayList to the ArrayAdapter, you have, effectively, coupled the two. In order to update the data, all you need to do is add a new element into the ArrayList.

.add()方法只是此方法的快捷方式.它所做的只是将提供的元素添加到ArrayList中.您可以使用任何一种方式添加元素,只是不要同时使用两种方式.

The .add() method is just a shortcut to this. All it does is add the provided element into the ArrayList. You can add the element either way, just don't do it both ways.

那么notifyDataSetChanged()有什么意义呢?仅仅因为更新ArrayList并不意味着ListView知道有新数据.因此,可能存在新数据,但视图可能不会刷新.调用notifyDataSetChanged()告诉ListView查找新数据并重新绘制自身,以便用户看到更改.

What's the point of notifyDataSetChanged() then? Just because you update the ArrayList doesn't mean that the ListView knows there is new data. Thus, new data might exist, but the view might not refresh itself. Calling notifyDataSetChanged() tells the ListView to look for new data and redraw itself so that the user sees the change.

来自ArrayAdapter.notifyDataSetChanged()的Android文档:

From the 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()

这篇关于Android-ArrayAdapter复制ListView项的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆