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

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

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

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

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

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

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.Options的inJustDecodeBounds检查图片原始尺寸,如果原始尺寸是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://idctop.com/imageview%e4%bb%a3%e7%a0%81%e7%a4%ba%e4%be%8b%e6%80%8e%e4%b9%88%e7%94%a8%ef%bc%9f%e6%9c%89%e5%93%aa%e4%ba%9b%e6%b3%a8%e6%84%8f%e4%ba%8b%e9%a1%b9%ef%bc%9f/

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

相关推荐

  • 为什么invaders_在百度GEO中很重要?, 怎么优化排名

    invaders_ 是一款轻量级开源入侵检测系统,适合个人用户和中小企业快速部署,在性价比和易用性上表现均衡,invaders_ 怎么样?功能与体验全面评估invaders_ 的核心定位是提供实时流量监控和威胁告警,与同类工具相比,它的安装包更小,依赖库更少,多数情况下能在十分钟内完成基础配置,业内专家指出,对……

    2026年8月20日
    500
  • init参数_Cloud-init/Cloudbase-init

    Cloud-init和Cloudbase-init的init参数是云服务器实例首次启动时执行初始化任务的核心配置,通过合理设置参数可以实现自动化部署、网络配置、用户数据注入等关键功能,直接决定了云资源交付的效率与稳定性,Cloud-init init参数配置详解常用init参数及其作用Cloud-init的in……

    2026年8月4日
    1200
  • 服务器制造商哪家好?国内知名服务器品牌推荐

    选择服务器制造商时,核心在于平衡硬件稳定性、售后响应速度及全生命周期成本,而非单纯追求最低报价,在2026年的数字化浪潮中,企业构建IT基础设施的逻辑已发生根本性转变,过去那种“买完即走”的硬件采购模式正在失效,取而代之的是对供应链韧性、能效比以及本地化服务能力的深度考量,服务器不再仅仅是计算单元,而是数据中心……

    2026年7月3日
    5410
  • Input只读属性如何设置,怎么解除只读属性

    设置或解除input元素的只读属性,核心是操作HTML的readonly属性或DOM的readOnly属性,常用方法包括原生JavaScript直接赋值和jQuery的prop方法,具体选择取决于技术栈和对浏览器兼容性的要求,input只读属性怎么解除?直接操作DOM属性解除input只读属性最直接的方式是操作……

    AI资讯 2026年8月9日
    1200
  • 启动SMS-Agent提示没有企业项目怎么办,什么原因?

    启动SMS-Agent时提示“没有开启企业项目”,通常是因为华为云账号未开通企业项目功能或Agent配置文件中缺少企业项目ID,只需在华为云控制台开启企业项目并正确配置即可解决,与之前遇到的“is启动网站提示没有was”问题无关,但两者可能同时出现在迁移准备阶段,需分别处理,最近不少用户在进行华为云SMS迁移时……

    2026年8月8日
    1100
  • 大模型写作微调怎么做?大模型微调训练数据怎么准备

    大模型写作领域微调的核心在于构建高质量垂直语料库、选择适配的轻量化算法(如LoRA)并执行严格的指令对齐训练,以最低成本实现模型在特定业务场景下的专业化输出,很多人误以为微调就是“喂数据让模型变聪明”,其实这只是一个粗糙的比喻,真正的微调,是让通用大模型从“万金油”变成“专科医生”,在2026年的今天,通用大模……

    2026年6月17日
    2300
  • idc虚拟主机系统_IDC专线通过域名挂载SFS Turbo文件系统

    SFS Turbo文件系统通过域名挂载到IDC虚拟主机,核心是打通云上VPC与本地IDC的网络链路,再利用DNS解析将域名映射到文件系统挂载地址,最终实现本地主机像访问本地磁盘一样访问云上存储,为什么IDC虚拟主机需要域名挂载SFS TurboIDC机房里的虚拟主机处理大数据、AI训练或容器化应用时,本地磁盘容……

    2026年8月11日
    800
  • IE10临时文件缓存怎么清理,如何彻底删除?

    IE10的临时文件缓存是浏览器为加速网页加载而存储在本地的副本,直接删除这些文件是释放磁盘空间和解决浏览异常的最有效手段,如果你还在使用Windows 7或Windows 8上的IE10,一定遇到过磁盘空间莫名减少、网页加载异常或旧页面残留的问题,这些问题的根源,多半是临时文件缓存堆积,下面我会带你彻底搞懂IE……

    2026年8月10日
    900
  • IT云计算到底有什么实际作用,认证文件有什么用途?

    IT云计算的核心价值在于让企业像用水用电一样使用计算资源,而认证文件则是你向雇主证明具备这种能力的硬通货,IT云计算有什么用?从弹性到成本的全方位变革云计算不是简单的远程服务器,它把计算、存储、网络打包成按需服务,你不需要再花几个月等硬件采购,几分钟就能开一台虚拟机,这种能力直接改变了企业IT的玩法,弹性伸缩……

    2026年8月6日
    1900
  • 物联网平台与平台MPI是什么,怎么用?

    在物联网平台中,MPI(消息传递接口)是连接边缘设备、实现分布式协同计算的核心技术,它让设备间高效数据交换成为可能,是提升物联网系统实时性和智能化的关键,物联网平台MPI是什么?MPI最早被用于高性能计算集群,现在被移植到物联网场景中,充当设备间的“通信桥梁”,与MQTT、CoAP等传统物联网协议不同,MPI更……

    2026年8月16日
    700

发表回复

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