图片不拉伸、不改变view大小的前提下,解决空白问题

如题所述

第1个回答  2022-07-16

对于这个情况,第一时间想到的方法,就是imageview增加scaleType="centerCrop"。
imageview自带的centerCrop是不管图片小于还是大于imageview的大小,都会等比例拉伸填充满,然后裁剪;

另外,如果图片加载框使用的是glide,那么glide自己也有一个centerCrop,但是跟imageview自带的不一样。
Glide的centerCrop对于大图是裁剪,如果图片小于imageview,则是等比例全部显示在imageview里而不是填满裁剪;

注意: 如果imageview自己设置了centeCrop,这时候Glide再设置圆角,如果图片原图小于imageview,圆角是无效的。
这是因为glide先处理了图片数据,同时由于图片是小于imageview的大小的,所以glide的处理是全部显示在imageview上,然后处理圆角。最后把处理完的图片数据(有圆角),设置在imageview上,由于imageview有centerCrop属性,图片会等比例拉伸填充裁剪,导致了圆角的失效。

imageview同时设置fitXY 和adjustViewBounds 也能达到效果。
fitXY 这种图片的显示方式的效果是:根据 ImageView 设置的大小拉伸图片以填充满空间,(单独设置此属性时)图片会变形。
adjustViewBounds 是限制图片在显示时保持原图比例。(和 fitXY 显示方式合用能到达自适应的效果)

①自定义view,继承iamgeview,重写onMeasure

但是如果利用glide来加载图片,又会发现,上面的方法也是不行的,因为glide是根据imageview的大小来加载的,由于上面设置的是warp_content,所以glide无法准确根据大小来加载图片。

解决方法:
1、你已经知道图片(或其他方式提前知道)图片的比例,然后在用 Glide 请求图片时限制图片的加载大小,即设置 override(int width, int height) 。这时候加载到的图片是原图比例,显示的时候虽然有拉伸/压缩但都会保存原比例的。这种方式适用于你加载的图片大小都比较规范固定的时候。

2、当你请求的图片源大小不一定一致。那这时候就可以使用下面这种方式了。这种方式的原理是,先使用 Glide 把图片的原图请求加载过来,然后再按原图来显示图片。

这两种方法中,其实更加提倡的是第一种方式,因为这种方式不会造成任何负面的影响。但第二种方式,由于Glide加载图片时是以全分辨率加载的,当加载图片过大且图片很多时,可能造成 OOM。同时第二种方式使用在列表上复用时会造成条目错乱错位。

其实也简单,也是需要自定义view。
①自定义view,重写ondraw方法。
②获得将要显示的图片的尺寸或者比例,传入自定义view中,备用。
③onMeasure可以获得控件的大小,记录下来。
④在ondraw方法里,根据控件的大小和图片的大小,利用canvas先把图片从左上角开始填充。
⑤记录填充后的位置,如果还小于控件的大小,那就继续接着填充同样的图片bitmap,直到填满为止。