Android - ArrayAdapter 重复 ListView 项目

标签 android android-listview android-arrayadapter android-adapter

我有一个 ListView 小部件(位于其他 UI 元素下方),它是不扩展 ListActivityActivity 的一部分。我正在尝试编写一个基本功能,在单击 Button 时向 ListView 添加额外的项目。此数据是从 EditText 获得的。我为 onCreate() 中的 ListView 定义了 Adapter,在我的例子中是一个 ArrayAdapter 并设置了适配器对于 ListView 使用 setListAdapter()。但是,当我尝试向 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(data);

单个项目被添加到列表中,这是预期的行为,因为 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。为什么会这样?

Q2。作为扩展,这是否意味着 ArrayList 与我的 ArrayAdapter“耦合”(因为它是使用 ArrayList 作为参数构造的)暗示我不需要调用像 add() 或 clear() 这样的适配器方法来操作我的 ListView

这也是我的 Activity 的完整代码:

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

对此的任何指示或解释将不胜感激。也非常感谢您的宝贵时间。

最佳答案

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

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

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


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

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 项目,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24486000/

相关文章:

android - 在 Android 中显示 ArrayAdapter 的空 View

android - Android 2.2 上 View 的兼容方法(setScale 和 setPivot)

java - 如何将字体更改为 Xml 中定义的默认字体?

android - 应用程序,内置于android studio中,未安装在低于7.0版本的android中

android - 如何在android中的基本适配器中删除自定义 ListView 中的行

带有复选框的 Android ListView : How to capture checked items?

java - ListView 中的复选框无法正常工作?

java - 在Android中使用适配器将两个 ListView 合并为一个

java - Android 中的登录应用程序

android - 如何禁用我的 ListView 中的项目