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程序崩溃的几种方式汇总

《防止SpringBoot程序崩溃的几种方式汇总》本文总结了8种防止SpringBoot程序崩溃的方法,包括全局异常处理、try-catch、断路器、资源限制、监控、优雅停机、健康检查和数据库连接池配... 目录1. 全局异常处理2. 使用 try-catch 捕获异常3. 使用断路器4. 设置最大内存和线

Android NDK版本迭代与FFmpeg交叉编译完全指南

《AndroidNDK版本迭代与FFmpeg交叉编译完全指南》在Android开发中,使用NDK进行原生代码开发是一项常见需求,特别是当我们需要集成FFmpeg这样的多媒体处理库时,本文将深入分析A... 目录一、android NDK版本迭代分界线二、FFmpeg交叉编译关键注意事项三、完整编译脚本示例四

SpringIOC容器Bean初始化和销毁回调方式

《SpringIOC容器Bean初始化和销毁回调方式》:本文主要介绍SpringIOC容器Bean初始化和销毁回调方式,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐... 目录前言1.@Bean指定初始化和销毁方法2.实现接口3.使用jsR250总结前言Spring Bea

Android与iOS设备MAC地址生成原理及Java实现详解

《Android与iOS设备MAC地址生成原理及Java实现详解》在无线网络通信中,MAC(MediaAccessControl)地址是设备的唯一网络标识符,本文主要介绍了Android与iOS设备M... 目录引言1. MAC地址基础1.1 MAC地址的组成1.2 MAC地址的分类2. android与I

Java遍历HashMap的6种常见方式

《Java遍历HashMap的6种常见方式》这篇文章主要给大家介绍了关于Java遍历HashMap的6种常见方式,方法包括使用keySet()、entrySet()、forEach()、迭代器以及分别... 目录1,使用 keySet() 遍历键,再通过键获取值2,使用 entrySet() 遍历键值对3,

使用FileChannel实现文件的复制和移动方式

《使用FileChannel实现文件的复制和移动方式》:本文主要介绍使用FileChannel实现文件的复制和移动方式,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐... 目录使用 FileChannel 实现文件复制代码解释使用 FileChannel 实现文件移动代码解释

Spring实现Bean的初始化和销毁的方式

《Spring实现Bean的初始化和销毁的方式》:本文主要介绍Spring实现Bean的初始化和销毁的方式,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录一、Bean的初始化二、Bean的销毁总结在前面的章节当中介绍完毕了ApplicationContext,也就

Java使用Stream流的Lambda语法进行List转Map的操作方式

《Java使用Stream流的Lambda语法进行List转Map的操作方式》:本文主要介绍Java使用Stream流的Lambda语法进行List转Map的操作方式,具有很好的参考价值,希望对大... 目录背景Stream流的Lambda语法应用实例1、定义要操作的UserDto2、ListChina编程转成M

嵌入式Linux之使用设备树驱动GPIO的实现方式

《嵌入式Linux之使用设备树驱动GPIO的实现方式》:本文主要介绍嵌入式Linux之使用设备树驱动GPIO的实现方式,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐... 目录一、设备树配置1.1 添加 pinctrl 节点1.2 添加 LED 设备节点二、编写驱动程序2.1

Android 实现一个隐私弹窗功能

《Android实现一个隐私弹窗功能》:本文主要介绍Android实现一个隐私弹窗功能,本文通过实例代码给大家介绍的非常详细,感兴趣的朋友一起看看吧... 效果图如下:1. 设置同意、退出、点击用户协议、点击隐私协议的函数参数2. 《用户协议》、《隐私政策》设置成可点击的,且颜色要区分出来res/l