Android笔记(三十六):封装一个Matrix从顶部/底部对齐的ImageView
背景

ImageView的scaleType默认显示图片是这样,但是有时候设计稿需求希望图片左右能紧贴着ImageView左右边缘,又不破坏图片的比例,用自带的matrix,centerCrop等都可以满足

但是都会造成图片的某些区域被裁剪了,如果设计稿只能接受底部被裁剪,其他边区域正常显示,那系统自带的scaleType则无法满足需求。这时需要自定义新的scaleType来满足设计要求
源码解析
- 以宽度为基准,计算图片与ImageView的缩放比例
scale = viewWidth.toFloat() / drawableWidth.toFloat()
- 根据自定义的scale_type,算出图片显示区域,viewHeight / scale为图片显示高度
var drawableRect: RectF? = nullif (mCropType == FROM_TOP) {drawableRect = RectF(0f, 0f, drawableWidth.toFloat(), viewHeight / scale)} else if (mCropType == FROM_BOTTOM) {drawableRect = RectF(0f,drawableHeight - viewHeight / scale,drawableWidth.toFloat(),drawableHeight.toFloat())}
- 使用setImageMatrix设置图片绘制边界
val viewRect = RectF(0f, 0f, viewWidth.toFloat(), viewHeight.toFloat())
matrix.setRectToRect(drawableRect, viewRect, Matrix.ScaleToFit.FILL)
setImageMatrix(matrix)
完整源码
class MatrixImageView @JvmOverloads constructor(context: Context,attrs: AttributeSet? = null,defStyleAttr: Int = 0
) : AppCompatImageView(context, attrs, defStyleAttr) {companion object {const val DEFAULT = 0const val FROM_TOP = 1const val FROM_BOTTOM = 2}private var mCropType = DEFAULTinit {val ta = context.obtainStyledAttributes(attrs, R.styleable.MatrixImageView, 0, 0)mCropType = ta.getInt(R.styleable.MatrixImageView_scale_type, DEFAULT)if (mCropType != DEFAULT) {setScaleType(ScaleType.MATRIX)}ta.recycle()}override fun onSizeChanged(w: Int, h: Int, oldw: Int, oldh: Int) {super.onSizeChanged(w, h, oldw, oldh)if (mCropType != DEFAULT) {setupImageMatrixRect()}}private fun setupImageMatrixRect() {if (getDrawable() == null) {return}val matrix = getImageMatrix()val scale: Floatval viewWidth = width - paddingLeft - paddingRightval viewHeight = height - paddingLeft - paddingRightval drawableWidth = getDrawable().intrinsicWidthval drawableHeight = getDrawable().intrinsicHeightscale = viewWidth.toFloat() / drawableWidth.toFloat()var drawableRect: RectF? = nullif (mCropType == FROM_TOP) {drawableRect = RectF(0f, 0f, drawableWidth.toFloat(), viewHeight / scale)} else if (mCropType == FROM_BOTTOM) {drawableRect = RectF(0f,drawableHeight - viewHeight / scale,drawableWidth.toFloat(),drawableHeight.toFloat())}val viewRect = RectF(0f, 0f, viewWidth.toFloat(), viewHeight.toFloat())matrix.setRectToRect(drawableRect, viewRect, Matrix.ScaleToFit.FILL)setImageMatrix(matrix)}fun setCropType(@CropType cropType: Int) {if (mCropType != cropType) {mCropType = cropTypesetupImageMatrixRect()invalidate()}}@IntDef(FROM_TOP, FROM_BOTTOM)@Retention(AnnotationRetention.SOURCE)annotation class CropType
}
<declare-styleable name="MatrixImageView"><attr name="scale_type"><enum name="matrix_top" value="1" /><enum name="matrix_bottom" value="2" /></attr></declare-styleable>
最终效果

相关文章:
Android笔记(三十六):封装一个Matrix从顶部/底部对齐的ImageView
背景 ImageView的scaleType默认显示图片是这样,但是有时候设计稿需求希望图片左右能紧贴着ImageView左右边缘,又不破坏图片的比例,用自带的matrix,centerCrop等都可以满足 但是都会造成图片的某些区域被裁剪了,如果设…...
web 入门
学习 Web 开发的基础,建议从以下几个方面入门,按步骤循序渐进学习核心知识: 1. 了解 Web 的基础概念 在开始编码之前,先理解 Web 开发的基本工作原理: Web 前端与后端: 前端:负责用户界面和用…...
京东 2025届秋招 自然语言处理
文章目录 个人情况一面/HR面 10min二面/技术面 1h三面/技术面 1h四面/线下HR面 20min 个人情况 先说一下个人情况: 学校情况:211本中9硕,本硕学校都一般,本硕都是计算机科班,但研究方向并不是NLP,而是图表…...
Mybatis框架之模板方法模式 (Template Method Pattern)
MyBatis 中也使用到了 模板方法模式 (Template Method Pattern),主要体现在 执行 SQL 语句的流程控制 上。模板方法模式允许 MyBatis 定义数据库操作的标准流程,并允许子类或特定实现类去实现某些步骤。这种模式使得 MyBatis 能够在处理不同类型的 SQL 操…...
【进阶系列】python简单爬虫实例
python有一个很强大的功能就是爬取网页的信息,这里是CNBlogs 网站,我们将以此网站为实例,爬取指定个页面的大标题内容。代码如下: 首先是导入库: # 导入所需的库 import requests # 用于发送HTTP请求 from bs4 impor…...
️虚拟机配置NAT和Bridge模式
虚拟机的网络配置 桥接 通过使用物理机网卡 具有单独ip NAT 把物理机为路由器进行上网 NAT模式: 所谓nat模式,就是虚拟系统会通过宿主机的网络来访问外网,而这里的宿主机相当于有两个网卡,一个是真实网卡,一个是虚拟…...
解决Spring Boot整合Redis时的连接问题
前言 在使用Spring Boot整合Redis的过程中,经常会遇到连接问题,尤其是当Redis服务部署在远程服务器上时。 问题描述 当你尝试连接到Redis服务器时,可能会遇到以下错误: org.springframework.data.redis.connection.PoolExcept…...
109. UE5 GAS RPG 实现检查点的存档功能
在这一篇文章里,我们接着实现存档的功能,保存当前玩家的生成位置,游戏里有很多中方式去实现玩家的位置存储,这里我们采用检查点的方式,当玩家接触到当前检查点后,我们可以通过检查点进行保存玩家的状态&…...
springboot005基于springboot学生心理咨询评估系统得设计与实现。
项目描述 临近学期结束,还是毕业设计,你还在做java程序网络编程,期末作业,老师的作业要求觉得大了吗?不知道毕业设计该怎么办?网页功能的数量是否太多?没有合适的类型或系统?等等。这里根据疫情当下,你想解决的问…...
ESC算法/逃生:一种基于人群疏散行为的优化方法
文章介绍了一种有用的算法,称为逃生或逃生算法(ESC),受人群疏散行为的启发,用于解决现实世界的案例和基准问题。ESC算法模拟了疏散过程中人群的行为,其中人群在探索阶段被分为平静、羊群和恐慌组࿰…...
构建安全的数据库环境:群晖NAS安装MySQL和phpMyAdmin详细步骤
文章目录 前言1. 安装MySQL2. 安装phpMyAdmin3. 修改User表4. 本地测试连接MySQL5. 安装cpolar内网穿透6. 配置MySQL公网访问地址7. 配置MySQL固定公网地址8. 配置phpMyAdmin公网地址9. 配置phpmyadmin固定公网地址 前言 本文将详细讲解如何在群晖NAS上安装MySQL及其数据库管理…...
【人工智能】深入理解图神经网络(GNN):用Python实现社交网络节点分类与分子结构分析
解锁Python编程的无限可能:《奇妙的Python》带你漫游代码世界 《Python OpenCV从菜鸟到高手》带你进入图像处理与计算机视觉的大门! 图神经网络(Graph Neural Network, GNN)是近年来在深度学习领域迅速发展的新兴方向,主要用于处理图结构数据。GNN在社交网络分析、化学分…...
Qt 日志文件的滚动写入
Qt 日志文件的滚动写入 flyfish 日志文件的滚动写入功能。在日志文件达到10MB时创建新的日志文件,并且在总日志文件大小达到10GB时开始覆盖最早的日志文件 以监控一个文件夹的写日志为例 日志文件创建与管理 初始化日志文件:在FileMonitor类的构造函…...
【c语言】数据包捕获和分析工具
请解释一下数据包捕获和分析工具(如Wireshark)的工作原理和用途。 数据包捕获和分析工具,如Wireshark(前身为Ethereal),是一种网络协议分析软件,它允许用户实时监控、抓取并分析计算机网络中的网…...
移情别恋c++ ദ്ദി˶ー̀֊ー́ ) ——14.哈希(2)(模拟实现)
1.概念介绍 1.1开散列 开散列(Open Hashing),也叫链地址法,是一种解决哈希冲突的方法。每个哈希表槽位保存一个链表,所有散列到同一位置的元素都存储在该链表中。当插入元素发生冲突时,将新元素添加到相应…...
请描述一下JVM(Java虚拟机)的生命周期及其对应用程序性能的影响
1、请描述一下JVM(Java虚拟机)的生命周期及其对应用程序性能的影响。 JVM(Java虚拟机)的生命周期主要涉及以下几个阶段:加载、验证、准备、解析、执行、卸载。每个阶段都有其特定的作用和影响。 加载:JVM…...
展会邀约|加速科技与您相约IC China 2024!
第二十一届中国国际半导体博览会( IC China 2024)将于 2024 年11月18日—11月20日在北京国家会议中心举行。加速科技将携高性能测试机ST2500EX、ST2500E、eATE及全系测试解决方案亮相E2馆B150展位。博览会期间,将同期举办"半导体产业前沿…...
鸿蒙中服务卡片数据的获取和渲染
1. 2.在卡片中使用LocalStorageProp接受传递的数据 LocalStorageProp("configNewsHead") configNewsHeadLocal: ConfigNewsHeadInfoItem[] [] 注意:LocalStorageProp括号中的为第一步图片2中的键 3.第一次在服务卡片的第一个卡片中可能会获取不到数据…...
运维篇-修复centos7无法下载docker问题
修复centos7无法下载docker问题 1、安装docker时报错2、docker无法下载镜像 1、安装docker时报错 linux的centos系统,安装docker时会报错 –> Finished Dependency Resolution Error: Package: glibc-2.17-307.el7.1.i686 (base) Requires: glibc-common 2.17…...
【论文阅读】WaDec: Decompiling WebAssembly Using Large Language Model
论文阅读笔记:WaDec: Decompiling WebAssembly Using Large Language Model 1. 来源出处 论文标题: WaDec: Decompiling WebAssembly Using Large Language Model作者: Xinyu She, Yanjie Zhao, Haoyu Wang会议: 39th IEEE/ACM International Conference on Automated Softwar…...
Python 爬虫高级实战:异地多机房爬虫协同采集
前言 随着爬虫业务规模扩张,单机、单机房部署模式逐渐暴露出单点故障、IP 池单一、地域访问延迟高、目标站点区域风控封禁、单机房带宽资源瓶颈等一系列问题。单一机房所有爬虫出口 IP 归属同一运营商、同一地域,极易被目标站点基于地域、IP 段整体封禁…...
二分查找算法:中间值左偏还是右偏?
还记得吗?我们在前面探讨了区间的选择和主循环的停止判断条件,但是没有提到 中间索引位置的计算公式 middle(st, ed)。当区间的长度是奇数时,中间索引只有一个位置 mid (st ed) / 2,而当区间长度是偶数时,中间索引就…...
英雄联盟智能助手League Akari:重新定义你的游戏体验边界
英雄联盟智能助手League Akari:重新定义你的游戏体验边界 【免费下载链接】League-Toolkit An all-in-one toolkit for LeagueClient. Gathering power 🚀. 项目地址: https://gitcode.com/gh_mirrors/le/League-Toolkit 在英雄联盟的竞技世界中&…...
Zutilo:为Zotero研究者量身打造的高效文献管理增强插件
Zutilo:为Zotero研究者量身打造的高效文献管理增强插件 【免费下载链接】Zutilo Zotero plugin providing some additional editing features 项目地址: https://gitcode.com/gh_mirrors/zu/Zutilo 作为一名Zotero用户,你是否曾为批量管理标签而烦…...
告别手动开关!用ESP8266+Arduino实现高精度定时(误差<1秒)的智能插座方案
告别手动开关!用ESP8266Arduino实现高精度定时(误差<1秒)的智能插座方案 在智能家居和物联网项目中,定时控制是最基础却最常被忽视的功能之一。许多开发者都遇到过这样的尴尬:用手机App远程控制电器很方便ÿ…...
降AI提示词够用吗?降AI工具比prompt强在哪?嘎嘎降AI双降!
降AI提示词够用吗?降AI工具比prompt强在哪?嘎嘎降AI双降! 用 AI 写论文的同学经常纠结一件事:0 元的降 AI 提示词够用吗?还是非得花钱买降 AI 工具不可? 直接给结论: 如果你 AI 写得不多、整体 …...
117.YOLOv5/v8数学原理+CSPDarknet架构,CUDA117环境一键部署
摘要 YOLO(You Only Look Once)系列算法是目标检测领域最主流的实时检测框架,其核心思想是将目标检测任务转化为一个端到端的回归问题。 本文从数学原理出发,系统阐述YOLOv5/v8的架构演进与核心机制,并提供一个从数据准备、模型训练到ONNX部署的完整可运行案例。 文章所有…...
CANN/GE动态输入算子样例
样例使用指导 【免费下载链接】ge GE(Graph Engine)是面向昇腾的图编译器和执行器,提供了计算图优化、多流并行、内存复用和模型下沉等技术手段,加速模型执行效率,减少模型内存占用。 GE 提供对 PyTorch、TensorFlow 前…...
基于MCP协议构建PrismHR连接器:打通HR数据孤岛,赋能AI原生应用
1. 项目概述:一个连接器,打通HR数据孤岛最近在做一个企业内部的HR系统集成项目,遇到了一个典型的老大难问题:核心的HRIS(人力资源信息系统)是PrismHR,但公司内部还有一大堆其他系统,…...
5G网络中的存储功能革新:NRF技术深度解析
5G网络中的存储功能革新:NRF技术深度解析 在5G通信技术的快速发展浪潮中,网络功能虚拟化(NFV)与软件定义网络(SDN)作为两大核心支柱,正引领着网络架构的深刻变革。其中,网络存储功能…...
