markdown

はじめに (対象読者・この記事でわかること)

本記事は、Android アプリ開発に携わっている Java エンジニアを対象としています。特に、スクロールやスワイプに合わせて ToolBar が自然に隠れたり表示されたりする UI を実装したい方に最適です。この記事を読むことで、以下のことができるようになります。

  • CoordinatorLayout の基本的な役割と仕組みが理解できる
  • AppBarLayout と Toolbar を組み合わせたレイアウト構成を作成できる
  • スクロールに応じて Toolbar がアニメーションで隠れる・表示される動作を実装できる
  • 実装時に陥りやすいエラーや挙動の違いを把握し、対処法を身につけられる

開発現場で「スクロール時にヘッダーを自動で隠す」要件が増えており、実装例が少ないことが背景です。本稿はそのギャップを埋め、すぐにプロジェクトに組み込めるコードとベストプラクティスを提供します。

前提知識

この記事を読み進める上で、以下の知識があるとスムーズです。

  • Java の基本文法と Android Studio の基本的な操作
  • XML による Android のレイアウト定義(View、ViewGroup の概念)
  • AndroidX ライブラリ(特に material コンポーネント)の導入方法

CoordinatorLayout と ToolBar の基礎

CoordinatorLayout は AndroidX が提供する高度なレイアウトコンテナで、子ビュー同士の相互作用(ビヘイビア)を宣言的に記述できます。ToolBar(正確には Toolbar)を AppBarLayout と組み合わせることで、スクロールに合わせた動的な表示・非表示が容易になります。

1. CoordinatorLayout の役割

  • 子ビューの位置やサイズを決定するだけでなく、Behavior クラスを通じてスクロールやタッチイベントに対する反応をカスタマイズできます。
  • app:layout_behavior 属性で個別のビューにビヘイビアを割り当て、例えば ScrollingViewBehavior でリストのスクロールに連動させることが可能です。

2. AppBarLayout と Toolbar の関係

  • AppBarLayout は垂直方向に配置されるコンテナで、主に Toolbar や TabLayout を保持します。app:layout_scrollFlags 属性でスクロール時の挙動を細かく設定できます。
  • Toolbar 自体は ActionBar の代替として使われ、タイトルやメニューアイコン、ナビゲーションボタンを配置可能です。

3. 典型的なレイアウト構成例

Xml
<androidx.coordinatorlayout.widget.CoordinatorLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:app="http://schemas.android.com/apk/res-auto" android:id="@+id/coordinator" android:layout_width="match_parent" android:layout_height="match_parent"> <com.google.android.material.appbar.AppBarLayout android:id="@+id/appbar" android:layout_width="match_parent" android:layout_height="wrap_content" android:theme="@style/ThemeOverlay.AppCompat.Dark.ActionBar"> <androidx.appcompat.widget.Toolbar android:id="@+id/toolbar" android:layout_width="match_parent" android:layout_height="?attr/actionBarSize" app:layout_scrollFlags="scroll|enterAlways" app:popupTheme="@style/ThemeOverlay.AppCompat.Light"/> </com.google.android.material.appbar.AppBarLayout> <androidx.recyclerview.widget.RecyclerView android:id="@+id/recycler" android:layout_width="match_parent" android:layout_height="match_parent" app:layout_behavior="@string/appbar_scrolling_view_behavior"/> </androidx.coordinatorlayout.widget.CoordinatorLayout>

この構成では、RecyclerView のスクロールに合わせて AppBarLayout(内部の Toolbar)が自動的に上に隠れ、下にスクロールすると再び表示されます。app:layout_scrollFlags の設定次第で、「スクロール時に完全に隠す」「半透明で残す」など多様な演出が可能です。

実装手順とアニメーション詳細

以下では、実際に Android Studio でプロジェクトを作成し、CoordinatorLayout と Toolbar のアニメーションを実装する流れをステップバイステップで解説します。

ステップ 1: プロジェクトのセットアップ

  1. Android Studio で新規プロジェクト作成
    - テンプレートは「Empty Activity」を選択。
    - 「Language」は Java、最小 API レベルは 21 以上を推奨。

  2. 依存ライブラリの追加
    build.gradle (app) に以下を追記し、material ライブラリを導入します。 gradle dependencies { implementation 'com.google.android.material:material:1.12.0' } Sync Project with Gradle Files を実行して変更を適用。

  3. テーマの設定
    styles.xmlTheme.MaterialComponents.DayNight.DarkActionBar を継承したテーマを設定し、AppBarLayout が正しくテーマカラーを取得できるようにします。

ステップ 2: XML レイアウトの作成

上記「典型的なレイアウト構成例」を activity_main.xml に貼り付け、以下のポイントに注意します。

  • AppBarLayoutapp:layout_scrollFlagsscroll|enterAlways を設定。これにより、ユーザーが下方向にスクロールしたときに Toolbar が即座に再表示されます。
  • RecyclerView(または NestedScrollView)に app:layout_behavior="@string/appbar_scrolling_view_behavior" を付与し、CoordinatorLayout がスクロールイベントを伝搬できるようにします。
  • 必要に応じて android:fitsSystemWindows="true"CoordinatorLayoutAppBarLayout に設定し、ステータスバー領域との重なりを防止します。

ステップ 3: Java コードで Toolbar を初期化

MainActivity.java で Toolbar を取得し、setSupportActionBar で ActionBar と紐付けます。

Java
public class MainActivity extends AppCompatActivity { private Toolbar toolbar; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); toolbar = findViewById(R.id.toolbar); setSupportActionBar(toolbar); // Optional: カスタムタイトルやメニューの設定 getSupportActionBar().setTitle("CoordinatorLayout Demo"); } }

ステップ 4: アニメーションのカスタマイズ

デフォルトの隠れ・表示アニメーションは即座に行われますが、AppBarLayoutOnOffsetChangedListener を利用すれば、スクロール位置に応じた細かいアニメーションが実装可能です。

Java
AppBarLayout appBarLayout = findViewById(R.id.appbar); appBarLayout.addOnOffsetChangedListener(new AppBarLayout.OnOffsetChangedListener() { private boolean isShown = true; @Override public void onOffsetChanged(AppBarLayout appBarLayout, int verticalOffset) { // verticalOffset が 0 の時は完全に表示、負の値は隠れていることを示す if (Math.abs(verticalOffset) >= appBarLayout.getTotalScrollRange()) { // 完全に隠れた if (isShown) { isShown = false; // 必要ならアニメーションを走らせる toolbar.animate().alpha(0f).setDuration(200).start(); } } else { // 表示中 if (!isShown) { isShown = true; toolbar.animate().alpha(1f).setDuration(200).start(); } } } });

このリスナーは、AppBar がスクロールされるたびに verticalOffset を通知し、隠れ始めた瞬間に Toolbar の透明度をフェードアウトさせ、再表示時にフェードインさせます。setDuration の数値を調整すれば、アニメーション速度を自由にカスタマイズできます。

さらに高度な演出例

  • スライドアニメーションtranslationY プロパティを操作し、Toolbar が上方向に滑り込むように見せる。
  • 色変化:スクロール位置に応じて Toolbar の背景色を段階的に変える。
  • アイコンサイズの縮小toolbar.findViewById(R.id.toolbar_logo)scaleX/Y を連動させ、アイコンが縮小するように演出可能。

これらはすべて OnOffsetChangedListener の中で ValueAnimatorObjectAnimator を組み合わせるだけで実装できます。

ハマった点やエラー解決

発生した問題 原因 解決策
Toolbar がスクロール時に全く隠れない RecyclerViewapp:layout_behavior が未指定 app:layout_behavior="@string/appbar_scrolling_view_behavior" を追加
スクロールで Toolbar がちらつく AppBarLayoutelevation がデフォルトで 0 のまま、影が消えるため app:elevation="4dp"AppBarLayout に設定
OnOffsetChangedListener が呼び出されない CoordinatorLayout の子ビューが NestedScrollingChild を実装していない RecyclerViewNestedScrollView を使用し、nestedScrollingEnabled="true" を明示
アニメーションが不自然に止まる toolbar.animate()setInterpolator がデフォルトの AccelerateDecelerateInterpolator で速すぎる setInterpolator(new LinearOutSlowInInterpolator()) で速度曲線を調整

まとめ

本記事では、Java で Android アプリを開発する際に、CoordinatorLayout と AppBarLayout を活用した Toolbar のアニメーション を実装する手順を詳細に解説しました。

  • CoordinatorLayout の仕組みと Behavior の設定方法 を理解し、スクロールに連動させる基礎を身につけました。
  • XML と Java の具体的なコード例 を通じて、Toolbar が自動で隠れ・表示されるレイアウトを構築しました。
  • OnOffsetChangedListener を使ったカスタムアニメーション によって、フェードやスライドといった演出を自由に追加できる方法を紹介しました。
  • 実装時に起きやすいエラーとその対処法 を一覧化し、トラブルシューティングの手がかりを提供しました。

これにより、読者は自分のアプリに自然で洗練された UI を簡単に組み込むことが可能になります。今後は、スクロール連動型のカラーテーマ切替MotionLayout を使った高度なトランジション についても記事化予定です。

参考資料