BottomSheetFragment (with Kotlin)

Purang·2023년 6월 18일
0

Android Studio

목록 보기
27/28

BottomSheetFragment에 대해 배워보았습니다.
안드로이드 공식 문서에서 자세한 내용을 확인할 수 있습니다.

첫 번째 방법

<style name="BottomSheetDialogTheme" parent="Theme.Design.BottomSheetDialog">
        <item name="bottomSheetStyle">@style/BottomSheetStyle</item>
    </style>

    <style name="BottomSheetStyle" parent="Widget.Design.BottomSheet.Modal">
        <item name="background">@android:color/transparent</item>
    </style>

테마 스타일을 지정해주고

<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout 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"
    app:layout_behavior="com.google.android.material.bottomsheet.BottomSheetBehavior"
    app:behavior_hideable="false"
    app:behavior_peekHeight="0dp"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:background="@drawable/bottom_sheet_background"
    >

    <TextView
        android:id="@+id/textView"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_gravity="center"
        android:layout_marginEnd="7dp"
        android:layout_marginBottom="34dp"
        android:text="Hello World"
        app:layout_constraintBottom_toTopOf="@+id/button"
        app:layout_constraintEnd_toEndOf="@+id/button" />

    <Button
        android:id="@+id/button"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_gravity="center"
        android:layout_marginBottom="193dp"
        android:text="Dismiss"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent" />

</androidx.constraintlayout.widget.ConstraintLayout>

R.layout.bottom_sheet_dialog을 생성해줍니다.

val bottomSheetDialog = BottomSheetDialog(
                requireActivity(), R.style.BottomSheetDialogTheme
            ).apply {
                behavior.state = BottomSheetBehavior.STATE_EXPANDED
                behavior.isDraggable = true
            }

            val bottomView = LayoutInflater.from(requireActivity()).inflate(
                R.layout.bottom_sheet_dialog, null
            )


            //bottomSheetDialog.behavior.state = BottomSheetBehavior.STATE_EXPANDED
            // bottomSheetDialog 뷰 생성
            bottomSheetDialog.setContentView(bottomView)

            // bottomSheetDialog 호출
            bottomSheetDialog.show()

스타일과 레이아웃을 통해 코드로 바로 생성 후 show를 통해 호출할 수 있습니다.

두 번째 방법

EmptyFragment를 생성해줍니다. (BottomSheetFragment로 저는 생성했습니다.)
똑같이 위와 같은 xml과 style을 생성 후 fragment로 생성 시에 넣어 줍니다.

package com.example.mio

import android.app.Dialog
import android.os.Bundle
import androidx.fragment.app.Fragment
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.view.WindowManager
import com.example.mio.databinding.FragmentBottomSheetBinding
import com.google.android.material.bottomsheet.BottomSheetBehavior
import com.google.android.material.bottomsheet.BottomSheetDialog
import com.google.android.material.bottomsheet.BottomSheetDialogFragment

// TODO: Rename parameter arguments, choose names that match
// the fragment initialization parameters, e.g. ARG_ITEM_NUMBER
private const val ARG_PARAM1 = "param1"
private const val ARG_PARAM2 = "param2"

class BottomSheetFragment : BottomSheetDialogFragment() {
    // TODO: Rename and change types of parameters
    private var param1: String? = null
    private var param2: String? = null

    private lateinit var bsBinding : FragmentBottomSheetBinding
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        arguments?.let {
            param1 = it.getString(ARG_PARAM1)
            param2 = it.getString(ARG_PARAM2)
        }
    }

    override fun onCreateView(
        inflater: LayoutInflater, container: ViewGroup?,
        savedInstanceState: Bundle?
    ): View? {
        bsBinding = FragmentBottomSheetBinding.inflate(inflater, container, false)


        return bsBinding.root
    }

    override fun onCreateDialog(savedInstanceState: Bundle?): Dialog {
        /*val dialog = BottomSheetDialog(requireContext(), R.style.BottomSheetDialogTheme).apply {
            behavior.state = BottomSheetBehavior.STATE_EXPANDED
            behavior.isDraggable = false
        }*/
        val dialog = BottomSheetDialog(requireContext(),  R.style.BottomSheetDialogTheme)
        dialog.setOnShowListener {

            val bottomSheetDialog = it as BottomSheetDialog
            val parentLayout =
                bottomSheetDialog.findViewById<View>(com.google.android.material.R.id.design_bottom_sheet)
            parentLayout?.let { it ->
                val behaviour = BottomSheetBehavior.from(it)
                setupFullHeight(it)
                behaviour.state = BottomSheetBehavior.STATE_EXPANDED
            }
        }

        return dialog
    }

    override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
        super.onViewCreated(view, savedInstanceState)
    }

    private fun setupFullHeight(bottomSheet: View) {
        val layoutParams = bottomSheet.layoutParams
        layoutParams.height = WindowManager.LayoutParams.MATCH_PARENT
        bottomSheet.layoutParams = layoutParams
    }


    companion object {
        /**
         * Use this factory method to create a new instance of
         * this fragment using the provided parameters.
         *
         * @param param1 Parameter 1.
         * @param param2 Parameter 2.
         * @return A new instance of fragment BottomSheetDialogFragment.
         */
        // TODO: Rename and change types and number of parameters
        @JvmStatic
        fun newInstance(param1: String, param2: String) =
            BottomSheetFragment().apply {
                arguments = Bundle().apply {
                    putString(ARG_PARAM1, param1)
                    putString(ARG_PARAM2, param2)
                }
            }
    }
}


...

//그 후 사용할 activity나 fragment에서 호출해줍니다.

val bottomSheet = BottomSheetFragment()
            bottomSheet.show(requireActivity().supportFragmentManager, bottomSheet.tag)

여기서 저는 풀스크린을 원해서 state를 STATE_EXPANDED로 생성했었습니다.

그러나 여러 가지가 존재하는데 필요한 state를 생성하여 사용하시기를 바랍니다.

STATE_EXPANDED : 완전히 펼쳐진 상태
STATE_COLLAPSED : 접혀있는 상태
STATE_HIDDEN : 아래로 숨겨진 상태 (보이지 않음)
STATE_HALF_EXPANDED : 절반으로 펼쳐진 상태
STATE_DRAGGING : 드래깅되고 있는 상태
STATE_SETTLING : 드래그/스와이프 직후 고정된 상태

BottomSheetBehavior

profile
몰입의 즐거움

0개의 댓글