【问题标题】:Top of ScrollView hidden behind status barScrollView 顶部隐藏在状态栏后面
【发布时间】:2018-01-05 19:37:59
【问题描述】:

我有一个FrameLayout,其中包含用于背景的ImageViewScrollView 中的LinearLayout,以显示我需要的所有视图。简化代码如下所示,用于我的Fragment

<FrameLayout 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">

    <ImageView
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:src="@drawable/ink"
        android:scaleType="center"/>

    <ScrollView
        android:layout_width="match_parent"
        android:layout_height="match_parent">

        <LinearLayout
            android:id="@+id/linear_layout_container"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:layout_gravity="center"
            android:orientation="vertical">
        </LinearLayout>

   </ScrollView>
</FrameLayout>

这个片段放在我的activity_main.xmlFrameLayout 中,看起来像这样

<FrameLayout
    xmlns:android="http://schemas.android.com/apk/res/android"

    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:fitsSystemWindows="true"
    >
</FrameLayout>

当项目高度总和大于屏幕高度时,ScrollView 启动,我可以像预期的那样滚动 LinearLayout 内的所有项目。

问题是当我滚动到LinearLayout 的顶部时,最上面的视图隐藏在状态栏后面,如下图所示:

我正在寻找的行为是这样的:

我怎样才能完成第二张图片中显示的结果?

我的styles.xml如下

<resources>
    <style name="AppTheme" parent="Theme.AppCompat.Light.NoActionBar">
        <!-- Customize your theme here. -->
        <item name="colorPrimary">@color/colorPrimary</item>
        <item name="colorPrimaryDark">@color/colorPrimaryDark</item>
        <item name="colorAccent">@color/colorAccent</item>
    </style>
</resources>

【问题讨论】:

  • 您能否编辑您的问题以包含此活动使用的主题的样式定义?
  • 它在实际设备或模拟器上能正常工作吗?
  • 嗯...不是我期望看到的。以防万一,将android:fitsSystemWindows="true" 添加到根框架布局可以解决问题吗?
  • 我实际上已经有android:fitsSystemWindows="true" 到我的根FrameLayout。当我在实际设备上运行它时,会发生与预览相同的事情,除非我将设备旋转到横向视图时,更大的部分隐藏在设备顶部之后,我无法向下滚动。另一方面,底部有额外的填充,可能与顶部的尺寸相同

标签: android android-layout statusbar android-scrollview


【解决方案1】:

以下是要遵循的规则:

  • 不要对ScrollView 的子级使用android:layout_gravity 属性。
    • 它会产生不受欢迎的行为,有关详细信息,请参阅 cmets。
  • 不要对ScrollView 的孩子使用android:layout_height="match_parent"
    • 孩子不想和屏幕一样大(滚动视图视口)。关键是孩子有一个精确的高度,或者想要扩大以适应自己的内容。
    • 虽然 match_parent 对于滚动视图的子项可能表现为 wrap_content,但从哲学上讲,这里没有任何意义。

如果您需要在整个屏幕上居中显示内容并且在不适合时允许滚动,请使用以下设置:

<ScrollView
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:fillViewport="true">
    <LinearLayout
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:gravity="center_vertical"
            android:orientation="vertical">
        <!-- Etc. -->
    </LinearLayout>
</ScrollView>

android:fillViewport="true" 如果子视图小于滚动视图,则展开它。

注意android:gravity 中缺少的layout_ 前缀。

  • android:gravity 告诉LinearLayout 如何将自己的孩子定位在自己内部。
  • android:layout_gravity 告诉父母是谁(这里是ScrollView)如何在父母中定位LinearLayout

【讨论】:

  • 哇,这很有效,你为我节省了数小时试图弄清楚这一点:) 非常感谢!
  • 没问题!查看编辑以获得更好的解释
  • 1/2 @BenP。好吧,孩子是由他们的父母定位的,layout_ 属性是孩子告诉父母他们想要如何定位的一种方式,对吗?现在让我们来看看 ScrollView 中发生了什么。首先,当内容测量小于视口时,一切都会正确显示layout_gravity 可以设置为任何值。其次,乍一看match_parent 被视为wrap_content,因此可以测量内容高于视口
  • 2/3 @BenP。关键是:当内容超出视口时(测量更大)您所看到的将遵循layout_gravity。如果是center,顶部和底部会出现截断。如果是bottom,内容将显示为底部对齐。问题是滚动机制仍然认为内容的左上角从视口的左上角开始 - 并且只允许您从初始位置向下滚动。您可以滚动的量“正确”计算为超过视口顶部的高度 + 超过视口底部的高度。
  • 3/3 @BenP。所以你去吧:layout_gravity 影响子布局位置 - 这在ScrollViewFrameLayout 中是相同的。但是滚动部分没有看到这一点,并假设内容的 [0, 0] 位于滚动视图的 [0, 0] 处。您可以滚动正确的数量,但它会被抵消(除非layout_gravity="top" 或等效项)。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-03-14
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多