使ListView滚动顺利进行

2018-08-31  本文已影响11人  鹿小纯0831

平滑滚动ListView的关键是保持应用程序的主线程(UI线程)免于繁重的处理。
确保在单独的线程中执行任何磁盘访问,网络访问或SQL访问。 要测试应用程序的状态,您可以启用StrictMode

一、使用后台线程

使用后台线程(“工作线程”)消除主线程的压力,使其可以专注于绘制UI。 在许多情况下,使用AsyncTask提供了一种在主线程外执行工作的简单方法。 AsyncTask自动将所有execute()请求排队并按顺序执行。 此行为对于特定进程是全局的,这意味着您无需担心创建自己的线程池。

在下面的示例代码中,AsyncTask用于在后台线程中加载图像,然后在完成后将它们应用到UI。 它还会在加载时显示进度微调器代替图像。

// Using an AsyncTask to load the slow images in a background thread
new AsyncTask<ViewHolder, Void, Bitmap>() {
    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(),并且可以根据可用的内核数量同时执行多个请求。

二、在视图持有者中保持视图对象

在滚动ListView期间,您的代码可能经常调用findViewById(),这会降低性能。 即使适配器返回一个膨胀的视图以进行回收,您仍然需要查找元素并更新它们。 绕过重复使用findViewById()的方法是使用“view holder”设计模式。

ViewHolder对象将每个组件视图存储在Layout的标记字段中,因此您可以立即访问它们而无需重复查找它们。 首先,您需要创建一个类来保存您的确切视图集。 例如:

static class ViewHolder {
  TextView text;
  TextView timestamp;
  ImageView icon;
  ProgressBar progress;
  int position;
}

然后填充ViewHolder并将其存储在布局中。

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);

现在,您无需查询即可轻松访问每个视图,从而节省宝贵的处理器周期。

上一篇 下一篇

猜你喜欢

热点阅读