Android:Dialogのデザインをカスタムして表示する
はじめに
AnalogDialogでDialogを狙ったデザインにしようとしましたが、ボタンの位置の細かい調整など融通がききませんでした。それなら最初からDialogのLayoutをつくって、表示させたほうが手戻りが少なくなりそうです。
そのDialogのlayoutをカスタムする方法を書き残します。
やりかた
Activityについて
サンプルコードは、Activityにはボタンが1つ設置してありそれを押すとダイアログが表示されます。
MainActivity.kt
class MainActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
setTitle("Dialog Test")
val displayDialog = findViewById<Button>(R.id.button)
displayDialog.setOnClickListener{
val dialog = CustomDialog()
val manager: FragmentManager = supportFragmentManager
dialog.show(manager, "simple")
}
}
}
activity_main.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"
tools:context=".MainActivity">
<Button
android:id="@+id/button"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Dialog"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
</androidx.constraintlayout.widget.ConstraintLayout>
ダイアログについて
ダイアログはDialogFragmentを使用します。
Dialogはカスタムしたlayoutをxmlファイルで記述して使用します。
custom_dialog.xml
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
xmlns:app="http://schemas.android.com/apk/res-auto">
<androidx.constraintlayout.widget.ConstraintLayout
android:id="@+id/custom_dialog"
android:layout_width="600dp"
android:layout_height="320dp"
android:background="@drawable/dialog_design"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintEnd_toEndOf="parent">
<TextView
android:id="@+id/dialogTitle"
android:layout_width="match_parent"
android:layout_height="50dp"
android:background="@drawable/dialog_design_titlebar"
android:gravity="center"
android:text="test"
android:textColor="@color/white"
android:textSize="@dimen/dialog_title_text_size"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="0.0"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<TextView
android:id="@+id/dialogMessage"
android:layout_width="match_parent"
android:layout_height="150dp"
android:layout_marginStart="20dp"
android:layout_marginTop="20dp"
android:layout_marginEnd="20dp"
android:text="テスト"
android:gravity="center"
android:textColor="@color/black"
android:textSize="@dimen/dialog_message_text_size"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="0.0"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/dialogTitle" />
<Button
android:id="@+id/dialogButtonPositive"
android:layout_width="150dp"
android:layout_height="60dp"
android:layout_gravity="center_vertical"
android:layout_marginTop="20dp"
android:layout_marginEnd="60dp"
android:backgroundTint="#00BCD4"
android:gravity="center"
android:text="はい"
android:textColor="@color/white"
android:textSize="@dimen/dialog_message_text_size"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toBottomOf="@+id/dialogMessage"
app:layout_constraintVertical_bias="0.0" />
<Button
android:id="@+id/dialogButtonNegative"
android:layout_width="150dp"
android:layout_height="60dp"
android:layout_gravity="center_vertical"
android:layout_marginStart="60dp"
android:layout_marginTop="20dp"
android:backgroundTint="#00BCD4"
android:gravity="center"
android:text="いいえ"
android:textColor="@color/white"
android:textSize="@dimen/dialog_message_text_size"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/dialogMessage"
app:layout_constraintVertical_bias="0.0" />
</androidx.constraintlayout.widget.ConstraintLayout>
</androidx.constraintlayout.widget.ConstraintLayout>
そして、下記のようにDialogFragmentを記述します。
Dialog.kt
class CustomDialog: DialogFragment(){
private lateinit var dTitle: String
private lateinit var dMessage: String
private lateinit var dButtonPositive: String
private lateinit var dButtonNegative: String
override fun onCreateDialog(savedInstanceState: Bundle?): Dialog {
val dialog = Dialog(requireContext())
// ダイアログを透過状態に変更
dialog.window?.setBackgroundDrawable(ColorDrawable(Color.TRANSPARENT))
// カスタムしたレイアウトをわたす
dialog.setContentView(R.layout.custom_dialog)
val dialogTitle = dialog.findViewById<TextView>(R.id.dialogTitle)
val dialogMessage = dialog.findViewById<TextView>(R.id.dialogMessage)
val dialogButtomPositive = dialog.findViewById<Button>(R.id.dialogButtonPositive)
val dialogButtomNegative = dialog.findViewById<Button>(R.id.dialogButtonNegative)
dTitle = "タイトルを表示"
dMessage = "テキストを表示"
dButtonPositive = "はい"
dButtonNegative = "いいえ"
dialogTitle.setText(dTitle)
dialogMessage.setText(dMessage)
dialogButtomPositive.setText(dButtonPositive)
dialogButtomNegative.setText(dButtonNegative)
dialogButtomPositive.setOnClickListener {
// 処理を記述
dialog.dismiss()
}
dialogButtomNegative.setOnClickListener {
// 処理を記述
dialog.dismiss()
}
// ダイアログのタップを無効にする場合、下記のコメントアウトを外す
// dialog.setCanceledOnTouchOutside(false)
return dialog
}
}
このとき、さきほどつくったlayoutをsetContentViewでわたすことで、自分で作成したlayoutのダイアログをつくることができます。
dialog.setContentView(R.layout.custom_dialog)
そして、それぞれのパーツをfindViewByIdでみつけ、setTextすることで文言を変更できます。またsetOnClickListenerをつかってボタンをおしたときの処理を記述できます。
その他のパラメータ
文字サイズやダイアログに使用する色はres/values直下にdimens.xmlやcolors.xmlに記述し管理すると、他のダイアログをつくったときにパラメータを共通化できるので便利です。今回のサンプルコードでは下記のように指定しています。
dimens.xml
<?xml version="1.0" encoding="utf-8"?>
<resources>
<dimen name="button_text_size">24sp</dimen>
<dimen name="dialog_title_text_size">34sp</dimen>
<dimen name="dialog_message_text_size">24sp</dimen>
<dimen name="dialog_corner_radius">10dp</dimen>
</resources>
ダイアログを角丸にする
ダイアログはそのままだと、直角形の形状です。
角丸にするには、res/drawable直下に下記のようにファイルをつくって、形状を記述します。
dialog_design.xml
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item>
<shape android:shape="rectangle">
<corners
android:topRightRadius="@dimen/dialog_corner_radius"
android:bottomRightRadius="@dimen/dialog_corner_radius"
android:bottomLeftRadius="@dimen/dialog_corner_radius"
android:topLeftRadius="@dimen/dialog_corner_radius"
/>
<solid android:color="@color/white" />
</shape>
</item>
</selector>
dialog_design.titlebar.xml
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item>
<shape android:shape="rectangle">
<corners
android:topRightRadius="@dimen/dialog_corner_radius"
android:topLeftRadius="@dimen/dialog_corner_radius"
/>
<solid android:color="#00BCD4" />
</shape>
</item>
</selector>
それをダイアログのxmlファイルで呼び出します。
android:background="@drawable/dialog_design"
android:background="@drawable/dialog_design_titlebar"
角丸の指定を2つのファイルに分けている理由は、今回作成したダイアログはタイトルを表示する部分(上部の色を塗りつぶして白抜きにした部分)とメッセージを表示する部分(白い背景色の部分)の2つのパーツが重なっているためです。
そのためタイトルを表示する部分は上の左右を角丸にして、さらにメッセージを表示する部分は4隅を角丸にすることで、全体を角丸のダイアログになるよう実現しています。
終わりに
一度理解してしまえば、ダイアログをカスタムしやすいかと思います。
Discussion