4
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

DialogFragmentのサイズを設定する方法

Posted at

今日は妙にAndroidのレイアウト調整に苦戦します。。

最近flutterとDjangoばかりやってるからAndroidの神様が怒ってるのかもしれません

ここに書くのはDialogFragmentのサイズの調整についてです。
xml側にwidth="match_parent"を書いても反映されず、困りました。
調べたところ、下記のようなDialogFragmentのクラス内のonStart()をoverrideして、widthとheightを設定するようです。

…こんな不便でしたっけ。。。

DialogFragmentのサイズの調整方法

SomeDialogFragment.kt
class SomeDialogFragment : DialogFragment() {
    override fun onStart() {
        super.onStart()
        val width = resources.displayMetrics.widthPixels - 16
        val height = resources.displayMetrics.heightPixels - 16
        dialog?.window?.setLayout(width, height)
    }
}

onStart()をoverrideしてごちゃごちゃ書きます。
これでもだいぶめんどくさいのですが、これpx指定なんですよね。。
dpで指定したい。。
ちなみに上記のコードは全画面から16pxだけ上下左右にmarginをあけています。

そもそも、

resources.displayMetrics.widthDips
resources.displayMetrics.heightDips

↑こういうのないの?!。。と思ったんですが、どうやらDisplayMetricsクラスを見たところContextなしで動くように作っているようで。。。(dipは端末依存なのでContextが必要ですよね)

仕方がないので頑張って変換しようと思います。

最終的に完成したものは

SomeDialogFragment.kt
class SomeDialogFragment : DialogFragment() {
    override fun onStart() {
        super.onStart()
        context?.also {
            val width = resources.displayMetrics.widthDips(it) - 16
            val height = resources.displayMetrics.heightDips(it) - 16
            dialog?.window?.setLayoutByDips(requireContext(), width, height)
        }
    }
}

↑こんな感じでdp指定でdialogFragmentのサイズを変更できるようになりました。

ここに至るまでに拡張をごちゃごちゃやったので、それらの拡張コードを載せておきます。
まずは手始めにpxとdpの変換コードを書きました。

pxとdpの変換

Context+Extensionx.kt
fun Context.convertDp2Px(dp: Int) : Int {
    val metrics: DisplayMetrics = this.resources.displayMetrics
    return (dp * metrics.density).toInt()
}

fun Context.convertPx2Dp(px: Int) : Int {
    val metrics: DisplayMetrics = this.resources.displayMetrics
    return (px / metrics.density).toInt()
}

↑こいつらを使えばpxとdpを相互に変換できます。

次に、DisplayMetricsクラスにdpの単位でwidthやheightを取得できるメソッドを生やしたいですね。

全画面サイズをdpで取得する

DisplayMetrics+Extensions.kt
fun DisplayMetrics.widthDips(context: Context) : Int {
    return context.convertPx2Dp(this.widthPixels)
}

fun DisplayMetrics.heightDips(context: Context) : Int {
    return context.convertPx2Dp(this.heightPixels)
}

Contextを渡して全画面サイズを取得できるようにしました。

で、最後にどうにかしなきゃいけないのは

dialog?.window?.setLayout(width, height)

ここですね。。。
setLayout()にはpixelを指定するので、できればdpで統一したいです。

WindowクラスのsetLayout()をdpで指定できるようにする

Window+Extensions.kt
fun Window.setLayoutByDips(context: Context, widthDips: Int, heightDips: Int) {
    this.setLayout(
        context.convertDp2Px(widthDips),
        context.convertDp2Px(heightDips)
    )
}

※dpで渡されたものをpxに変換して渡してるだけです。

上記のdp指定のメソッドを使ってonStart()を書き換えてみる

最初のpxによるdialogのサイズ変更方法は

SomeDialogFragment.kt
class SomeDialogFragment : DialogFragment() {
    override fun onStart() {
        super.onStart()
        val width = resources.displayMetrics.widthPixels - 16
        val height = resources.displayMetrics.heightPixels - 16
        dialog?.window?.setLayout(width, height)
    }
}

最終的なdpによるdialogのサイズ変更方法は

SomeDialogFragment.kt
class SomeDialogFragment : DialogFragment() {
    override fun onStart() {
        super.onStart()
        context?.also {
            val width = resources.displayMetrics.widthDips(it) - 16
            val height = resources.displayMetrics.heightDips(it) - 16
            dialog?.window?.setLayoutByDips(requireContext(), width, height)
        }
    }
}

ちょっと大変でしたが、pxではなくdpでdialogのサイズを調整できるようになりました。

探したりないだけでどこかにdp指定でサイズ変更する方法があったりして。。。

参考

4
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
4
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?