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…...

SpringBoot+uniapp 的 Champion 俱乐部微信小程序设计与实现,论文初版实现
摘要 本论文旨在设计并实现基于 SpringBoot 和 uniapp 的 Champion 俱乐部微信小程序,以满足俱乐部线上活动推广、会员管理、社交互动等需求。通过 SpringBoot 搭建后端服务,提供稳定高效的数据处理与业务逻辑支持;利用 uniapp 实现跨平台前…...

高危文件识别的常用算法:原理、应用与企业场景
高危文件识别的常用算法:原理、应用与企业场景 高危文件识别旨在检测可能导致安全威胁的文件,如包含恶意代码、敏感数据或欺诈内容的文档,在企业协同办公环境中(如Teams、Google Workspace)尤为重要。结合大模型技术&…...

Ascend NPU上适配Step-Audio模型
1 概述 1.1 简述 Step-Audio 是业界首个集语音理解与生成控制一体化的产品级开源实时语音对话系统,支持多语言对话(如 中文,英文,日语),语音情感(如 开心,悲伤)&#x…...
Python如何给视频添加音频和字幕
在Python中,给视频添加音频和字幕可以使用电影文件处理库MoviePy和字幕处理库Subtitles。下面将详细介绍如何使用这些库来实现视频的音频和字幕添加,包括必要的代码示例和详细解释。 环境准备 在开始之前,需要安装以下Python库:…...
rnn判断string中第一次出现a的下标
# coding:utf8 import torch import torch.nn as nn import numpy as np import random import json""" 基于pytorch的网络编写 实现一个RNN网络完成多分类任务 判断字符 a 第一次出现在字符串中的位置 """class TorchModel(nn.Module):def __in…...
安卓基础(aar)
重新设置java21的环境,临时设置 $env:JAVA_HOME "D:\Android Studio\jbr" 查看当前环境变量 JAVA_HOME 的值 echo $env:JAVA_HOME 构建ARR文件 ./gradlew :private-lib:assembleRelease 目录是这样的: MyApp/ ├── app/ …...

sipsak:SIP瑞士军刀!全参数详细教程!Kali Linux教程!
简介 sipsak 是一个面向会话初始协议 (SIP) 应用程序开发人员和管理员的小型命令行工具。它可以用于对 SIP 应用程序和设备进行一些简单的测试。 sipsak 是一款 SIP 压力和诊断实用程序。它通过 sip-uri 向服务器发送 SIP 请求,并检查收到的响应。它以以下模式之一…...

HDFS分布式存储 zookeeper
hadoop介绍 狭义上hadoop是指apache的一款开源软件 用java语言实现开源框架,允许使用简单的变成模型跨计算机对大型集群进行分布式处理(1.海量的数据存储 2.海量数据的计算)Hadoop核心组件 hdfs(分布式文件存储系统)&a…...

人工智能(大型语言模型 LLMs)对不同学科的影响以及由此产生的新学习方式
今天是关于AI如何在教学中增强学生的学习体验,我把重要信息标红了。人文学科的价值被低估了 ⬇️ 转型与必要性 人工智能正在深刻地改变教育,这并非炒作,而是已经发生的巨大变革。教育机构和教育者不能忽视它,试图简单地禁止学生使…...

Netty从入门到进阶(二)
二、Netty入门 1. 概述 1.1 Netty是什么 Netty is an asynchronous event-driven network application framework for rapid development of maintainable high performance protocol servers & clients. Netty是一个异步的、基于事件驱动的网络应用框架,用于…...