しめ鯖日記

swift, iPhoneアプリ開発, ruby on rails等のTipsや入門記事書いてます

CoordinatorLayout+AppBarLayoutで動的なツールバーを作る

CoordinatorLayoutとAppBarLayoutを使ってスクロールすると自動で畳まれるツールバーを作ってみました。

まずはスクロールのテスト用にRecyclerViewを表示します。
activity_main.xmlを下のように変更します。

layout_behaviorはツールバー これがない場合、ツールバーとRecyclerViewが重なって表示されてしまいます。

layout_behaviorはRecyclerViewのレイアウトに関するプロパティーです。
これがない場合、ツールバーとRecyclerViewが重なって表示されてしまいます。

<?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"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".MainActivity">

    <androidx.recyclerview.widget.RecyclerView
            android:id="@+id/recycler_view"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            app:layout_behavior="@string/appbar_scrolling_view_behavior" />
</androidx.coordinatorlayout.widget.CoordinatorLayout>

次はRecyclerViewのコンテンツをセットします。
MainActivityを変更します。

class MainActivity : AppCompatActivity() {
    private lateinit var binding: ActivityMainBinding

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)

        binding = ActivityMainBinding.inflate(layoutInflater)
        setContentView(binding.root)

        binding.recyclerView.apply {
            layoutManager = LinearLayoutManager(this@MainActivity)

            val texts = (0..20).map { "test$it" }
            adapter = MyAdapter(texts)
        }
    }
}

class MyAdapter(private val texts: List<String>): RecyclerView.Adapter<MyAdapter.ViewHolder>() {
    class ViewHolder(view: View) : RecyclerView.ViewHolder(view) {
        val textView: TextView

        init {
            textView = view.findViewById(R.id.my_text_view)
        }
    }

    override fun onCreateViewHolder(viewGroup: ViewGroup, viewType: Int): ViewHolder {
        val itemView = LayoutInflater.from(viewGroup.context)
            .inflate(R.layout.row_main_activity, viewGroup, false)
        return ViewHolder(itemView)
    }

    override fun onBindViewHolder(viewHolder: ViewHolder, position: Int) {
        viewHolder.textView.text = texts[position]
    }

    override fun getItemCount() = texts.count()
}

これでRecyclerViewが表示されました。

次はツールバーを表示します。
activity_main.xmlのRecyclerViewの上に下のコードを追加します。
今回はツールバーの上にボタンを表示するようにしました。

<com.google.android.material.appbar.AppBarLayout
    android:layout_width="match_parent"
    android:layout_height="200dp"
    android:theme="@style/Theme.MyApplication.AppBarOverlay">

    <com.google.android.material.appbar.CollapsingToolbarLayout
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:minHeight="?attr/actionBarSize"
        app:layout_scrollFlags="scroll|exitUntilCollapsed">

        <Button
            android:layout_width="match_parent"
            android:layout_height="44dp"
            android:text="test" />

        <androidx.appcompat.widget.Toolbar
            android:id="@+id/toolbar"
            android:layout_width="match_parent"
            android:layout_height="?attr/actionBarSize"
            android:background="?attr/colorPrimary"
            app:popupTheme="@style/Theme.MyApplication.PopupOverlay" />
    </com.google.android.material.appbar.CollapsingToolbarLayout>
</com.google.android.material.appbar.AppBarLayout>

ツールバーを表示するためにMainActivityのonCreateに下の処理も追加します。

setSupportActionBar(binding.toolbar)

アプリを起動すると下のようにツールバーの上にボタンが表示されます。

RecyclerViewをスクロールすると下のように折りたたまれます。

CollapsingToolbarLayoutのlayout_scrollFlagsを変える事でスクロール時の処理を変える事が可能です。
例えばlayout_scrollFlagsをscroll|enterAlwaysCollapsedに変えると、スクロール時にツールバーがすべて隠れるようになります。