0

システムは、リストビューに正しい位置のビューをロードするまでビューをリサイクルしているようで、画像とテキストが数秒間重複します。誰でも助けることができますか?

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

まるで数秒間、位置が間違っているかのようです。

4

3 に答える 3

6

ViewHolder に AsyncTask への参照を保持させることができます。の場合、 ViewHolder が保持する AsyncTaskconvertView != nullを呼び出すことができます。これは、読み込み中の画像がこの新しい行に対して正しくないことがわかっているためです。とcancel()では、何かを行う前にまず確認してください。doInBackgrond()onPostExecute()if(!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(...);
    ...
}
于 2013-08-05T02:32:28.220 に答える
2

Android の開発者向けドキュメントには、これに関する優れたセクションがあります。

http://developer.android.com/training/displaying-bitmaps/process-bitmap.html

上記のように、この問題は、AsyncTask が既にリサイクルされたビューへのハード参照を保持していることです。

于 2013-08-05T02:35:31.193 に答える
0

現在のアイテムの画像ビューを標準の読み込み画像に設定するか、アダプターを介してビューを提供するときにすぐに何も設定しないことができます。これにより、非同期タスクにロードされている間、常にイメージが「リセット」されます。これは、リサイクルされたビューのパフォーマンス上の利点を維持するためのおそらく最良の方法です。テキストについても同様です。

于 2013-08-05T02:32:56.213 に答える