当前流程:
用户加载应用。 应用查找默认文件夹 应用程序使用该文件夹内部和下方的音乐填充列表视图 用户移动到树下面的文件夹,列表视图将根据所选文件夹重新填充 用户再次移动....列表根据所选文件夹重新填充...
所以我想知道的是 - 使用以下过程更快/更有效: 用户加载应用 应用查找默认文件夹 应用程序使用该文件夹内部和下方的音乐填充列表视图 用户移动到树中的文件夹,列表被过滤到文件夹 如果用户在树上移动的位置高于默认数据(即新文件的可能性),则会重新填充列表视图,但仅限于此情况。
基本上,我的问题是“过滤与重新填充相比如何?”
答案 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();
}
}