Android Listview过滤与重新填充

时间:2012-07-19 07:01:05

标签: android listview filter android-listview

经过一些建议后真的。我的应用程序使用mediastore游标填充加载列表视图。这是拉动链接到用户定义文件夹的音乐,在大多数情况下,这些文件将是他们存储的所有音乐。我有一个beta测试人员使用Archos平板电脑,上面有大约10000首歌曲,运行android 2.2。虽然大多数用户的性能非常好,但我希望改善这类用户的体验。

当前流程:

用户加载应用。 应用查找默认文件夹 应用程序使用该文件夹内部和下方的音乐填充列表视图 用户移动到树下面的文件夹,列表视图将根据所选文件夹重新填充 用户再次移动....列表根据所选文件夹重新填充...

所以我想知道的是 - 使用以下过程更快/更有效: 用户加载应用 应用查找默认文件夹 应用程序使用该文件夹内部和下方的音乐填充列表视图 用户移动到树中的文件夹,列表被过滤到文件夹 如果用户在树上移动的位置高于默认数据(即新文件的可能性),则会重新填充列表视图,但仅限于此情况。

基本上,我的问题是“过滤与重新填充相比如何?”

1 个答案:

答案 0 :(得分:3)

一个非常好的问题。让我试着回答这个问题。

过滤实际上是ListView的重新填充,而您创建/获取新集合并通过调用Adapter告诉notifyDataSetChanged其内容已更改。

listView的'繁重'工作是getView调用它的适配器。我自己测试了这个,如果每次调用getView时都会给新视图充气,性能会下降。天上。

构建ListView的适配器,以便可以重用已经膨胀的视图,从而解决上面提到的问题。此外,只加载了可见的视图,因此,如果你告诉它的集合是10000个大项,那么Adapter就不会创建10000个视图。

notifyDataSetChanged将告诉适配器重建listviews内容,但它仍然包含以前膨胀的视图。所以这是一场重大的表现胜利。

所以我的建议是,当您使用相同的“行布局”时,只需使用ListView重新填充notifyDataSetChanged。我自己多次实现了这一点,但没有注意到任何UI性能问题。只需确保将您的集合过滤为后台线程。 (AsyncTask在这里派上用场了。)

最后一个提示:你有任何相当老的手机吗?或者你认识的人吗?找到最慢的手机并在其上测试您的应用程序的性能。我自己有一个HTC Legend,如果f * ck已经过时且速度很慢,但对于性能测试来说非常完美。如果它在我的(旧)手机上运行,​​它可以在任何手机上运行。

如果您的应用程序流动,则为伪代码示例:

public class FolderListActivity extends Activity implements OnItemSelected {

    // NOTE: THIS IS PSEUDO CODE

    private ListView listView
    private Adapter adapter;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstaceState);

        // setContentView here 
        listView = (ListView)findViewById(R.id.your_listview_here);
        listView.setOnItemSelectedListener(this);
    }

    public class AsyncLoadMusicLocationTask extends AsyncTask<Void, Void, List<String>> {

        public List<String> doInBackground(Void... params) {
            // Load the information here, this happens in the background
            // using that cursor, i'm not sure what kind of things you are using
            // So I assumed a List of Strings
        }

        @Override
        public void onPostExecute(List<String> result) {
            // Here we have our collection that was retrieved in a background thread
            // This is on the UI thread

            // Create the listviews adapter here
            adapter = new Adapter(result, and other parameters);
            listView.setAdapter(adapter);
        }
    }

    @Override
    public void onItemSelect(Some params, not sure which) {

        // THIS SHOULD BE DONE ON THE BACKGROUND THE PREVENT UI PERFORMANCE ISSUES

        List<String> collection = adapter.getObjects();
        for (int i = 0; i < collection.size(); i++) {
            // Filter here
        }

// this method will most probably not exist, so you will need to implement your own Adapter class
        adapter.setObjects(collections);
        adapter.notifyDataSetChanged();
    }
}