翻自Android官方文档:http://developer.android.com/training/improving-layouts/smooth-scrolling.html 让ListView滑动流畅的要点在于让主线程(UI)脱离繁重的处理,确保磁盘访问,网络访问,SQL查询在分离的线程里。你可以开启StrictMode测试你的App状态。 使用后台线程 使用后台线程(工作线程)从主线程中分离繁重的任务,让主线程可以专注于UI绘制。在大多数情况下,AsyncTask提供了在主线程外执行任务的简单方法。AsyncTask自动排队请求,在execute()方法里顺序执行(AsyncTask默认共享一个static单线程池,所以是单线程的),你不需要自己创建管理线程池。 在下面的例子里,AsyncTask用于在后台线程载入图片,载入完成后,在UI线程应用。在载入的时候同时显示一个ProgressBar.
// Using an AsyncTask to load the slow images in a background thread
new AsyncTask() {
private ViewHolder v;
@Override
protected Bitmap doInBackground(ViewHolder... params) {
v = params[0];
return mFakeImageLoader.getImage();
}
@Override
protected void onPostExecute(Bitmap result) {
super.onPostExecute(result);
if (v.position == position) {
// If this item hasn't been recycled already, hide the
// progress and set and show the image
v.progress.setVisibility(View.GONE);
v.icon.setVisibility(View.VISIBLE);
v.icon.setImageBitmap(result);
}
}
}.execute(holder);
从Android 3.0(API 11)开始,AsyncTask针对多核处理器增加了一个新特性,你可以通过调用executeOnExecutor()取代execute(),指定自己的线程池,实现多线程同时操作。 通过ViewHolder保留View对象 你的代码可能会在滑动ListView时频繁调用findViewById,这可能是降低性能.即使Apapter返回了一个复用的view(convertView不为空),你仍然需要查找对象并更新.一种避免重复findViewById的方法是使用ViewHolder设计模式. 一个ViewHolder对象在Layout的tag字段里保存了每个View组件的引用,所以你可以立即访问而不需要重新查找。首先,你需要定义一个ViewHolder类保存你的View:
static class ViewHolder {
TextView text;
TextView timestamp;
ImageView icon;
ProgressBar progress;
int position;
}
然后填充ViewHolder并保存在Layout的tag里:
ViewHolder holder = new ViewHolder();
holder.icon = (ImageView) convertView.findViewById(R.id.listitem_image);
holder.text = (TextView) convertView.findViewById(R.id.listitem_text);
holder.timestamp = (TextView) convertView.findViewById(R.id.listitem_timestamp);
holder.progress = (ProgressBar) convertView.findViewById(R.id.progress_spinner);
convertView.setTag(holder);
现在你可以很轻松地访问每个view(通过getTag),节省处理器资源。