使用Picasso将图像调整为全宽和可变高度

wen*_*igo 78 android picasso

我有一个listView与适配器,包含ImageView可变大小(宽度和高度).我需要将Picasso的图片大小调整为布局的最大宽度,并根据图片的宽高比给出可变高度.

我已经检查了这个问题: 用Picasso将图像调整到全宽和固定高度

fit()作品,但我还没有发现什么,以保持画面的纵横比.

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

Picasso.with(this.context).load(message_pic_url)
.placeholder(R.drawable.profile_wall_picture)
.fit().centerInside()
.into(holder.message_picture);
Run Code Online (Sandbox Code Playgroud)

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

提前致谢.

Geo*_*ard 83

从Picasso 2.4.0开始,现在可以直接支持此操作.只需添加.resize()其中一个维度的请求即可0.例如,要具有可变宽度,您的调用将变为:

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

请注意,此调用使用.getHeight()并因此假设message_picture已经测量过.如果不是这种情况,例如当您在a中夸大新视图时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);
            }
        });
Run Code Online (Sandbox Code Playgroud)

  • 有了这个解决方案,我收到了`java.lang.IllegalArgumentException:至少有一个维度必须是正数.轮换错误,这是在片段中,任何想法为什么会发生这种情况? (8认同)
  • 你给了我这个主意.谢谢.对于那些想要具有可变高度的全宽图像的人,请使用:```Display display = getWindowManager().getDefaultDisplay(); Point size = new Point(); display.getSize(大小); int width = size.x;``````.resize(width,0)``` (4认同)
  • @Lukasz'Severiaan'Grela我遇到了同样的问题.要修复此示例以匹配原始问题,您必须转换参数:`.resize(holder.message_picture.getWidth(),0)` (2认同)

drs*_*boo 78

我遇到了同样的问题,我花了一段时间来追踪解决方案,但我终于找到了对我有用的东西.

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

Picasso.with(this.context).load(message_pic_url)
.placeholder(R.drawable.profile_wall_picture)
.into(holder.message_picture);
Run Code Online (Sandbox Code Playgroud)

删除fitcenterInside.接下来,您需要将以下行添加到XML中的ImageView

android:scaleType="fitStart"
android:adjustViewBounds="true"
Run Code Online (Sandbox Code Playgroud)

希望它也适合你.

  • 很抱歉听到这个消息.这将是这种方法的缺点.Picasso根本没有调整图像的大小,只需加载它的全尺寸即可.可能会导致内存问题. (4认同)
  • 谢谢,但这不适合我.我看不到图片,得到关于Bitmap大小的logcat警告(经典消息:2048x2048是最大大小). (2认同)
  • "fitStart"并没有为我工作,但"fitXY"完成了这个伎俩. (2认同)

wen*_*igo 59

最后我解决了它对Picasso的转换,这里是片段:

    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);
            }
    });
Run Code Online (Sandbox Code Playgroud)

此行用于自定义您想要的宽度:

int targetWidth = holder.message_picture.getWidth();
Run Code Online (Sandbox Code Playgroud)

此外,这个剪辑包括用于加载隐藏的回调和错误可绘制的内置毕加索.

如果您需要更多信息来调试任何错误,您必须实现自定义侦听器(Picasso构建器),因为onError Callback信息是"null".您只知道UI行为有错误.

我希望这可以帮助别人节省很多时间.


Pra*_*ani 9

May Accepted Answer对所有人都很有用但是如果你绑定Multiple ViewHolderfor Multiple Views那么你可以通过Creating Transformation for Transformation和从中传递ImageView来减少你的代码ViewHolder.

/**
 * 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";
            }
        };
    }
}
Run Code Online (Sandbox Code Playgroud)

来自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);
Run Code Online (Sandbox Code Playgroud)

希望它会帮助你.


小智 5

    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"/>
Run Code Online (Sandbox Code Playgroud)

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