[Android/Kotlin] CoordinatorLayout - 축소되는 앱 바

Notepad96

·

2022. 8. 28. 13:24

300x250

 

 

1. 요약

 

결과

이번 글에서는 CollapsingTollbarLayout을 사용하여 App Bar가 축소되며 상단의 고정되는 기능을 구현하는 방법을 기술한다.

 

이에 추가적으로 RecyclerView를 아래 추가함으로써 아래로 스크롤되는 것에 따라서 App Bar가 어떻게 축소되며 고정되는가를 확인할 수 있다.

 

 

 

 

2. 레이아웃

 

2-1. activity_main.xml

구조적으로 다음과 같이 구성되어 있으며 상단의 고정이 될 주요 레이아웃은 CollapsingToolbarLayout 아래 Toolbar와 ImageView를 통하여 나타내게 된다.

 

<CoordinatorLayout>
    <AppBarLayout>
        <CollapsingToolbarLayout>
            <Toolbar>
            <ImageView>
    <RecyclerView>

 

 

 

● CoordinatorLayout

CoordinatorLayout은 강력한 FrameLayout이며 Behaviors을 통하여 단일 부모 내에서 다양한 상호 작용을 구현해낼 수 있다.

 

 

 

● AppBarLayout

AppBarLayout은 Vertical LinearLayout 앱바 개념의 스크롤 제스처와 같은 기능을 구현한다.

 

 

 

● CollapsingToolbarLayout

축소되는 앱 바를 구현하기 위한 wrapper로서 AppBarLayout의 직접 자식으로 사용되도록 설계되었으며 다음과 같은 기능이 포함되어 있다.

 

  • Collapsing title
  • Content scrim
  • Status bar scrim
  • Parallax scrolling children
  • Pinned position children

 

app:layout_scrollFlags의 값으로 "scroll|exitUntilCollapsed"를 줌으로써 스크롤을 내릴 경우 AppBar가 Sticky 되어 상단에 고정되는 모습을 볼 수 있다.

 

<?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">

    <com.google.android.material.appbar.AppBarLayout
        android:id="@+id/appBarLayout"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:fitsSystemWindows="true">

        <com.google.android.material.appbar.CollapsingToolbarLayout
            android:layout_width="match_parent"
            android:layout_height="250dp"
            app:expandedTitleTextColor="@color/white"
            app:layout_scrollFlags="scroll|exitUntilCollapsed"
            app:contentScrim="#D3D3D3">

            <ImageView
                android:layout_width="match_parent"
                android:layout_height="250dp"
                android:scaleType="fitXY"
                app:layout_collapseMode="parallax"
                android:src="@drawable/sample" />

            <androidx.appcompat.widget.Toolbar
                android:layout_width="match_parent"
                android:layout_height="?attr/actionBarSize"
                app:title="Today Cafe"
                app:titleTextColor="@color/white"
                app:layout_collapseMode="pin" />

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

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

</androidx.coordinatorlayout.widget.CoordinatorLayout>

 

이 이후의 레이아웃의 속성으로 app:layout_behavior="@string/appbar_scrolling_view_behavior"을 주어야만 간격에 맞춰 레이아웃이 배치된다.

 

따라서 그다음으로는 RecyclerView 1개가 있으므로 속성으로 넣어주면 레이아웃이 맞춰져 보이게 된다.

 

 

 

 

3. 코드 및 설명

 

3-1. ListAdapter.kt

RecyclerView에 나타낼 Adapter를 정의한 파일로서 TextView 2개로 구성된 레이아웃에 각 텍스트를 초기화해주었다.

 

 

package com.notepad96.coordinatorlayout

import android.view.LayoutInflater
import android.view.ViewGroup
import androidx.recyclerview.widget.RecyclerView
import com.notepad96.coordinatorlayout.databinding.ItemListBinding
import java.text.DecimalFormat

class ListAdapter: RecyclerView.Adapter<ListAdapter.MyView>() {

    inner class MyView(private val binding: ItemListBinding): RecyclerView.ViewHolder(binding.root) {
        fun bind(position: Int) {
            binding.mainText.text = "Menu $position"
            val price = DecimalFormat("#,###")
            binding.subText.text = "${price.format(position * 10000)} WON"
        }
    }

    override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): MyView {
        val view = ItemListBinding.inflate(LayoutInflater.from(parent.context), parent, false)
        return MyView(view)
    }

    override fun onBindViewHolder(holder: MyView, position: Int) {
        holder.bind(position)
    }

    override fun getItemCount(): Int {
        return 40
    }
}

 

 

 

 

4. 전체 파일

 

 

GitHub - Notepad96/BlogExample02

Contribute to Notepad96/BlogExample02 development by creating an account on GitHub.

github.com

 

 

300x250