背景
ダイアログは基本小さめの画面なことが多いが、カスタムUIでフルスクリーンで表示したり画面比率何%で表示したり自在に操りたいなと思ったので実装してみた備忘録です
・androidX環境
・色々なサイズで使いたい
・xmlはConstraintLayoutで中身を書きたい
stackoverflowはじめ古い記事を見ていると、ParentをRelativeLayoutやLineaLayoutにしようとか、Styleを定義しようと書かれていましたがこちらが簡単かな?と思ったので書くことにします
フルスクリーン
実装
package com.example.coroutines
import android.os.Bundle
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.widget.Toast
import androidx.fragment.app.DialogFragment
import kotlinx.android.synthetic.main.view_full_screen_dialog.view.*
class FullScreenDialogFragment : DialogFragment() {
override fun onCreateView(
inflater: LayoutInflater,
container: ViewGroup?,
savedInstanceState: Bundle?
): View? {
return inflater.inflate(R.layout.view_full_screen_dialog, container, false).apply {
text.setOnClickListener {
Toast.makeText(it.context, text.text, Toast.LENGTH_SHORT).show()
}
close.setOnClickListener {
dismiss()
}
}
}
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
dialog?.setCancelable(true)
}
override fun onStart() {
super.onStart()
dialog?.window?.setBackgroundDrawable(null)
dialog?.window?.setLayout(
ViewGroup.LayoutParams.MATCH_PARENT,
ViewGroup.LayoutParams.MATCH_PARENT
)
}
companion object {
fun newInstance() = FullScreenDialogFragment()
}
}
<?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/white">
<TextView
android:id="@+id/close"
android:layout_width="24dp"
android:layout_height="24dp"
android:layout_marginTop="24dp"
android:layout_marginEnd="24dp"
android:drawableLeft="@drawable/ic_close_24"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toTopOf="parent"
tools:ignore="RtlHardcoded" />
<TextView
android:id="@+id/text"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:gravity="center"
android:text="TEXT"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
</androidx.constraintlayout.widget.ConstraintLayout>
肝なのはActivity
に関連するonStart
でsetBackGroundDrawable/setLayout
でwindow
に対してサイズを決めてしまうということ
なぜxmlでmatch_parentとか適当にXXXdpとか設定してもうまくいかないのは、あくまでDialogFragmentはDialogのwrapperにすぎないので、サイズ調整するのはcontainerではなくwindowで行う必要があるということですね。
DialogFragmentのスタイルを設定するDialogFragment#setTyle
でもこのような記述があります。
The same effect can be achieve by manually setting Dialog and Window attributes yourself. Calling this after the fragment's Dialog is created will have no effect.
/**
* Call to customize the basic appearance and behavior of the
* fragment's dialog. This can be used for some common dialog behaviors,
* taking care of selecting flags, theme, and other options for you. The
* same effect can be achieve by manually setting Dialog and Window
* attributes yourself. Calling this after the fragment's Dialog is
* created will have no effect.
*
* @param style Selects a standard style: may be {@link #STYLE_NORMAL},
* {@link #STYLE_NO_TITLE}, {@link #STYLE_NO_FRAME}, or
* {@link #STYLE_NO_INPUT}.
* @param theme Optional custom theme. If 0, an appropriate theme (based
* on the style) will be selected for you.
*/
public void setStyle(@DialogStyle int style, @StyleRes int theme) {
mStyle = style;
if (mStyle == STYLE_NO_FRAME || mStyle == STYLE_NO_INPUT) {
mTheme = android.R.style.Theme_Panel;
}
if (theme != 0) {
mTheme = theme;
}
}
サイズ指定
上記も踏まえてとあるサイズを指定したい場合は以下のようになります
override fun onStart() {
super.onStart()
dialog?.window?.setBackgroundDrawable(null)
val width = (resources.displayMetrics.widthPixels * 0.95).toInt()
val height = (resources.displayMetrics.heightPixels * 0.95).toInt()
dialog?.window?.setLayout(width, height)
}
setLayout
にはwidth
, height
で指定できるので各々好きなサイズで実装ができます
まとめ
・onStartにサイズの記載をしよう
・xmlでParentViewのサイズをコントロールしてもうまくはいかない
間違い等ありましたら遠慮なく指摘していただけると幸いです