微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

android – Listview在投掷和滚动时显示错误视图几秒钟

系统似乎是回收视图,直到它在我的列表视图中加载正确位置的视图,导致重复的图像和文本几秒钟.有人可以帮忙吗?

@Override
public View getView(final int position, View convertView, ViewGroup parent) {
    View v = convertView;
    Log.d("position",""+position);

    if(v==null){
        LayoutInflater inflater = LayoutInflater.from(mContext);
        v = inflater.inflate(R.layout.layout_appinfo, null);

        holder = new ViewHolder();
        holder.ivAppIcon = (ImageView)v.findViewById(R.id.ivIconApp);
        holder.tvAppName = (TextView)v.findViewById(R.id.tvNameApp);
        holder.progress = (ProgressBar)v.findViewById(R.id.progress_spinner);
        v.setTag(holder);
    } else {
        holder = (ViewHolder) v.getTag();
    }
    holder.ivAppIcon.setimageDrawable(null);
    holder.tvAppName.setText(null);
    holder.progress.setVisibility(View.VISIBLE);
    holder.ivAppIcon.setVisibility(View.GONE);

    // Using an AsyncTask to load the slow images in a background thread
    new AsyncTask<ViewHolder, Void, Drawable>() {
        private ViewHolder v;
        private ResolveInfo entry = (ResolveInfo) mListAppInfo.get(position);

        @Override
        protected Drawable doInBackground(ViewHolder... params) {
            v = params[0];
            return entry.loadIcon(mPackManager);
        }

        @Override
        protected void onPostExecute(Drawable result) {
            super.onPostExecute(result);
            // If this item hasn't been recycled already, hide the
            // progress and set and show the image
            v.progress.setVisibility(View.GONE);
            v.ivAppIcon.setVisibility(View.VISIBLE);
            v.ivAppIcon.setimageDrawable(result);
            v.tvAppName.setText(entry.loadLabel(mPackManager));
        }
    }.execute(holder);
    return v;
}

static class ViewHolder {
      TextView tvAppName;
      ImageView ivAppIcon;
      ProgressBar progress;
      //int position;
}

这几乎就好像位置设置错了几秒钟.

解决方法:

您可以让ViewHolder保存对AsyncTask的引用.当convertView!= null时,您可以在ViewHolder持有的AsyncTask上调用cancel(),因为您知道它正在加载的图像对于这个新行不正确.在doInBackgrond()和onPostExecute()中,首先检查是否(!isCancelled())然后再做任何事情.

static class ViewHolder {
    TextView tvAppName;
    ImageView ivAppIcon;
    ProgressBar progress;
    AsyncTask task;
}

public View getView(int position, View convertView, ViewGroup parent) {
    ViewHolder holder;
    if (convertView == null) {
        /* inflate new view, make new ViewHolder, etc. */
        ...
    } else {
        holder = (ViewHolder) convertView.getTag();
        holder.task.cancel();
    }

    // always make a new AsyncTask, they cannot be reused
    holder.task = new AsyncTask ...
    holder.execute(...);
    ...
}

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐