12

我有一个 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
}
}

谁能看到我哪里出错了?

4

3 回答 3

39

对于 ArrayAdapter,notifyDataSetChanged只有在适配器上使用 、 、 和 函数add时才insert有效removeclear

  1. 使用 clear 清除适配器 -arrayAdapter.clear()
  2. 使用 Adapter.addAll 并添加新形成的列表 -arrayAdapter.addAll(deviceList)
  3. 调用 notifyDataSetChanged

备择方案:

  1. 形成新的设备列表后重复此步骤 - 但这是多余的

    arrayAdapter = new ArrayAdapter<Device>(this, android.R.layout.simple_list_item_1, deviceList);
    
  2. 创建您自己的从 BaseAdapter 和 ListAdapter 派生的类,从而为您提供更大的灵活性。这是最推荐的。
于 2012-11-07T18:02:26.333 回答
12

虽然接受的答案解决了问题,但解释为什么不正确,因为这是一个重要的概念,我想我会试图澄清。

SlartibartfastnotifyDataSetChanged()仅在适配器上调用 、 、 或 时有效的解释是不 add正确insertremoveclear

setNotifyOnChange()方法的解释是正确的,如果设置为 true (默认情况下),将notifyDataSetChanged()在这四个操作中的任何一个发生时自动调用。

我认为海报混淆了这两种方法。 notifyDatasetChanged()本身没有这些限制。它只是告诉适配器它正在查看的列表已更改,而列表的更改实际上是如何发生的并不重要。

虽然我看不到您的源代码createNewDeviceList(),但我猜您的问题来自这样一个事实,即您的适配器引用了您创建的原始列表,然后您在 中创建了一个新列表createNewDeviceList(),并且由于适配器仍然指向旧的列表它看不到变化。

slartibartfast 提到的解决方案有效,因为它清除了适配器并专门将更新的列表添加到该适配器。因此,您不会遇到适配器指向错误位置的问题。

希望这对某人有帮助!

于 2014-09-05T06:34:59.113 回答
0

您的方法 addDevice 导致无限循环。不要像您在这里所做的那样从自身调用方法:

deviceList = addDevice();
于 2012-11-07T17:30:57.857 回答