imageview代码示例怎么用?,有哪些注意事项?

ImageView是Android开发中最基础的图片显示控件,核心用法就是通过setImageResource()setImageBitmap()把图片资源塞进去,配合ScaleType控制缩放模式,但真正写好它需要处理内存复用、加载策略和裁剪细节。

很多初级开发者在ListView或RecyclerView里直接加载本地图片,结果滑动卡顿甚至OOM崩溃,问题不在ImageView本身,而是没有理解它的工作边界,下面直接拆解日常开发里最常用的几个代码场景,从基础属性到进阶封装,每一步都给出可复制的写法。

29使用代码修改ImageView
加载中
29使用代码修改ImageView

ImageView基础用法与src和background的区别

ImageView在XML布局里最常用的属性是srcbackground,新手经常混用,但两者的行为差异很大。

src设置的是图片内容,会按照scaleType属性缩放;background设置的是背景,默认拉伸填充整个View区域,如果同时设置两者,前景图会盖在背景上面,实际开发中,背景通常放纯色或渐变Drawable,内容图放src,这样逻辑清晰,也方便做占位图。

<ImageView
    android:id="@+id/iv_avatar"
    android:layout_width="80dp"
    android:layout_height="80dp"
    android:src="@drawable/ic_default_avatar"
    android:background="@drawable/bg_circle_white"
    android:scaleType="centerCrop" />

scaleType是最容易忽略的属性,它决定了图片在View里怎么缩放,常用的几个值:

  • centerCrop:按比例放大或缩小使得图片填满View,超出部分裁剪,适合头像、封面图。
  • fitCenter:按比例缩放使得整张图完整显示在View内,可能留白,适合展示完整图片。
  • fitXY:不保持比例,拉伸填满View,容易变形,一般不用。
  • center:不做缩放,居中显示原图,大图会溢出不显示。

Java/Kotlin代码里动态设置也一样:

imageView.setImageResource(R.drawable.ic_place_holder)
imageView.scaleType = ImageView.ScaleType.CENTER_CROP

ImageView加载大图OOM怎么解决

这是百度搜索里出现频率很高的长尾词,“imageview加载大图oom怎么解决”,一张几MB的图片直接setImageResource(),在内存里解码后可能膨胀到几十MB,低端机上必崩。

行业共识是:不要在UI线程直接解码大图,正确做法是先读取图片的尺寸信息,再根据ImageView的实际大小进行采样压缩。

imageview代码示例怎么用?,有哪些注意事项?

fun loadSampledBitmap(resId: Int, reqWidth: Int, reqHeight: Int): Bitmap {
    val boundsOptions = BitmapFactory.Options().apply {
        inJustDecodeBounds = true
    }
    BitmapFactory.decodeResource(resources, resId, boundsOptions)
    val inSampleSize = calculateInSampleSize(boundsOptions, reqWidth, reqHeight)
    val decodeOptions = BitmapFactory.Options().apply {
        this.inSampleSize = inSampleSize
        inPreferredConfig = Bitmap.Config.RGB_565
    }
    return BitmapFactory.decodeResource(resources, resId, decodeOptions)
}
fun calculateInSampleSize(options: BitmapFactory.Options, reqWidth: Int, reqHeight: Int): Int {
    val (height: Int, width: Int) = options.outHeight to options.outWidth
    var inSampleSize = 1
    if (height > reqHeight || width > reqWidth) {
        val halfHeight = height / 2
        val halfWidth = width / 2
        while (halfHeight / inSampleSize >= reqHeight && halfWidth / inSampleSize >= reqWidth) {
            inSampleSize = 2
        }
    }
    return inSampleSize
}

这个calculateInSampleSize方法就是业内常用的采样率计算逻辑。inJustDecodeBounds为true时只读尺寸不解码像素,开销极小,拿到采样率后再正式解码,内存占用可以降到原来的1/4甚至1/8。

inPreferredConfig设为RGB_565,每个像素只占2字节,相比默认的ARGB_8888少一半内存,但注意,RGB_565不支持透明通道,带透明度的PNG图片会显示黑色背景,需要保留透明度的场景不要用这个配置。

ImageView和Glide怎么选:对比与配合

很多开发者纠结“imageview和glide区别”,其实两者不是替代关系,Glide本身就是基于ImageView工作的,Glide负责加载、缓存、解码,最后把Bitmap或者Drawable设置到ImageView上。

选型建议:

  • 简单场景、少量本地图片:直接用ImageView配合BitmapFactory,不引入额外依赖。
  • 网络图片、列表加载、需要缓存:用Glide,它能解决大部分性能问题。
Glide.with(this)
    .load("https://example.com/image.jpg")
    .placeholder(R.drawable.ic_default)
    .error(R.drawable.ic_error)
    .override(300, 300)
    .centerCrop()
    .into(imageView)

override()指定加载尺寸,源码内部会先查缓存,再决定是否压缩,列表滑动时Glide自动复用ImageView的bitmap,避免GC抖动。实际项目中,90%以上的图片加载任务交给Glide是稳妥的,自己写原生解码容易踩坑。

但Glide也不是万能,如果图片需要频繁修改像素(比如拍照后的水印合成),还是得用原生Bitmap操作,Glide适合展示,不适合加工。

imageview代码示例怎么用?,有哪些注意事项?

ImageView实现圆角和圆形图片的代码示例

UI设计里圆角头像、圆形logo是标配,实现方式有两种:原生ShapeableImageView或者自定义BitmapShader

ShapeableImageView是Material库提供的控件,代码简洁,适合圆角固定不变的场景

<com.google.android.material.imageview.ShapeableImageView
    android:id="@+id/iv_round"
    android:layout_width="100dp"
    android:layout_height="100dp"
    android:src="@drawable/ic_avatar"
    app:shapeAppearanceOverlay="@style/ShapeAppearance.App.CornerSize" />

对应样式:

<style name="ShapeAppearance.App.CornerSize">
    <item name="cornerSize">16dp</item>
</style>

圆形只要把cornerSize设为50%即可,这种方式处理静态UI高效,但动态改圆角大小比较麻烦。

自定义BitmapShader适合需要动态控制圆角程度的场景,核心思路是,把Bitmap作为Shader绘制到圆角矩形路径里。

class RoundImageView @JvmOverloads constructor(
    context: Context,
    attrs: AttributeSet? = null,
    defStyleAttr: Int = 0
) : AppCompatImageView(context, attrs, defStyleAttr) {
    private val path = Path()
    private val paint = Paint(Paint.ANTI_ALIAS_FLAG)
    private var radius = 0f
    override fun onDraw(canvas: Canvas) {
        val bitmap = getBitmapFromDrawable() ?: return
        val shader = BitmapShader(bitmap, Shader.TileMode.CLAMP, Shader.TileMode.CLAMP)
        paint.shader = shader
        path.reset()
        path.addRoundRect(RectF(0f, 0f, width.toFloat(), height.toFloat()), radius, radius, Path.Direction.CW)
        canvas.drawPath(path, paint)
    }
}

这段代码里的getBitmapFromDrawable()需要自己实现,从drawable里取出Bitmap,注意Glide加载的图片要等回调拿到Bitmap后再设置给自定义View。

ImageView在RecyclerView中的复用与性能优化

列表滑动卡顿的常见原因就是ImageView在复用过程中频繁触发解码。RecyclerView的ViewHolder复用机制下,ImageView被反复setImageResource,每次都是重新解码,这是性能瓶颈

优化思路有三个层面:

  • 使用Glide并开启缓存,diskCacheStrategy设为ALL,避免重复网络请求。
  • onBindViewHolder里使用Glide.with(holder.itemView.context).load(...).into(holder.imageView)

    imageview代码示例怎么用?,有哪些注意事项?

    ,不要自己new Bitmap。

  • 图片尺寸提前裁剪,列表缩略图用override()固定到列表项大小,避免加载原图。
override fun onBindViewHolder(holder: ViewHolder, position: Int) {    val item = dataList[position]    Glide.with(holder.itemView.context)        .load(item.thumbnailUrl)        .override(200, 200)        .centerCrop()        .into(holder.imageView)}

固定尺寸的override配合centerCrop,是列表图片性能优化的标准写Fa,Glide会先查内存缓存,再查磁盘缓存,最后才走网络,滑动时上一个Item的加载请求会被自动取消,不会出现图片错位。

图片错位问题排查

错位的根源是ViewHolder复用导致旧图片还没来得及显示,新请求就到了,Glide的into()方法内部会处理这种情况,但如果你用原生setImageBitmap,必须在绑定数据时先清空ImageView:

holder.imageView.setImageDrawable(null)

这一行放在加载新图之前,能避免大部分错位问题。

Q&A:ImageView高频疑问解答

ImageView的adjustViewBounds属性有什么用

当ImageView的宽高至少有一个是wrap_content时,adjustViewBounds设为true可以让ImageView的尺寸根据图片的宽高比自动调整,典型的场景是聊天界面里的图片消息,宽度固定,高度根据图片比例自适应,注意,这个属性只在src有效时起作用,对background无效。

ImageView设置图片后内存仍然偏高怎么办

先用BitmapFactory.OptionsinJustDecodeBounds检查图片原始尺寸,如果原始尺寸是4000×3000,而显示区域只有200×200,采样率至少设置为8,另外检查是否引用了大图资源,Android drawable目录的密度限定也会影响解码后的像素尺寸,把图片放到drawable-nodpi可以避免自动缩放,如果用了Glide,确认override()设置了合理的尺寸,并且skipMemoryCache()没有被误调用。

Glide加载的图片怎么转成Bitmap操作

into()之前用addListener或者在asBitmap()回调里获取,推荐用asBitmap()配合into(new SimpleTarget,但SimpleTarget已废弃,新版本用CustomTarget,拿到Bitmap后做水印、裁剪、滤镜处理,再setImageBitmap给ImageView,注意CustomTarget持有外部Context时需要处理生命周期,避免内存泄漏。

首发原创文章,作者:王坚‌,如若转载,请注明出处:https://test.idctop.com/article/556433.html

(0)
服务器内存如何查看?,linux怎么查看内存使用情况?
上一篇 2026年8月8日 09:27
importnew是什么网站,Java新手学习网站哪里找?
下一篇 2026年8月8日 09:29

相关推荐

  • 房地产网站开发公司哪家好?如何选择靠谱的建站服务商

    选择专业的房地产网站开发公司,关键在于考察其是否具备“高并发承载能力”、“移动端自适应体验”以及“CRM系统深度集成”这三大核心能力,这直接决定了获客转化率与品牌信任度,在2026年的数字营销环境中,房地产行业的竞争早已从单纯的线下拓客转向线上流量的精细化运营,传统的展示型官网已经无法支撑复杂的业务需求,开发商……

    2026年7月8日
    16000
  • 服务器IP地址变更后有什么影响?,如何解决

    服务器IP地址变更后,首要任务是更新DNS解析记录并全面排查代码及配置文件中的硬编码IP,确保各项服务平滑过渡且SEO排名不流失,服务器ip地址变更后如何快速恢复网站访问当咱们拿到一个新IP,别急着把老服务器关机,你得先让互联网知道你搬家了,这就好比换了手机号,得先去营业厅把呼叫转移办好,否则别人打过来全是空号……

    2026年7月17日
    1700
  • 服务呼叫中心怎么搭建?企业呼叫中心系统搭建方案

    服务呼叫中心的核心价值在于通过智能化技术整合多渠道客户交互,实现从被动接听向主动服务与数据驱动营销的转型,从而显著降低运营成本并提升客户满意度,呼叫中心的技术演进与核心架构解析传统的呼叫中心往往被视为单纯的成本中心,主要承担电话接听功能,随着云计算和人工智能技术的成熟,现代呼叫中心已演变为集语音、文本、视频于一……

    2026年7月5日
    12200
  • 服务器二级等保怎么过?等保测评流程及费用详解

    服务器通过二级等保认证,核心在于落实物理安全、网络安全、主机安全及数据安全四大维度的合规整改,通常需投入3-8万元不等,周期约1-3个月,是互联网企业合规经营的必选项,很多站长和业务负责人一听到“等保”两个字就头大,觉得这是财务部门的事,或者是个麻烦的行政流程,二级等保更像是给您的服务器系统做了一次全面的“体检……

    2026年7月3日
    2800
  • IAR STM32内存管理函数是什么,怎么用

    IAR STM32内存管理的核心答案是:通过IAR编译器提供的堆管理函数(如malloc、free、realloc)配合启动文件中的堆栈配置,实现对STM32内部SRAM的动态分配与释放,而内存管理函数便是这套机制中最关键的执行单元,在STM32嵌入式开发中,内存管理是绕不开的话题,尤其是在项目复杂度上升、功能……

    AI资讯 2026年8月18日
    700
  • IDEA如何读取MySQL数据库中的数据,教程

    在IDEA中读取MySQL数据库,核心是通过内置的Database工具窗口或安装Database Navigator插件,配置JDBC驱动后建立连接,即可浏览、查询和管理数据, 无需离开IDE,你就能完成建表、查询、导出等操作,整个过程比传统命令行直观得多,准备工作:确保环境就绪在开始连接前,先确认几项基础条件……

    2026年8月12日
    600
  • 如何修改IDC描述提升排名,IDC排名优化技巧有哪些?

    修改IDC描述是提升IDC排名的核心环节,精准更新描述能直接改善搜索表现和用户信任度, 无论你是IDC服务商还是运营人员,掌握描述修改的技巧都能让排名竞争事半功倍,修改IDC描述后排名多久能恢复?描述更新对排名的即时影响提交IDC描述修改后,搜索引擎会重新抓取页面,据行业共识,简单的文本修改在24-48小时内能……

    2026年8月13日
    700
  • inodes调整3276800怎么做?,容量调整方法?

    调整inode数量到3276800是解决文件系统inode不足的有效手段,但必须与容量调整配合,确保数据安全并满足长期需求,什么时候需要调整inode到3276800文件系统inode耗尽的典型表现服务器无法创建新文件,但df -h显示磁盘仍有大量剩余空间使用df -i命令检查,inode使用率显示100%或接……

    2026年8月17日
    400
  • 大模型部署为何采用发布订阅模式?

    大模型部署采用发布订阅模式,核心在于通过消息队列实现推理服务与业务逻辑的解耦,从而在应对高并发请求时显著提升系统的稳定性与扩展性,当企业开始将大语言模型(LLM)落地到实际业务中时,往往会发现直接调用API或本地部署单节点服务难以应对流量洪峰,发布订阅模式(Pub/Sub)就像是一个高效的邮局系统,业务方不需要……

    2026年6月17日
    3300
  • FreeBSD虚拟主机性能怎么样,哪个好?

    对于追求极致稳定性和安全性的业务场景,FreeBSD虚拟主机凭借其ZFS文件系统、Jail轻量级虚拟化和严格的网络协议栈,在性能一致性和资源隔离方面优于多数Linux虚拟主机方案,什么是FreeBSD虚拟主机?核心技术与优势FreeBSD虚拟主机是基于FreeBSD操作系统构建的虚拟化托管环境,与Linux虚拟……

    2026年7月14日
    400

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注