解决 Material Design 中的 CollapsingToolbarLayout 与 Toolbar 的高度不一致问题

问题描述

在 Android 中,我们经常需要使用 Material Design 的布局来创建具有美观效果的应用程序。其中,CollapsingToolbarLayout 和 Toolbar 组成了许多优秀 Material Design 应用程序中的重要布局元素。不过,在使用 CollapsingToolbarLayout 和 Toolbar 时,我们可能会遇到一个问题:他们的高度不一致,导致页面在滚动时出现明显问题。

如下图所示:

可以看到,在未滚动时,CollapsingToolbarLayout 的高度与 Toolbar 相等,但是一旦向下滚动,CollapsingToolbarLayout 就会收缩并留下一定的空白,使其高度小于 Toolbar 的高度。

解决方案

解决这个问题有多种方法。下面将介绍两种常用的方法。

方法一:设置 Toolbar 的高度和 CollapsingToolbarLayout 的高度相等

这是最简单的解决方法之一。我们只需将 CollapsingToolbarLayout 的高度设置为 Toolbar 的高度即可。可以通过以下两种方式进行设置:

方式一:在 xml 文件中设置

在 xml 文件中设置时,我们可以使用 app:layout_collapseMode 属性。将该属性设置为 parallaxpin,表示 CollapsingToolbarLayout 元素具有折叠或固定的能力。

在这种情况下,我们只需使用 android:layout_height 属性将 CollapsingToolbarLayout 的高度设置为 Toolbar 的高度即可。示例代码如下:

<android.support.design.widget.CollapsingToolbarLayout
    android:id="@+id/collapsing_toolbar"
    android:layout_width="match_parent"
    android:layout_height="?attr/actionBarSize"
    app:contentScrim="?attr/colorPrimary"
    app:layout_scrollFlags="scroll|exitUntilCollapsed"
    app:layout_collapseMode="parallax">

    <android.support.v7.widget.Toolbar
        android:id="@+id/toolbar"
        android:layout_width="match_parent"
        android:layout_height="?attr/actionBarSize"
        app:layout_collapseMode="pin" />

</android.support.design.widget.CollapsingToolbarLayout>

方式二:在代码中设置

在代码中设置时,我们可以使用 Toolbar.getHeight() 方法获取 Toolbar 的高度,然后将 CollapsingToolbarLayout 的高度设置为 Toolbar 的高度。示例代码如下:

Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
CollapsingToolbarLayout collapsingToolbar =
    (CollapsingToolbarLayout) findViewById(R.id.collapsing_toolbar);
collapsingToolbar.setMinimumHeight(toolbar.getHeight());

方法二:构建不同高度的布局资源文件

如果您不想使用前面介绍的简单方法,那么您可以构建不同高度的布局资源文件。通过这种方法,我们可以通过创建多个布局文件来解决高度不一致的问题。

首先,我们需要在 res 文件夹中创建文件夹 layout-xlarge,表示我们要创建的布局文件仅针对大屏幕手机或平板电脑。随后,我们需要在 layout-xlarge 文件夹中创建两个布局资源文件,分别为 activity_main.xmlactivity_main_collapsed.xml

activity_main.xml 表示未滚动时的布局文件,而 activity_main_collapsed.xml 表示滚动时的布局文件。其中,我们需要在 activity_main.xml 中使用 app:layout_collapseMode 属性将 Toolbar 设置为固定位置的布局元素。而在 activity_main_collapsed.xml 中,我们需要将 Toolbar 设置为滚动的布局元素。

示例代码如下:

activity_main.xml

<?xml version="1.0" encoding="utf-8"?>
<android.support.design.widget.CoordinatorLayout
  xmlns:android="http://schemas.android.com/apk/res/android"
  xmlns:app="http://schemas.android.com/apk/res-auto"
  android:layout_width="match_parent"
  android:layout_height="match_parent">

  <android.support.design.widget.AppBarLayout
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:theme="@style/AppTheme.AppBarOverlay">

    <android.support.design.widget.CollapsingToolbarLayout
      android:id="@+id/toolbar_layout"
      android:layout_width="match_parent"
      android:layout_height="match_parent"
      app:contentScrim="?attr/colorPrimary"
      app:layout_scrollFlags="scroll|exitUntilCollapsed"
      app:layout_collapseMode="parallax">

      <ImageView
        android:id="@+id/toolbar_image"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:adjustViewBounds="true"
        android:scaleType="fitCenter"
        android:src="@drawable/your_image" />

      <android.support.v7.widget.Toolbar
        android:id="@+id/toolbar"
        android:layout_width="match_parent"
        android:layout_height="?attr/actionBarSize"
        app:layout_collapseMode="pin" />

    </android.support.design.widget.CollapsingToolbarLayout>

  </android.support.design.widget.AppBarLayout>

  <include layout="@layout/content_main" />

  <android.support.design.widget.FloatingActionButton
    android:id="@+id/fab"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:layout_margin="@dimen/fab_margin"
    android:src="@android:drawable/ic_dialog_email"
    app:layout_anchor="@id/content"
    app:layout_anchorGravity="bottom|end" />

</android.support.design.widget.CoordinatorLayout>

activity_main_collapsed.xml

<?xml version="1.0" encoding="utf-8"?>
<android.support.design.widget.CoordinatorLayout
  xmlns:android="http://schemas.android.com/apk/res/android"
  xmlns:app="http://schemas.android.com/apk/res-auto"
  android:layout_width="match_parent"
  android:layout_height="match_parent">

  <android.support.design.widget.AppBarLayout
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:theme="@style/AppTheme.AppBarOverlay">

    <android.support.design.widget.CollapsingToolbarLayout
      android:id="@+id/toolbar_layout"
      android:layout_width="match_parent"
      android:layout_height="wrap_content"
      app:contentScrim="?attr/colorPrimary"
      app:layout_scrollFlags="scroll|exitUntilCollapsed"
      app:layout_collapseMode="pin">

      <ImageView
        android:id="@+id/toolbar_image"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:adjustViewBounds="true"
        android:scaleType="fitCenter"
        android:src="@drawable/your_image" />

      <android.support.v7.widget.Toolbar
        android:id="@+id/toolbar"
        android:layout_width="match_parent"
        android:layout_height="?attr/actionBarSize" />

    </android.support.design.widget.CollapsingToolbarLayout>

  </android.support.design.widget.AppBarLayout>

  <include layout="@layout/content_main" />

  <android.support.design.widget.FloatingActionButton
    android:id="@+id/fab"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:layout_margin="@dimen/fab_margin"
    android:src="@android:drawable/ic_dialog_email"
    app:layout_anchor="@id/content"
    app:layout_anchorGravity="bottom|end" />

</android.support.design.widget.CoordinatorLayout>

最后,我们需要在代码中根据屏幕尺寸加载相应的布局文件。示例代码如下:

// Activity 中 onCreate() 方法中加载布局文件
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(getScreenSize() >= 10 ?
        R.layout.activity_main_xlarge : R.layout.activity_main);
}

private int getScreenSize() {
    DisplayMetrics metrics = new DisplayMetrics();
    getWindowManager().getDefaultDisplay().getMetrics(metrics);
    return Math.round(Math.max(metrics.widthPixels, metrics.heightPixels) /
        (metrics.densityDpi / (float) DisplayMetrics.DENSITY_DEFAULT));
}

总结

本文介绍了如何解决 Android 中使用 Material Design 的 CollapsingToolbarLayout 和 Toolbar 出现高度不一致的问题。我们详细介绍了两种解决方案,并给出了示例代码。希望读者们通过本文的介绍,掌握解决这一问题的方法,能够在实际开发中更好地运用 Material Design 布局元素,创建出具有美观效果的应用程序。

来源:JavaScript中文网 ,转载请注明来源 本文地址:https://www.javascriptcn.com/post/65968c6feb4cecbf2da5b2b0


纠错反馈