NotifyDataSetChanged无法在Android 2.1上运行

时间:2012-10-04 20:48:02

标签: android listview

我正在开发一款Android应用程序,该应用程序将支持Ice cream三明治API,但可以在较旧的设备上运行,例如运行android 2.1。

我这样做的方法是检查当前的API版本是什么,如果它的后冰淇淋三明治调用一个活动,然后如果它的任何内容,请调用另一个活动。

我允许用户执行搜索,当它获得结果时,它会清除ArrayList,然后将搜索中的项添加回来,然后调用arrayadapter.notifydatasetchanged。这段代码我已经从ICS版本复制并粘贴到预ICS版本中,ICS工作正常,但在pre -ics版本上,列表视图不会更新。以下是我的代码。

public void performSearch(ArrayList<Spanned> searchPasswords)
    {
        if (searchPasswords.size() > 0)
        {
            btnClearSearch.setVisibility(View.VISIBLE);
            passwords.clear();
            for (int i = 0; i < searchPasswords.size(); i++)
            {
                passwords.add(searchPasswords.get(i));
            }

            passwordArrayAdapter.notifyDataSetChanged();
            btnClearSearch.setOnClickListener(mBtnClearSearch);
            common.showToastMessage(searchPasswords.size() + " result(s) found", Toast.LENGTH_LONG);
        }
        else
        {
            common.showToastMessage("No search results found", Toast.LENGTH_LONG);
        }
    }

我已经调试了这个函数,因此它正在定义调用它,并显示toast messags并说明找到了多少结果,但列表视图不会被更改。

更新

我刚刚发现了一个有点令人困惑的发现。作为执行列表视图初始加载的函数中的一个测试,我手动创建一个新的搜索ArrayList<Spanned>并将其传递给我遇到问题的同一个PerformSearch(ArrayList<Spanned>,这样就无需任何操作问题。

只有在从onActivityResult调用时,才会发生performSearch不更新ListView的问题。我知道onActivityResult工作正常,因为当调用performSearch函数时它会打印出来,因为找到了1个结果,所以它肯定得到的数据只是列表视图没有从调用performSearch函数的onActivityResult中刷新。

7 个答案:

答案 0 :(得分:0)

您可以尝试:

passwordArrayAdapter = new WHAT_EVER_ADAPTER_THIS_IS(searchPasswords, extra_constructor_params);
YOUR_LIST_VIEW.setAdapter(passwordArrayAdapter)

而不是:

    passwordArrayAdapter.notifyDataSetChanged();

答案 1 :(得分:0)

我有类似的问题。 notidfyDataSetChanged()和setAdapter()都没有工作。

最后,我找到了一个解决方案,它可能不如使用notifyDataSetChanged()那样有效,但它可以工作。

/**
 * Updates courses' list adapter.
 */
private void updateListAdapter()
{
    final ArrayAdapter a = (ArrayAdapter) coursesList.getAdapter();

    runOnUiThread(new Runnable()
    {
        public void run()
        {
            populteCoursesList();
            a.clear();

            for (MainScreenListModel model : listModels)
            {
                a.add(model);
            }
            a.notifyDataSetChanged();
        }
    });
}

courseList是我的自定义列表。 populateCoursesList()从db获取数据,listModels是列表视图模型的Vector。 如您所见,我必须清除适配器并再次填充它。

答案 2 :(得分:0)

我认为你的错误是忘记清除适配器,如果你这样尝试它应该可以工作:

public void performSearch(ArrayList<Spanned> searchPasswords)
    {
        if (searchPasswords.size() > 0)
        {
            btnClearSearch.setVisibility(View.VISIBLE);
            passwordArrayAdapter.clear();
            for (int i = 0; i < searchPasswords.size(); i++)
            {
                passwordArrayAdapter.add(searchPasswords.get(i));
            }
            passwordArrayAdapter.notifyDataSetChanged();
            btnClearSearch.setOnClickListener(mBtnClearSearch);
            common.showToastMessage(searchPasswords.size() + " result(s) found", Toast.LENGTH_LONG);
        }
        else
        {
            common.showToastMessage("No search results found", Toast.LENGTH_LONG);
        }
    }

答案 3 :(得分:0)

passwords.clear();
for (int i = 0; i < searchPasswords.size(); i++)
{
  passwords.add(searchPasswords.get(i));
}
passwordArrayAdapter.notifyDataSetChanged();

根据代码,您可以修改列表(密码),但它是适配器使用的相同实例(passwordArrayAdapter)。如果没有,则notifyDataSetChanged()将不起作用。

根据我的理解,您可以使用passwordArrayAdapter的新实例再次设置列表。

ur_list_view.setAdapter(new PasswordArrayAdapter(newly_formed_password_list, and other parameters));

或使用getter和setter更新列表(密码),然后调用notifyDataSetChanged()

答案 4 :(得分:0)

我不知道你刚粘贴的代码片段,但是从我看到密码和passwordsArrayAdapter之间没有持久的链接.... passwordsArrayAdapter用密码和密码的元素初始化自己.ArrayAdapter不会知道密码何时变化。要添加新项,您应该调用passwordsArrayAdapter.add(searchPasswords)。不要显式调用notifyDataSetChanged()。

public void performSearch(ArrayList<Spanned> searchPasswords)
    {
       if (searchPasswords.size() > 0)
       {
            btnClearSearch.setVisibility(View.VISIBLE);
           passwordArrayAdapter.clear();
           passwordArrayAdapter.setNotifyOnChange(true);
         for (int i = 0; i < searchPasswords.size(); i++)
         {
               passwordArrayAdapter.add(searchPasswords.get(i));
         }
            btnClearSearch.setOnClickListener(mBtnClearSearch);
            common.showToastMessage(searchPasswords.size() + " result(s) found", Toast.LENGTH_LONG);
       }
        else
        {
            common.showToastMessage("No search results found", Toast.LENGTH_LONG);
        }
    }

我不认为与onActivityResult位有关系 - 上面的代码应该修复它。

答案 5 :(得分:0)

在清除并添加新条目之前调用notifyOnChange(false)。否则,clear()和每个add()会在内部触发对notifyDataSetChanged()的调用,正如我所经历的那样,这会混淆ListView。明确notifyDataSetChanged(),这也会将内部notifyOnChange标记重新设置为true

答案 6 :(得分:0)

感谢大家的帮助和建议,我已经设法找出问题所在。

在我的活动的OnResume方法中,我调用了一个名为populateListArray的函数,该函数从ListView中检索数据库和列表中的所有信息。

当返回活动时,它正在调用OnResume方法,因此在获得结果后,它会重新使用所有原始内容重新显示列表视图。

为了解决这个问题,我添加了一个名为performingSearch的变量,我将其初始化为false。当我执行搜索时,我将其设置为true,并在onResume中,如果变量为true,我不做任何事情,并且在执行搜索功能完成后,我再次将变量设置为false。

再次感谢大家的帮助