Android Listview过滤与重新填充

Android Listview过滤与重新填充,android,listview,filter,android-listview,Android,Listview,Filter,Android Listview,在一些建议之后,真的。我的应用程序使用mediastore光标在加载时填充列表视图。这是拉音乐链接到用户定义的文件夹,在大多数情况下,这将是他们所有存储的音乐。我有一个beta测试仪,它使用Archos平板电脑,上面有大约10000首歌曲,运行android 2.2。虽然大多数用户的性能都很好,但我想改善这样的用户的体验 目前的进程: 用户加载应用程序。 应用程序找到默认文件夹 应用程序使用文件夹内和文件夹下的音乐填充列表视图 用户移动到树下更远的文件夹,列表视图将基于所选文件夹重新填充 用户再

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

目前的进程:

用户加载应用程序。 应用程序找到默认文件夹 应用程序使用文件夹内和文件夹下的音乐填充列表视图 用户移动到树下更远的文件夹,列表视图将基于所选文件夹重新填充 用户再次移动…将根据所选文件夹重新填充列表

因此,我想知道的是,使用以下流程是否更快/更有效: 用户加载应用程序 应用程序找到默认文件夹 应用程序使用文件夹内和文件夹下的音乐填充列表视图 用户移动到树中的某个文件夹时,列表将过滤到该文件夹 如果用户在树上移动的位置高于默认数据(即可能有新文件),则列表视图将重新填充,但仅在这种情况下


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

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

过滤实际上是重新填充
列表视图
,而您创建/获取一个新集合,并通过调用
notifyDataSetChanged
告诉
适配器它的内容已更改

listView的“繁重”工作是调用它的适配器。我自己也测试过,如果每次调用getView时都膨胀一个新视图,那么性能就会下降。天啊

ListView的适配器的构建使得已经膨胀的视图可以被重用,从而解决了上述问题。此外,只加载可见视图,因此,如果告诉它的集合是10000个项目,那么
适配器不会创建10000个视图

notifyDataSetChanged
将告诉适配器重建ListView内容,但它仍然包含以前膨胀的视图。因此,这是一个巨大的性能胜利

因此,我给您的建议是,当您使用相同的“行布局”时,只需使用
notifyDataSetChanged
重新填充
ListView
。我自己已经实现了多次,但没有注意到任何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();
    }
}
公共类FolderListActivity扩展活动已选中{
//注意:这是伪代码
私有ListView ListView
专用适配器;
@凌驾
创建时受保护的void(Bundle savedInstanceState){
super.onCreate(savedinstacetate);
//在这里设置内容视图
listView=(listView)findViewById(R.id.your\u listView\u在此);
setOnItemSelectedListener(这个);
}
公共类AsyncLoadMusicLocationTask扩展了AsyncTask{
公共列表doInBackground(无效…参数){
//在这里加载信息,这在后台发生
//使用光标,我不确定您使用的是什么类型的东西
//所以我假设了一个字符串列表
}
@凌驾
public void onPostExecute(列表结果){
//这里是在后台线程中检索到的集合
//这是在UI线程上
//在此处创建listviews适配器
适配器=新适配器(结果和其他参数);
setAdapter(适配器);
}
}
@凌驾
public void onItemSelect(某些参数,不确定是哪个参数){
//这应该在后台完成,以防止UI性能问题
List collection=adapter.getObjects();
对于(int i=0;i
你好,谢谢你的回答。如果我读得正确,我的过程将是:加载应用程序,创建列表视图。用户选择文件夹,过滤列表内容并发送notifyDataSetChanged,并且不调用游标适配器代码?这将只从listview中删除项,而不重新展开视图?至于性能,不幸的是,我没有一部旧手机,但我想ebay可能会非常方便!如果您已经有了集合,请使用循环或其他方法“手动”筛选此集合。Android中的游标并不是大性能野兽。notifyDataSetChanged将告诉适配器重建ListView内容,但它仍然包含以前膨胀的视图。这是一个巨大的性能胜利。太好了,谢谢。我会做一些阅读到它是如何做到的,并张贴我的结果回到这里!谢谢你花时间来帮助我,非常感谢。嗨,这是我正在做的事情。我让Async doinbackground做查询mediastore和抛出游标的繁重工作。onPostExecute将光标卡盘到光标适配器。目前,在我的应用程序中,每次用户选择一个新文件夹时,都会调用相同的asynctask,该任务通过光标适配器重新查询并放大视图。因此,我需要为每个单击事件检查数据是否为原始数据的子集,如果执行一些手动筛选,则notifydatasetchanged。如果没有,,