一个非常好的问题。让我试着回答这个问题。
过滤实际上是重新填充ListView
,而您创建/获取一个新集合并Adapter
通过调用notifyDataSetChanged
.
listView 的“繁重”工作是getView
调用它的适配器。我自己对此进行了测试,如果每次调用 getView 时都膨胀一个新视图,性能就会下降。天上。
构建 ListView 的适配器以便可以重新使用已经膨胀的视图,从而解决上述问题。此外,仅加载可见视图,因此Adapter
如果您告诉它的集合是 10000 个项目,它不会创建 10000 个视图。
notifyDataSetChanged
将告诉适配器重建 listviews 内容,但它仍然包含以前膨胀的视图。所以这是一个巨大的性能胜利。
所以我对你的建议是,当你使用相同的“行布局”来重新填充ListView
using时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();
}
}