玩转 ImageView.ScaleType:图片的缩放与裁剪技巧

ImageView 是最常用的控件之一,它用于展示各种类型的图片。为了能够根据需求调整图片的显示效果,Android 提供了 ImageView.ScaleType 枚举,它可以灵活地控制图片如何适应 ImageView 的尺寸。本文将探讨 ImageView.ScaleType 的不同选项、使用场景及其实现技巧。

ImageView 是最常用的控件之一,它用于展示各种类型的图片。为了能够根据需求调整图片的显示效果,Android 提供了 ImageView.ScaleType 枚举,它可以灵活地控制图片如何适应 ImageView 的尺寸。本文将探讨 ImageView.ScaleType 的不同选项、使用场景及其实现技巧。

什么是 ImageView.ScaleType?

ImageView.ScaleType 是一个枚举类,它定义了不同的缩放方式,用于控制图片如何在 ImageView 中展示。

public enum ScaleType {
      MATRIX      (0),
      FIT_XY      (1),
      FIT_START   (2),
      FIT_CENTER  (3),
      FIT_END     (4),
      CENTER      (5),
      CENTER_CROP (6),
      CENTER_INSIDE (7);

      ScaleType(int ni) {
         nativeInt = ni;
      }
      final int nativeInt;
}

先看下源图:

图片1尺寸是1200x857,且宽 > 高;图片2尺寸967x1301,且宽<高;图片3尺寸60x60,且宽=高。XML代码如下:

<LinearLayout
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:layout_centerInParent="true"
    android:orientation="horizontal"
    android:gravity="center">

    <ImageView
        android:id="@+id/iv_1"
        android:layout_width="120dp"
        android:layout_height="120dp"
        android:background="@color/gray_normal"
        android:src="@drawable/icon_cat_w" />

    <ImageView
        android:id="@+id/iv_2"
        android:layout_width="120dp"
        android:layout_height="120dp"
        android:background="@color/gray_normal"
        android:layout_marginStart="10dp"
        android:src="@drawable/icon_cat_h" />

    <ImageView
        android:id="@+id/iv_3"
        android:layout_width="120dp"
        android:layout_height="120dp"
        android:layout_marginStart="10dp"
        android:background="@color/gray_normal"
        android:src="@drawable/chat_ask_message_error" />
</LinearLayout>

我的测试机上density = 3,而ImageView控件的目标宽高都是120dp,即宽高都是360x360。

FIT_XY

图片完全填充 ImageView,不保持原始宽高比,可能会导致图片拉伸或压缩变形。本质上使用Matrix.ScaleToFit.FILL来实现,上面代码中加上android:scaleType="fitXY",效果如下:

FIT_START

等比缩放图片,使其宽高都不超过 ImageView 的尺寸,然后左上角对齐。上面代码中加上android:scaleType="fitStart",效果如下:

FIT_CENTER

等比缩放图片,使其宽高都不超过 ImageView 的尺寸,然后居中显示。上面代码中加上android:scaleType="fitCenter",效果如下:

FIT_END

等比缩放图片,使其宽高都不超过 ImageView 的尺寸,然后对齐到底部或右侧。上面代码中加上android:scaleType="fitEnd",效果如下:

CENTER

不缩放图片,直接居中显示,如果图片大于 ImageView,超出的部分不会显示。上面代码中加上android:scaleType="center",效果如下:

CENTER_CROP

等比放大图片,确保 ImageView 填满,超出的部分裁剪掉,居中对齐,适用于头像、封面图等,填满 ImageView 且保持图片比例。上面代码中加上android:scaleType="centerCrop",效果如下:

CENTER_INSIDE

等比缩小图片,确保整个图片显示在 ImageView 里。如果图片小于 ImageView,不会放大。上面代码中加上android:scaleType="fitStart",效果如下:

MATRIX

完全由开发者控制,允许精确地设置图片的缩放、旋转、平移等变换。ScaleType.MATRIX不会自动进行缩放或平移,开发者需要通过 Matrix 来手动调整。默认上面代码中加上android:scaleType="matrix",效果如下:

特殊需求:从顶部裁剪图片

在某些情况下,你可能希望图片从顶部开始展示,裁剪掉底部溢出的部分。默认的CENTER_CROP会居中裁剪图片,但如果希望图片从顶部开始裁剪,可以使用scaleType="matrix",然后通过 Matrix 来控制,代码如下:

imageView.post {
    val drawable = imageView.drawable
    drawable?.let {
        val matrix = Matrix()
        //计算缩放比例,确保宽度填充满 ImageView
        val scale = imageView.width.toFloat() / it.intrinsicWidth
        matrix.setScale(scale, scale)
        //不平移,确保图片从顶部开始展示
        matrix.postTranslate(0f0f)
        //应用 Matrix 到 ImageView
        imageView.imageMatrix = matrix
    }
}

执行效果:


可以看到结果中,图片1 因为宽>高,所以会直接从上往下排完;而图片2 宽<高,所以从上往下排列后,底部被裁剪了;图片3 宽等于高,所以还是可以完全展示。

结论

  • • 以FIT_开头的4种(fitCenter、fitXY、fitStart、fitEnd),都可以对图片进行缩放;
  • • 以CENTER_开头的3种(center、centerCrop、centerInside),都可以居中显示;图片中心点与ImageView中心点重叠;
  • fitCentercenterInside都可以居中展示,两者区别:centerInside 只缩小,不放大;fitCenter 可放大可缩小。
  • MATRIX是最灵活的 ScaleType,能够完全控制图片的缩放、平移和旋转,适合需要自定义展示的场景。

ScaleType
缩放方式
是否填满
ImageView是否裁剪
对齐方式
MATRIX
自定义
由 Matrix 决定
FIT_XY
拉伸填充
是(可能会变形)
填充整个 ImageView
FIT_START
等比缩放
顶部/左侧对齐
FIT_CENTER
等比缩放
居中对齐
FIT_END
等比缩放
底部/右侧对齐
CENTER
不缩放
可能裁剪
居中对齐
CENTER_CROP
等比放大
可能裁剪
居中对齐
CENTER_INSIDE
等比缩小
居中对齐

选择合适的 ScaleType,可以大大提高图片显示的效果和用户体验。理解并灵活应用这些选项,可以帮助我们更好地处理不同的图片展示需求。



文章来源:公众号
作者:代码说

原文地址:玩转 ImageView.ScaleType:图片的缩放与裁剪技巧

来源: 公众号
本文观点不代表码客-全球程序员交流社区立场,不承担法律责任,文章及观点也不构成任何投资意见。

赞 ()

相关推荐

  • 置顶 开发项目接单群,免费入群了

    无论你是Android、ios、java、php,或者你是产品经理、老板,都可以免费入群接单或者发布项目,全程不收取任何费用。

    2025年02月21日 15点27分
  • Android 布局优化:利用 ViewStub 和 Merge 提升性能

    提升界面渲染性能是一个至关重要的任务,尤其是在应用启动时,渲染界面需要快速且流畅。为了优化 UI 渲染速度,Android 提供了许多工具,其中 ViewStub 和 Merge 标签是非常有效的布局优化手段。通过合理使用这两者,可以延迟加载不必要的视图、减少布局的嵌套层级,从而加速应用的启动和运行。

    2025年02月26日 22点47分
  • 玩转 ImageView.ScaleType:图片的缩放与裁剪技巧

    ImageView 是最常用的控件之一,它用于展示各种类型的图片。为了能够根据需求调整图片的显示效果,Android 提供了 ImageView.ScaleType 枚举,它可以灵活地控制图片如何适应 ImageView 的尺寸。本文将探讨 ImageView.ScaleType 的不同选项、使用场景及其实现技巧。

    2025年02月26日 22点45分
  • Android加快你的编译速度

    工欲善其事,必先利其器。如果每次运行项目都要花费5-10分钟,那人的心态都要崩了。

    2025年02月25日 15点40分
  • Flutter多渠道打包的解决方案(walle)

    我们的应用集成了TalkingData这个第三方工具来统计日活、事件等,需要在应用启动时初始化SDK,这个时候需要传入当前渠道,以便数据的统计。 由于最开始是用脚本一个个打包,一直想解决打包过慢的问题,但是网上大多教程是基于命令行参数或flavor,实质上并没有根本解决打包效率的问题。直到发现了文章的主角 walle。

    2025年02月25日 15点36分
  • Android-分享一个对RecyclerView二次封装的库(EasyRecyclerView)

    在日常的Android开发当中,我们肯定会有使用到RecyclerView的需求,这里分享一个对RecyclerView二次封装的开源库——EasyRecyclerView。它基本上满足基本的开发需求,希望能帮看文章的小伙伴提高开发效率。

    2025年02月25日 15点31分
  • Android原生系统真的那么好用吗?安卓原生系统吊打其他系统,因为有Google-Play,所以应用都是纯净的?

    实际方面,原生 Android 的最大优势是更新快速,对供应商特别是 Android 上游的补丁的合并速度非常快,几乎总能在第一时间更新。因为系统越原生,更新的代价就越小。反之,如果一个停止更新的原生 Android 其实是没有多大意义的,它失去了它最大的优势。

    2025年02月25日 15点30分
  • Application 作为 Dialog 的 Context?小心踩坑!

    大家好,相信大家在使用 Dialog 时,都有一个非常基本的认知:就是 Dialog 的 context 只能是 Activity,而不能是 Application,不然会导致弹窗崩溃:

    2025年02月25日 15点25分
  • Android 应用的线程世界:最少需要几个线程才能启动?

    这篇文章主要介绍了 Android App 中的多种线程,包括守护线程(如 Signal Catcher 等)、渲染线程、主线程、三方线程(如 OkHttp、Glide、ARouter 相关线程)等,还提及三方库中线程池的情况及可能存在的问题。

    2025年02月25日 15点13分
  • Android 复杂项目崩溃率收敛至0.01%实践

    在我们的项目中,每个版本发布之后,我们会创建一个opt分支,用于修复线上崩溃以及业务逻辑BUG。

    2025年02月25日 15点11分
  • Android 能悄悄知道用户截屏?这里有你想要的答案

    很多应用在当你截屏的时候能够感知到,并提示你是否要发送截屏等等。

    2025年02月25日 15点07分
  • 科大讯飞讯飞星火API能力免费开放,引领大模型商业化新篇章

    合肥本土科技巨头科大讯飞传来振奋人心的消息:讯飞星火API能力正式向公众免费开放,其中,讯飞星火Lite API更是实现了永久免费。这一举措无疑为整个行业注入了新的活力,也彰显了科大讯飞在大模型商业化进程中的坚定决心。

    2025年02月21日 15点57分
  • 一木林接入AI大模型,实现智能体功能

    一木林——全能型AI电子工具箱。这是一款集多功能于一体的工具类应用,凭借小巧的体积与全面且强大的功能,赢得了极高的口碑。应用内汇聚了上百款实用工具,诸如指南针、计算器、分贝仪等,一应俱全。如今,一木林已携手星火AI大模型,实现了AI对话与智能体的创新功能。

    2025年02月21日 15点42分
  • PrivacySentry:隐私政策守护利器

    近年来,工信部对APP个人隐私要求越来越多,之后各大应用市场也开始要求,有违规情况的会导致APP下架或者无法上架。这不,我的app就因为三方SDK频繁获取Android ID 导致无法上架,等SDK商场更新也很浪费时间,所以只能想办法去处理这件事,好在找到了PrivacySentry这个神器,可规避应用市场上架合规检测的大部分问题

    2025年02月18日 23点20分
  • Kotlin协程:MutableSharedFlow的实现原理

    在Koltin协程:异步热数据流的设计与使用中,提到了可以通过MutableSharedFlow方法创建一个MutableSharedFlow接口指向的对象,代码如下:

    2025年02月18日 11点03分
  • 探索Markdown之父John Gruber对Markdown的看法

    Markdown的缔造者——约翰·格鲁伯,其形象正如上方头像所示。不禁让人遐想,国外的大师们是否都偏爱蓄须? 约翰·格鲁伯,1973年出生于美国宾夕法尼亚州,他是一位才华横溢的作家、博主、UI设计师,更是Markdown的创始人。他毕业于Drexel University(卓克索大学),并获得了计算机科学学士学位。在职业生涯中,他曾在Joyent公司任职,为大型企业提供了基础架构和平台服务。自2002年起,他开始撰写备受欢迎的科技博客《Daring Fireball》,并主持了知名的播客节目The Talk Show。2013年,他与两位友人共同创立了Q Branch,并开发了Vesper笔记应用。

    2025年02月18日 10点52分

发表回复

评论列表

点击查看更多

    联系我们

    在线咨询: QQ交谈

    微信:dxmcpjl

    邮件:1529097251#qq.com

    工作时间:周一至周五,9:30-18:30,节假日休息

    微信