정상에서 IT를 외치다

[Android, DialogFragment] 커스텀 다이얼로그 프래그먼트 만들기 본문

안드로이드

[Android, DialogFragment] 커스텀 다이얼로그 프래그먼트 만들기

Black-Jin 2020. 11. 18. 22:15
반응형

안녕하세요. 블랙진입니다.

 

우리는 안드로이드에서 기본으로 제공해 주는 다양한 알림 요소를 사용하고 있습니다.

다이얼로그

토스트 

 

스낵바

 

이번 포스팅은 각 알림 요소들을 사용자 지정 레이아웃로 커스텀하는 법에 대해 알아보고자 합니다. 첫 번째 포스팅으로 커스텀 다이얼로그 프래그먼트 생성하는 법에 대해서 살펴보겠습니다!

 

Custom Dialog Fragment 만들기 (현재)

Custom Toast 만들기

Custom SnackBar 만들기

 

 

커스텀 다이얼로그 프래그먼트 만들기

 

 

만들 예제는 위와 같은 문구와 버튼이 한 개씩 있는 다이얼 로그입니다. 

 

 

1. layout 만들기

 

다이얼로그 그릴때 2가지 경우에 맞춰 유의해서 작업해 주셔야 합니다.

 

1) 가로 세로의 사이즈가 고정이 아닐 때

<?xml version="1.0" encoding="utf-8"?>
<layout xmlns:android="http://schemas.android.com/apk/res/android">

    <LinearLayout
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:padding="24dp"
        android:background="#2B353E"
        android:gravity="center"
        android:orientation="vertical">

        <TextView
            android:id="@+id/tvSample"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="Hello World!"
            android:textColor="@android:color/white"
            android:textSize="15dp" />

        <Button
            android:id="@+id/btnSample"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_marginTop="20dp"
            android:text="GO" />
    </LinearLayout>
</layout>

위와 같이 부모뷰가 wrap_content인 경우에는 다이얼로그가 화면에 잘 그러집니다. 위 xml의 경우 아래와 같이 패딩이 24dp인 다이얼로그가 잘 그려짐을 확인할 수 있습니다. 그럼 가로와 세로 사이즈가 고정인 경우에는 어떻게 될까요?

 

 

2) 가로와 세로 사이즈가 고정인 경우

<?xml version="1.0" encoding="utf-8"?>
<layout xmlns:android="http://schemas.android.com/apk/res/android">

    <LinearLayout
        android:layout_width="300dp"
        android:layout_height="200dp"
        android:background="#2B353E"
        android:gravity="center"
        android:orientation="vertical"
        android:padding="24dp">

        <TextView
            android:id="@+id/tvSample"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="Hello World!"
            android:textColor="@android:color/white"
            android:textSize="15dp" />

        <Button
            android:id="@+id/btnSample"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_marginTop="20dp"
            android:text="GO" />
    </LinearLayout>
</layout>

위와 같이 가로 300dp, 세로 200dp로 해서 작동해 보면 고정된 사이즈는 적용이 안되고 위 1번에서와 같은 wrap_content의 사이즈가 적용됩니다.

 

 

해결법?

 

FrameLayout 등 뷰그룹을 사용해 감싸주면 원하는 사이즈의 다이얼로그가 노출됩니다.

<?xml version="1.0" encoding="utf-8"?>
<layout xmlns:android="http://schemas.android.com/apk/res/android">
<!-- FrameLayout 등 뷰를 한번 wrapping 해줘야 화면에 정삭적으로 View가 보입니다. -->
<FrameLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content">

<!-- 사이즈가 고정된 View -->
<LinearLayout
android:layout_width="300dp"
android:layout_height="200dp"
android:background="#2B353E"
android:gravity="center"
android:orientation="vertical"
android:padding="24dp">

<TextView
android:id="@+id/tvSample"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Hello World!"
android:textColor="@android:color/white"
android:textSize="15dp" />

<Button
android:id="@+id/btnSample"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="20dp"
android:text="GO" />
</LinearLayout>
</FrameLayout>
</layout>

위와 같이 만들어주어야 화면에 가로 300dp, 세로 200dp의 다이얼로그가 아래와 같이 보여집니다.

 

가로 300dp, 세로 200dp가 적용된 다이얼로그 프래그먼트

 

 

2. SampleFragmentDialog 만들기

class SampleFragmentDialog : DialogFragment() {

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        //false로 설정해 주면 화면밖 혹은 뒤로가기 버튼시 다이얼로그라 dismiss 되지 않는다.
        isCancelable = true
    }

    private lateinit var binding: DialogFragmentSampleBinding

    override fun onCreateView(
        inflater: LayoutInflater,
        container: ViewGroup?,
        savedInstanceState: Bundle?
    ): View? {
        binding = DialogFragmentSampleBinding.inflate(inflater, container, false)
        return binding.root
    }

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

        val text = "Hello, Welcome to blackjin Tisotry"

        binding.tvSample.text = text

        binding.btnSample.setOnClickListener {
            Toast.makeText(requireContext(), text, Toast.LENGTH_SHORT).show()
        }
    }
}

Hello, Welcome to blackjin Tistory 문구가 화면에 보이고 버튼을 누르면 toast가 나오도록 작성해 보았습니다.

 

 

3. MainActivity 에서 사용하기

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

        btnSample.setOnClickListener {
            SampleFragmentDialog().show(
                    supportFragmentManager, "SampleDialog"
            )
        }
    }
}

프래그먼트 다이얼로그는 show 함수를 사용해 화면에 보여줄 수 있습니다.

 

 

 

풀스크린 다이얼로그 만들기

 

이번에는 스타일을 변경해서 풀스크린의 다이얼로그를 만들어 보겠습니다.

 

1. style 생성하기

 

<style name="dialog_fullscreen" parent="Theme.AppCompat.Dialog">
<item name="android:windowIsFloating">false</item>
<item name="android:windowFullscreen">false</item>
<item name="android:windowBackground">@android:color/transparent</item>
</style>

위 3가지 속성을 적용하면 전체 화면의 다이얼로그가 돕니다.

참고로 windowFullscreen 속성을 false로 주었는데요. 만약 속성을 true로 주면 statue bar가 안보이게 됩니다.

 

 

2. DialogFragment에 적용하기

override fun onCreate(savedInstanceState: Bundle?) {
    super.onCreate(savedInstanceState)
    setStyle(STYLE_NO_TITLE, R.style.dialog_fullscreen)
    isCancelable = true
}

DialogFragment의 onCreate 부분에 setStyle을 사용해 dualog_fullscreen을 적용하실 수 있습니다.

 

 

보시는 바와 같이 전체화면에 Dialog가 표시되었습니다. 여기서 최상단에 시간, 배터리 정보등을 보여주는 부분을 status bar 라고 합니다. 추가로 status bar의 색을 변경해 보겠습니다.

 

<style name="dialog_fullscreen" parent="Theme.AppCompat.Dialog">
<item name="android:windowIsFloating">false</item>
<item name="android:windowFullscreen">false</item>
<item name="android:windowBackground">@android:color/transparent</item>

<!-- status bar 노랑색으로 설정 -->
<item name="android:statusBarColor">#FFFF00</item>
</style>

 

 

status bar가 노랑색이 되는것을 확인할 수 있습니다.

 

 

TIP 1 : 가로 세로 사이즈 고정

풀스크린 다이얼로그도 마찬가지로 가로 세로 사이즈를 고정하고 싶다면 뷰그룹을 사용해 한번 더 감싸주는 작업이 필요합니다. 

 

 

TIP 2 : 배경 dim 설정

<style name="dialog_fullscreen" parent="Theme.AppCompat.Dialog">
<item name="android:windowIsFloating">false</item>
<item name="android:windowFullscreen">false</item>
<item name="android:windowBackground">@android:color/transparent</item>

<!-- status bar 노랑색으로 설정 -->
<item name="android:statusBarColor">#FFFF00</item>

<!-- 배경 dim 설정 -->
<item name="android:backgroundDimEnabled">true</item>
<!-- 0.0 (투명) ~ 1.0 (검정색) 값을 가집니다 -->
<item name="android:backgroundDimAmount">0.5</item>
</style>

스타일 아래에 추가된 두가지 속성을 사용해 다이얼로그 Dim의 투명도를 조절할 수 있습니다.

 

 

이정도 예제를 익히셨다면 앞으로 사용자 지정 다이얼로그 프래그먼트를 충분히 잘 커스텀할 수 있을겁니다. 

 

참고로 저도 계속 공부하고 있는중이지만 가로와 세로 사이즈를 고정했을 때 새로운 뷰로 감싸주어야만 원하는 화면이 나오는지에 대해 아시는 분이 있다면 댓글 부탁드리겠습니다. 감사힙니다 :)

 

참고로 아래 링크는 alert dialog관련해서 정리해놓은 포스팅입니다.

기본 다이얼로그 사용법 정리

반응형
Comments