Android 控件保持宽高比得几种方式

2024-05-29 18:12

本文主要是介绍Android 控件保持宽高比得几种方式,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

文章目录

  • Android 控件保持宽高比得几种方式
    • adjustViewBounds
    • 百分比布局
    • ConstraintLayout
    • 自定义View

Android 控件保持宽高比得几种方式

adjustViewBounds

仅适用于 ImageView,保持横竖比。

<ImageViewandroid:layout_width="match_parent"android:layout_height="wrap_content"android:layout_gravity="center"android:adjustViewBounds="true"android:scaleType="fitXY"android:src="@drawable/bg" />

百分比布局

宽高比为 16:9

<androidx.percentlayout.widget.PercentFrameLayout xmlns:android="http://schemas.android.com/apk/res/android"xmlns:app="http://schemas.android.com/apk/res-auto"xmlns:tools="http://schemas.android.com/tools"android:layout_width="match_parent"android:layout_height="match_parent"tools:context=".ratio.PercentFragment"><ImageViewandroid:layout_width="0dp"android:layout_height="0dp"android:scaleType="fitXY"android:src="@drawable/bg"app:layout_aspectRatio="178%"app:layout_widthPercent="100%" /></androidx.percentlayout.widget.PercentFrameLayout>

ConstraintLayout

宽高比为 16:9

<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"xmlns:app="http://schemas.android.com/apk/res-auto"xmlns:tools="http://schemas.android.com/tools"android:layout_width="match_parent"android:layout_height="match_parent"tools:context=".ratio.ConstraintLayoutFragment"><ImageViewandroid:layout_width="0dp"android:layout_height="0dp"android:scaleType="fitXY"android:src="@drawable/bg"app:layout_constraintDimensionRatio="16:9"app:layout_constraintLeft_toLeftOf="parent"app:layout_constraintRight_toRightOf="parent" /></androidx.constraintlayout.widget.ConstraintLayout>

自定义View

自定义View:

<declare-styleable name="MyRatioFrameLayout"><attr name="whRatio" format="string" />
</declare-styleable>
class MyRatioFrameLayout @JvmOverloads constructor(context: Context,attrs: AttributeSet? = null,defStyleAttr: Int = 0
) : FrameLayout(context, attrs, defStyleAttr) {private var widthRatio: Float = 0Fprivate var heightRatio: Float = 0Finit {val a = context.obtainStyledAttributes(attrs, R.styleable.MyRatioFrameLayout)val whRatio = a.getString(R.styleable.MyRatioFrameLayout_whRatio)a.recycle()whRatio?.let {val strs = it.split(":");when (strs.size) {1 -> {widthRatio = strs[0].toFloat()heightRatio = 1F}2 -> {widthRatio = strs[0].toFloat()heightRatio = strs[1].toFloat()}}}}override fun onMeasure(widthMeasureSpec: Int, heightMeasureSpec: Int) {var wMeasureSpec = widthMeasureSpecvar hMeasureSpec = heightMeasureSpecif (widthRatio != 0F && heightRatio != 0F) {val ratio = getRatio()val lp: ViewGroup.LayoutParams = layoutParamsval widthMode = MeasureSpec.getMode(widthMeasureSpec)val widthSize = MeasureSpec.getSize(widthMeasureSpec)val heightMode = MeasureSpec.getMode(heightMeasureSpec)val heightSize = MeasureSpec.getSize(heightMeasureSpec)if (lp.width != ViewGroup.LayoutParams.WRAP_CONTENT && widthMode == MeasureSpec.EXACTLY &&lp.height != ViewGroup.LayoutParams.WRAP_CONTENT && heightMode == MeasureSpec.EXACTLY) {// 宽度和高度都是固定值if (widthSize / ratio < heightSize) {// 如果计算后高度小于原有高度hMeasureSpec = MeasureSpec.makeMeasureSpec((widthSize / ratio).toInt(),MeasureSpec.EXACTLY)} else if (heightSize * ratio <= widthSize) {// 如果计算后的宽度小于原有宽度wMeasureSpec = MeasureSpec.makeMeasureSpec((heightSize * ratio).toInt(),MeasureSpec.EXACTLY)}} else if (lp.width != ViewGroup.LayoutParams.WRAP_CONTENT && widthMode == MeasureSpec.EXACTLY && heightMode != MeasureSpec.EXACTLY) {// 宽度固定值hMeasureSpec =MeasureSpec.makeMeasureSpec((widthSize / ratio).toInt(), MeasureSpec.EXACTLY)} else if (lp.height != ViewGroup.LayoutParams.WRAP_CONTENT && heightMode == MeasureSpec.EXACTLY && widthMode != MeasureSpec.EXACTLY) {// 高度固定值wMeasureSpec =MeasureSpec.makeMeasureSpec((heightSize * ratio).toInt(), MeasureSpec.EXACTLY)}}super.onMeasure(wMeasureSpec, hMeasureSpec)}fun setRatio(widthRatio: Float, heightRatio: Float) {this.widthRatio = widthRatiothis.heightRatio = heightRatio}fun getRatio(): Float {return widthRatio / heightRatio}
}

使用:

在这里插入图片描述

<?xml version="1.0" encoding="utf-8"?>
<ScrollView xmlns:android="http://schemas.android.com/apk/res/android"xmlns:app="http://schemas.android.com/apk/res-auto"xmlns:tools="http://schemas.android.com/tools"android:layout_width="match_parent"android:layout_height="match_parent"android:orientation="vertical"tools:context=".ratio.RatioViewFragment"><LinearLayoutandroid:layout_width="match_parent"android:layout_height="wrap_content"android:orientation="vertical"><com.example.tools.ratio.MyRatioFrameLayoutandroid:layout_width="match_parent"android:layout_height="wrap_content"android:background="#ff0000"app:whRatio="16:9"><ImageViewandroid:layout_width="match_parent"android:layout_height="match_parent"android:scaleType="fitXY"android:src="@drawable/bg" /></com.example.tools.ratio.MyRatioFrameLayout><com.example.tools.ratio.MyRatioFrameLayoutandroid:layout_width="200dp"android:layout_height="300dp"android:layout_marginTop="10dp"android:background="#00ff00"app:whRatio="16:9"><ImageViewandroid:layout_width="match_parent"android:layout_height="match_parent"android:scaleType="fitXY"android:src="@drawable/bg" /></com.example.tools.ratio.MyRatioFrameLayout><com.example.tools.ratio.MyRatioFrameLayoutandroid:layout_width="300dp"android:layout_height="200dp"android:layout_marginTop="10dp"android:background="#0000ff"app:whRatio="16:9"><ImageViewandroid:layout_width="match_parent"android:layout_height="match_parent"android:scaleType="fitXY"android:src="@drawable/bg" /></com.example.tools.ratio.MyRatioFrameLayout></LinearLayout>
</ScrollView>

这篇关于Android 控件保持宽高比得几种方式的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/1014273

相关文章

SpringBoot中六种批量更新Mysql的方式效率对比分析

《SpringBoot中六种批量更新Mysql的方式效率对比分析》文章比较了MySQL大数据量批量更新的多种方法,指出REPLACEINTO和ONDUPLICATEKEY效率最高但存在数据风险,MyB... 目录效率比较测试结构数据库初始化测试数据批量修改方案第一种 for第二种 case when第三种

python生成随机唯一id的几种实现方法

《python生成随机唯一id的几种实现方法》在Python中生成随机唯一ID有多种方法,根据不同的需求场景可以选择最适合的方案,文中通过示例代码介绍的非常详细,需要的朋友们下面随着小编来一起学习学习... 目录方法 1:使用 UUID 模块(推荐)方法 2:使用 Secrets 模块(安全敏感场景)方法

Linux线程之线程的创建、属性、回收、退出、取消方式

《Linux线程之线程的创建、属性、回收、退出、取消方式》文章总结了线程管理核心知识:线程号唯一、创建方式、属性设置(如分离状态与栈大小)、回收机制(join/detach)、退出方法(返回/pthr... 目录1. 线程号2. 线程的创建3. 线程属性4. 线程的回收5. 线程的退出6. 线程的取消7.

golang程序打包成脚本部署到Linux系统方式

《golang程序打包成脚本部署到Linux系统方式》Golang程序通过本地编译(设置GOOS为linux生成无后缀二进制文件),上传至Linux服务器后赋权执行,使用nohup命令实现后台运行,完... 目录本地编译golang程序上传Golang二进制文件到linux服务器总结本地编译Golang程序

Linux下删除乱码文件和目录的实现方式

《Linux下删除乱码文件和目录的实现方式》:本文主要介绍Linux下删除乱码文件和目录的实现方式,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录linux下删除乱码文件和目录方法1方法2总结Linux下删除乱码文件和目录方法1使用ls -i命令找到文件或目录

Linux在线解压jar包的实现方式

《Linux在线解压jar包的实现方式》:本文主要介绍Linux在线解压jar包的实现方式,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录linux在线解压jar包解压 jar包的步骤总结Linux在线解压jar包在 Centos 中解压 jar 包可以使用 u

Android kotlin中 Channel 和 Flow 的区别和选择使用场景分析

《Androidkotlin中Channel和Flow的区别和选择使用场景分析》Kotlin协程中,Flow是冷数据流,按需触发,适合响应式数据处理;Channel是热数据流,持续发送,支持... 目录一、基本概念界定FlowChannel二、核心特性对比数据生产触发条件生产与消费的关系背压处理机制生命周期

Android ClassLoader加载机制详解

《AndroidClassLoader加载机制详解》Android的ClassLoader负责加载.dex文件,基于双亲委派模型,支持热修复和插件化,需注意类冲突、内存泄漏和兼容性问题,本文给大家介... 目录一、ClassLoader概述1.1 类加载的基本概念1.2 android与Java Class

Jenkins分布式集群配置方式

《Jenkins分布式集群配置方式》:本文主要介绍Jenkins分布式集群配置方式,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录1.安装jenkins2.配置集群总结Jenkins是一个开源项目,它提供了一个容易使用的持续集成系统,并且提供了大量的plugin满

Java通过驱动包(jar包)连接MySQL数据库的步骤总结及验证方式

《Java通过驱动包(jar包)连接MySQL数据库的步骤总结及验证方式》本文详细介绍如何使用Java通过JDBC连接MySQL数据库,包括下载驱动、配置Eclipse环境、检测数据库连接等关键步骤,... 目录一、下载驱动包二、放jar包三、检测数据库连接JavaJava 如何使用 JDBC 连接 mys