ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • Bottom Sheet Dialog, Slider, ProgressBar
    Android 2025. 6. 8. 22:06

     

    안녕하세요~ 오늘은 유저 인터페이스(UI) 에 관련된 요소 3가지를 다뤄보려고 합니다 🫠

    1. Bottom Sheet Dialog

    화면 아래에서 위로 슬라이드 되어 올라오는 창으로, 부가적인 내용을 사용자에게 제공될 때 사용됩니다. 전체 화면을 덮지 않고 일부만 덮어 효율적이고 직관적으로 화면을 구성하기 좋습니다. 구현 방법부터 알아보겠습니다!

    <androidx.coordinatorlayout.widget.CoordinatorLayout 
        android:layout_width="match_parent"
        android:layout_height="match_parent">
        
        <include
        	android:id="@+id/bottomSheetDialog"
            layout="@layout/bottom_sheet_dialog"/>
            
    </androidx.coordinatorlayout.widget.CoordinatorLayout>

     

    먼저 루트 레이아웃을 FrameLayout 기반인 CoordinatorLayout 으로 해줘야 합니다. bottom sheet dialog 와 관련된 레이아웃은 따로 작성하여 포함시키기 위해 include 속성을 사용합니다. 

    // @layout/bottom_sheet_dialog
    <androidx.constraintlayout.widget.ConstraintLayout 
        app:layout_behavior="com.google.android.material.bottomsheet.BottomSheetBehavior"
        app:behavior_hideable="false"
        app:behavior_peekHeight="100dp"
        app:behavior_fitToContents="false"
        app:behavior_expandedOffset="300dp"
        android:background="@drawable/bg_bottom_sheet"
        android:layout_width="match_parent"
        android:layout_height="match_parent">
    
       	// ...
    
    </androidx.constraintlayout.widget.ConstraintLayout>

     

    첫 번째로, layout_behavior 속성은 CoordinatorLayout 과 상호작용하기 위해 필수적입니다. 자신이 Bottom Sheet 와 관련된 레이아웃임을 명시해야합니다. 두 번째로, behavior_hideable 속성은 bottom sheet 를 완전히 숨길 수 있는지 여부를 나타냅니다. true 로 설정할 경우 화면에서 아예 보이지 않으며, false 로 설정할 경우에는 화면에서 아래쪽에 일부가 보입니다. 세 번째로, behavior_peekHeight 은 bottom sheet 가 접혀있는 상태에서 얼만큼의 높이로 보일건지를 의미합니다. 100dp 로 지정하면 화면 맨 아래 기준으로 100dp 위쪽까지 보입니다. 네 번째로, behavior_fitToContents 는 bottom sheet 가 펼쳐진 상태에서 완전히 화면을 가리게 할 것인지 여부를 나타냅니다. true 로 설정하면 화면 맨 상단까지 올라가고, false 로 설정하면 올라가는 지점을 따로 제어할 수 있습니다. 다섯 번째로, behavior_expandedOffset 은 bottom sheet 가 화면 상단 기준으로 얼만큼 떨어진 지점까지만 올라갈 지를 의미합니다. 만약에 300dp 라고 하면, bottom sheet 를 펼쳤을 때 화면 상단에서 300dp 만큼 떨어진 지점까지만 올라갑니다. 

    // @drawable/bg_bottom_sheet
    <shape xmlns:android="http://schemas.android.com/apk/res/android">
        <solid android:color="@color/white"/>
        <corners android:topLeftRadius="30dp" android:topRightRadius="30dp"/>
    </shape>

     

    background 속성으로 drawable 를 지정하여 bottom sheet 의 색깔과 모서리가 깎인 정도를 커스텀할 수 있습니다. 

    <View
        android:id="@+id/view"
        android:layout_width="40dp"
        android:layout_height="2dp"
        android:background="#D9D9D9"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintTop_toTopOf="parent"
        android:layout_marginTop="16dp"/>
            
    <androidx.recyclerview.widget.RecyclerView
        android:id="@+id/recyclerview_stay_list"
        android:layout_width="0dp"
        android:layout_height="0dp"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintTop_toBottomOf="@id/view"
        app:layout_constraintBottom_toBottomOf="parent"
        android:layout_marginTop="16dp"
        android:padding="16dp"/>

     

    저는 하위에 View 와 RecyclerView 를 추가해보았습니다. 이렇게 코드를 추가하고 나서 완성된 화면을 보겠습니다.

    2. Slider

    슬라이더(Slider) 는 사용자가 특정 범위 내 값을 손가락으로 끌어 선택하도록 돕는 요소입니다. 구현 방법을 알아보겠습니다!

    implementation("com.google.android.material:material: 1.12.0")

     

    material design 3 를 사용할 것이기에 의존성을 추가해야합니다. 버전은 달라질 수 있습니다!

    <com.google.android.material.slider.Slider
            android:id="@+id/slider"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:valueFrom="1"
            android:valueTo="100"
            android:contentDescription="slider example"
            style="@style/Widget.App.Slider"/>

     

     

    여기서 valueFrom 은 값의 시작점, valueTo 는 값의 끝점을 의미합니다. 슬라이더를 좀 더 개성있게 만들려면 style 을 지정해주는 것이 좋습니다.

    <!-- Slider -->
    <style name="Widget.App.Slider" parent="Widget.Material3.Slider.Legacy">
    <item name="materialThemeOverlay">@style/ThemeOverlay.App.Slider</item>
    <item name="labelStyle">@style/Widget.App.Tooltip</item>
    <item name="trackHeight">12dp</item>
    </style>
    
    <style name="ThemeOverlay.App.Slider" parent="">
        <item name="colorPrimary">#F44336</item>
        <item name="colorOnPrimary">@color/black</item>
        <item name="colorOnSurface">#0000FF</item>
    </style>
    
    <style name="Widget.App.Tooltip" parent="Widget.Material3.Tooltip">
        <item name="android:textAppearance">@style/TextAppearance.App.Tooltip</item>
        <item name="backgroundTint">#FFFFFF</item>
        <item name="android:padding">12dp</item>
    </style>
    
    <style name="TextAppearance.App.Tooltip" parent="TextAppearance.Material3.BodySmall">
        <item name="android:textSize">16sp</item>
    </style>

     

     

    ThemeOverlay.App.Slider 는 색상을 설정하는 부분인데 colorPrimary 는 활성화된 track 과 thumb 의 색상이고, colorOnPrimary 는 말풍선 안쪽 글자색입니다. Widget.App.Tooltip 은 말풍선과 관련된 부분으로 padding 을 이용해 말풍선 크기를 조절할 수 있습니다. backgroundTint 는 말풍선 배경색상입니다. TextAppearance.App.Tooltip 은 말풍선 안쪽 글자색을 나타냅니다. textSize 를 이용해 글자 크기를 조절할 수 있습니다.

    val sliderAge = view.findViewById<Slider>(R.id.slider)
    sliderAge.setLabelFormatter { value ->
        "${value.toInt()}살"
    }
    sliderAge.addOnSliderTouchListener(object: Slider.OnSliderTouchListener {
        override fun onStartTrackingTouch(slider: Slider) {
    
        }
    
        override fun onStopTrackingTouch(slider: Slider) {
            Toast.makeText(requireContext(), "value:${slider.value.toInt()}살", Toast.LENGTH_SHORT).show()
        }
    
    })

     

     

    setLabelFormatter 을 이용해 말풍선에 해당 값이 어떻게 나올지 설정할 수 있습니다. 저 같은 경우엔 나이로 지정하여 "~살" 을 붙여봤습니다. value 값은 실수형(Float)으로 받아오기 때문에 저는 정수형(Int) 으로 바꿨습니다. 또한 addOnSliderTouchListener 콜백 함수를 통해 값을 받아올 수 있습니다. onStopTrackingTouch 오버라이드 함수는 사용자가 슬라이더를 움직이다가 멈출 때 호출됩니다.

    3. ProgressBar

    프로그래스바(ProgressBar) 는 작업의 진행도를 나타낼 때 사용하는 UI 입니다. 기존 ProgressBar 도 있지만 material design 3 에 사용되는 LinearProgressIndicator 을 알아보겠습니다.

    <com.google.android.material.progressindicator.LinearProgressIndicator
        android:id="@+id/progressBar"
        android:layout_width="0dp"
        android:layout_height="wrap_content"
        android:progress="40"
        android:max="100"
        app:indicatorColor="@color/sleep_primary"
        app:trackColor="@color/white"
        app:trackCornerRadius="12dp"
        app:trackThickness="10dp"/>

     

    progress 는 진행 상태, max 는 최대 진행 상태를 나타냅니다. indicatorColor 는 진행이 완료되어 채워진 색상을 의미합니다. trackColor 는 프로그래스바 막대기 색상을 의미합니다. trackCornerRadius 를 통해 모서리를 둥글게 만들 수 있고, thickThickness 는 막대의 두께를 설정할 수 있습니다. 이때, layout_height 값은 적용되지 않기에 wrap_content 로 설정합니다.

    Material 3 프로그래스바

     

    view.findViewById<LinearProgressIndicator>(R.id.progressBar).setProgress(progress, true)

     

    setProgress첫번째 인자로는 얼마만큼 진행되었는지 Int 형 값을 넣어주고, 두번째 인자로는 애니메이션 효과를 줄 것인지 boolean 값을 넣어줍니다.

     

    프로그래스바 애니메이션이 부분적으로 조금 이상하게 들어가는데 이 부분은 나중에 해결되면 글 수정하겠습니다!

     

    오늘은 bottom sheet dialog, slider, progressbar 에 대해 알아보았습니다. 읽어주셔서 감사합니다 ^^

Designed by Tistory.