列表视图显示错误的观点了几秒钟,而扔和滚动视图、几秒钟、观点、错误

2023-09-06 07:08:33 作者:眉目成书

的系统,似乎是循环次,直到它装载正确位置的视图在我的列表视图,导致重复的图像和​​文本的几秒钟。任何人都可以帮忙吗?

The system seems to be recycling views until it loads the correct position's view in my listview, resulting in duplicated images and text for a few seconds. Can anyone help?

@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;
}

有几乎一样,如果该位置被设置错了几秒钟。

It is almost as if the position is being set wrong for a few seconds.

推荐答案

可以让ViewHolder持有引用AsyncTask的。当 convertView!= NULL ,你可以叫取消()由ViewHolder举行,因为你知道图像的AsyncTask的它装载不正确,此新行。在 doInBackgrond() onPostExecute(),首先检查如果(!isCancelled()) 之前,做任何事情。

You can let the ViewHolder hold a reference to the AsyncTask. When convertView != null, you can call cancel() on the AsyncTask held by the ViewHolder since you know the image it is loading will not be correct for this new row. In doInBackgrond() and onPostExecute(), first check if(!isCancelled()) before doing anything.

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(...);
    ...
}