Collapsing Toolbar (折りたたみツールバー) の典型的な実装方法
ここでは、Android Design Support Library でサポートされる、 折り畳みツールバー (Collapsing Toolbars) の典型的な実装方法について説明します。
そもそも、Collapsing Toolbar とは何でしょうか?
Collapsing Toolbar というのは不要な時に小さくなり画面上部に隠れ、必要に応じてスワイプによって再表示されるタイプのツールバーです。
Android Design Support Library では、こうしたツールバーを実装するための、CollapsingToolbarLayout がサポートされています。
CollapsingToolbarLayout では単にツールバー部分の表示・非表示を制御するだけではなく、任意のウィジェットをツールバーに付随させることができます。 例えば今回紹介する例では、以下のように画像を表示しています。
ここで作成するサンプルコードは次のように動作します。
ここではツールバーは、上部にスライドした後に消えてなくなっています。
タイトルだけの表示に切り替わります。オプションメニューはなくなっていますね。
これは折り畳みモード (layout_collapseMode) を parallax にしているためです。 ここで "pin" を指定すればツールバーを上部に表示したままにすることも可能です。
このプログラムを Android Studio の Empty Project をベースにして、作成してみましょう。
レイアウトリソース res/layout/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:fitsSystemWindows="true">
<android.support.design.widget.AppBarLayout
android:layout_width="match_parent"
android:layout_height="300dp"
android:fitsSystemWindows="true"
android:theme="@style/ThemeOverlay.AppCompat.Dark.ActionBar">
<android.support.design.widget.CollapsingToolbarLayout
android:id="@+id/collapsingToolbarLayout"
android:layout_width="match_parent"
android:layout_height="match_parent"
app:layout_scrollFlags="scroll|exitUntilCollapsed"
app:contentScrim="?attr/colorPrimary"
android:fitsSystemWindows="true"
app:title="Hello, title!">
<ImageView
android:src="@drawable/flower"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:scaleType="centerCrop"
android:minHeight="100dp"
app:layout_collapseMode="parallax"/>
<android.support.v7.widget.Toolbar
android:id="@+id/toolbar"
android:layout_width="match_parent"
android:layout_height="?attr/actionBarSize"
android:background="?attr/colorPrimary"
app:popupTheme="@style/ThemeOverlay.AppCompat.Light"
app:layout_collapseMode="parallax"/>
</android.support.design.widget.CollapsingToolbarLayout>
</android.support.design.widget.AppBarLayout>
<android.support.v7.widget.RecyclerView
android:id="@+id/recyclerView"
android:scrollbars="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent"
app:layout_behavior="@string/appbar_scrolling_view_behavior"/>
</android.support.design.widget.CoordinatorLayout>
注意点としては、 AppBarLayout の1つ目の子要素として CollapsingToolbarLayout を定義します。
ここではその中に、花の画像 (drawable/flower.jpg) を表示する ImageView と Toolbar を定義しています。
サンプルデータ (スクリーンショットで A ~ Z を表示している箇所) は RecyclerView を用いて表示しているので、 RecyclerView の行毎のレイアウト res/layout/my_row1.xml も用意しておきます。単に TextView を保持する RelativeLayout です。
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<TextView
android:id="@+id/textView1"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_alignParentTop="true"
android:layout_alignParentLeft="true"
android:layout_margin="16dp"
android:textSize="30sp"/>
</RelativeLayout>
オプションメニュー res/menu/options.xml も一応セットしています。
<?xml version="1.0" encoding="utf-8"?>
<menu
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto">
<item
android:id="@+id/action_settings"
android:orderInCategory="100"
android:title="Settings"
app:showAsAction="never"/>
</menu>
その他、デフォルトから変更したリソースは次の通り。
res/values/colors.xml
<?xml version="1.0" encoding="utf-8"?>
<resources>
<color name="colorPrimary">#009688</color>
<color name="colorPrimaryDark">#00796B</color>
<color name="colorAccent">#FF4081</color>
</resources>
配色は Material Design のカラーパレットから選ぶと良いです。基本、Primary が 500 で Dark が 700 です。
res/values/styles.xml
<resources>
<style name="AppTheme" parent="Theme.AppCompat.Light.NoActionBar">
<item name="colorPrimary">@color/colorPrimary</item>
<item name="colorPrimaryDark">@color/colorPrimaryDark</item>
<item name="colorAccent">@color/colorAccent</item>
</style>
</resources>
テーマを Theme.AppCompat.Light.NoActionBar に変更しています。
さて、上記を準備してしまえば後は特に Collapsing Toolbar に関しては、コードで準備する箇所は特にありません。 コードは主に オプションメニュー と RecyclerView に関するものです。
MainActivity.java
package com.keicode.android.test2.collapsingtoolbar1;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.support.v7.widget.LinearLayoutManager;
import android.support.v7.widget.RecyclerView;
import android.support.v7.widget.Toolbar;
import android.view.Menu;
import java.util.ArrayList;
public class MainActivity extends AppCompatActivity {
private RecyclerView.Adapter mAdapter;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
setSupportActionBar(toolbar);
// Recycle View
RecyclerView recyclerView = (RecyclerView) findViewById(R.id.recyclerView);
RecyclerView.LayoutManager layoutManager = new LinearLayoutManager(this);
recyclerView.setLayoutManager(layoutManager);
ArrayList<String> dataList = new ArrayList<>();
for(char ch='A'; ch<='Z'; ch++) {
dataList.add(Character.toString(ch));
}
mAdapter = new MyAdapter(dataList);
recyclerView.setAdapter(mAdapter);
}
@Override
public boolean onCreateOptionsMenu(Menu menu){
getMenuInflater().inflate(R.menu.options, menu);
return true;
}
}
RecyclerView のデータアダプター MyAdapter.java は次の通り。
package com.keicode.android.test2.collapsingtoolbar1;
import android.support.v7.widget.RecyclerView;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.TextView;
import java.util.ArrayList;
public class MyAdapter extends RecyclerView.Adapter<MyAdapter.ItemViewHolder> {
ArrayList<String> mArrayList;
public static class ItemViewHolder extends RecyclerView.ViewHolder{
public TextView mTextView;
public ItemViewHolder(View v){
super(v);
mTextView = (TextView) v.findViewById(R.id.textView1);
}
}
public MyAdapter(ArrayList<String> arrayList){
this.mArrayList = arrayList;
}
@Override
public ItemViewHolder onCreateViewHolder( ViewGroup parent, int viewType ){
View v = LayoutInflater.from(parent.getContext()).inflate(R.layout.my_row1, parent, false);
return new ItemViewHolder(v);
}
@Override
public void onBindViewHolder(ItemViewHolder holder ,int position){
final String data;
data = mArrayList.get(position);
holder.mTextView.setText(data);
}
@Override
public int getItemCount(){
return mArrayList.size();
}
}
以上で、上記のアニメーションのような動作が実現できるはずです。