使用毕加索将图像调整为全宽和可变高度

我有一个适配器,包含可变大小(宽度和高度) ImageView的ListView。 我需要调整与毕加索图片加载的最大宽度的布局和由图片的纵横比给出的variables高度。

我已经检查了这个问题: 调整图像到全宽和固定高度的毕加索

fit()作品,但我还没有发现任何东西保持图片的纵横比。

如果我在适配器的布局中固定高度,此代码部分工作:

 Picasso.with(this.context).load(message_pic_url) .placeholder(R.drawable.profile_wall_picture) .fit().centerInside() .into(holder.message_picture); 

但它会在listView的图片之间生成空格,因为图片可能没有那个高度。

提前致谢。

从毕加索2.4.0开始, 现在直接支持这个操作 。 只需添加一个尺寸为0.resize()请求。 例如,要有一个可变的宽度,你的呼叫将变成:

 Picasso.with(this.context) .load(message_pic_url) .placeholder(R.drawable.profile_wall_picture) .resize(0, holder.message_picture.getHeight()), .into(holder.message_picture); 

请注意,此调用使用.getHeight() ,因此假定message_picture已被测量。 如果不是这种情况,比如在ListAdapter添加了一个新视图,那么可以延迟这个调用,直到在测量之后,向视图添加一个OnGlobalLayoutListener

 holder.message_picture.getViewTreeObserver() .addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() { // Wait until layout to call Picasso @Override public void onGlobalLayout() { // Ensure we call this only once imageView.getViewTreeObserver() .removeOnGlobalLayoutListener(this); Picasso.with(this.context) .load(message_pic_url) .placeholder(R.drawable.profile_wall_picture) .resize(0, holder.message_picture.getHeight()) .into(holder.message_picture); } }); 

我遇到了同样的问题,我花了一段时间来追查解决scheme,但我终于遇到了一些适合我的东西。

首先,我改变了毕加索的电话

 Picasso.with(this.context).load(message_pic_url) .placeholder(R.drawable.profile_wall_picture) .into(holder.message_picture); 

删除fitcenterInside 。 接下来,您需要在XML中将以下几行添加到ImageView中

 android:scaleType="fitStart" android:adjustViewBounds="true" 

希望它也能为你工作。

最后我解决了做毕加索的转型,这里是片段:

  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); } }); 

这行是用你想要的宽度自定义的:

 int targetWidth = holder.message_picture.getWidth(); 

此外,这个剪切包括加载隐藏和错误绘制内置毕加索的callback。

如果您需要更多信息来debugging任何错误,则必须实现自定义侦听器(毕加索构build器),因为onError Callback信息为“null”。 您只知道UI行为存在错误。

我希望这能帮助别人节省很多时间。

可接受的答案是有用的,但如果你绑定多个Views多个ViewHolder ,那么你可以通过创build转换类和从ViewHolder传递ImageView来减less你的代码。

 /** * 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"; } }; } } 

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); 

希望它会帮助你。

  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"/> 

这将帮助您为所有设备提供可变高度的图像

我写了一个简单的助手,在布局过程完成时,注意添加布局完整的侦听器并调用(imageView)。

 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); } 

}

所以你可以很容易地使用它,例如在片段的onViewCreated()

 new PicassoDelegate(customerPhoto, Picasso.with(getActivity()).load(user.getPhotoUrl()).centerCrop()); 
 imageView.post(new Runnable() { @Override public void run() { Picasso.with(context) .resize(0, imageView.getHeight()) .onlyScaleDown() .into(imageView, new ImageCallback(callback, null)); } }); 
 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 + ")"; } 

更多的转换: https : //github.com/wasabeef/picasso-transformations

扩展ImageView然后覆盖onMeasure方法,如下所示。

 @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); } }