1. 程式人生 > >Android ImageView中scaleType="centerCrop"實現左對齊效果

Android ImageView中scaleType="centerCrop"實現左對齊效果

在開發過程中,用於顯示圖片大家用的比較多的應該是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"展示圖片,左對齊效果