android - propiedades - ¿Cómo escala una ImageView como centerCrop, pero desde arriba?
propiedades imageview android (2)
Digamos que estoy obteniendo una imagen de una API. No tengo idea de cuáles serán las dimensiones de la imagen antes de tiempo, pero sé que quiero que esa imagen se convierta en la src
de un ImageView
que he configurado en un tamaño específico. Quiero cualquier imagen que obtenga de la API para llenar toda la imagen, quiero conservar la relación de aspecto, y no me importa si una dimensión (ancho o alto) se vuelve demasiado grande para el tamaño establecido de la vista, así que uso centerCrop
.
<ImageView
android:layout_width="400px"
android:layout_height="300px"
android:scaleType="centerCrop" />
Si la imagen que vuelve de la API es esta:
Cuando se establece como src de ImageView
, el resultado será algo similar a esto (las partes sombreadas se recortan):
Sin embargo, recibo una solicitud de que siempre debemos mostrar la parte superior de la imagen y recortar desde abajo hacia arriba. Entonces el resultado deseado es algo como esto:
Estoy seguro de que esto es posible, pero soy un tipo de red que opera fuera de su alcance aquí. ¿Será mejor extender ImageView
alguna manera, o probar scaleType="matrix"
y setImageMatrix()
, o alguna tercera opción no mencionada?
Use esta idea de TopCropImageView
import android.content.Context;
import android.graphics.Matrix;
import android.widget.ImageView;
/**
* ImageView to display top-crop scale of an image view.
*
* @author Chris Arriola
*/
public class TopCropImageView extends ImageView {
public TopCropImageView(Context context) {
super(context);
setScaleType(ScaleType.MATRIX);
}
@Override
protected void onLayout(boolean changed, int left, int top, int right, int bottom) {
super.onLayout(changed, left, top, right, bottom);
recomputeImgMatrix();
}
@Override
protected boolean setFrame(int l, int t, int r, int b) {
recomputeImgMatrix();
return super.setFrame(l, t, r, b);
}
private void recomputeImgMatrix() {
final Matrix matrix = getImageMatrix();
float scale;
final int viewWidth = getWidth() - getPaddingLeft() - getPaddingRight();
final int viewHeight = getHeight() - getPaddingTop() - getPaddingBottom();
final int drawableWidth = getDrawable().getIntrinsicWidth();
final int drawableHeight = getDrawable().getIntrinsicHeight();
if (drawableWidth * viewHeight > drawableHeight * viewWidth) {
scale = (float) viewHeight / (float) drawableHeight;
} else {
scale = (float) viewWidth / (float) drawableWidth;
}
matrix.setScale(scale, scale);
setImageMatrix(matrix);
}
}
Si está utilizando Glide, puede usar una transformación personalizada. Siéntase libre de usar el mío (que es una copia casi exacta de CenterCrop Class by Glide), que toma porcentajes:
https://gist.github.com/bjornson/3ff8888c09908d5c6cc345d0a8e1f6a7
Úselo como cualquier otra transformación de mapa de bits:
Glide.with(getContext())
.load(imagePath)
.transform(new PositionedCropTransformation(getContext(), 1, 0))
.into(imageView);
Valores necesarios: arriba a la izquierda: 0, 0 arriba a la derecha: 0, 1 abajo a la izquierda: 1, 0 abajo a la derecha: 1, 1
Use 0.5f para el centro