Glide centerCrop fitCenter和ImageView的scaleType的关系,互相影响的探讨

转载请注明出处,谢谢http://blog.csdn.net/harryweasley/article/details/71526216

在使用Glide的过程中,你一定见过下面的代码方式:

        ImageView imageView = (ImageView) findViewById(R.id.image);
        imageView.setScaleType(ImageView.ScaleType.FIT_START);
        Glide.with(this).load("https://zhitu.isux.us/assets/img/imgSample/test-60.jpg").fitCenter().into(imageView);

ImageView有自己的scaleType,Glide又有自己的fitCenter或者centerCrop,那这两者的关系到底是怎么样的,是否会互相影响呢,本篇博客就来探讨这个问题的。

Glide提供了两个标准选项来处理图像的显示问题,一个是centerCrop一个是fitCenter:

CenterCrop

CenterCrop()是一个裁剪技术,即缩放图像让它填充到 ImageView 界限内并且裁剪额外的部分。ImageView 会被完全填充,但图像可能不会完整显示。

FitCenter

fitCenter() 是一个裁剪技术,即缩放图像让图像都测量出来等于或小于 ImageView 的边界范围。该图像将会完全显示,但可能不会填满整个 ImageView。

看本篇博客开头的那三句代码,我们先看Glide源码的fitCenter方法:
com.bumptech.glide.DrawableRequestBuilder

public DrawableRequestBuilder<ModelType> fitCenter() {
        return transform(glide.getDrawableFitCenter());
    }
public DrawableRequestBuilder<ModelType> transform(Transformation<GifBitmapWrapper>... transformation) {
        super.transform(transformation);
        return this;
    }

DrawableRequestBuilder的transform调用父类的transform,继续看父类的源码:
com.bumptech.glide.GenericRequestBuilder

/**
     * Transform resources with the given {@link Transformation}s. Replaces any existing transformation or
     * transformations.
     * 用给定的Transformation转换资源。替换任何已存在的transformation或者transformations。⭐1
     * @param transformations the transformations to apply in order.
     * @return This request builder.
     */
    public GenericRequestBuilder<ModelType, DataType, ResourceType, TranscodeType> transform(
            Transformation<ResourceType>... transformations) {
        //这个变量之后要用到,请留意 ⭐2
        isTransformationSet = true;
        if (transformations.length == 1) {
            transformation = transformations[0];
        } else {
            transformation = new MultiTransformation<ResourceType>(transformations);
        }

        return this;
    }

我们看到将fitCenter的对象glide.getDrawableFitCenter()加入到了transformation;同理,如果是centerCrop,那么会将glide.getDrawableCenterCrop()加入到transformtion,之后Glide会根据传入的transformtion以某个图片处理格式来从网络下载图片。

fitCenter源码先分析到这里,现在我们进入Glide的源码查看into方法都做了哪些操作,

com.bumptech.glide.GenericRequestBuilder

public Target<TranscodeType> into(ImageView view) {
        Util.assertMainThread();
        if (view == null) {
            throw new IllegalArgumentException("You must pass in a non null View");
        }

        if (!isTransformationSet && view.getScaleType() != null) {
            switch (view.getScaleType()) {
                case CENTER_CROP:
                    applyCenterCrop();
                    break;
                case FIT_CENTER:
                case FIT_START:
                case FIT_END:
                    applyFitCenter();
                    break;
                //$CASES-OMITTED$
                default:
                    // Do nothing.
            }
        }

        return into(glide.buildImageViewTarget(view, transcodeClass));
    }

首先看这个判断 if (!isTransformationSet && view.getScaleType() != null)
由ImageView的源码可知,每一个ImageView都有个默认的fitCenter的scaleType,ImageView的源码:

 public ImageView(Context context) {
        super(context);
        initImageView();
    }

    public ImageView(Context context, @Nullable AttributeSet attrs) {
        this(context, attrs, 0);
    }

    public ImageView(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
        this(context, attrs, defStyleAttr, 0);
    }

    public ImageView(Context context, @Nullable AttributeSet attrs, int defStyleAttr,
            int defStyleRes) {
        super(context, attrs, defStyleAttr, defStyleRes);

        initImageView();
        ...
        }
    private void initImageView() {
         ...
         //将FIT_CENTER设置为默认的scaleType
         mScaleType = ScaleType.FIT_CENTER;
         ...
      }

我们可以看到,每个ImageView都会默认将 mScaleType = ScaleType.FIT_CENTER

由以上得知unview.getScaleType() != null一定为true,

这里的isTransformationSet 是不是很熟悉,没错,就是上面⭐2说的要用到的那个变量,

从这里可以看出如果Glide如果执行了centerCrop或者fitCenter,那么 if (!isTransformationSet && view.getScaleType() != null)里面的代码将不会执行。

那么如果Glide没有执行centerCrop和fitCenter,if (!isTransformationSet && view.getScaleType() != null)里面的代码将会执行,我们会看到,他根据传入的ImageView的scaleType做了两件事情,执行applyCenterCrop()或者applyFitCenter(),我们去源码中看看:

com.bumptech.glide.GenericRequestBuilder

 void applyCenterCrop() {
        // To be implemented by subclasses when possible.
    }

    void applyFitCenter() {
        // To be implemented by subclasses when possible.
    }

我们看到是一个空方法,具体实现是在子类中实现的,那我们就去子类DrawableRequestBuilder中看看,源码如下:
com.bumptech.glide.DrawableRequestBuilder

 @Override
    void applyFitCenter() {
        fitCenter();
    }

    @Override
    void applyCenterCrop() {
        centerCrop();
    }

看到这里有没有恍然大悟,从这里我们可以到一个结论,如果我们没有给Glide手动添加centerCrop和fitCenter方法,Glide会根据传入的ImageView的scaleType来自己去执行centerCrop或者fitCenter方法。(我知道你一定会说,scaleType不仅仅是CENTER_CROP,FIT_CENTER,FIT_START,FIT_END,这个我知道的哈,后面还会继续说的。)

你以为这就是ImageView的scaleType在Glide里的作用吗,错了,这个scaleType在最后将图片设置到ImageView还起了一次作用。
在Glide获取到图片资源,会执行ImageView的setImageDrawable将图片设置进去,源码如下:

com.bumptech.glide.request.target.GlideDrawableImageViewTarget

/**
     * Sets the drawable on the view using
     * {@link android.widget.ImageView#setImageDrawable(android.graphics.drawable.Drawable)}.
     *
     * @param resource The {@link android.graphics.drawable.Drawable} to display in the view.
     */
    @Override
    protected void setResource(GlideDrawable resource) {
        view.setImageDrawable(resource);
    }

综上可以总结一个结论:ImageView的scaleType在Glide加载图片到ImageView的过程中至少起一次作用。

经过我的多次测试,得出一个结论,如果ImageView的scaleType不是centerCrop,并且Glide没有调用centerCrop方法,那么Glide从服务器获取的图片格式是fitCenter格式,最终设置到ImageView图片的格式,还要根据ImageView的scaleType才能确定。

不知道,你是否注意到⭐1的标志,那边的一个注释说明了一个问题,如果Glide同时执行了centerCrop和fitCenter方法,那么谁在后面,就以谁的格式下载图片。
打个比方,代码如下:

 Glide.with(this).load("https://zhitu.isux.us/assets/img/imgSample/test-60.jpg").fitCenter().centerCrop().into(imageView);

那么从网络下载到的图片是以centerCrop格式下载到的。

本篇博客最后,分析一下ImageView的8个scaleType:

CENTER将图像置于视图中,但不执行缩放。
CENTER_CROP缩放图像(保持图像的纵横比),使图像的尺寸(宽度和高度)都等于或大于视图的相应尺寸(减去填充)。所以会占满ImageView,但是可能会显示不完全图片
CENTER_INSIDE缩小图像均匀(保持图像的纵横比),使图像的尺寸(宽度和高度)都等于或小于视图的对应尺寸(减去填充)。
FIT_CENTER保持原图的纵横比计算一个比例,但是也要确保原图完全放入目标视图内, 至少一个轴(X或Y)将精确配合。 结果以目标视图为中心。默认属性
FIT_END保持原图的纵横比计算一个比例,但是也要确保原图完全放入目标视图内, 至少一个轴(X或Y)将精确配合。END将结果对齐到目标视图右下边缘。
FIT_START保持原图的纵横比计算一个比例,但是也要确保原图完全放入目标视图内, 至少一个轴(X或Y)将精确配合。 START将结果对齐到目标视图左上边缘。
FIT_XY独立地缩放X和Y,使原图与目标完全匹配。 这可能会改变原图的宽高比。
MATRIX绘制时使用图像矩阵进行缩放。

最后再次总结一下本篇博客:

Glide从网络下载到的图片,会按照两种格式来下载,一种是centerCrop,一种是fitCenter,一旦下载下来后,设置到ImageView的时候,还会根据ImageView的scaleType来确立图片位置。
如果Glide没有手动调用过centerCrop和fitCenter,那么Glide从网络下载的图片格式,由ImageView的scaleType决定,如果scaleType是center_crop,那么Glide以centerCrop下载图片,如果scaleType是 FIT_CENTER,FIT_START,FIT_END,那么Glide以fitCenter格式下载图片。不过根据我这边的测试结果发现,如果scaleType是CENTER,CENTER_INSIDE,MATRIX,Glide也是以fitCenter格式下载图片的。

参考文章:
https://developer.android.com/reference/android/widget/ImageView.ScaleType.html
https://futurestud.io/tutorials/glide-image-resizing-scaling
http://www.jianshu.com/p/96fc561eada1

  • 3
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
智慧校园整体解决方案是响应国家教育信息化政策,结合教育改革和技术创新的产物。该方案以物联网、大数据、人工智能和移动互联技术为基础,旨在打造一个安全、高效、互动且环保的教育环境。方案强调从数字化校园向智慧校园的转变,通过自动数据采集、智能分析和按需服务,实现校园业务的智能化管理。 方案的总体设计原则包括应用至上、分层设计和互联互通,确保系统能够满足不同用户角色的需求,并实现数据和资源的整合与共享。框架设计涵盖了校园安全、管理、教学、环境等多个方面,构建了一个全面的校园应用生态系统。这包括智慧安全系统、校园身份识别、智能排课及选课系统、智慧学习系统、精品录播教室方案等,以支持个性化学习和教学评估。 建设内容突出了智慧安全和智慧管理的重要性。智慧安全管理通过分布式录播系统和紧急预案一键启动功能,增强校园安全预警和事件响应能力。智慧管理系统则利用物联网技术,实现人员和设备的智能管理,提高校园运营效率。 智慧教学部分,方案提供了智慧学习系统和精品录播教室方案,支持专业级学习硬件和智能化网络管理,促进个性化学习和教学资源的高效利用。同时,教学质量评估中心和资源应用平台的建设,旨在提升教学评估的科学性和教育资源的共享性。 智慧环境建设则侧重于基于物联网的设备管理,通过智慧教室管理系统实现教室环境的智能控制和能效管理,打造绿色、节能的校园环境。电子班牌和校园信息发布系统的建设,将作为智慧校园的核心和入口,提供教务、一卡通、图书馆等系统的集成信息。 总体而言,智慧校园整体解决方案通过集成先进技术,不仅提升了校园的信息化水平,而且优化了教学和管理流程,为学生、教师和家长提供了更加便捷、个性化的教育体验。
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值