ScrollView 被 toolbar 覆盖

ScrollView gets covered by toolbar

我不明白为什么我的滚动视图会发生这种情况。当没有编辑文本聚焦时,布局似乎没问题,如下图所示。

但是当用户碰巧位于其中一个编辑文本框时,工具栏和键盘布局会占用所有 space 隐藏滚动视图,如下所示

此布局是:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout 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:id="@+id/activity_meal_viewer"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:background="@color/light_gray"
    android:orientation="vertical">


    <include
        android:id="@+id/tool_bar"
        layout="@layout/toolbar"
        android:layout_width="match_parent"
        android:layout_height="wrap_content" />

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

        <android.support.v7.widget.CardView
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:layout_margin="@dimen/activity_horizontal_margin"
            android:background="@android:color/white">

            <LinearLayout
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:orientation="vertical"
                android:padding="@dimen/activity_horizontal_margin">


                <EditText
                    android:id="@+id/person_name"
                    android:layout_width="match_parent"
                    android:layout_height="wrap_content"
                    android:layout_marginBottom="@dimen/activity_horizontal_margin"
                    android:background="@drawable/generic_shape_rect"
                    android:drawableLeft="@drawable/ic_people"
                    android:drawablePadding="@dimen/activity_horizontal_margin"
                    android:drawableStart="@drawable/ic_people"
                    android:gravity="center_vertical"
                    android:hint="@string/full_name"
                    android:inputType="textPersonName"
                    android:maxLines="1"
                    android:typeface="serif" />

                <EditText
                    android:id="@+id/person_address"
                    android:layout_width="match_parent"
                    android:layout_height="wrap_content"
                    android:background="@drawable/generic_shape_rect"
                    android:drawableLeft="@drawable/ic_pin"
                    android:drawablePadding="@dimen/activity_horizontal_margin"
                    android:drawableStart="@drawable/ic_pin"
                    android:gravity="center_vertical"
                    android:hint="@string/address"
                    android:inputType="text"
                    android:maxLines="1"
                    android:typeface="serif" />

            </LinearLayout>
        </android.support.v7.widget.CardView>

        <android.support.v7.widget.CardView
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:layout_marginBottom="@dimen/activity_horizontal_margin"
            android:layout_marginLeft="@dimen/activity_horizontal_margin"
            android:layout_marginRight="@dimen/activity_horizontal_margin"
            android:layout_marginTop="0dp"
            android:background="@android:color/white"
            app:cardCornerRadius="2dp">


            <LinearLayout
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:orientation="vertical"
                android:padding="@dimen/activity_horizontal_margin">

                <EditText
                    android:id="@+id/person_email"
                    android:layout_width="match_parent"
                    android:layout_height="wrap_content"
                    android:layout_marginBottom="@dimen/activity_horizontal_margin"
                    android:background="@drawable/generic_shape_rect"
                    android:drawableLeft="@drawable/ic_email"
                    android:drawablePadding="@dimen/activity_horizontal_margin"
                    android:drawableStart="@drawable/ic_email"
                    android:ems="10"
                    android:hint="@string/email"
                    android:inputType="textEmailAddress"
                    android:maxLines="1"
                    android:typeface="serif" />


                <EditText
                    android:id="@+id/person_phone"
                    android:layout_width="match_parent"
                    android:layout_height="wrap_content"
                    android:background="@drawable/generic_shape_rect"
                    android:drawableLeft="@drawable/ic_telephone"
                    android:drawablePadding="@dimen/activity_horizontal_margin"
                    android:drawableStart="@drawable/ic_telephone"
                    android:ems="10"
                    android:hint="@string/phone"
                    android:inputType="phone"
                    android:typeface="serif" />
            </LinearLayout>


        </android.support.v7.widget.CardView>

        <android.support.v7.widget.CardView
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:layout_marginBottom="@dimen/activity_horizontal_margin"
            android:layout_marginLeft="@dimen/activity_horizontal_margin"
            android:layout_marginRight="@dimen/activity_horizontal_margin"
            android:layout_marginTop="0dp"
            android:background="@android:color/white"
            app:cardCornerRadius="2dp">


            <LinearLayout
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:orientation="vertical"
                android:padding="@dimen/activity_horizontal_margin">


                <EditText
                    android:id="@+id/person_initial_fund"
                    android:layout_width="match_parent"
                    android:layout_height="wrap_content"
                    android:background="@drawable/generic_shape_rect"
                    android:drawableLeft="@drawable/ic_dollar"
                    android:drawablePadding="@dimen/activity_horizontal_margin"
                    android:drawableStart="@drawable/ic_dollar"
                    android:ems="10"
                    android:hint="@string/initial_fund"
                    android:inputType="numberSigned"
                    android:maxLines="1"
                    android:typeface="serif" />
            </LinearLayout>


        </android.support.v7.widget.CardView>

        <ImageButton
            android:layout_width="48dp"
            android:layout_height="48dp"
            android:layout_gravity="center"
            android:layout_marginBottom="@dimen/activity_horizontal_margin"
            android:layout_marginLeft="@dimen/activity_horizontal_margin"
            android:layout_marginRight="@dimen/activity_horizontal_margin"
            android:layout_marginTop="0dp"
            android:background="@drawable/selector_button_accent"
            android:contentDescription="@string/done"
            android:onClick="handlePeople"
            android:src="@drawable/ic_action_done" />
    </LinearLayout>
</LinearLayout>

工具栏布局文件是:

<?xml version="1.0" encoding="utf-8"?>
<android.support.v7.widget.Toolbar xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="?attr/actionBarSize"
    android:fitsSystemWindows="true"
    android:theme="@style/ThemeOverlay.AppCompat.Dark.ActionBar" />

Note : i also tried NestesScrollView but that didn't work either

也许您应该使用 google 支持设计中的 CoordinatorLayout 而不是 LinearLayout。并在工具栏内添加AppBarLayout。 文档显示 this

默认情况下,当 fitsSystemWindows 用于 View 时,系统提供的 WindowInsetsView 用作填充,这就是为什么您的工具栏有额外的 space在上面,由于状态栏是透明的,系统在接收到WindowInsets的时候会添加一些topPadding。

但是,当键盘出现时,系统会抛出一个新的WindowInsets,并将键盘的高度作为底部插图。而且,由于您的工具栏将对这个新的 WindowInsets 作出反应,工具栏将添加键盘的高度作为底部填充,因此,像您的屏幕截图一样增长。

如果您想解决此问题,您有 2 个解决方案: 首先,让键盘跨越 activity 的内容而不是调整 Activity 的大小。您可以通过在 Activity 的清单条目中进行设置来做到这一点:

<activity
        android:name=".YourActivity"
        android:windowSoftInputMode="adjustPan"/>

这将使键盘将所有内容推到顶部,确保在键盘弹起时 EditText 仍然可见。但这可以在键盘启动时将工具栏推到 window 之外。是否接受由您决定。

如果您不满意,您可以编写一些代码来手动处理 WindowInset 以仅将顶部填充应用于工具栏并忽略底部插图。 你可以这样做:

ViewCompat.setOnApplyWindowInsetsListener(toolbar, new OnApplyWindowInsetsListener() {
    @Override
    public WindowInsetsCompat onApplyWindowInsets(
        View v, WindowInsetsCompat insets
    ) {
        v.setPadding(0, insets.getSystemWindowInsetTop(), 0, 0);
        insets.consumeSystemWindowInsets();
        return insets;
    }
});

但请注意,即使此代码可以在任何 API 级别上编译和 运行(它使用来自 support-v4 的内容),这也仅在 API 上有效21 及之后,他们改变了 WindowInsets 的工作方式。 如果您使用 API 19 中的 transparentStatusBar,则必须编写更多代码才能使用已弃用的 API ... 我倾向于忽略这一点,只允许 transparentStatusBar 从 API 21 开始,老实说,正确处理它的痛苦要少得多。

希望对您有所帮助。