2

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

目前的流程:

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

所以我想知道的是 - 使用以下过程是否更快/更有效:用户加载应用程序应用程序找到默认文件夹应用程序使用该文件夹内和该文件夹下的音乐填充列表视图用户移动到树中的一个文件夹,列表被过滤到那个文件夹如果用户移动到比默认数据更高的树(即潜在的新文件),列表视图被重新填充,但仅在这种情况下。

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

4

1 回答 1

3

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

过滤实际上是重新填充ListView,而您创建/获取一个新集合并Adapter通过调用notifyDataSetChanged.

listView 的“繁重”工作是getView调用它的适配器。我自己对此进行了测试,如果每次调用 getView 时都膨胀一个新视图,性能就会下降。天上。

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

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

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

最后一个提示:你有没有很旧的手机?或者你认识的人会这样做?找到你能找到的最慢的手机,并在上面测试你的应用程序的性能。我自己有一个 HTC Legend,它已经过时而且速度很慢,但非常适合性能测试。如果它在我的(旧)手机上运行,​​它可以在任何手机上运行。

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

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();
    }
}
于 2012-07-19T08:18:03.793 回答