ImageView中有個很重要也很經常使用的屬性android:scaleType
,相信你們都應該不陌生,主要用於控制圖片在ImageView中顯示的樣式,好比顯示大小、顯示位置、顯示內容區域。固然也能夠在代碼中設置: setScaleType(ImageView.ScaleType.xxx);
ScaleType的取值一共有8種:fitCenter
,fitEnd
,center
,centerCrop
,centerInside
,matrix
,fitXY
,fitStart
。其中默認值是fitCenter。 咱們先來看比較簡單的center
吧,一個60dp*40dp的ImageView(爲了顯示效果,背景設成藍色)裏面放了張20dp*20dp的圖片。上圖看看效果:java
center
的含義是:保持原圖的大小,顯示在ImageView的中心。當原圖的size大於ImageView的size,超過部分裁剪處理。 再來看比較「暴力」的fitXY
:android
fitXY
的含義:拉伸顯示圖片,不保持原比例,填滿ImageView.嗯,果真很暴力。canvas
嗯,接下來咱們...什麼?難道你覺得我要把剩下的6種樣式都貼張圖出來,而後愉快地水一篇博客嗎? ide
因此接下來我放大招了,開始分析源碼!工具
上面設置了這麼多種ScaleType
,那麼最終生效的位置在哪呢?答案就在 configureBounds()
方法裏,限於篇幅我貼了上面兩種樣式的法,其餘的樣式實現也都相似。post
private void configureBounds() {
//圖片寬高
final int dwidth = mDrawableWidth;
final int dheight = mDrawableHeight;
//Imageview寬高
final int vwidth = getWidth() - mPaddingLeft - mPaddingRight;//
final int vheight = getHeight() - mPaddingTop - mPaddingBottom;
final boolean fits = (dwidth < 0 || vwidth == dwidth)
&& (dheight < 0 || vheight == dheight);
if (dwidth <= 0 || dheight <= 0 || ScaleType.FIT_XY == mScaleType) {
mDrawable.setBounds(0, 0, vwidth, vheight);
mDrawMatrix = null;
} else {
mDrawable.setBounds(0, 0, dwidth, dheight);
if (ScaleType.MATRIX == mScaleType) {//樣式應用自定義MATRIX
if (mMatrix.isIdentity()) {
mDrawMatrix = null;
} else {
mDrawMatrix = mMatrix;
}
}
if (ScaleType.CENTER == mScaleType) {
// Center bitmap in view, no scaling.
mDrawMatrix = mMatrix;
mDrawMatrix.setTranslate(Math.round((vwidth - dwidth) * 0.5f),
Math.round((vheight - dheight) * 0.5f));
}
複製代碼
能夠看到最終的實現用到了Drawable類和Matrix類的方法。前者你們都很熟悉,就是咱們設置的要顯示的圖片,而Matrix叫作矩陣,是一個專門用來處理圖形變換中的重要工具類,熟悉自定義View的同窗應該對它不陌生,canvas.setMatrix(matrix)
能夠作出不少獨特效果來。而咱們今天的主角是ImageView
,因此沒錯imageView
也有這個方法:spa
經過上述方法咱們就能將本身定義的Matrix應用到ImageView中。能夠看到源碼,要使這個方法生效,ScaleType必定要設爲MATRIX,否則執行完本身的變換後仍是會執行樣式本身的變換,至關於沒執行。code
FIT_XY
的實現很簡單,就用到了setBounds(int left, int top, int right, int bottom)
,這個四參數指的是drawable的繪製區域。 center
用到了postTranslate(float dx, float dy)
,將Drawable
移到ImageView中間,由於沒有其餘處理,圖片若是比ImageView大,那麼多餘的區域就會被裁剪掉,不顯示了。cdn
說了這麼多來個小栗子來加深理解吧: 仍是上面那張圖片,scaleType設爲matrix,咱們再加一個按鈕,點擊事件以下:blog
int m = 20;
//平移
private void onClick(View v) {
Matrix matrix = new Matrix();
matrix.postTranslate(m, m);
imageView.setImageMatrix(matrix);
m = m + 3;
}
複製代碼
來看看效果:
經過改變postTranslate
參數的值咱們就能改變圖片在View中繪製的起始位置。 固然不會這麼簡單。Matrix還有其餘方法: postRotate(float degrees, float px, float py)
//旋轉: 咱們仿照center的處理將圖片移到ImageView中心,而後進行旋轉:
int m = 20;
//旋轉
private void onClick(View v) {
Matrix matrix = new Matrix();
int width = imageView.getDrawable().getIntrinsicWidth();
int height = imageView.getDrawable().getIntrinsicHeight();
final int vwidth = imageView.getWidth();
final int vheight = imageView.getHeight();
matrix.setTranslate(Math.round((vwidth - width) * 0.5f),
Math.round((vheight - height) * 0.5f));
matrix.postRotate(m, vwidth * 0.5f, vheight * 0.5f);
imageView.setImageMatrix(matrix);
m = m + 3;
}
複製代碼
看看效果:
還有一種是錯切,將圖片的形狀改變: void setSkew(float kx, float ky)
實際用到的比較少,就不貼代碼了,直接看效果吧:
說了這麼多,這篇文章就是給你們介紹了android:scaleType
的自定義用法,當遇到Imageview預設的顯示模式不能知足咱們現有需求的時候(好比我就遇到原圖按照原來的大小居底部顯示,若是原圖的大小超過了ImageView的大小,那麼就剪裁掉多餘部分,保留底部,和centerCrop裁剪四周有所不一樣),咱們就能夠動態設置本身的matrix來自定義顯示效果。固然若是你常常要用到這種方式的時候,能夠繼承Imageview,封裝這些自定義樣式。