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

相关文章

Java中List转Map的几种具体实现方式和特点

《Java中List转Map的几种具体实现方式和特点》:本文主要介绍几种常用的List转Map的方式,包括使用for循环遍历、Java8StreamAPI、ApacheCommonsCollect... 目录前言1、使用for循环遍历:2、Java8 Stream API:3、Apache Commons

虚拟机与物理机的文件共享方式

《虚拟机与物理机的文件共享方式》文章介绍了如何在KaliLinux虚拟机中实现物理机文件夹的直接挂载,以便在虚拟机中方便地读取和使用物理机上的文件,通过设置和配置,可以实现临时挂载和永久挂载,并提供... 目录虚拟机与物理机的文件共享1 虚拟机设置2 验证Kali下分享文件夹功能是否启用3 创建挂载目录4

linux报错INFO:task xxxxxx:634 blocked for more than 120 seconds.三种解决方式

《linux报错INFO:taskxxxxxx:634blockedformorethan120seconds.三种解决方式》文章描述了一个Linux最小系统运行时出现的“hung_ta... 目录1.问题描述2.解决办法2.1 缩小文件系统缓存大小2.2 修改系统IO调度策略2.3 取消120秒时间限制3

Linux alias的三种使用场景方式

《Linuxalias的三种使用场景方式》文章介绍了Linux中`alias`命令的三种使用场景:临时别名、用户级别别名和系统级别别名,临时别名仅在当前终端有效,用户级别别名在当前用户下所有终端有效... 目录linux alias三种使用场景一次性适用于当前用户全局生效,所有用户都可调用删除总结Linux

Git中恢复已删除分支的几种方法

《Git中恢复已删除分支的几种方法》:本文主要介绍在Git中恢复已删除分支的几种方法,包括查找提交记录、恢复分支、推送恢复的分支等步骤,文中通过代码介绍的非常详细,需要的朋友可以参考下... 目录1. 恢复本地删除的分支场景方法2. 恢复远程删除的分支场景方法3. 恢复未推送的本地删除分支场景方法4. 恢复

Mybatis官方生成器的使用方式

《Mybatis官方生成器的使用方式》本文详细介绍了MyBatisGenerator(MBG)的使用方法,通过实际代码示例展示了如何配置Maven插件来自动化生成MyBatis项目所需的实体类、Map... 目录1. MyBATis Generator 简介2. MyBatis Generator 的功能3

C#实现WinForm控件焦点的获取与失去

《C#实现WinForm控件焦点的获取与失去》在一个数据输入表单中,当用户从一个文本框切换到另一个文本框时,需要准确地判断焦点的转移,以便进行数据验证、提示信息显示等操作,本文将探讨Winform控件... 目录前言获取焦点改变TabIndex属性值调用Focus方法失去焦点总结最后前言在一个数据输入表单

Python数据处理之导入导出Excel数据方式

《Python数据处理之导入导出Excel数据方式》Python是Excel数据处理的绝佳工具,通过Pandas和Openpyxl等库可以实现数据的导入、导出和自动化处理,从基础的数据读取和清洗到复杂... 目录python导入导出Excel数据开启数据之旅:为什么Python是Excel数据处理的最佳拍档

SpringBoot项目启动后自动加载系统配置的多种实现方式

《SpringBoot项目启动后自动加载系统配置的多种实现方式》:本文主要介绍SpringBoot项目启动后自动加载系统配置的多种实现方式,并通过代码示例讲解的非常详细,对大家的学习或工作有一定的... 目录1. 使用 CommandLineRunner实现方式:2. 使用 ApplicationRunne

VUE动态绑定class类的三种常用方式及适用场景详解

《VUE动态绑定class类的三种常用方式及适用场景详解》文章介绍了在实际开发中动态绑定class的三种常见情况及其解决方案,包括根据不同的返回值渲染不同的class样式、给模块添加基础样式以及根据设... 目录前言1.动态选择class样式(对象添加:情景一)2.动态添加一个class样式(字符串添加:情