[TIL][내일배움캠프]

[내일배움캠프][TIL] 24.03.15 (금) - 최종 프로젝트 4주차 : 추가 구현

kimlaurant 2024. 3. 15. 20:51
1. 기술 면접 연습

 

어제부터 시작한 기술 면접 연습.

 

오늘도 한 가지 질문을 고르고, 그 질문에 대한 답을 적어보았다.

 

함수형 프로그래밍(Functional Programming)에 대해 설명해주세요.

함수형 프로그래밍(Functional Programming)은 계산을 수학적 함수의 평가로 취급하고 상태와 가변 데이터를 피하는 것을 중요한 특징으로 하는 프로그래밍 패러다임입니다. 보통 부작용(side effects)을 최소화하고 불변성(Immutability)을 유지하여 코드를 더 예측 가능하고 안정적으로 만들기 위함을 목표로 이 프로그래밍 기법을 많이 사용하고 있습니다.

 

 

이렇게 적다보니 내심 '과연 실전에서도 이렇게 말할 수 있는가?'에 대한 의문이 좀 강하게 들기는 하는데….

 

 

2. 최종 프로젝트 4주차

 

 

Dialog 띄우기

 

어제는 대략적으로 Dialog의 UI를 만들었다.

 

오늘은 이 Dialog를 Fragment에서 띄우는 방법을 한 번 생각해봤다.

 

Fragment에서는 Dialog를 그냥 띄울 수는 없고 DialogFragment를 따로 만들어서 그걸 보여주는 방법을 많이 사용하고 있었다. 이게 커스텀 다이얼로그를 이용하기에도 수월하다 생각해서 이 방법을 채택했다.

 

방법은 간단하다. 어차피 저 다이얼로그에서 edit하거나 확인, 취소가 필요한 부분은 없어서 연결만 시키면 된다.

 

LvDialogFragment.kt

class LvDialogFragment : DialogFragment() {
    private var _binding : DialogLvBinding? = null
    private val binding get() = _binding!!

    override fun onCreateView(
        inflater: LayoutInflater,
        container: ViewGroup?,
        savedInstanceState: Bundle?
    ): View {
        _binding = DialogLvBinding.inflate(inflater, container, false)
        val view = binding.root

        binding.ivBack.setOnClickListener {
            dismiss()
        }

        return view
    }

    override fun onResume() {
        super.onResume()

        context?.dialogFragmentResize(this, 0.9f, 0.65f)
        context?.dialogRoundedBackground(this)
    }

    override fun onDestroyView() {
        super.onDestroyView()
        _binding = null
    }

    // Dialog 크기 비율 조절
    private fun Context.dialogFragmentResize(dialogFragment: DialogFragment, width: Float, height: Float) {
        val windowManager = getSystemService(Context.WINDOW_SERVICE) as WindowManager

        if (Build.VERSION.SDK_INT < 30) {

            val display = windowManager.defaultDisplay
            val size = Point()

            display.getSize(size)

            val window = dialogFragment.dialog?.window

            val x = (size.x * width).toInt()
            val y = (size.y * height).toInt()
            window?.setLayout(x, y)

        } else {

            val rect = windowManager.currentWindowMetrics.bounds

            val window = dialogFragment.dialog?.window

            val x = (rect.width() * width).toInt()
            val y = (rect.height() * height).toInt()

            window?.setLayout(x, y)
        }
    }

    private fun Context.dialogRoundedBackground(dialogFragment: DialogFragment) {

        dialog?.window?.setBackgroundDrawable(
            context?.let { ContextCompat.getDrawable(it, R.drawable.ic_rounded_background_dialog) }
        )
    }
}

 

그리고 이걸 Fragment에서 show를 이용해서 적용시키면 끝이다.

 

MyDetailFragment.kt

    private fun setLvDialog() {
        binding.ivLvInfo.setOnClickListener {
            val dialog = LvDialogFragment()
            dialog.show(childFragmentManager, "LvDialog")
        }
    }

 

참고) 이 함수는 onViewCreated()에서만 적용 가능하다. onCreateVIew()에 이 함수를 넣어봤더니 바로 Unreached Code 경고가 떴다.

 

 

아, 그리고 LvDialogFragment에서 설명하지 않은 부분이 두 가지가 있는데 바로 Dialog 크기 비율 조절Dialog 테두리 처리이다.

 

처음에는 다이얼로그 크기 비율 조절을 하지 않은 상태애서 곧바로 실행해봤더니 다이얼로그 크기가 너무 작아서 거의 짜부러지듯이 UI가 배치되어 있었다.

 

이 문제 때문에 다이얼로그를 Device의 화면 크기에 따라서 조절할 수 있는 기능을 추가해야겠다고 생각했다.

그래서 추가한 것이 바로 이것.

    // Dialog 크기 비율 조절
    private fun Context.dialogFragmentResize(dialogFragment: DialogFragment, width: Float, height: Float) {
        val windowManager = getSystemService(Context.WINDOW_SERVICE) as WindowManager

        if (Build.VERSION.SDK_INT < 30) {

            val display = windowManager.defaultDisplay
            val size = Point()

            display.getSize(size)

            val window = dialogFragment.dialog?.window

            val x = (size.x * width).toInt()
            val y = (size.y * height).toInt()
            window?.setLayout(x, y)

        } else {

            val rect = windowManager.currentWindowMetrics.bounds

            val window = dialogFragment.dialog?.window

            val x = (rect.width() * width).toInt()
            val y = (rect.height() * height).toInt()

            window?.setLayout(x, y)
        }
    }

 

SDK 버전이 30 미만이면 위의 식을, 이상이면 밑의 식을 이용해서 화면 크기를 조절한다.

나는 다이얼로그의 크기를 가로는 디바이스 가로의 90%, 세로는 디바이스 세로의 65% 비율로 조절했다.

 

그리고 이렇게 완성된 다이얼로그를 팀원에게 보여줬더니 현재 다이얼로그가 직각이어서 이걸 좀 원형으로 깎으면 어떻겠냐고 하더라.

 

그래서 DialogFragment에 이것도 하나 추가해두었다.

    private fun Context.dialogRoundedBackground(dialogFragment: DialogFragment) {

        dialog?.window?.setBackgroundDrawable(
            context?.let { ContextCompat.getDrawable(it, R.drawable.ic_rounded_background_dialog) }
        )
    }

 

ic_rounded_background_dialog.xml

<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android">
    <solid android:color="#FFFFFF"/>
    <corners android:radius="30dp"/>
    <stroke android:width="2dp" android:color="@color/offroader_outline"/>
</shape>

 

 

위의 사진은 그 결과다.

 

음. 확실히 이쁘게 잘 나오고 있다.

 

 

그리고 이 외에도 프로필 부분에 Blur 처리하는 부분도 도전해봤지만, 어째서인지 먹히지 않았다.

이건 왜일까…?