2
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

【Kotlin研修14日目】CoordinatorLayoutを利用したスクロールと連動するツールバー・FABの実装

Last updated at Posted at 2021-06-22

アクションバーとツールバー

参考: 研修4日目(アクションバー)

アクションバー

アクティビティのタイトルやアクションを視覚的に表現する、アプリ上部に表示されるバー。

アクションバー.png

ツールバー

アクティビティのタイトルやアクションを視覚的に表現するバー。
レイアウトファイル(=activity_main.xml)に記述してビューとして定義できるため、アクションバーに比べて柔軟性に富む。

ツールバー.png


ツールバーの代用

アクションバーの代わりに自作したツールバーを表示する手順は、以下の通り。

  1. アクションバーを非表示にする
  2. レイアウトファイルへのToolbarタグの記述
  3. アクティビティクラスでのツールバーの定義

アクションバーの非表示

参考: 研修14日目(代替テーマ)
アクションバーを非表示にする場合、テーマファイル(=themes.xml)で.NoActionBar代替テーマを使用する。

サンプルコード

app/res/values/themes/themes.xml
<resources xmlns:tools="http://schemas.android.com/tools">
    <style name="Theme.Toolbar" 
           parent="Theme.MaterialComponents.DayNight.NoActionBar">
</resources>

レイアウトファイルへの記述

ツールバーレイアウトファイル(=activity_main.xml)に<Toolbar>タグを用いて記述する。
ただし、Android Xライブラリに含まれるツールバーを利用する場合、パッケージ名を含めて記述する必要がある。

なお、標準でマテリアルデザインが採用されたテーマの設定値を属性値として利用する場合、属性値を?attr/<テーマ属性値>で記述する。

また、UI部品に影をつける場合、android:elevation属性の値を調整する。

サンプルコード

activity_main.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout ...>
    <androidx.appcompat.widget.Toolbar
        android:id="@+id/toolbar"
        android:layout_width="match_parent"
        android:layout_height="?attr/actionBarSize"
        android:background="?attr/colorPrimary"
        android:elevation="10dp"/>
    ...
</LinearLayout>

ツールバーの定義

レイアウトファイルで定義したツールバーアクティビティに表示する場合は、
AppCompatActivityクラスのsetSupportActionBar()メソッドを用いる。

また、ロゴ文字列に関する情報はレイアウトではないため、アクティビティクラスで定義する必要がある。

定義

AppCompatActivity.setSupportActionBar(
    @Nullable toolbar: Toolbar?
): Unit
// パラメータ
// toolbar: アクションバーとして設定するToolbarオブジェクト

サンプルコード

MainActivity.kt
override fun onCreate(savedInstanceState: Bundle?) {
    super.onCreate(savedInstanceState)
    setContentView(R.layout.activity_main)

    // Toolbar
    val toolbar = findViewById<Toolbar>(R.id.toolbar)

    // ロゴの表示
    toolbar.setLogo(R.mipmap.ic_launcher)

    // タイトルの文字列
    toolbar.setTitle(R.string.toolbar_title)

    // タイトルの文字色
    toolbar.setTitleTextColor(Color.WHITE)

    // サブタイトルの文字列
    toolbar.setSubtitle(R.string.toolbar_subtitle)

    // サブタイトルの文字色
    toolbar.setSubtitleTextColor(Color.LTGRAY)

    // ツールバーをアクションバーとして指定
    setSupportActionBar(toolbar)
}

スクロールと連動するツールバーの実装

画面のスクロールに応じて見え隠れするツールバーを実装する手順は、以下の通り。

  1. スクロール部分連動部分の両方を<CoordinatorLayout>タグで囲う
  2. スクロールに連動して見え隠れするUI部品<AppBarLayout>タグで囲い、
    UI部品のタグにapp:layout_scrollFrags属性を記述
  3. スクロール部分<NestedScrollView>タグで囲う
  4. アクティビティクラスでのツールバーの定義(上記サンプルコードと同じ)

スクロール部分・連動部分全体の記述

スクロール部分スクロールに連動して動く連動部分の両方を<CoordinatorLayout>タグで囲うことで、
UI部品同士を連動させながらz方向に重ねることができる。

CoordinatorLayout

UI部品同士を連動させながらz方向に重ねるレイアウト部品
ただし、スクロール部分UI部品NestedScrollingChildインタフェースを実装したビューである必要がある。

FrameLayoutとCoordinatorLayout

参考: 研修1日目(レイアウト部品)
参考: FrameLayoutとCoordinatorLayout
UI部品同士をz方向に重ねられるレイアウト部品であるFrameLayoutCoordinatorLayoutの違いは、以下の通り。

レイアウト部品 UI部品を束ねる方向 UI部品間の連動
FrameLayout z方向 x
CoordinatorLayout z方向 o

サンプルコード

activity_main.xml
<?xml version="1.0" encoding="utf-8"?>
<!-- CoordinatorLayout -->
<androidx.coordinatorlayout.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">

    <!-- 連動部分 -->

    <!-- スクロール部分 -->

</androidx.coordinatorlayout.widget.CoordinatorLayout>

連動部分の記述

連動部分<AppBarLayout>タグで囲うことで、子ビューに対してスクロールに連動する動きを付与することができる。

<AppBarLayout>タグ内の子ビューapp:layout_scrollFlags属性を設定することで、
属性値に応じたモーションを付与することができる。

ここで、app:layout_scrollFlags属性の属性値は、scroll|<スクロールモード>で表される。

AppBarLayout

子ビューに対してスクロールに連動する動きを付与することができるレイアウト部品

app:layout_scrollFlags属性の属性値(=スクロールモード)

スクロールによってツールバーが縮小されるenterAlwaysCollapsedモードとexitUntilCollapsedモードについては、
連動部分を、後述する<CollapsingToolbarLayout>タグで囲い、
<CollapsingToolbarLayout>タグにapp:layout_scrollFlags属性を付与し、
連動部分app:layout_collapseMode属性を記述する必要がある。

モード 下スクロール時の挙動 上スクロール時の挙動 ツールバーのサイズ
enterAlways 消失 出現 不変
enterAlwaysCollapsed 消失 上端到達時のみ出現 変動
exitUntilCollapsed 一部出現 上端到達時のみ完全に出現 変動

サンプルコード

activity_main.xml
<!-- AppBarLayout -->
<com.google.android.material.appbar.AppBarLayout
    ...
    android:elevation="10dp">

    <!-- Toolbar -->
    <androidx.appcompat.widget.Toolbar
        ...
        app:layout_scrollFlags="scroll|enterAlways"
        .../>

</com.google.android.material.appbar.AppBarLayout>

スクロール部分の記述

CoordinatorLayoutと連携するScrollView」にあたる、
NestedScrollingChildインタフェースを実装したNestedScrollViewを用いてスクロール部分を記述する。

ここで、NestedScrollViewCoordinatorLayoutと連携させるためには、
NestedScrollViewapp:layout_behavior属性に対して、
xmlns:app="http://schemas.android.com/apk/res-auto"が提供する
appbar_scrolling_view_behaviorタグの属性値を付与する必要がある。

サンプルコード

activity_main.xml
<?xml version="1.0" encoding="utf-8"?>
<androidx.coordinatorlayout.widget.CoordinatorLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    ...>

    <!-- 連動部分 -->

    <!-- スクロール部分 -->
    <androidx.core.widget.NestedScrollView
        ...
        app:layout_behavior="@string/appbar_scrolling_view_behavior">

        <TextView .../>

    </androidx.core.widget.NestedScrollView>

</androidx.coordinatorlayout.widget.CoordinatorLayout>

まとめ

activity_main.xml
<!-- CoordinatorLayoutでスクロール部分・連動部分を囲う -->
<CoordinatorLayout>

    <!-- 連動部分 -->
    <!-- 連動部分はAppBarLayoutで囲う -->
    <AppBarLayout
        ...
        android:elevation="4dp">

        <Toolbar
            ...
            app:layout_scrollFlags="scroll|enterAlways"
        .../>

    </AppBarLayout>

    <!-- スクロール部分 -->
    <!-- スクロール部分はNestedScrollViewで囲う -->
    <NestedScrollView
        ...
        app:layout_behavior="@string/appbar_scrolling_view_behavior">

        <!-- スクロールするビュー -->

    </NestedScrollView>

</CoordinatorLayout>

enterAlwaysCollapsed/exitUntilCollapsedモードで動作するツールバーの実装

ツールバーenterAlwaysCollapsedexitUntilCollapseモードで動作させる場合、
レイアウトファイルに、ツールバーサイズを変動させる<CollapsingToolbarLayout>タグを記述する必要がある。

  1. スクロール部分連動部分の両方を<CoordinatorLayout>タグで囲う
  2. スクロールに連動してサイズを変えながら見え隠れするUI部品<CollapsingToolbarLayout>タグで囲い、
    <CollapsingToolbarLayout>タグにapp:layout_scrollFrags属性を、
    UI部品のタグにapp:layout_collapseMode属性を記述
  3. <CollapsingToolbarLayout>タグを<AppBarLayout>タグで囲い、
    <AppBarLayout>タグでツールバーのサイズ初期値`を定義
  4. アクティビティクラスでのツールバーの定義(上記サンプルコードとは異なる)
  5. スクロール部分<NestedScrollView>タグで囲う

連動部分の記述

スクロールによってツールバーが縮小されるenterAlwaysCollapsedモードとexitUntilCollapsedモードについては、
連動部分を、ツールバーのサイズを変動させる<CollapsingToolbarLayout>タグで囲い、
<CollapsingToolbarLayout>タグにapp:layout_scrollFlags属性を付与する必要がある。

また、子ビューに対してスクロールに連動する動きを付与する<AppBarLayout>タグで<CollapsingToolbarLayout>を囲い、
<AppBarLayout>タグでツールバーの初期状態のサイズを指定する必要がある。

なお、exitUntilCollapsedモードについては、サイズの縮小下限を指定するために、
<Toolbar>タグにapp:layout_collapseMode属性を記述する必要がある。

CollapsingToolbarLayout

スクロールに連動してツールバーのサイズを変更できるレイアウト部品

app:layout_collapseMode属性の属性値(=折りたたみモード)

属性値 縮小時の表示コンテンツ 縮小中のヘッダーの挙動
pin 全て表示 そのまま上方向へ移動
parallax タイトルのみ表示 視差方式で上方向へ移動
none タイトルのみ表示 そのまま上方向へ移動

サンプルコード

activity_main.xml
<?xml version="1.0" encoding="utf-8"?>
<androidx.coordinatorlayout.widget.CoordinatorLayout ...>

    <!-- 連動部分 -->
    <!-- 連動部分はAppBarLayoutで囲い、サイズの初期値を記述する -->
    <com.google.android.material.appbar.AppBarLayout
        ...
        android:layout_height="180dp"
        android:elevation="10dp">

        <!-- 連動するビューはCollapsingToolbarLayoutで囲う -->
        <com.google.android.material.appbar.CollapsingToolbarLayout
            ...
            app:layout_scrollFlags="scroll|enterAlwaysCollapsed">

            <!-- 連動するビュー -->
            <androidx.appcompat.widget.Toolbar
                ...
                app:layout_collapseMode="pin"/>

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

    </com.google.android.material.appbar.AppBarLayout>

    <!-- スクロール部分 -->

</androidx.coordinatorlayout.widget.CoordinatorLayout>

ツールバーの定義

ツールバーに表示されるコンテンツを保持するオブジェクトは、コンテンツによって以下のように異なる。

コンテンツ 保持オブジェクト
ロゴ Toolbar
タイトル文字列 Toolbar
および
CollapsingToolbarLayout
タイトル文字色 CollapsingToolbarLayout

このため、ツールバーを定義する際はロゴタイトルで分離して定義する必要がある。

タイトル文字列CollapsingToolbarLayouttitleプロパティ、
タイトル文字色CollapsingToolbarLayoutsetExpandedTitleColor()setCollapsedTitleTextColor()メソッドで定義する。

setExpandedTitleColor()メソッドは通常時タイトル文字色
setCollapsedTitleTextColor()メソッドは縮小時タイトル文字色を設定する。

サンプルコード

MainActivity.kt
// Toolbar
val toolbar = findViewById<Toolbar>(R.id.toolbar)

// ロゴの表示
toolbar.setLogo(R.mipmap.ic_launcher)

// ツールバーをアクションバーとして指定
setSupportActionBar(toolbar)

// CollapsingToolbarLayout
val toolbarLayout = findViewById<CollapsingToolbarLayout>(R.id.toolbarLayout)

// タイトルの文字列
toolbarLayout.title = getString(R.string.toolbar_title)

// 通常サイズ時のタイトルの文字色
toolbarLayout.setExpandedTitleColor(Color.WHITE)

// 縮小サイズ時のタイトルの文字色
toolbarLayout.setCollapsedTitleTextColor(Color.LTGRAY)

FABの実装

FABは、レイアウトファイル<CoordinatorLayout>タグ配下に<FloatingActionButton>タグを記述することで実装することができる。

FABを重ねて表示するUI部品app:layout_anchor属性で指定し、
UI部品内でのFABの表示位置をapp:layout_anchorGravity属性で指定する。

また、FABアイコンapp:srcCompat属性で指定できる。

FAB(Floating Action Button)

UI部品に重なり、浮いているように表示されるボタン。

FAB.png

app:layout_anchorGravity属性の属性値

top/start top/center_horizontal top/end
center_vertical/start center center_vertical/end
bottom/start bottom/center_horizontal bottom/end

サンプルコード

activity_main.xml
<?xml version="1.0" encoding="utf-8"?>
<androidx.coordinatorlayout.widget.CoordinatorLayout ...>
    <!-- FABを重ねるUI部品 -->

    <!-- FAB -->
    <com.google.android.material.floatingactionbutton.FloatingActionButton
        android:id="@+id/fabEmail"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_margin="20dp"
        app:layout_anchor="@id/appbar"
        app:layout_anchorGravity="bottom|end"
        app:srcCompat="@android:drawable/ic_dialog_email"
    />

</androidx.coordinatorlayout.widget.CoordinatorLayout>

Scrolling Activity

スクロールを実装したアクティビティを作成できるプロジェクトテンプレート

2
2
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
2
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?