Re: Gregs comment: Ich gab es einen weiteren Schuss (mit fast einem Jahr zusätzliche XP) und kam mit dieser:
<ImageView android:scaleType="center" ... />
ähnlich wie meine anderen Lösung und die folgende Animation Wrapper:
...
.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);
}
}
Trivial Teile der Implementierungen sind weggelassen, jeder Konstruktor der Klasse initialisiert die Felder von Argumenten. Vollständiger Code verfügbar unter GitHub in TWiStErRob/glide-support.
.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));
}
})
Hinweis, wie die beiden Lösungen:

Wenn Sie eine ältere Version von Glide (vor 3.8.0) stecken, kann der gleiche Effekt erreicht werden durch benötigen die gleiche Menge an Klassen, aber die Post-3.8.0-Lösung hat eine bessere Trennung von Bedenken und kann in einer Variablen zwischengespeichert werden, um Zuweisungen zu verhindern.
Sehr schön gemacht danke –
Diese Lösung funktioniert für uns auf Android 5.x und darunter. Auf 6 und N sieht es jedoch so aus, als ob sich die PaddingAnimation nicht wie erwartet verhält, und wir sehen erneut, wie der Platzhalter für Verhalten während des Übergangs in die centerCrop-Ansicht wächst. Wir werden recherchieren, aber wenn irgendjemand sonst den Fehler auf 6 & N gesehen hat, würde ich gerne irgendwelche Lösungen finden. –
@JakeHall können Sie bitte eine Bildschirmkappe davon teilen? Sieht InsetDrawable wie erwartet aus, wenn es in einem eigenständigen ImageView verwendet wird? Ist es möglich, dass Ihr Platzhalter zwischen diesen Versionen inkonsistente Größen hat (d. H. Neuere Version -> höhere dpi -> anderes Asset). Ich denke, die Mathematik und "scaleType = center" funktioniert nur, wenn der Platzhalter kleiner als die Ansicht/voll geladene Ressource ist; Beachten Sie, dass padXY zum Beispiel negativ werden kann. – TWiStErRob