Android ViewPager不支持wrap_content的原因

2024-03-19 08:20

本文主要是介绍Android ViewPager不支持wrap_content的原因,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

文章目录

  • Android ViewPager不支持wrap_content的原因
    • 问题
    • 源码分析
    • 解决

Android ViewPager不支持wrap_content的原因

问题

<androidx.viewpager.widget.ViewPagerandroid:id="@+id/wrap_view_pager"android:layout_width="match_parent"android:layout_height="wrap_content"android:background="#666666" />

将 ViewPager 的高度设置为 wrap_content,但是实现显示的效果却是填充了整个父容器。

源码分析

// ViewPager#onMeasure()
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {setMeasuredDimension(getDefaultSize(0, widthMeasureSpec),getDefaultSize(0, heightMeasureSpec));
}
// View#getDefaultSize()
public static int getDefaultSize(int size, int measureSpec) {int result = size;int specMode = MeasureSpec.getMode(measureSpec);int specSize = MeasureSpec.getSize(measureSpec);switch (specMode) {case MeasureSpec.UNSPECIFIED:result = size;break;case MeasureSpec.AT_MOST:case MeasureSpec.EXACTLY:result = specSize;break;}return result;
}

在这里插入图片描述

源码分析:

  • 前提:View的MeasureSpec是由MeasureMode和MeasureSize构成,子View的MeasureSpec是由父View的MeasureSpec和子View的LayoutParams计算来的。
  • 在 ViewPager 中,onMeasure() 直接调用 setMeasuredDimension() 设置宽高,并没有根据子View来计算测量。
  • 接着调用 getDefaultSize() 方法,第一个参数传入0,第二个参数传入ViewPager的measureSpec,根据上图父View的MeasureMode和子View的LayoutParams对照关系,由此可得:
    • ViewPager的MeasureMode为EXACTLY时,specSize为具体值或父View的剩余空间。
    • ViewPager的MeasureMode为AT_MOST时,specSize为父View的剩余空间。

因此当ViewPager设置为wrap_content时,ViewPager为父容器的高度。

解决

重写 onMeasure() 方法,先主动测量子View的大小,将测量后的结果设置给ViewPager。

class WrapContentViewPager @JvmOverloads constructor(context: Context,attrs: AttributeSet? = null
) : ViewPager(context, attrs) {override fun onMeasure(widthMeasureSpec: Int, heightMeasureSpec: Int) {for (i in 0 until childCount) {val child = getChildAt(i)measureChild(child,widthMeasureSpec,MeasureSpec.makeMeasureSpec(child.layoutParams.height, MeasureSpec.UNSPECIFIED))}val heightSize = MeasureSpec.getSize(heightMeasureSpec)val heightMode = MeasureSpec.getMode(heightMeasureSpec)var height = 0when (heightMode) {MeasureSpec.EXACTLY -> {height = heightSize}else -> {for (i in 0 until childCount) {val child = getChildAt(i)height = Math.max(height, child.measuredHeight)}}}super.onMeasure(widthMeasureSpec,MeasureSpec.makeMeasureSpec(height, MeasureSpec.EXACTLY))}
}

这篇关于Android ViewPager不支持wrap_content的原因的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



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

相关文章

SpringSecurity显示用户账号已被锁定的原因及解决方案

《SpringSecurity显示用户账号已被锁定的原因及解决方案》SpringSecurity中用户账号被锁定问题源于UserDetails接口方法返回值错误,解决方案是修正isAccountNon... 目录SpringSecurity显示用户账号已被锁定的解决方案1.问题出现前的工作2.问题出现原因各

Android DataBinding 与 MVVM使用详解

《AndroidDataBinding与MVVM使用详解》本文介绍AndroidDataBinding库,其通过绑定UI组件与数据源实现自动更新,支持双向绑定和逻辑运算,减少模板代码,结合MV... 目录一、DataBinding 核心概念二、配置与基础使用1. 启用 DataBinding 2. 基础布局

Android ViewBinding使用流程

《AndroidViewBinding使用流程》AndroidViewBinding是Jetpack组件,替代findViewById,提供类型安全、空安全和编译时检查,代码简洁且性能优化,相比Da... 目录一、核心概念二、ViewBinding优点三、使用流程1. 启用 ViewBinding (模块级

k8s上运行的mysql、mariadb数据库的备份记录(支持x86和arm两种架构)

《k8s上运行的mysql、mariadb数据库的备份记录(支持x86和arm两种架构)》本文记录在K8s上运行的MySQL/MariaDB备份方案,通过工具容器执行mysqldump,结合定时任务实... 目录前言一、获取需要备份的数据库的信息二、备份步骤1.准备工作(X86)1.准备工作(arm)2.手

javax.net.ssl.SSLHandshakeException:异常原因及解决方案

《javax.net.ssl.SSLHandshakeException:异常原因及解决方案》javax.net.ssl.SSLHandshakeException是一个SSL握手异常,通常在建立SS... 目录报错原因在程序中绕过服务器的安全验证注意点最后多说一句报错原因一般出现这种问题是因为目标服务器

华为鸿蒙HarmonyOS 5.1官宣7月开启升级! 首批支持名单公布

《华为鸿蒙HarmonyOS5.1官宣7月开启升级!首批支持名单公布》在刚刚结束的华为Pura80系列及全场景新品发布会上,除了众多新品的发布,还有一个消息也点燃了所有鸿蒙用户的期待,那就是Ha... 在今日的华为 Pura 80 系列及全场景新品发布会上,华为宣布鸿蒙 HarmonyOS 5.1 将于 7

MyBatis Plus 中 update_time 字段自动填充失效的原因分析及解决方案(最新整理)

《MyBatisPlus中update_time字段自动填充失效的原因分析及解决方案(最新整理)》在使用MyBatisPlus时,通常我们会在数据库表中设置create_time和update... 目录前言一、问题现象二、原因分析三、总结:常见原因与解决方法对照表四、推荐写法前言在使用 MyBATis

IDEA中Maven Dependencies出现红色波浪线的原因及解决方法

《IDEA中MavenDependencies出现红色波浪线的原因及解决方法》在使用IntelliJIDEA开发Java项目时,尤其是基于Maven的项目,您可能会遇到MavenDependenci... 目录一、问题概述二、解决步骤2.1 检查 Maven 配置2.2 更新 Maven 项目2.3 清理本

Android学习总结之Java和kotlin区别超详细分析

《Android学习总结之Java和kotlin区别超详细分析》Java和Kotlin都是用于Android开发的编程语言,它们各自具有独特的特点和优势,:本文主要介绍Android学习总结之Ja... 目录一、空安全机制真题 1:Kotlin 如何解决 Java 的 NullPointerExceptio

Java空指针异常NullPointerException的原因与解决方案

《Java空指针异常NullPointerException的原因与解决方案》在Java开发中,NullPointerException(空指针异常)是最常见的运行时异常之一,通常发生在程序尝试访问或... 目录一、空指针异常产生的原因1. 变量未初始化2. 对象引用被显式置为null3. 方法返回null