Vintage appMaker의 Tech Blog

BottomSheetDialogFragment 배경을 투명하게 본문

Source code or Tip/Android(Java, Kotlin)

BottomSheetDialogFragment 배경을 투명하게

VintageappMaker 2021. 6. 29. 08:22

BottomSheetDialogFragment는 앱 하단에 팝업으로 표시해야 할 경우, 자주사용하는 클래스이다.

그런데 배경을 라운드로 처리할 경우, 투명화 처리를 해주는 것이 조금은 번거롭다. 

 

1. onCreateDialog에서 Dialog를 받아서

2. Dialog의 setOnShowListener를 등록하며 

 

아래와 같은 코드를 작성해주어야 한다. 

val bottomSheet = findViewById<View>(com.google.android.material.R.id.design_bottom_sheet) as FrameLayout
bottomSheet.setBackgroundResource(android.R.color.transparent)

그래서 다음과 같은 클래스를 구현하여 사용하면 편리하게 사용할 수 있다. 

 

[BottomSheetDialogFragment을 상속받아 처리하는 QuickBottomDialog]

// 하단 Dialog
open class QuickBottomDialog:  BottomSheetDialogFragment(){

    private lateinit var fnSetup : ( ()-> Unit ) -> View?
    private var _data : Any? = null
    var paramData : Any?
        get() = _data
        set(value) {_data = value}

    // 실행 시, expanded하게 보이기 위해서 보관한다.
    private lateinit var dlg : BottomSheetDialog
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        isCancelable = true
    }

    override fun onCreateDialog(savedInstanceState: Bundle?): Dialog {
        // 이 코드를 실행하지 않으면
        // XML에서 round 처리를 했어도 적용되지 않는다.
        dlg = ( super.onCreateDialog(savedInstanceState).apply {
            // window?.setDimAmount(0.2f) // Set dim amount here
            setOnShowListener {
                val bottomSheet = findViewById<View>(com.google.android.material.R.id.design_bottom_sheet) as FrameLayout
                bottomSheet.setBackgroundResource(android.R.color.transparent)
                
                
                // 아래와 같이하면 Drag를 불가능하게 한다.
                //val behavior = BottomSheetBehavior.from(bottomSheet!!)
                //behavior.isDraggable = false
            }
        } ) as BottomSheetDialog
        return dlg
    }

    override fun onCreateView(
        inflater: LayoutInflater,
        container: ViewGroup?,
        savedInstanceState: Bundle?
    ): View? {

        return fnSetup(::dismiss)
    }

    // 단지 이름을 통일해서 외부에서
    // 사용하기 위한 메소드
    open fun launch(fm : FragmentManager, title : String, fnCallBack : (Any)-> Unit = {} ){

    }

    fun QShow(fm : FragmentManager, title: String, fnInitView : (()-> Unit ) -> View? ){
        this.fnSetup = fnInitView
        show(fm, title)
    }

    override fun onStart() {
        super.onStart()
        
        // 시작하자마자 Expanded 한다.
        dlg.behavior.state = BottomSheetBehavior.STATE_EXPANDED
    }
}

 

사용법은 다음과 같다.

[TestBottomDialogActivity]

class TestBottomDialogActivity : AppCompatActivity() {
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main3)

        val btnBottomDialog = findViewById<Button>(R.id.button)
        btnBottomDialog.setOnClickListener {
            QuickBottomDialog().apply {
                QShow(this@TestBottomDialogActivity.supportFragmentManager, "", {

                        fnDismiss ->
                    val inflater = getSystemService(Context.LAYOUT_INFLATER_SERVICE) as LayoutInflater
                    val view = inflater.inflate(R.layout.dialog_quick, null)

                    return@QShow view

                })
            }
        }
    }
}

[dialog_quick,xml]

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:background="@drawable/custom_dialog_back"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content">

    <FrameLayout
        android:layout_width="wrap_content"
        android:layout_height="wrap_content">

        <!--    FrameLayout으로 wrap하고 그 안에서 크기를 지정    -->
        <RelativeLayout
            android:layout_width="320dp"
            android:layout_height="100dp">

            <TextView
                android:textColor="#efefef"
                android:text="Test"
                android:gravity="center"
                android:layout_width="match_parent"
                android:layout_height="match_parent"/>

        </RelativeLayout>
    </FrameLayout>

</LinearLayout>

[custom_dialog_back.xml]

<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android" android:shape="rectangle" >
    <corners
        android:radius="13dp"
        android:bottomLeftRadius="0dp"
        android:bottomRightRadius="0dp"
        />
    <solid
        android:color="#4DA1F4"
        />
    <padding
        android:left="0dp"
        android:top="0dp"
        android:right="0dp"
        android:bottom="0dp"
        />
</shape>
Comments