ImageView实现原理分析

ImageView 是 Android 中用于显示图片的一个基本视图组件。它继承自 View 类,并且可以用来展示静态的图像资源,如位图、动画 GIF、矢量图形等。下面我们将结合源码分析 ImageView 的实现原理。

1. 构造方法与初始化

ImageView 的构造方法和其他 View 子类类似,通常接受一个 Context 对象,可能还包含 AttributeSetint 类型的默认样式。在构造方法中,ImageView 初始化其样式属性,设置默认的缩放类型等。

1public ImageView(Context context) {
2    super(context);
3    init(null, null, 0, 0);
4}
5
6public ImageView(Context context, AttributeSet attrs) {
7    this(context, attrs, 0);
8}
9
10public ImageView(Context context, AttributeSet attrs, int defStyleAttr) {
11    super(context, attrs, defStyleAttr);
12    init(attrs, null, defStyleAttr, 0);
13}
14
15private void init(AttributeSet attrs, AttributeSet defStyleAttrRes, int defStyleAttr, int defStyleRes) {
16    // 初始化ImageView的属性
17}

2. 设置图片资源

ImageView 支持多种方式来设置图片资源,包括从资源文件、Drawable 对象、位图或者 URL 加载图片。

  • 从资源文件加载

     Java 

    深色版本

    1public void setImageResource(@DrawableRes int resId) {
    2    Drawable drawable = null;
    3    if (resId != 0) {
    4        drawable = ContextCompat.getDrawable(getContext(), resId);
    5    }
    6    setImageDrawable(drawable);
    7}
  • 从 Drawable 设置

    1public void setImageDrawable(Drawable drawable) {
    2    if (mImage != drawable) {
    3        if (drawable != null) {
    4            drawable.setCallback(this);
    5            if (mAdjustViewBounds && drawable instanceof ScaleDrawable) {
    6                ((ScaleDrawable) drawable).setTargetDensity(getDrawableDensity());
    7            }
    8        }
    9        if (mImage != null) {
    10            mImage.setCallback(null);
    11        }
    12        mImage = drawable;
    13        requestLayout();
    14        invalidate();
    15    }
    16}
  • 从位图设置

    1public void setImageBitmap(Bitmap bm) {
    2    setImageDrawable(new BitmapDrawable(getResources(), bm));
    3}

3. 缩放类型

ImageView 支持不同的缩放类型,如 FIT_XY, CENTER_CROP, CENTER_INSIDE 等。缩放类型决定了如何在 ImageView 内部调整图片的大小和位置。

1public void setScaleType(ScaleType scaleType) {
2    if (scaleType != mScaleType) {
3        mScaleType = scaleType;
4        requestLayout(); // 请求重新布局
5    }
6}

4. 测量与布局

ImageView 需要根据图片的大小和缩放类型来确定自己的大小。onMeasure 方法负责计算 ImageView 的大小。

1@Override
2protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
3    super.onMeasure(widthMeasureSpec, heightMeasureSpec);
4    setMeasuredDimension(getDefaultSize(getSuggestedMinimumWidth(), widthMeasureSpec),
5                         getDefaultSize(getSuggestedMinimumHeight(), heightMeasureSpec));
6
7    final int width = getMeasuredWidth();
8    final int height = getMeasuredHeight();
9    if (getDrawable() != null) {
10        // 根据图片和缩放类型计算ImageView的大小
11        final int childWidth = getDrawable().getIntrinsicWidth();
12        final int childHeight = getDrawable().getIntrinsicHeight();
13        final ScaleType scaleType = getScaleType();
14
15        int widthSize = width;
16        int heightSize = height;
17
18        if (scaleType == ScaleType.FIT_XY) {
19            // FIT_XY 会拉伸图片以填满ImageView
20            widthSize = childWidth;
21            heightSize = childHeight;
22        } else if (scaleType == ScaleType.CENTER_CROP) {
23            // CENTER_CROP 会裁剪图片以适应ImageView
24            // 计算新的宽度和高度
25        }
26
27        setMeasuredDimension(resolveSizeAndState(widthSize, widthMeasureSpec, 0),
28                             resolveSizeAndState(heightSize, heightMeasureSpec, 0));
29    }
30}

5. 绘制图片

onDraw 方法中,ImageView 负责将图片绘制到屏幕上。

1@Override
2protected void onDraw(Canvas canvas) {
3    super.onDraw(canvas);
4    final Drawable drawable = getDrawable();
5    if (drawable != null) {
6        final Rect bounds = drawable.getBounds();
7        if (!bounds.isEmpty()) {
8            final int saveCount = canvas.save();
9            final int w = bounds.width();
10            final int h = bounds.height();
11            final int tw = getWidth() - getPaddingLeft() - getPaddingRight();
12            final int th = getHeight() - getPaddingTop() - getPaddingBottom();
13            final int scaleType = getScaleType();
14            if (scaleType != null) {
15                switch (scaleType) {
16                    case FIT_XY:
17                        canvas.scale((float) tw / w, (float) th / h);
18                        break;
19                    case CENTER_CROP:
20                        // ... 其他缩放类型 ...
21                    default:
22                        break;
23                }
24            }
25            canvas.translate(getPaddingLeft(), getPaddingTop());
26            drawable.draw(canvas);
27            canvas.restoreToCount(saveCount);
28        }
29    }
30}

总结

ImageView 的实现涉及到构造、图片资源的加载和管理、缩放类型的设置、测量与布局逻辑以及图片的绘制。这些功能的实现确保了 ImageView 可以灵活地显示不同类型的图片资源,并能适应不同的布局需求。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/diannao/48936.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

WPF串口通讯程序

目录 一 设计原型 二 后台源码 一 设计原型 二 后台源码 using HardwareCommunications; using System.IO.Ports; using System.Windows;namespace PortTest {/// <summary>/// Interaction logic for MainWindow.xaml/// </summary>public partial class MainW…

怀庄之醉是勾兑酒吗?

关于“怀庄之醉是否是勾兑酒”的问题&#xff0c;需要从多个角度进行分析。 勾兑酒在白酒生产中是一个广泛存在的工艺过程&#xff0c;它并非贬义词&#xff0c;而是指将不同口味、不同生产时间、不同度数的纯粮食酒&#xff0c;或固态法白酒与液态法白酒、食用酒精等&#xff…

软件缺陷(Bug)、禅道

目录 软件缺陷的判定标准 软件缺陷的核心内容 构成缺陷的基本要素 缺陷报告 缺陷管理 缺陷的跟踪流程 项目管理工具--禅道 软件在使用过程中存在的任何问题&#xff08;如&#xff1a;错误、异常等&#xff09;&#xff0c;都叫软件的缺陷&#xff0c;简称bug。 软件缺…

如何选择海洋船舶用总线NMEA 2000连接器

NMEA 2000连接器概述 NMEA 2000连接器是现代船舶通信系统中不可或缺的部分&#xff0c;主要用于连接船上各种电子设备&#xff0c;实现数据传输和设备控制。这些连接器遵循NMEA 2000协议标准&#xff0c;支持高速数据传输&#xff0c;并具有良好的防水、耐腐蚀性能&#xff0c…

神经网络之循环神经网络

目录 一、循环神经网络概述&#xff1a;1.传统神经网络与循环神经网络的区别&#xff1a;2.循环神经网络定义&#xff1a; 图片来自&#xff1a;深度学习———循环神经网络 一、循环神经网络概述&#xff1a; 1.传统神经网络与循环神经网络的区别&#xff1a; MLP、卷积神经…

【PostgreSQL教程】PostgreSQL 选择数据库

博主介绍:✌全网粉丝20W+,CSDN博客专家、Java领域优质创作者,掘金/华为云/阿里云/InfoQ等平台优质作者、专注于Java技术领域✌ 技术范围:SpringBoot、SpringCloud、Vue、SSM、HTML、Nodejs、Python、MySQL、PostgreSQL、大数据、物联网、机器学习等设计与开发。 感兴趣的可…

关于unicloud 云函数开发 加密的问题

解决的问题&#xff1a; 1.在云函数请求过程中入参参数暴露 2.云函数请求结束之后 出参结果暴露 解决方法&#xff1a; 1.在请求过程中对云函数的入参进行加密&#xff0c;在后端接收的时候将加密信息进行解密&#xff0c;根据自己的逻辑成功之后加密返回给前端 前端解密之…

多目标遗传算法(NSGAⅢ)的原理和matlab实现

参考文献&#xff1a; [1] Deb K , Jain H .An Evolutionary Many-Objective Optimization Algorithm Using Reference-Point-Based Nondominated Sorting Approach, Part I: Solving Problems With Box Constraints[J].IEEE Transactions on Evolutionary Computation, 2014,…

【Simple PIR】单服务器开源最快匿踪查询算法解析

7月17日&#xff0c;我们在《隐私计算匿踪查询技术深入浅出》中介绍了关于隐私计算中匿踪查询的定义和常见算法&#xff0c;并引出了前沿算法Simple PIR的介绍&#xff0c;本次将对Simple PIR进行正式的算法原理介绍。 1. Simple PIR快览 1.1 性能介绍 Simple PIR是Alexandra…

docker 打包orbbec

docker pull humble容器 sudo docker run -it osrf/ros:humble-desktop docker 启动容器 sudo docker run -u root --device/dev/bus/usb:/dev/bus/usb -it -v /home/wl:/share --name wl4 osrf/ros:humble-desktop /bin/bash新开一个终端 查看本地存在的容器&#xff1a;…

每类数据保留前n条(sql)

1、前言 因为遇到过好几次该需求&#xff0c;所以想着总结下&#xff0c;以后可以直接复用 2、背景及需求 背景&#xff1a;数据库中有多类数据&#xff0c;每类数据都有很多条 需求&#xff1a;每类数据按id排序&#xff0c;保留id较大的前1000条数据&#xff08;注意是每…

高速ADC模拟输入接口设计

目录 基本输入接口考虑 输入阻抗 输入驱动 带宽和通带平坦度 噪声 失真 变压器耦合前端 有源耦合前端网络 基本输入接口考虑 采用高输入频率、高速模数转换器(ADC)的系统设计是一 项具挑战性的任务。ADC输入接口设计有6个主要条件&#xff1a; 输入阻抗、输入驱动、带宽…

MYSQL设计和开发规范(简易版)

MYSQL设计和开发规范 1. 整体描述2. 数据库设计规范2.1 表名命名规则2.2 是否字段2.3 字母与数字2.4 禁止使用保留字2.5 可变字符串规范2.6 字段设计 3. 数据库索引规范3.1 命名规则3.2 唯一索引规范3.3 join规范3.4 varchar规范3.5 模糊搜索规范 4. 数据库SQL语句规范4.1 语句…

开源模型应用落地-FastAPI-助力模型交互-进阶篇-中间件(四)

一、前言 FastAPI 的高级用法可以为开发人员带来许多好处。它能帮助实现更复杂的路由逻辑和参数处理&#xff0c;使应用程序能够处理各种不同的请求场景&#xff0c;提高应用程序的灵活性和可扩展性。 在数据验证和转换方面&#xff0c;高级用法提供了更精细和准确的控制&#…

IPython魔法命令的深入应用

目录 IPython魔法命令的深入应用 一、魔法命令基础 1. 魔法命令的分类 2. 基本使用 二、高级应用技巧 1. 数据交互与处理 2. 交互式编程与调试 三、魔法命令的进阶操作 1. 自定义魔法命令 2. 利用魔法命令优化工作流程 四、总结与展望 IPython魔法命令的深入应用 IP…

vulnhub——Ai-Web1靶机渗透

Ai-Web1靶机渗透 靶机下载&#xff1a; 官网地址&#xff1a;https://www.vulnhub.com/entry/ai-web-1,353/ 攻击机&#xff1a;kali2024 一、信息收集 发下目标主机的IP为&#xff1a;192.168.201.141 用nmap工具扫描一下对方主机和服务 发现他打开了80端口 发现搜不到于是…

人是一个AI Agent吗?

人是一个AI Agent吗&#xff1f; 什么是AI Agent&#xff1f;人类的感知能力人类的推理与决策人类的执行能力人类的学习能力人类作为AI Agent的局限性结论 随着人工智能&#xff08;AI&#xff09;技术的不断发展&#xff0c;AI已经在许多领域展现出其强大的能力。AI Agent&…

详解数据结构之二叉树(堆)

详解数据结构之二叉树(堆) 树 树的概念 树是一个非线性结构的数据结构&#xff0c;它是由 n(n>0)个有限节点组成的一个具有层次关系的集合&#xff0c;它的外观形似一颗倒挂着的树&#xff0c;根朝上&#xff0c;叶朝下&#xff0c;所以称呼为树。每颗子树的根节点有且只…

C#调用非托管dll的两种方式

C#调用非托管DLL的两种方式 在开发过程中&#xff0c;我们经常需要调用一些非托管的DLL库&#xff0c;比如用Delphi编写的DLL。本文将介绍两种在C#中调用非托管DLL的方法。 示例DLL 首先&#xff0c;我们有一个Delphi编写的DLL&#xff0c;它导出了一个名为MyFunction的方法…

TextView实现原理分析

TextView 是 Android 中用于显示文本的核心组件&#xff0c;它的实现原理涉及多个方面&#xff0c;包括文本渲染、布局计算、滚动支持等。下面&#xff0c;我将结合源码分析 TextView 的关键实现细节。 1. 构造和初始化 TextView 是 View 的子类&#xff0c;同时继承自 AppCo…