2

我正在开发一个支持冰淇淋三明治 API 的 Android 应用程序,但可以在运行 android 2.1 等旧设备上工作。

我通过检查当前的 API 版本来做到这一点,如果它的冰淇淋三明治后调用一个活动,然后如果它在下面的任何内容,调用另一个活动。

我允许用户执行搜索,当它获得结果时,它会清除 ArrayList,然后将搜索中的项目添加回来,然后调用 arrayadapter.notifydatasetchanged。这段代码我从 ICS 版本复制并粘贴到 ICS 之前的版本中,ICS 工作正常,但在 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 消息,说明找到了多少结果,但列表视图没有改变。

更新

我刚刚发现了一个有点令人困惑的发现。作为对执行列表视图初始加载的函数的测试,我手动创建了一个新搜索ArrayList<Spanned>并将其传递给PerformSearch(ArrayList<Spanned>我遇到问题的相同),并且这可以正常工作。

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

4

7 回答 7

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);
        }
    }
于 2012-10-05T12:38:35.233 回答
0

我仅从您粘贴的代码片段中了解不多,但据我所知,密码和 passwordsArrayAdapter 之间没有持久的链接....passwordsArrayAdapter 使用密码元素初始化自身,而passwordsArrayAdapter 将不知道密码何时更改。要添加新项目,您应该调用 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 位有关系——上面的代码应该修复它。

于 2012-10-09T07:56:33.410 回答
0

Thanks everyone for your help and suggestions, I've managed to find out what the problem was.

In my OnResume method for the activity I call a function called populateListArray which retrieves all of the information from the database and lists in the ListView.

When the activity was returned it was calling the OnResume method so after it got the results it then reset the list view back with all the original content.

To get round it I added a variable called performingSearch which I initialise to false. When I perform the search I set this to true and in the onResume, if the variable is true I don't do anything and after the perform search function has finished I set the variable back to false again.

Thanks everyone again for your help

于 2012-12-01T23:34:29.253 回答
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 是列表视图的模型向量。如您所见,我必须清除适配器并再次填充它。

于 2012-10-04T22:11:58.023 回答
0
passwords.clear();
for (int i = 0; i < searchPasswords.size(); i++)
{
  passwords.add(searchPasswords.get(i));
}
passwordArrayAdapter.notifyDataSetChanged();

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

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

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

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

于 2012-10-08T13:02:34.820 回答
0

notifyOnChange(false)在清除和添加新条目之前调用。否则,clear()and eachadd()内部会触发对 的调用notifyDataSetChanged(),正如我所经历的那样,这会使 ListView 感到困惑。保持你的显式notifyDataSetChanged(),这也将内部notifyOnChange标志true重新设置为。

于 2012-10-14T14:55:50.623 回答
0

你可以试试:

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

代替:

    passwordArrayAdapter.notifyDataSetChanged();
于 2012-10-04T20:51:10.590 回答