[안드로이드 / Kotlin] BottomSheetDialogFragment

2022. 3. 16. 10:39·Android
반응형

안녕하세요! 최근 안드로이드 앱들을 살펴보면 기존 우리가 알고있던 다이얼로그와는 조금은 다르게 아래에서 위로 올라오는 구조로 되어있는 다이얼로그를 종종 볼 수 있습니다.

그래서 오늘은 그런 다이얼로그를 BottomSheetDialogFragment를 이용하여 간단히 구현하는 방법을 소개하고자 합니다.

 

 


 

 

Gradle 추가하기

implementation 'com.google.android.material:material:1.5.0'

 

 

 

코드예시

 

<Style XML>

<style name="BottomSheetDialog" parent="Theme.Design.Light.BottomSheetDialog">
    <!-- <item name="android:windowIsTranslucent">true</item> -->
    <item name="android:windowIsFloating">false</item>
    <item name="android:navigationBarColor">@color/background</item>
    <item name="android:windowSoftInputMode">adjustResize</item>
    <item name="bottomSheetStyle">@style/bottomSheetStyleWrapper</item>
</style>
<style name="bottomSheetStyleWrapper" parent="Widget.Design.BottomSheet.Modal">
    <item name="android:background">@android:color/transparent</item>
</style>
  • android:windowIsFloating 
    true : 자식 뷰만큼의 뷰사이즈를 가집니다.
    false : 다이얼로그가 전체화면을 가집니다.
  • android:navigationBarColor 
    하단 네비게이션 색
    을 정합니다. 저같은 경우 다이얼로그가 흰색 바탕인 반면, 하단의 네비게이션바 색이 어두운 불투명색이기 때문에 네비게이션바 색을 배경색과 같게 설정했습니다.


  • android:windowSoftInputMode
    다이얼로그 내에 EditText가 있는 경우 사용자가 작성시 화면을 Resize합니다.

  • bottomSheetStyle
    모서리가 둥근 다이얼로그를 구현하기 위해 배경색을 투명으로하는 커스텀 Style 'bottomSheetStyleWrapper'를 적용합니다.

 

<Animation XML>

<style name="BottomSheetDialogAnimation">
    <item name="android:windowEnterAnimation">@anim/slide_in_bottom</item>
    <item name="android:windowExitAnimation">@anim/slide_out_bottom</item>
</style>

(저의 경우 큰 크기의 다이얼로그에서 Default 애니메이션이 심심하게 끝나, 직접 커스텀 애니메이션을 위와 같이 적용했습니다!)

 

 

<구현>

class MyBottomSheetDialog: BottomSheetDialogFragment() {
	
    override fun getTheme(): Int = R.style.BottomSheetDialog	// custom style
    
    override fun onCreateView(
        inflater: LayoutInflater,
        container: ViewGroup?,
        savedInstanceState: Bundle?
    ): View? {
        return inflater.inflate(R.layout.my_bottom_sheet_dialog, container, false)
    }
    
    override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
        super.onViewCreated(view, savedInstanceState)
        // 좌우 margin
        ((view.parent as View).layoutParams as CoordinatorLayout.LayoutParams).apply {
            leftMargin = Utils.dpToPx(requireContext(), 7)
            rightMargin = Utils.dpToPx(requireContext(), 7)
        }
        // dialog?.window?.setBackgroundDrawable(ColorDrawable(Color.TRANSPARENT))	// 배경투명
        dialog?.window?.attributes?.windowAnimations = R.style.BottomSheetDialogAnimation	// 애니메이션
        
        // 항상 확장된 상태 유지
        val bottomSheet = dialog?.findViewById<View>(com.google.android.material.R.id.design_bottom_sheet)
        val behavior = BottomSheetBehavior.from<View>(bottomSheet!!)
        behavior.skipCollapsed = true
        behavior.state = BottomSheetBehavior.STATE_EXPANDED
    }
}

위에서 만든 XML 커스텀 스타일을 getTheme()을 구현하여 적용합니다. 

만약 다이얼로그에 margin효과를 주고 싶다면, 부모 뷰의 layoutParams을 세팅하시면 됩니다.

또한 다이얼로그가 열리고 닫힐때의 커스텀 애니메이션을 적용하기 위해서는 window.attributes.windowAnimations를 이용해 적용하였습니다.

 

BottomSheetDialogFragment는 BottomSheetBehavior를 이용하는 구조로 되어있습니다. 그렇기 때문에 bottomSheet 및 bottomSheetBehavior 객체를 가져오는게 핵심이라고 생각합니다. 그래서 구글링을 해본결과  'com.google.android.material.R.id.design_bottom_sheet' 를 이용하면 위의 객체들을 가져올 수 있습니다!

 

저는 다이얼로그가 항상 확장된 상태를 유지시키기 위해 behavior.state를 STATE_EXPANDED로 주었습니다. 추가적으로 접히는 상태(collapsed)를 스킵하고 싶을때는 behavior.skipCollapsed를 true로 하시면 되겠습니다.

 

 


 

 

Tip) Dp를 Px로 변환하기

 

/**
 * Dp -> Px
 */
fun dpToPx(context: Context, dp: Int): Int {
//            val px = TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, dp, context.resources.displayMetrics)
//            return px.roundToInt()
    val density = context.resources.displayMetrics.density
    return (dp * density).roundToInt()
}

 

 

 

 

 

참고 : https://developer-eungb.tistory.com/12

 

[Android/Kotlin] 안드로이드 BottomSheetDialogFragment 구현하기

새로 들어가는 프로젝트에서 처음으로 BottomSheetDialogFragment를 구현 할 일이 생겼다. BottomSheetDialog는 앱의 하단에서 올라오는 팝업창을 구현할 때 사용한다. 라이브러리 의존성 추가 implementation 'co

developer-eungb.tistory.com

 

반응형

'Android' 카테고리의 다른 글

[안드로이드 / Kotlin] 코루틴(Coroutine)  (0) 2022.03.21
[안드로이드 / Kotlin] 타이머(Timer) 구현하기  (0) 2022.03.18
[안드로이드 / Kotlin] RecyclerView Drag&Drop / Swipe 구현  (0) 2022.03.15
[안드로이드 / Kotlin] 저전력 블루투스 BLE(3), 기기 연결  (0) 2022.03.15
[안드로이드 / Kotlin] 화면 전환 시 작업 처리, 구성 변경 처리(onConfigurationChanged)  (0) 2022.03.06
'Android' 카테고리의 다른 글
  • [안드로이드 / Kotlin] 코루틴(Coroutine)
  • [안드로이드 / Kotlin] 타이머(Timer) 구현하기
  • [안드로이드 / Kotlin] RecyclerView Drag&Drop / Swipe 구현
  • [안드로이드 / Kotlin] 저전력 블루투스 BLE(3), 기기 연결
서주냥
서주냥
간단한 것도 기록하는 습관을 가지자
  • 서주냥
    DroidLog
    서주냥
  • 전체
    오늘
    어제
    • 전체보기 (58)
      • 알고리즘 (12)
        • 백준 (4)
        • 프로그래머스 (5)
        • 개념 (3)
      • Android (43)
        • Compose (1)
      • Java (2)
      • Kotlin (1)
  • 링크

    • GitHub
  • 인기 글

  • 태그

    뷰모델
    백준
    viewmodel
    안드로이드
    투 포인터
    프로그래머스
    코루틴
    Hilt
    클린 아키텍처
    코틀린
    SnackBar
    이진 탐색
    debounce
    reified
    RecyclerView
    ConstraintLayout
    자바
    moshi
    textunit
    Coroutine
    viewpager2
    Coroutine Flow
    FusedLocationProviderClient
    Clean Architecture
    최단 경로
    알고리즘
    블루투스
    BLE
    다이나믹 프로그래밍
    벨만 포드
  • 최근 댓글

  • 최근 글

  • hELLO· Designed By정상우.v4.10.3
서주냥
[안드로이드 / Kotlin] BottomSheetDialogFragment
상단으로

티스토리툴바