8
9

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の大きさを自由に変えたい

Last updated at Posted at 2020-08-07

背景

ダイアログは基本小さめの画面なことが多いが、カスタムUIでフルスクリーンで表示したり画面比率何%で表示したり自在に操りたいなと思ったので実装してみた備忘録です

・androidX環境
・色々なサイズで使いたい
・xmlはConstraintLayoutで中身を書きたい

stackoverflowはじめ古い記事を見ていると、ParentをRelativeLayoutやLineaLayoutにしようとか、Styleを定義しようと書かれていましたがこちらが簡単かな?と思ったので書くことにします

フルスクリーン

実装

FullScreenDialogFragment.kt
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()
    }
}
view_full_screen_dialog.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/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に関連するonStartsetBackGroundDrawable/setLayoutwindowに対してサイズを決めてしまうということ

なぜ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.

DialogFragment.java
    /**
     * 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;
        }
    }

サイズ指定

上記も踏まえてとあるサイズを指定したい場合は以下のようになります

snippet.kt
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のサイズをコントロールしてもうまくはいかない

間違い等ありましたら遠慮なく指摘していただけると幸いです

8
9
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
8
9

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?