다음과 같은 화면이 있다고 가정하자. 아마 리스트뷰의 어떤 아이템을 클릭했을때 보여지는 상세화면으로 판단된다. 가운데에는 카드처럼 생긴 DialogFragment가 띄워져있고 DialogFragment 바깥으로 생성하기(Register) 버튼과 X(Cancel) 버튼이 존재한다.
이와 같이 DialogFramgnet 영역밖에 버튼을 어떻게 구현해줘야할까, 독립적인 버튼만 있는 뷰를 DialogFragment가 띄워질때 동시에 띄워야 할까? 아니다.
영역 크기에 대해 훼이크를 걸어주면된다.
실제 다이얼로그의 크기는 모든 버튼을 포함하는 좀 더 큰 영역이다!
대충 이정도
하늘색으로 표시한 영역을 전체 영역의 크기로 잡고 버튼들을 만들어주고 카드뷰를 전체 영역 내부에 넣어주면 된다. 그리고 바깥의 background를 투명하게 설정하면 만들고자했던 레이아웃을 만들어낼 수 있다.
예시 코드는 다음과 같다.
framgment.xml
<?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"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="@android:color/transparent">
<androidx.constraintlayout.widget.ConstraintLayout
android:layout_width="match_parent"
android:layout_height="match_parent">
<ImageView
android:id="@+id/iv_update_cancel"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="48dp"
android:layout_marginEnd="24dp"
android:src="@drawable/ic_cancel"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toTopOf="parent"
tools:ignore="ContentDescription" />
<androidx.cardview.widget.CardView
android:id="@+id/cv_update"
android:layout_width="296dp"
android:layout_height="444dp"
app:cardCornerRadius="48dp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent">
<androidx.constraintlayout.widget.ConstraintLayout
android:id="@+id/cl_update"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="@drawable/bg_dialog_rounded">
<androidx.appcompat.widget.Toolbar
android:id="@+id/tb_update"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginTop="32dp"
android:backgroundTint="@color/purple_200"
android:elevation="0dp"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:popupTheme="@style/ThemeOverlay.AppCompat.Light"
app:theme="@style/ThemeOverlay.AppCompat.Dark.ActionBar">
<EditText
android:id="@+id/et_update_regionNickname"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="32dp"
android:background="@null"
android:inputType="text"
android:shadowColor="#000000"
android:shadowDx="1"
android:shadowDy="1"
android:shadowRadius="5"
android:text="@string/region"
android:textColor="@color/white"
android:textSize="20sp"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
</androidx.appcompat.widget.Toolbar>
<TextView
android:id="@+id/tv_update_date"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="32dp"
android:layout_marginTop="6dp"
android:shadowColor="#000000"
android:shadowDx="1"
android:shadowDy="1"
android:shadowRadius="5"
android:text="@string/date"
android:textColor="#DBDBDB"
android:textSize="14sp"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/tb_update" />
<ImageView
android:id="@+id/iv_update_image"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:contentDescription="@string/play"
android:src="@drawable/ic_image"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<EditText
android:id="@+id/et_update_comment"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginStart="32dp"
android:layout_marginEnd="32dp"
android:layout_marginBottom="131dp"
android:background="@null"
android:inputType="text"
android:shadowColor="#000000"
android:shadowDx="1"
android:shadowDy="1"
android:shadowRadius="5"
android:singleLine="true"
android:text="@string/comment"
android:textColor="@color/white"
android:textSize="20sp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintStart_toStartOf="parent" />
<TextView
android:id="@+id/tv_update_music_name"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginStart="32dp"
android:layout_marginEnd="32dp"
android:layout_marginBottom="84dp"
android:ellipsize="marquee"
android:marqueeRepeatLimit="marquee_forever"
android:shadowColor="#000000"
android:shadowDx="1"
android:shadowDy="1"
android:shadowRadius="5"
android:singleLine="true"
android:text="@string/music_title"
android:textColor="@color/white"
android:textSize="20sp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintStart_toStartOf="parent" />
<TextView
android:id="@+id/tv_update_artist"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginStart="32dp"
android:layout_marginEnd="32dp"
android:layout_marginBottom="55dp"
android:ellipsize="marquee"
android:marqueeRepeatLimit="marquee_forever"
android:shadowColor="#000000"
android:shadowDx="1"
android:shadowDy="1"
android:shadowRadius="5"
android:singleLine="true"
android:text="@string/artist"
android:textColor="#DBDBDB"
android:textSize="20sp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintStart_toStartOf="parent" />
<TextView
android:id="@+id/tv_update_music_reference"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="32dp"
android:layout_marginBottom="32dp"
android:shadowColor="#000000"
android:shadowDx="1"
android:shadowDy="1"
android:shadowRadius="5"
android:text="@string/music_reference"
android:textColor="#C3C3C3"
android:textSize="14sp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintStart_toStartOf="parent" />
<ProgressBar
android:id="@+id/pb_update"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:visibility="gone"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
</androidx.constraintlayout.widget.ConstraintLayout>
</androidx.cardview.widget.CardView>
<androidx.appcompat.widget.AppCompatButton
android:id="@+id/btn_update"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="24dp"
android:background="@drawable/bg_update_round"
android:text="@string/update_complete"
android:textColor="@color/black"
android:textStyle="bold"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/cv_update" />
</androidx.constraintlayout.widget.ConstraintLayout>
</androidx.constraintlayout.widget.ConstraintLayout>
해당 fragment(DialogFragment) 의 코드
전체 화면을 차지하지않고 특정한 크기를 맞춰줘야 하기때문에
onResume() 내부에서 dialog의 height와 width 를 설정해주었다.
override fun onCreateView(
inflater: LayoutInflater,
container: ViewGroup?,
savedInstanceState: Bundle?
): View {
_binding = FragmentUpdateDotBinding.inflate(inflater, container, false)
fragment = activity?.supportFragmentManager?.findFragmentByTag("UpdateDotFragment")!!
// 타이틀 바 제거
dialog?.requestWindowFeature(Window.FEATURE_NO_TITLE)
// 다이얼로그 radius 적용
dialog?.window?.setBackgroundDrawable(ColorDrawable(Color.TRANSPARENT))
showProgress()
initData()
return binding.root
}
override fun onResume() {
super.onResume()
val windowManager =
requireContext().getSystemService(Context.WINDOW_SERVICE) as WindowManager
val width: Int
val height: Int
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) {
defaultDisplay = requireContext().display!!
val windowMetrics = windowManager.currentWindowMetrics
val windowInsets: WindowInsets = windowMetrics.windowInsets
val insets = windowInsets.getInsetsIgnoringVisibility(
WindowInsets.Type.navigationBars() or WindowInsets.Type.displayCutout()
)
val insetsWidth = insets.right + insets.left
val insetsHeight = insets.top + insets.bottom
val b = windowMetrics.bounds
width = b.width() - insetsWidth
height = b.height() - insetsHeight
} else {
@Suppress("DEPRECATION")
defaultDisplay = windowManager.defaultDisplay
val size = Point()
@Suppress("DEPRECATION")
defaultDisplay.getSize(size)
width = size.x
height = size.y
}
dialog!!.window!!.setLayout(width, height)
}
Reference)
DialogFragment 영역 밖 버튼 만들기
Place a button outside my layout on DialogFragment
화면 전체 사이즈 구하기
DialogFragment의 size(width, height)조절
DialogFramgent 관련 Deprecated 해결
Getter for defaultDisplay: Display!' is deprecated. Deprecated in Java
getSize() deprecated in API level 30
DialogFragment 띄우기
안드로이드 Fragment에서 Dialog 띄우기 ==> DialogFragment
DialogFragment 종료시키기
DialogFragment의 dismiss 질문입니다.