【问题标题】:Android ScrollView clipped bottom with transparent statusbar带有透明状态栏的 Android ScrollView 裁剪底部
【发布时间】:2021-12-16 19:30:56
【问题描述】:

我有一个带有透明状态栏的屏幕和一个包含英雄图像和其他一些元素的 ScrollView。图像应绘制在状态栏下方。第一眼看起来一切都很好,但我注意到 ScrollView 中的最后一个视图被剪裁了。看起来 ScrollView 的高度扩展至低于屏幕高度的限制。我可以看到从屏幕下方某处开始的过度滚动效果。当我在 ScrollView 上使用 android:fitsSystemWindows="true" 时,它解决了问题,但是我没有在状态栏下绘图。

一些相关代码:

Fragment.onCreate

 WindowCompat.setDecorFitsSystemWindows(requireActivity().window, false)

应用主题

<item name="android:statusBarColor">@android:color/transparent</item>

我不确定粘贴 XML 布局是否有意义,但在伪代码中:

<?xml version="1.0" encoding="utf-8"?>
<ScrollView xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent">

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

        <ImageView />

        <TextView />

        <TextView />

        <TextView />

        <TextView />
    </LinearLayout>
</ScrollView>

【问题讨论】:

    标签: android xml user-interface statusbar


    【解决方案1】:

    实际上,让状态栏下方的绘图按预期工作是一件很痛苦的事情。我自己使用以下几行来完成这项工作,但是现在使用标志已被标记为已弃用。

        private fun drawBelowStatusBar(window: Window) {
        if (!BitFlagsUtil.isFlagSet(
                source = window.decorView.systemUiVisibility,
                flag = View.SYSTEM_UI_FLAG_LAYOUT_STABLE or View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN
            )
        ) {
            window.decorView.systemUiVisibility = BitFlagsUtil.setFlag(
                source = window.decorView.systemUiVisibility,
                flag = View.SYSTEM_UI_FLAG_LAYOUT_STABLE or View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN
            )
        }
    }
    

    而 util 类由这 3 个方法组成。

    object BitFlagsUtil {
    fun isFlagSet(source: Int, flag: Int): Boolean {
        return source and flag == flag
    }
    
    fun setFlag(source: Int, flag: Int): Int {
        return (source or flag)
    }
    
    fun unsetFlag(source: Int, flag: Int): Int {
        return (source and flag.inv())
    }}
    

    PS。 android:fitsSystemWindows CoordinatorLayout 和 CollapsingToolbarLayout 变得棘手

    【讨论】:

      【解决方案2】:

      WindowCompat.setDecorFitsSystemWindows(requireActivity().window, false)

      From documentation: 使用这段代码可确保您的应用采用边到边,即使用显示屏的整个宽度和高度进行布局。

      但这可能会使系统底部导航栏与隐藏其底部的活动重叠,在您的情况下是ScorllView的底部

      解决方案:

      documentation offers a solution 到使用插图的那个:

      您可以通过对插图做出反应来解决重叠问题,插图指定了哪些 屏幕的某些部分与导航等系统 UI 相交 栏或状态栏。相交可能意味着简单地显示 上面的内容,但它也可以通知你的应用程序关于系统 手势也是。

      这需要知道活动布局的顶级根ViewGroup,以便使用适当的LayoutParams。在你的情况下这是ScrollView

      val root = findViewById<ScrollView>(R.id.root) // Cast that to the id of your root layout (ScrollView)
      ViewCompat.setOnApplyWindowInsetsListener(root) { view, windowInsets ->
          val insets = windowInsets.getInsets(WindowInsetsCompat.Type.systemBars())
      
          view.layoutParams =  (view.layoutParams as FrameLayout.LayoutParams).apply {
              leftMargin = insets.left
              bottomMargin = insets.bottom // to draw above the navigation bar
              rightMargin = insets.right
          }
      
          // Return CONSUMED if you don't want want the window insets to keep being
          // passed down to descendant views.
          WindowInsetsCompat.CONSUMED
      }
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2016-10-27
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2021-10-10
        • 1970-01-01
        相关资源
        最近更新 更多