Android ImageView中scaleType="centerCrop"實現左對齊效果
阿新 • • 發佈:2018-11-29
在開發過程中,用於顯示圖片大家用的比較多的應該是ImageView,在顯示圖片時是通常我們會設定scaleType以達到不同的展示效果。然後通常scaleType能設定的屬性僅為:
- CENTER /center 按圖片的原來size居中顯示,當圖片長/寬超過View的長/寬,則擷取圖片的居中部分顯示
- CENTER_CROP / centerCrop 按比例擴大圖片的size居中顯示,使得圖片長(寬)等於或大於View的長(寬)
- CENTER_INSIDE / centerInside 將圖片的內容完整居中顯示,通過按比例縮小或原來的size使得圖片長/寬等於或小於View的長/寬
- FIT_CENTER / fitCenter 把圖片按比例擴大/縮小到View的寬度,居中顯示
- FIT_END / fitEnd 把圖片按比例擴大/縮小到View的寬度,顯示在View的下部分位置
- FIT_START / fitStart 把圖片按比例擴大/縮小到View的寬度,顯示在View的上部分位置
- FIT_XY / fitXY 把圖片不按比例擴大/縮小到View的大小顯示
- MATRIX / matrix 用矩陣來繪製,動態縮小放大圖片來顯示。
但是如果我們想達到scaleType為CENTER_CROP型別的展示圖片方式且左對齊時,就感覺很無力了,ImageView並沒有提供這個型別。
這時我們通過檢視ImageView原始碼中處理scaleType為CENTER_CROP的邏輯,原始碼如下:
private void configureBounds() {
if (mDrawable == null || !mHaveFrame) {
return;
}
final int dwidth = mDrawableWidth;
final int dheight = mDrawableHeight;
final int vwidth = getWidth() - mPaddingLeft - mPaddingRight;
final int vheight = getHeight() - mPaddingTop - mPaddingBottom;
final boolean fits = (dwidth < 0 || vwidth == dwidth)
&& (dheight < 0 || vheight == dheight);
...
if (ScaleType.CENTER_CROP == mScaleType) {
mDrawMatrix = mMatrix;
float scale;
float dx = 0, dy = 0;
if (dwidth * vheight > vwidth * dheight) {
scale = (float) vheight / (float) dheight;
dx = (vwidth - dwidth * scale) * 0.5f;
} else {
scale = (float) vwidth / (float) dwidth;
dy = (vheight - dheight * scale) * 0.5f;
}
mDrawMatrix.setScale(scale, scale);
mDrawMatrix.postTranslate(Math.round(dx), Math.round(dy));
}
...
}
}
可知,它的計算公式,那我們就通過外部設定matrix的方式來達到這種效果。
具體步驟如下:
- 1、設定android:scaleType=“matrix”,它的圖片呈現效果前文已做解釋
- 2、設定圖片載入載入成功的監聽,這裡我使用的是Glide,程式碼如下:
Glide.with(mContext)
.load(tempImageUrl)
.placeholder(R.drawable.a_theme_banner_top_bg)
.error(R.drawable.a_theme_banner_top_bg)
.listener(mRequestListener)
.dontAnimate()
.into(imageView);
其中mRequestListener的程式碼為:
private RequestListener mRequestListener=new RequestListener<Object, GlideDrawable>() {
@Override
public boolean onException(Exception e, Object model, Target<GlideDrawable> target, boolean isFirstResource) {
return false;
}
@Override
public boolean onResourceReady(GlideDrawable resource, Object model, Target<GlideDrawable> target, boolean isFromMemoryCache, boolean isFirstResource) {
//這塊是重點程式碼,我們單獨摘抄出來進行講解
return false;
}
};
- 3、程式碼邏輯處理,這塊是重點
//先判斷是否為ImageView型別的Target
if (target instanceof ImageViewTarget) {
final AppCompatImageView imageView = (AppCompatImageView) ((ImageViewTarget) target).getView();
Matrix matrix;
//由於我實在ViewPager中做的圖片展示,故先從快取中取matrix,如果沒有在做建立,為了防止物件重複的建立,加大記憶體的開銷
if (imageView.getTag(R.id.common_data_id) == null) {
//這裡先獲取Drawable原始大小
final int dwidth = resource.getIntrinsicWidth();
final int dheight = resource.getIntrinsicHeight();
//這裡獲取ImageView的大小,用於後面做比例計算
final int vwidth = imageView.getWidth() - imageView.getPaddingLeft() - imageView.getPaddingRight();
final int vheight = imageView.getHeight() - imageView.getPaddingTop() - imageView.getPaddingBottom();
float scale;
//這個公式是從ImageView對CENTER_CROP型別的處理的程式碼段,
if (dwidth * vheight > vwidth * dheight) {
scale = (float) vheight / (float) dheight;
} else {
scale = (float) vwidth / (float) dwidth;
}
matrix = new Matrix();
//設定縮放比例
matrix.setScale(scale, scale);
//將matrix快取到View中
imageView.setTag(R.id.common_data_id, matrix);
} else {
matrix = (Matrix) imageView.getTag(R.id.common_data_id);
}
//將我們設定好的matrix設定給ImageView
imageView.setImageMatrix(matrix);
}
至此達到scaleType="centerCrop"展示圖片,左對齊效果