Android ViewPager2 不动态包裹不同大小片段的高度

2024-01-13

我有一个 ViewPager2,它具有不同高度的片段作为子项,子项的高度在数据加载后会发生变化

        <com.google.android.material.appbar.CollapsingToolbarLayout
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            app:expandedTitleGravity="top"
            app:layout_scrollFlags="scroll|exitUntilCollapsed">

            <LinearLayout
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:orientation="vertical">

                <com.google.android.material.tabs.TabLayout
                    android:id="@+id/tabs_header"
                    android:layout_width="match_parent"
                    android:layout_height="wrap_content">

                    <com.google.android.material.tabs.TabItem
                        android:layout_width="wrap_content"
                        android:layout_height="match_parent"
                        android:text="@string/prospect_detail_tab_prospect" />

                    <com.google.android.material.tabs.TabItem
                        android:layout_width="wrap_content"
                        android:layout_height="match_parent"
                        android:text="@string/prospect_detail_tab_influencers" />

                    <com.google.android.material.tabs.TabItem
                        android:layout_width="wrap_content"
                        android:layout_height="match_parent"
                        android:text="@string/prospect_detail_tab_sales" />

                </com.google.android.material.tabs.TabLayout>

                <androidx.viewpager2.widget.ViewPager2
                    android:id="@+id/pager_header"
                    android:layout_width="match_parent"
                    android:layout_height="wrap_content" />

            </LinearLayout>
        </com.google.android.material.appbar.CollapsingToolbarLayout>

我尝试了几种不同的解决方案,但是如果它返回到较小的片段,则没有任何方法可以调整 viewpager2 的大小,它只是保持与最高片段相同的高度


发生的情况是,当片段的高度发生变化时,ViewPager2 不会刷新自己的高度(例如,如果您在内部使用 RecyclerView)。

为了解决这个问题,我们需要计算用户选择选项卡时的高度。这可以使用以下方法完成注册页面更改回调 https://developer.android.com/reference/androidx/viewpager2/widget/ViewPager2?authuser=1#registerOnPageChangeCallback(androidx.viewpager2.widget.ViewPager2.OnPageChangeCallback) and onPageSelected

registerOnPageChangeCallback(object : ViewPager2.OnPageChangeCallback() {
                override fun onPageSelected(position: Int) {
                    super.onPageSelected(position)

                    // Here we need to calculate height
                }
            })

现在,我们需要计算片段的高度。为此,我们需要访问片段及其根视图。这可以在创建 ViewPagerAdapter 时使用提供给 ViewPagerAdapter 的fragmentManager 来完成,例如这里我们使用childFragmentManager:PagerViewAdapter(childFragmentManager, lifecycle)


registerOnPageChangeCallback(object : ViewPager2.OnPageChangeCallback() {
    override fun onPageSelected(position: Int) {
        super.onPageSelected(position)
    
        // Because the fragment might or might not be created yet, 
        // we need to check for the size of the fragmentManager 
        // before accessing it.
        if (childFragmentManager.fragments.size > position) {
            val fragment = childFragmentManager.fragments.get(position)
            fragment.view?.let {
                // Now we've got access to the fragment Root View
                // we will use it to calculate the height and 
                // apply it to the ViewPager2
                updatePagerHeightForChild(it, binding.viewPager)
            }
        }
    }
})
// This function can sit in an Helper file, so it can be shared across your project.
fun updatePagerHeightForChild(view: View, pager: ViewPager2) {
    view.post {
        val wMeasureSpec =
                View.MeasureSpec.makeMeasureSpec(view.width, View.MeasureSpec.EXACTLY)
        val hMeasureSpec = View.MeasureSpec.makeMeasureSpec(0, View.MeasureSpec.UNSPECIFIED)
        view.measure(wMeasureSpec, hMeasureSpec)

        if (pager.layoutParams.height != view.measuredHeight) {
            pager.layoutParams = (pager.layoutParams)
                    .also { lp ->
                        // applying Fragment Root View Height to
                        // the pager LayoutParams, so they match
                        lp.height = view.measuredHeight
                    }
        }
    }
}

注意:我们正在访问viewPager使用绑定,如果您不使用绑定,请以您自己的方式提供 viewPager,也许可以使用findViewById()

限制:异步加载内容

如果您有一些动态加载内容,您可能需要结合解决方案ViewTreeObserver.OnGlobalLayoutListener,我还没有测试过。

参考:https://issuetracker.google.com/u/0/issues/143095219 https://issuetracker.google.com/u/0/issues/143095219

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Android ViewPager2 不动态包裹不同大小片段的高度 的相关文章

  • 新的 Material Design 底部导航应使用哪个视图? [复制]

    这个问题在这里已经有答案了 我相信你们都听说过添加底部导航 https www google com design spec components bottom navigation html材料设计指南 我计划将其添加到我的应用程序中 但
  • Android 滚动分页

    Android 操作系统有可以实现滚动分页的功能吗 Edit滚动分页是指像主屏幕上一样的分页 您可以左右滑动并转到下一页或上一页 您可以在 android git kernel org 上查看 Launcher 的源代码作为示例 查找名为
  • 使用 iOS 分布式应用程序时 Google Cloud Messaging 显示“notRegistered”

    我在 iOS 应用程序上实现了 GCM 服务 我使用 PHP 在服务器上发送 GCM 当应用程序由开发配置文件签名时 它可以完美运行 也就是说 当应用程序使用 GCM 配置注册自身时 它始终返回一个正常运行的设备令牌 我可以使用令牌向设备发
  • 当用户将 Android 11 应用程序置于后台时,除非手机已连接电源,否则我的 Android 11 应用程序将停止运行

    我编写了一个前台服务 以确保我的应用程序在进入后台时可以继续运行 该应用程序需要在后台运行 因为在计时器到期后 它会发出声音并振动以提醒用户 但是 当按下电源或主页按钮时 应用程序的计时器将在大约 15 分钟后停止运行 除非手机已插入电源
  • android 中 y + 高度必须 <= bitmap.height()

    我想从另一个创建位图 但每次尝试都会崩溃 这是错误消息 java lang IllegalArgumentException y 高度必须 这是我尝试创作的地方 public void saveBitmap Bitmap bitmapToS
  • Android - 如何获取文本视图中字符的坐标

    是否可以从 Android 中的 TextView 中的字符获取 x 坐标 我不是在寻找 TextView 本身的坐标 我需要 TextView 中最后一个字符的坐标 多行 提前致谢 Java解决方案 以下是如何获得x and y特定字符的
  • Camera.Parameters.FLASH_MODE_ON 在 Moto X 上不起作用

    我正在 moto x 上测试我的应用程序 即使打开闪光灯模式后 闪光灯也无法工作 应用程序在其他设备上运行良好 但在 Moto X 上运行不佳 这是一个代码片段 cameraInstance getCameraInstance camera
  • 如何计算android中位图擦除区域的百分比?

    我是安卓新手 我正在制作一个可以使用手指擦除画布上的位图的应用程序 像手指画橡皮擦之类的东西 我想计算擦除区域的百分比 例如 60 已从完整图像中擦除 请帮助我做到这一点 提前致谢 我尝试了一些方法 它总是给我 0 它不起作用 请参阅该方法
  • 像 Google Play 商店一样在垂直 RecyclerView 中动态不同图像水平 RecyclerView

    我一直在关注这个教程 http android pratap blogspot co za 2015 12 horizo ntal recyclerview in vertical html http android pratap blog
  • 没有 GUI 的 Android Activity

    我创建了一个仅从链接启动的活动 使用意图过滤器 我不希望此活动有 GUI 我只希望它启动服务并在栏中放置通知 我尝试将链接的意图过滤器放入我的服务中 但这不起作用 有没有更好的方法可以响应意图过滤器 或者我可以让我的活动没有 GUI 吗 抱
  • Android:TelephonyManager 类

    我不明白为什么 API 文档中这么写TelephonyManager类是public 但是当我尝试创建一个实例时 它说它不是公共类 并且无法从包中访问 我看到它也说使用Context getSystemService Context TEL
  • 如何使用Multipart将图像上传到php服务器

    我一直很头疼 如何将图像上传到服务器 这对我来说是新任务 但对我来说很困惑 我在 stackoverflow 上搜索并用谷歌搜索 但我遇到了问题 我的意图是从 SD 卡上传照片并从相机拍照并上传到服务器 在ios中 这个任务已经完成 在io
  • Facebook 好友请求 - 失踪好友

    我请求从我正在开发的 Android 应用程序中获取用户好友 从 Facebook Api V2 0 开始 我知道我应该只获取已经通过我的应用程序登录的用户好友 但是 尽管我知道用户的某些朋友已通过我的应用程序登录 但在请求该用户的朋友时
  • 如何在Android 11中获取dir文件列表

    我想编写自己的精简版文件浏览器 文件 API 现在不适用于外部存储 该版本还提供了对范围存储的改进 这使得开发人员可以更轻松地迁移到使用此存储模型 我不明白如何使用范围存储来访问 sdcard 如果您正在寻找文件选择器体验 存储访问框架 h
  • 安卓浮动键盘

    是否可以通过编程方式更改键盘的位置 我正在开发一个图腾应用程序 如果键盘停靠在底部 则很难使用 我尝试创建一个扩展 InputMethodService 的自定义键盘 并且我能够更改按键的布局 但我无法更改键盘的视图位置 快捷键 https
  • 自定义支持对话框片段文本颜色错误

    如果我放一个TextView在自定义对话框中 文本默认为黑色 不幸的是 支持片段对话框背景是深灰色的 灰底黑字很难读 我可以改变TextView白色或类似的东西android textColor android attr textColor
  • Android Lollipop:将应用程序小部件添加到主屏幕时启动器崩溃

    添加小部件时 启动器在 Android Lollipop 上崩溃 并显示以下消息 在以前的 Android 版本上运行良好 编辑 这只发生在横向方向 12 16 12 35 10 208 E AndroidRuntime 960 java
  • Android 10 通知彩色操作按钮

    I m trying to color the buttons Action in Notification like this So far this is what i m achieved so far 下面是我正在使用的代码 通知服
  • Android Webview:无法调用确定的可见性() - 从未见过 pid 的连接

    我有一个 Android Webview 当我单击链接下载文件 pdf 图像等 时 我收到一条错误消息 Error message Cannot call determinedVisibility never saw a connectio
  • 为什么 fork 炸弹没有使 android 崩溃?

    这是最简单的叉子炸弹 我在许多 Linux 发行版上执行了它 但它们都崩溃了 但是当我在 android 终端中执行此操作时 即使授予后也没有效果超级用户权限 有什么解释为什么它没有使 Android 系统崩溃吗 一句话 ulimit Li

随机推荐