25

Glide を使用してプレースホルダーを割り当て、この画像を元の縮尺のままにする方法はありますか? 呼び出す前に設定したImageView可変サイズ (着信画像に応じて) がありGlide.with().load().into()、プレースホルダーを使用したいが、プレースホルダーのサイズを のサイズに変更しImageViewたくない、オリジナルを保持したいサイズ。

これまでのところ、これを行う方法を見つけることができませんでした。

4

3 に答える 3

19

プレースホルダーがロードされた画像をゆがめたり、その逆の既知のグライドの問題があります。しかし、あなたはその影響を受けていないと思います。

あなたが望むのは、プレースホルダーのドローアブルを表示することでscaleType="center"あり、ロードされた画像をscaleType="fitCenter". それをグライドで表現するとこうなります。android:scaleType="center"XML に追加し、次の Glide ロード行を使用します。

Glide.with(...).load(...).placeholder(R.drawable....).fitCenter().into(imageView);

トリックは、プレースホルダーが経由で設定されてsetImageDrawable()いるため、ImageView は通常どおり表示するだけですがFitCenter、ロードされた画像が Transformation 経由で ImageView のレイアウトされたサイズ内にうまく収まるように明示的に使用するように Glide に指示し、経由で設定することsetImageDrawable()です。フィットした画像は完全にフィットするためcenter、ビューの全領域をカバーする画像を描画します。

使い方.centerCrop()も同じです。

何か問題がある場合は、試してみる.asBitmap().dontAnimate()、ほとんどの場合、何らかの形で役立ちます。

于 2015-10-01T11:08:45.050 に答える
13

Re:グレッグのコメント: もう 1 度試してみて (ほぼ 1 年間の追加の XP を使用して)、次のように思いつきました。

<ImageView android:scaleType="center" ... />

私の他のソリューションと次のアニメーションラッパーに似ています:

...
    .fitCenter()
    .animate(new PaddingAnimationFactory<>(new DrawableCrossFadeFactory<GlideDrawable>(2000)))
    .into(imageView)
;

class PaddingAnimationFactory<T extends Drawable> implements GlideAnimationFactory<T> {
    private final DrawableCrossFadeFactory<T> realFactory;
    @Override public GlideAnimation<T> build(boolean isFromMemoryCache, boolean isFirstResource) {
        return new PaddingAnimation<>(realFactory.build(isFromMemoryCache, isFirstResource));
    }
}

class PaddingAnimation<T extends Drawable> implements GlideAnimation<T> {
    private final GlideAnimation<? super T> realAnimation;
    @Override public boolean animate(T current, final ViewAdapter adapter) {
        int width = current.getIntrinsicWidth();
        int height = current.getIntrinsicHeight();
        return realAnimation.animate(current, new PaddingViewAdapter(adapter, width, height));
    }
}

class PaddingViewAdapter implements ViewAdapter {
    @Override public Drawable getCurrentDrawable() {
        Drawable drawable = realAdapter.getCurrentDrawable();
        if (drawable != null) {
            int padX = Math.max(0, targetWidth - drawable.getIntrinsicWidth()) / 2;
            int padY = Math.max(0, targetHeight - drawable.getIntrinsicHeight()) / 2;
            if (padX != 0 || padY != 0) {
                drawable = new InsetDrawable(drawable, padX, padY, padX, padY);
            }
        }
        return drawable;
    }
    @Override public void setDrawable(Drawable drawable) {
        if (VERSION.SDK_INT >= VERSION_CODES.M && drawable instanceof TransitionDrawable) {
            // For some reason padding is taken into account differently on M than before in LayerDrawable
            // PaddingMode was introduced in 21 and gravity in 23, I think NO_GRAVITY default may play
            // a role in this, but didn't have time to dig deeper than this.
            ((TransitionDrawable)drawable).setPaddingMode(TransitionDrawable.PADDING_MODE_STACK);
        }
        realAdapter.setDrawable(drawable);
    }
}

実装の些細な部分は省略され、各クラスのコンストラクターは引数からフィールドを初期化します。完全なコードはGitHub の TWiStErRob/glide-support で入手できます。

crossFaded プレースホルダー


Glide の古いバージョン (3.8.0 より前) に固執している場合は、次の方法で同じ効果を得ることができます。

.fitCenter()
.placeholder(R.drawable.glide_placeholder)
.crossFade(2000)
.into(new GlideDrawableImageViewTarget(imageView) {
    @Override public void onResourceReady(GlideDrawable resource,
            GlideAnimation<? super GlideDrawable> animation) {
        super.onResourceReady(resource, new PaddingAnimation<>(animation));
    }
})

2 つのソリューションで必要なクラスの数は同じですが、3.8.0 以降のソリューションでは問題がより適切に分離されており、割り当てを防ぐために変数にキャッシュできることに注意してください。

于 2016-04-29T17:12:11.433 に答える