11

NOSTRAUniversal-Image-Loaderライブラリを評価して、画像を非同期でダウンロードしてListViewに表示しています。これまでのところ、1つの問題を除いて正常に動作します。

ImageViewsリストがスクロールされているときに、メモリキャッシュのビットマップが間違ってアタッチされることがあります。スクロールを停止すると、正しい画像が添付されます。このような状況は非常にまれであり、100%再現する方法を見つけることができませんでした。前回ビデオを撮りました。

これがArticleAdapterコードです。UIL構成とbindView()メソッドの両方がそこにあります。

public class ArticleAdapter extends CursorAdapter {
    private LayoutInflater inflater;
    private ViewHolder holder;

    public ArticleAdapter(Context context, Cursor cursor, boolean autoRequery) {
        super(context, cursor, autoRequery);
        imageLoader = ImageLoader.getInstance();
        DisplayImageOptions options = new DisplayImageOptions.Builder()
                .showStubImage(R.drawable.download_progress_thumb)
                .cacheInMemory()
                .cacheOnDisc()
                .imageScaleType(ImageScaleType.IN_SAMPLE_POWER_OF_2)
                .build();
        ImageLoaderConfiguration configuration = new ImageLoaderConfiguration.Builder(context)
                .threadPriority(Thread.NORM_PRIORITY - 2)
                .threadPoolSize(4)
                .discCache(new UnlimitedDiscCache(Utils.getCacheDirectory(context)))
                .defaultDisplayImageOptions(options)
                .build();
        imageLoader.init(configuration);

        titleIndex = cursor.getColumnIndex(Articles.TITLE);
        descriptionIndex = cursor.getColumnIndex(Articles.DESCRIPTION);
        isUnreadIndex = cursor.getColumnIndex(Articles.IS_UNREAD);
        isNewIndex = cursor.getColumnIndex(Articles.IS_NEW);
        urlIndex = cursor.getColumnIndex(Articles.URL);
        hostIndex = cursor.getColumnIndex(Articles.HOST);
        timeIndex = cursor.getColumnIndex(Articles.PUBLISH_TIME);

        bkgUnreadArticle = context.getResources().getColor(R.color.list_bkg_unread_article);
        bkgReadArticle = context.getResources().getColor(R.color.list_bkg_read_article);
        textUnreadTitle = context.getResources().getColor(R.color.list_text_unread_title);
        textReadTitle = context.getResources().getColor(R.color.list_text_read_title);

        inflater = LayoutInflater.from(context);
    }

    @Override
    public void bindView(View view, Context context, Cursor cursor) {
        String date = Utils.format(cursor.getLong(timeIndex), Utils.DATE);
        holder = (ViewHolder) view.getTag();

        holder.titleView.setText(cursor.getString(titleIndex));
        holder.descriptionView.setText(date);

        int isNew = cursor.getInt(isNewIndex);
        if (isNew == 1)
            holder.isNewView.setVisibility(View.VISIBLE);
        else
            holder.isNewView.setVisibility(View.INVISIBLE);

        int isUnread = cursor.getInt(isUnreadIndex);
        if (isUnread == 1){
            holder.titleView.setTextColor(textUnreadTitle);
            holder.rowLayout.setBackgroundColor(bkgUnreadArticle);
        } else {
            holder.titleView.setTextColor(textReadTitle);
            holder.rowLayout.setBackgroundColor(bkgReadArticle);
        }

        String url = cursor.getString(urlIndex);
        String host = cursor.getString(hostIndex);
        if (host.equalsIgnoreCase(Consts.HOST_LENTA) || host.equalsIgnoreCase(Consts.HOST_REALTY)) {
            holder.thumbView.setVisibility(View.VISIBLE);
            imageLoader.displayImage(Utils.makeImageUrl(url, Utils.THUMBNAIL), holder.thumbView);
        } else 
            holder.thumbView.setVisibility(View.GONE);
    }

    @Override
    public View newView(Context context, Cursor cursor, ViewGroup parent) {
        View v = inflater.inflate(R.layout.articlelist_item, null);
        ViewHolder holder = new ViewHolder();
        holder.titleView = (TextView) v.findViewById(R.id.list_title);
        holder.descriptionView = (TextView) v.findViewById(R.id.list_description);
        holder.thumbView = (ImageView) v.findViewById(R.id.list_thumb);
        holder.isNewView = (TextView) v.findViewById(R.id.list_read_unread);
        holder.rowLayout = (LinearLayout) v.findViewById(R.id.list_row);

        v.setTag(holder);
        return v;
    }
}

この件に関して何か助けていただければ幸いです。

4

5 に答える 5

20

ListViews、GridViews、およびそのアダプターでビューを再利用するために使用されるその他のリストの場合、この影響を防ぐためにDisplayImageOptionsを呼び出す必要があります。.resetViewBeforeLoading()

また、ドキュメントには次のように書かれています。

設定を1回だけにしてImageLoaderを初期化する

あなたは一度だけそれをしますか?アダプタのコンストラクタは、そのための適切な場所ではありません。

UPD:申し訳ありませんが、私の答えは役に立ちません。.resetViewBeforeLoading()を使用するため、役に立ちません.showStubImage(...)。したがって、正しいUILが機能するはずですが、そうではありません。そして、それは非常に奇妙です。

于 2012-12-29T10:51:02.540 に答える
3

この問題は定期的に発生しました。ImageLoaderを開始したのは1回だけでしたが、(アダプターで)必要なときにだけ実行していませんでした。Applicationクラスのinit()部分を変更した後、見事に機能しました。 。restartViewOnLoading()またはsetStubImage()を使用する必要さえありませんでした。必要に応じて、次のコードを使用します。

import android.content.Context;

import com.nostra13.universalimageloader.core.DisplayImageOptions;
import com.nostra13.universalimageloader.core.ImageLoader;
import com.nostra13.universalimageloader.core.ImageLoaderConfiguration;

public class Application extends android.app.Application {

    private static Context mContext;

    @Override
    public void onCreate() {
        super.onCreate();
        mContext = getApplicationContext();

        DisplayImageOptions imgOptions = new DisplayImageOptions.Builder()
            .cacheInMemory(true)
            .showImageOnLoading(R.drawable.default_picture)
            .build();
        ImageLoaderConfiguration imgConfig = new ImageLoaderConfiguration.Builder(mContext)
            .defaultDisplayImageOptions(imgOptions)
            .build();
        ImageLoader.getInstance().init(imgConfig);
    }

    public static Context getAppContext(){
        return mContext;
    }
}

編集:問題のより深い理解のためにここでこの会話をチェックすることができます。基本的に3つの解決策があります

1)ImageViewsのandroid:layout_widthおよびandroid:layout_heightパラメーターをディップで設定します(「wrap_content」および「match_parent」は受け入れられません)

2)ImageViewが描画された後にImageLoaderを呼び出します(imageView.post(...)内:

imageView.post(new Runnable() {
        @Override
        public void run() {
            imageLoader.displayImage(imageUri, imageView);
        }
     });

3)実際のビューサイズを考慮しないImageViewAware(ImageViewの代わりに)を渡します。

の代わりに:

imageLoader.displayImage(imageUri, imageView);

次の手順を実行します。

ImageAware imageAware = new ImageViewAware(imageView, false)
imageLoader.displayImage(imageUri, imageAware);
于 2015-08-04T07:43:39.023 に答える
0

ホルダーの設定方法をご覧くださいAdapter。これは、ビューを繰り返している理由として、内部に誤ったロジックを記述していると思われるためです。

ホルダー付きのカスタムカーソルアダプタとGetView &BindViewのディスカッションもあります。

于 2012-12-29T08:52:11.393 に答える
-1

この行をコードに追加します::

holder.thumbView.setTag(Utils.makeImageUrl(url, Utils.THUMBNAIL).get(position));
imageLoader.displayImage(Utils.makeImageUrl(url, Utils.THUMBNAIL), view_holder.image);
于 2012-12-29T08:57:36.537 に答える
-1

私は同じ問題を抱えており、それを修正しました。Universal-Image-Loaderライブラリのためではありません。これは、間違ったロジックでホルダーを使用して画像をロードしているためです。

交換してみてください

    @Override
    public View newView(Context context, Cursor cursor, ViewGroup parent) {
        View v = inflater.inflate(R.layout.articlelist_item, null);
        ViewHolder holder = new ViewHolder();
        holder.titleView = (TextView) v.findViewById(R.id.list_title);
        holder.descriptionView = (TextView) v.findViewById(R.id.list_description);
        holder.thumbView = (ImageView) v.findViewById(R.id.list_thumb);
        holder.isNewView = (TextView) v.findViewById(R.id.list_read_unread);
        holder.rowLayout = (LinearLayout) v.findViewById(R.id.list_row);

        v.setTag(holder);
        return v;
    }

@Override
    public View newView(Context context, Cursor cursor, ViewGroup parent) {
        View v = inflater.inflate(R.layout.articlelist_item, null);
        ViewHolder holder = new ViewHolder();
        holder.titleView = (TextView) v.findViewById(R.id.list_title);
        holder.descriptionView = (TextView) v.findViewById(R.id.list_description);
        ImageView thumbView = (ImageView) v.findViewById(R.id.list_thumb);
        imageLoader.displayImage("Your image URL", thumbView);
        holder.isNewView = (TextView) v.findViewById(R.id.list_read_unread);
        holder.rowLayout = (LinearLayout) v.findViewById(R.id.list_row);

        v.setTag(holder);
        return v;
    }

また、bindView関数でimageloaderを削除することを忘れないでください

于 2015-02-05T18:17:27.330 に答える