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"展示图片,左对齐效果

猜你喜欢

转载自blog.csdn.net/weixin_37618354/article/details/84547325
今日推荐