對于這個(gè)情況肚豺,第一時(shí)間想到的方法,就是imageview增加scaleType="centerCrop"界拦。
imageview自帶的centerCrop是不管圖片小于還是大于imageview的大小吸申,都會等比例拉伸填充滿,然后裁剪享甸;
另外截碴,如果圖片加載框使用的是glide,那么glide自己也有一個(gè)centerCrop蛉威,但是跟imageview自帶的不一樣隐岛。
Glide的centerCrop對于大圖是裁剪,如果圖片小于imageview瓷翻,則是等比例全部顯示在imageview里而不是填滿裁剪;
注意:如果imageview自己設(shè)置了centeCrop,這時(shí)候Glide再設(shè)置圓角割坠,如果圖片原圖小于imageview齐帚,圓角是無效的。
這是因?yàn)間lide先處理了圖片數(shù)據(jù)彼哼,同時(shí)由于圖片是小于imageview的大小的对妄,所以glide的處理是全部顯示在imageview上,然后處理圓角敢朱。最后把處理完的圖片數(shù)據(jù)(有圓角)剪菱,設(shè)置在imageview上,由于imageview有centerCrop屬性拴签,圖片會等比例拉伸填充裁剪孝常,導(dǎo)致了圓角的失效。
imageview同時(shí)設(shè)置fitXY 和adjustViewBounds 也能達(dá)到效果蚓哩。
fitXY 這種圖片的顯示方式的效果是:根據(jù) ImageView 設(shè)置的大小拉伸圖片以填充滿空間构灸,(單獨(dú)設(shè)置此屬性時(shí))圖片會變形。
adjustViewBounds 是限制圖片在顯示時(shí)保持原圖比例岸梨。(和 fitXY 顯示方式合用能到達(dá)自適應(yīng)的效果)
不使用Android自帶屬性喜颁,怎么達(dá)到一樣的效果稠氮?
①自定義view,繼承iamgeview半开,重寫onMeasure
@SuppressLint("AppCompatCustomView")
public class ResizableImageView extends ImageView {
private int value=0;
public ResizableImageView(Context context) {
super(context);
}
public ResizableImageView(Context context, AttributeSet attrs) {
super(context, attrs);
}
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec){
Drawable d = getDrawable();
if(d!=null){
int width = MeasureSpec.getSize(widthMeasureSpec);
int height = width;
//高度根據(jù)使得圖片的寬度充滿屏幕計(jì)算而得(這個(gè)是默認(rèn)計(jì)算)
// int height = (int) Math.ceil((float) width * (float) d.getIntrinsicHeight() / (float) d.getIntrinsicWidth());
if (value==1){
height = (int) Math.ceil((float) (width*4/3));
}
setMeasuredDimension(width, height);
}else{
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
}
}
//根據(jù)傳過來的值隔披,1是寬度3:4,其它值是1:1
public void setMeasure(int value){
this.value= value;
}
}
但是如果利用glide來加載圖片寂拆,又會發(fā)現(xiàn)奢米,上面的方法也是不行的,因?yàn)間lide是根據(jù)imageview的大小來加載的漓库,由于上面設(shè)置的是warp_content恃慧,所以glide無法準(zhǔn)確根據(jù)大小來加載圖片。
解決方法:
1渺蒿、你已經(jīng)知道圖片(或其他方式提前知道)圖片的比例痢士,然后在用 Glide 請求圖片時(shí)限制圖片的加載大小,即設(shè)置 override(int width, int height) 茂装。這時(shí)候加載到的圖片是原圖比例怠蹂,顯示的時(shí)候雖然有拉伸/壓縮但都會保存原比例的。這種方式適用于你加載的圖片大小都比較規(guī)范固定的時(shí)候少态。
2城侧、當(dāng)你請求的圖片源大小不一定一致。那這時(shí)候就可以使用下面這種方式了彼妻。這種方式的原理是嫌佑,先使用 Glide 把圖片的原圖請求加載過來,然后再按原圖來顯示圖片侨歉。
Glide.with(mContext)
.load(url)
.asBitmap()
.into(new SimpleTarget<Bitmap>() {
@Override
public void onResourceReady(Bitmap resource, GlideAnimation<? super Bitmap> glideAnimation) {
ivOcnyang.setImageBitmap(resource);
}
});
這兩種方法中屋摇,其實(shí)更加提倡的是第一種方式,因?yàn)檫@種方式不會造成任何負(fù)面的影響幽邓。但第二種方式炮温,由于Glide加載圖片時(shí)是以全分辨率加載的,當(dāng)加載圖片過大且圖片很多時(shí)牵舵,可能造成 OOM柒啤。同時(shí)第二種方式使用在列表上復(fù)用時(shí)會造成條目錯(cuò)亂錯(cuò)位。
但是我們要圖片不拉伸畸颅,view大小也不改變担巩,將空白解決。
其實(shí)也簡單没炒,也是需要自定義view兵睛。
①自定義view,重寫ondraw方法。
②獲得將要顯示的圖片的尺寸或者比例祖很,傳入自定義view中笛丙,備用。
③onMeasure可以獲得控件的大小假颇,記錄下來胚鸯。
④在ondraw方法里,根據(jù)控件的大小和圖片的大小笨鸡,利用canvas先把圖片從左上角開始填充姜钳。
⑤記錄填充后的位置,如果還小于控件的大小形耗,那就繼續(xù)接著填充同樣的圖片bitmap哥桥,直到填滿為止。