0%

Android开发:提高布局性能-让ListView滑动更流畅

翻自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),节省处理器资源。