更改数组列表时,带有 ArrayList 和 ListView 的 Android 数组适配器不会更新
Posted
技术标签:
【中文标题】更改数组列表时,带有 ArrayList 和 ListView 的 Android 数组适配器不会更新【英文标题】:Android Array Adapter with ArrayList and ListView not updating when the arraylist is changed 【发布时间】:2012-10-27 19:37:43 【问题描述】:我有一个 android 应用程序,其屏幕由一个 ListView 组成,我用它来显示设备列表。这些设备被保存在一个阵列中。
我正在尝试使用 ArrayAdapter 在列表中的屏幕上显示数组中的内容。
当我第一次加载 SetupActivity 类时它可以工作,但是,在 addDevice() 方法中可以添加新设备,这意味着数组保存设备已更新。
我正在使用 notifyDataSetChanged() 应该更新列表,但它似乎不起作用。
public class SetupActivity extends Activity
private ArrayList<Device> deviceList;
private ArrayAdapter<Device> arrayAdapter;
private ListView listView;
private DevicesAdapter devicesAdapter;
private Context context;
public void onCreate(Bundle savedInstanceState) //Method run when the activity is created
super.onCreate(savedInstanceState);
setContentView(R.layout.setup); //Set the layout
context = getApplicationContext(); //Get the screen
listView = (ListView)findViewById(R.id.listView);
deviceList = new ArrayList<Device>();
deviceList = populateDeviceList(); //Get all the devices into the list
arrayAdapter = new ArrayAdapter<Device>(this, android.R.layout.simple_list_item_1, deviceList);
listView.setAdapter(arrayAdapter);
protected void addDevice() //Add device Method (Simplified)
deviceList = createNewDeviceList(); //Add device to the list and returns an updated list
arrayAdapter.notifyDataSetChanged(); //Update the list
谁能看出我哪里出错了?
【问题讨论】:
【参考方案1】:对于 ArrayAdapter,notifyDataSetChanged
仅在您使用适配器上的 add
、insert
、remove
和 clear
函数时才有效。
-
使用 clear 清除适配器 -
arrayAdapter.clear()
使用 Adapter.addAll 并添加新形成的列表 - arrayAdapter.addAll(deviceList)
调用 notifyDataSetChanged
替代方案:
形成新的设备列表后重复此步骤 - 但这是 多余的
arrayAdapter = new ArrayAdapter<Device>(this, android.R.layout.simple_list_item_1, deviceList);
创建您自己的从 BaseAdapter 和 ListAdapter 派生的类
给你更多的灵活性。这是最推荐的。
【讨论】:
这不是真的,请参阅@Laura 回复【参考方案2】:虽然接受的答案解决了问题,但对原因的解释是不正确的,因为这是一个重要的概念,我想我会尝试澄清一下。
Slartibartfast 关于notifyDataSetChanged()
仅在适配器上调用add
、insert
、remove
或clear
时有效的解释不正确。
setNotifyOnChange()
方法的解释是正确的,如果设置为 true(默认情况下),当这四个操作中的任何一个发生时,它将自动调用 notifyDataSetChanged()
。
我认为海报混淆了这两种方法。 notifyDatasetChanged()
本身没有这些限制。它只是告诉适配器它正在查看的列表已更改,而列表的更改实际上是如何发生的并不重要。
虽然我看不到您的 createNewDeviceList()
的源代码,但我猜您的问题来自这样一个事实,即您的适配器引用了您创建的原始列表,然后您在 createNewDeviceList()
中创建了一个新列表,并且由于适配器仍指向旧列表,因此无法看到更改。
slartibartfast 提到的解决方案有效,因为它清除了适配器并专门将更新的列表添加到该适配器。因此,您不会遇到适配器指向错误位置的问题。
希望这对某人有所帮助!
【讨论】:
【参考方案3】:您的方法 addDevice 导致无限循环。不要像您在这里所做的那样从自身调用方法:
deviceList = addDevice();
【讨论】:
打扰了,这只是我的一个错字...抱歉造成混乱 您可以发布您的 createNewDeviceList(),它可能不会在您的列表中添加任何新内容,而是使用与原始元素和顺序相同的元素和顺序创建新列表以上是关于更改数组列表时,带有 ArrayList 和 ListView 的 Android 数组适配器不会更新的主要内容,如果未能解决你的问题,请参考以下文章
关于JAVA核心技术(卷一)读后的思考(泛型数组列表的讨论)