Tengo un listView con un adaptador que contiene un ImageView
tamaño variable (ancho y alto). Necesito cambiar el tamaño de la carga de imágenes con Picasso al ancho máximo de diseño y una altura variable dada por la relación de aspecto de la imagen.
He comprobado esta pregunta: Cambiar el tamaño de la imagen a ancho completo y alto fijo con Picasso
El fit()
funciona pero no he encontrado nada para mantener la relación de aspecto de la imagen.
Este código funciona parcialmente si arreglé la altura en el diseño del adaptador:
Picasso.with(this.context).load(message_pic_url)
.placeholder(R.drawable.profile_wall_picture)
.fit().centerInside()
.into(holder.message_picture);
Pero genera espacios en blanco entre las imágenes del listView porque las imágenes pueden ser que no tengan esa altura.
Gracias por adelantado.
java.lang.IllegalArgumentException: At least one dimension has to be positive number.
error en la rotación, esto está en el fragmento, ¿alguna idea de por qué puede suceder esto?.resize(holder.message_picture.getWidth(), 0)
Display display = getWindowManager().getDefaultDisplay(); Point size = new Point(); display.getSize(size); int width = size.x;
.resize(width, 0)
onGlobalLayout()
no se llama y la imagen no se muestra.Me encontré con el mismo problema y me tomó un tiempo encontrar una solución, pero finalmente encontré algo que funciona para mí.
Primero cambié la llamada de Picasso a
Picasso.with(this.context).load(message_pic_url) .placeholder(R.drawable.profile_wall_picture) .into(holder.message_picture);
Eliminar el
fit
y elcenterInside
. A continuación, debe agregar las siguientes líneas a ImageView en su XMLandroid:scaleType="fitStart" android:adjustViewBounds="true"
Con suerte, también funcionará para usted.
fuente
layout_width
ylayout_height
en ImageView? Lo intento conmatch_parent
ywrap_content
respectivamente, pero no funciona :(0dp
ymatch_parent
con un peso de1
pero no 100% seguro y no creo que tengamos esto en nuestra aplicación más.Finalmente lo resolví haciendo una transformación de Picasso, aquí está el fragmento:
Transformation transformation = new Transformation() { @Override public Bitmap transform(Bitmap source) { int targetWidth = holder.message_picture.getWidth(); double aspectRatio = (double) source.getHeight() / (double) source.getWidth(); int targetHeight = (int) (targetWidth * aspectRatio); Bitmap result = Bitmap.createScaledBitmap(source, targetWidth, targetHeight, false); if (result != source) { // Same bitmap is returned if sizes are the same source.recycle(); } return result; } @Override public String key() { return "transformation" + " desiredWidth"; } }; mMessage_pic_url = message_pic_url; Picasso.with(this.context) .load(message_pic_url) .error(android.R.drawable.stat_notify_error) .transform(transformation) .into(holder.message_picture, new Callback() { @Override public void onSuccess() { holder.progressBar_picture.setVisibility(View.GONE); } @Override public void onError() { Log.e(LOGTAG, "error"); holder.progressBar_picture.setVisibility(View.GONE); } });
Esta línea es para personalizar con el ancho deseado:
int targetWidth = holder.message_picture.getWidth();
Además, este recorte incluye la devolución de llamada para cargar la ocultación y el error de Picasso integrado.
Si necesita más información para depurar cualquier error, DEBE implementar un oyente personalizado (constructor de Picasso) porque la
onError
Callback
información es "nula". Solo sabe que hay un error en el comportamiento de la interfaz de usuario.Espero que esto ayude a alguien a ahorrar muchas horas.
fuente
holder.message_picture.getWidth()
devuelve 0 y provoca un errorwidth and height must be > 0
. ¿Alguna idea de cómo solucionar este error?May Accepted Answer es útil para todos, pero si está vinculando Multiple
ViewHolder
for MultipleViews
, puede reducir su código creando Class for Transformation y pasando ImageView desdeViewHolder
./** * Created by Pratik Butani */ public class ImageTransformation { public static Transformation getTransformation(final ImageView imageView) { return new Transformation() { @Override public Bitmap transform(Bitmap source) { int targetWidth = imageView.getWidth(); double aspectRatio = (double) source.getHeight() / (double) source.getWidth(); int targetHeight = (int) (targetWidth * aspectRatio); Bitmap result = Bitmap.createScaledBitmap(source, targetWidth, targetHeight, false); if (result != source) { // Same bitmap is returned if sizes are the same source.recycle(); } return result; } @Override public String key() { return "transformation" + " desiredWidth"; } }; } }
Llamando desde
ViewHolder
:Picasso.with(context).load(baseUrlForImage) .transform(ImageTransformation.getTransformation(holder.ImageView1)) .error(R.drawable.ic_place_holder_circle) .placeholder(R.drawable.ic_place_holder_circle) .into(holder.mMainPhotoImageView1);
Espero que te ayude.
fuente
imageView.getWidth()
devuelve 0 y provoca un errorwidth and height must be > 0
. ¿Alguna idea de cómo solucionar este error?Picasso.with(this).load(url).resize(1800, 1800).centerInside().into(secondImageView) <ImageView android:id="@+id/SecondImage" android:layout_width="fill_parent" android:layout_height="wrap_content" android:layout_alignParentStart="true" android:layout_alignParentLeft="true" android:adjustViewBounds="true" android:layout_margin="10dp" android:visibility="gone"/>
Esto le ayudará con la altura variable de las imágenes para todos los dispositivos.
fuente
Escribí un asistente simple que se encarga de agregar un oyente completo de diseño y llamar a (imageView) cuando se completa el proceso de diseño.
public class PicassoDelegate { private RequestCreator mRequestCreator; public PicassoDelegate(ImageView target, RequestCreator requestCreator) { if (target.getWidth() > 0 && target.getHeight() > 0) { complete(target, requestCreator); } else { mRequestCreator = requestCreator; target.addOnLayoutChangeListener(new View.OnLayoutChangeListener() { @Override public void onLayoutChange(View v, int left, int top, int right, int bottom, int oldLeft, int oldTop, int oldRight, int oldBottom) { v.removeOnLayoutChangeListener(this); complete((ImageView) v, mRequestCreator); } }); } } private void complete(ImageView target, RequestCreator requestCreator) { if (target.getWidth() > 0 && target.getHeight() > 0) { requestCreator.resize(target.getWidth(), target.getHeight()); } requestCreator.into(target); }
}
Para que pueda usarlo fácilmente así, por ejemplo, en onViewCreated () del fragmento
new PicassoDelegate(customerPhoto, Picasso.with(getActivity()).load(user.getPhotoUrl()).centerCrop());
fuente
imageView.post(new Runnable() { @Override public void run() { Picasso.with(context) .resize(0, imageView.getHeight()) .onlyScaleDown() .into(imageView, new ImageCallback(callback, null)); } });
fuente
public class CropSquareTransformation implements Transformation { private int mWidth; private int mHeight; @Override public Bitmap transform(Bitmap source) { int size = Math.min(source.getWidth(), source.getHeight()); mWidth = (source.getWidth() - size) / 2; mHeight = (source.getHeight() - size) / 2; Bitmap bitmap = Bitmap.createBitmap(source, mWidth, mHeight, size, size); if (bitmap != source) { source.recycle(); } return bitmap; } @Override public String key() { return "CropSquareTransformation(width=" + mWidth + ", height=" + mHeight + ")"; }
Más transformaciones: https://github.com/wasabeef/picasso-transformations
fuente
layout_width
ylayout_height
delImageView
en este caso?extienda ImageView y luego anule el método onMeasure como el siguiente.
@Override protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec){ Drawable d = getDrawable(); if(d!=null && fittingType == FittingTypeEnum.FIT_TO_WIDTH){ int width = MeasureSpec.getSize(widthMeasureSpec); int height = (int) Math.ceil((float) width * (float) d.getIntrinsicHeight() / (float) d.getIntrinsicWidth()); setMeasuredDimension(width, height); }else{ super.onMeasure(widthMeasureSpec, heightMeasureSpec); } }
fuente
En realidad, estaba ingresando mientras cargaba la imagen en CustomImageView que tenía funcionalidad con zoom
El error fue
java.lang.RuntimeException: Transformation transformation desiredWidth crashed with exception.
Lo resolví editando el código dado a partir de la respuesta aceptada. Obtuve el ancho máximo de mi pantalla como si el ancho de mi vista de imagen ya fuera match_parent.
if (! imgUrl.equals ("")) {
DisplayMetrics displayMetrics = new DisplayMetrics(); ((Activity) context).getWindowManager().getDefaultDisplay().getMetrics(displayMetrics); int height = displayMetrics.heightPixels; int width = displayMetrics.widthPixels; Picasso.with(context).load(imgUrl) .transform(getTransformation(width, imageView)) .into(imageView, new Callback() { @Override public void onSuccess() { if (progressBar != null) { progressBar.setVisibility(View.GONE); } } @Override public void onError() { if (progressBar != null) { progressBar.setVisibility(View.GONE); } } }); } public static Transformation getTransformation(final int width, final ImageView imageView) { return new Transformation() { @Override public Bitmap transform(Bitmap source) { int targetWidth = width; double aspectRatio = (double) source.getHeight() / (double) source.getWidth(); int targetHeight = (int) (targetWidth * aspectRatio); Bitmap result = Bitmap.createScaledBitmap(source, targetWidth, targetHeight, false); if (result != source) { // Same bitmap is returned if sizes are the same source.recycle(); } return result; } @Override public String key() { return "transformation" + " desiredWidth"; } }; }
fuente
Picasso.get() .load(message_pic_url) .fit() .centerCrop() .placeholder(R.drawable.profile_wall_picture) .into(holder.message_picture);
Prueba este código, funcionó para mí.
fuente
@Override protected void onResume() { super.onResume(); imageView.getViewTreeObserver().addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() { @Override public void onGlobalLayout() { loadImageIfReady(); } }); } private void loadImageIfReady() { if (imageView.getMeasuredWidth() <= 0 || mPayload == null) this.finish(); // if not ready GTFO Picasso.with(this) .load(mPayload) .resize(imageView.getMeasuredWidth(), imageView.getMeasuredWidth()) .centerInside() .into(imageView); }
fuente