diff --git a/alerts/README.md b/alerts/README.md index b4d5aa5..edb2100 100644 --- a/alerts/README.md +++ b/alerts/README.md @@ -4,8 +4,10 @@ alerts ### Общее описание Модуль содержит: -`ViewableAlertDialog` - служит для демонстрации AlertDialog с использованием View, необходимо вызвать метод `showAlertDialog`, который +`AlertDialogManager` - служит для демонстрации AlertDialog с использованием View, необходимо вызвать метод `showAlertDialog`, который в качестве агруметов может принимать: +* context +* style - стиль для элементов дефолтного диалога (по умолчанию R.style.AlertDialogDefault) * title - Заголовок диалога * message - дополнительное сообщение * positiveButtonText - текст правой кнопки (по умолчанию "ОК") @@ -29,9 +31,9 @@ alerts ### Примеры -View версия (ViewableAlertDialog): +View версия (ViewableAlertDialog) ok/cancel диалога: ```kotlin -ViewableAlertDialog.showAlertDialog( +alertDialogManager.showAlertDialog( activity, title = "Ой, что-то пошло не так", message = "Попробуйте ещё раз", @@ -41,6 +43,24 @@ ViewableAlertDialog.showAlertDialog( ) ``` +View версия (ViewableAlertDialog) ok диалога: +```kotlin +alertDialogManager.showOkDialog( + dialog?.window?.decorView?.context ?: throw Exception(), + title = "Необходимо изменить настройки", + okButtonText = "Ок", + onOkAction = { + viewModel.dispatchAction(ItemAction.ChangeSettings) + } +) +``` + +Для катомизации стилей элементов в дефолтной разметке диалога необходимо создать стиль - наследника от `ThemeOverlay.MaterialComponents.MaterialAlertDialog` и переопределить стили: +* materialAlertDialogTitleTextStyle - стиль для заголока (наследник от `MaterialAlertDialog.MaterialComponents.Title.Text`) +* materialAlertDialogBodyTextStyle - стиль для подзаголовка (наследник от `MaterialAlertDialog.MaterialComponents.Body.Text`) +* buttonBarPositiveButtonStyle - стиль для позитивной кнопки (наследник от `Widget.MaterialComponents.Button.TextButton.Dialog`) +* buttonBarNegativeButtonStyle - стиль для негативной кнопки (наследник от `Widget.MaterialComponents.Button.TextButton.Dialog`) + Compose версия (ComposableAlertDialog): ```kotlin val isDialogOpen = remember { mutableStateOf(false)} @@ -52,4 +72,4 @@ ComposableAlertDialog .... //Отображение диалога isDialogOpen.value = true -``` \ No newline at end of file +``` diff --git a/alerts/build.gradle b/alerts/build.gradle index 9c438b5..6c08de1 100644 --- a/alerts/build.gradle +++ b/alerts/build.gradle @@ -13,6 +13,7 @@ android { dependencies { implementation("androidx.core:core-ktx") implementation("androidx.constraintlayout:constraintlayout") + implementation("com.google.android.material:material") implementation project(":kotlin-extensions") implementation "androidx.compose.runtime:runtime:$composeVersion" @@ -36,5 +37,11 @@ dependencies { require '2.2.0-alpha03' } } + + implementation("com.google.android.material:material") { + version { + require '1.1.0' + } + } } } diff --git a/alerts/src/main/java/ru/touchin/roboswag/composable dialog/ComposableAlertDialog.kt b/alerts/src/main/java/ru/touchin/roboswag/composable dialog/ComposableAlertDialog.kt deleted file mode 100644 index 7ae6011..0000000 --- a/alerts/src/main/java/ru/touchin/roboswag/composable dialog/ComposableAlertDialog.kt +++ /dev/null @@ -1,63 +0,0 @@ -package com.ptut.statehandlingcompose - -import androidx.compose.material.AlertDialog -import androidx.compose.material.Text -import androidx.compose.material.TextButton -import androidx.compose.runtime.Composable -import androidx.compose.runtime.MutableState - -object ComposableAlertDialog { - var customTitle: @Composable (() -> Unit)? = null - var customMessage: @Composable (() -> Unit)? = null - var customConfirmBtn: @Composable (() -> Unit)? = null - var customNegativeBtn: @Composable (() -> Unit)? = null - - @Composable - fun ShowAlertDialog( - isDialogOpen: MutableState, - title: String? = null, - message: String? = null, - positiveButtonText: String? = null, - onPositiveAction: (() -> Unit)? = null, - negativeBtnTitle: String? = null, - onNegativeAction: (() -> Unit)? = null - ) { - if (isDialogOpen.value) { - AlertDialog( - onDismissRequest = { isDialogOpen.value = false }, - - title = customTitle ?: { Text(title.orEmpty()) }, - text = customMessage ?: { Text(message.orEmpty()) }, - - confirmButton = customConfirmBtn ?: { - TextButton( - onClick = { - onPositiveAction?.invoke() - isDialogOpen.value = false - } - ) { - Text(positiveButtonText.orEmpty()) - } - }, - - dismissButton = when { - customNegativeBtn != null -> customNegativeBtn - else -> { - negativeBtnTitle?.let { positiveText -> - { - TextButton( - onClick = { - onNegativeAction?.invoke() - isDialogOpen.value = false - } - ) { - Text(positiveText) - } - } - } - } - } - ) - } - } -} diff --git a/alerts/src/main/java/ru/touchin/roboswag/composable_dialog/ComposableAlertDialog.kt b/alerts/src/main/java/ru/touchin/roboswag/composable_dialog/ComposableAlertDialog.kt new file mode 100644 index 0000000..64ff4c6 --- /dev/null +++ b/alerts/src/main/java/ru/touchin/roboswag/composable_dialog/ComposableAlertDialog.kt @@ -0,0 +1,63 @@ +package ru.touchin.roboswag.composable_dialog + +import androidx.compose.material.AlertDialog +import androidx.compose.material.Text +import androidx.compose.material.TextButton +import androidx.compose.runtime.Composable +import androidx.compose.runtime.MutableState + +object ComposableAlertDialog { + var customTitle: @Composable (() -> Unit)? = null + var customMessage: @Composable (() -> Unit)? = null + var customConfirmBtn: @Composable (() -> Unit)? = null + var customNegativeBtn: @Composable (() -> Unit)? = null + + @Composable + fun ShowAlertDialog( + isDialogOpen: MutableState, + title: String? = null, + message: String? = null, + positiveButtonText: String? = null, + onPositiveAction: (() -> Unit)? = null, + negativeBtnTitle: String? = null, + onNegativeAction: (() -> Unit)? = null + ) { + if (isDialogOpen.value) { + AlertDialog( + onDismissRequest = { isDialogOpen.value = false }, + + title = customTitle ?: { Text(title.orEmpty()) }, + text = customMessage ?: { Text(message.orEmpty()) }, + + confirmButton = customConfirmBtn ?: { + TextButton( + onClick = { + onPositiveAction?.invoke() + isDialogOpen.value = false + } + ) { + Text(positiveButtonText.orEmpty()) + } + }, + + dismissButton = when { + customNegativeBtn != null -> customNegativeBtn + else -> { + negativeBtnTitle?.let { positiveText -> + { + TextButton( + onClick = { + onNegativeAction?.invoke() + isDialogOpen.value = false + } + ) { + Text(positiveText) + } + } + } + } + } + ) + } + } +} diff --git a/alerts/src/main/java/ru/touchin/roboswag/viewable_dialog/AlertDialogManager.kt b/alerts/src/main/java/ru/touchin/roboswag/viewable_dialog/AlertDialogManager.kt new file mode 100644 index 0000000..e2f847c --- /dev/null +++ b/alerts/src/main/java/ru/touchin/roboswag/viewable_dialog/AlertDialogManager.kt @@ -0,0 +1,87 @@ +package ru.touchin.roboswag.viewable_dialog + +import android.content.Context +import android.view.LayoutInflater +import android.widget.TextView +import androidx.appcompat.view.ContextThemeWrapper +import com.google.android.material.dialog.MaterialAlertDialogBuilder +import ru.touchin.roboswag.alerts.R + +class AlertDialogManager { + + fun showAlertDialog( + context: Context, + style: Int = R.style.AlertDialogDefault, + title: String? = null, + message: String? = null, + positiveButtonText: String = context.getString(R.string.positive_btn), + onPositiveAction: (() -> Unit)? = null, + negativeBtnTitle: String? = null, + onNegativeAction: (() -> Unit)? = null, + dialogLayout: Int = R.layout.dialog_alert, + cancelable: Boolean = true, + onCancelAction: () -> Unit = {} + ) { + val styledContext = ContextThemeWrapper(context, style) + MaterialAlertDialogBuilder(styledContext) + .setView(LayoutInflater.from(styledContext).inflate(dialogLayout, null)) + .show() + .apply { + setupAlertDialog( + dialog = this, + title = title, + message = message, + positiveButtonText = positiveButtonText, + onPositiveClick = onPositiveAction, + negativeButtonText = negativeBtnTitle, + onNegativeClick = onNegativeAction, + cancelable = cancelable, + onCancelAction = onCancelAction + ) + } + } + + fun showOkDialog( + context: Context, + style: Int = R.style.AlertDialogDefault, + title: String? = null, + message: String? = null, + okButtonText: String = context.getString(R.string.positive_btn), + onOkAction: (() -> Unit)? = null, + cancelable: Boolean = true, + onCancelAction: () -> Unit = {} + ) = showAlertDialog( + context = context, + style = style, + title = title, + message = message, + positiveButtonText = okButtonText, + onPositiveAction = onOkAction, + cancelable = cancelable, + onCancelAction = onCancelAction + ) + + + private fun setupAlertDialog( + dialog: androidx.appcompat.app.AlertDialog, + title: String? = null, + message: String? = null, + positiveButtonText: String, + onPositiveClick: (() -> Unit)? = null, + negativeButtonText: String? = null, + onNegativeClick: (() -> Unit)? = null, + cancelable: Boolean = true, + onCancelAction: () -> Unit = {} + ) { + dialog.setCancelable(cancelable) + dialog.setOnDismissListener { onCancelAction() } + dialog.findViewById(R.id.alert_title)?.setTextOrGone(title) + dialog.findViewById(R.id.alert_message)?.setTextOrGone(message) + dialog.findViewById(R.id.alert_positive_button)?.let { buttonView -> + setupButton(dialog, buttonView, positiveButtonText, onPositiveClick) + } + dialog.findViewById(R.id.alert_negative_button)?.let { buttonView -> + setupButton(dialog, buttonView, negativeButtonText, onNegativeClick) + } + } +} diff --git a/alerts/src/main/java/ru/touchin/roboswag/viewable_dialog/AlertDialogUtils.kt b/alerts/src/main/java/ru/touchin/roboswag/viewable_dialog/AlertDialogUtils.kt index 6664c1a..340b3da 100644 --- a/alerts/src/main/java/ru/touchin/roboswag/viewable_dialog/AlertDialogUtils.kt +++ b/alerts/src/main/java/ru/touchin/roboswag/viewable_dialog/AlertDialogUtils.kt @@ -1,11 +1,10 @@ -package ru.touchin.roboswag.alerts.dialog_view +package ru.touchin.roboswag.viewable_dialog -import android.app.AlertDialog import android.widget.TextView import androidx.core.view.isVisible import ru.touchin.extensions.setOnRippleClickListener -fun setupButton(alertDialog: AlertDialog, buttonView: TextView, text: String?, onButtonClick: (() -> Unit)?) { +fun setupButton(alertDialog: androidx.appcompat.app.AlertDialog, buttonView: TextView, text: String?, onButtonClick: (() -> Unit)?) { buttonView.setTextOrGone(text) buttonView.setOnRippleClickListener { onButtonClick?.invoke() diff --git a/alerts/src/main/java/ru/touchin/roboswag/viewable_dialog/ViewableAlertDialog.kt b/alerts/src/main/java/ru/touchin/roboswag/viewable_dialog/ViewableAlertDialog.kt deleted file mode 100644 index 0ff2d76..0000000 --- a/alerts/src/main/java/ru/touchin/roboswag/viewable_dialog/ViewableAlertDialog.kt +++ /dev/null @@ -1,63 +0,0 @@ -package ru.touchin.roboswag.alerts - -import android.app.AlertDialog -import android.content.Context -import android.view.LayoutInflater -import android.widget.TextView -import ru.touchin.roboswag.alerts.dialog_view.setTextOrGone -import ru.touchin.roboswag.alerts.dialog_view.setupButton - -object ViewableAlertDialog { - - fun showAlertDialog( - context: Context, - title: String? = null, - message: String? = null, - positiveButtonText: String = context.getString(R.string.positive_btn), - onPositiveAction: (() -> Unit)? = null, - negativeBtnTitle: String? = null, - onNegativeAction: (() -> Unit)? = null, - dialogLayout: Int = R.layout.dialog_alert, - cancelable: Boolean = true, - onCancelAction: () -> Unit = {} - ) { - AlertDialog.Builder(context) - .setView(LayoutInflater.from(context).inflate(dialogLayout, null)) - .show() - .apply { - setupAlertDialog( - dialog = this, - title = title, - message = message, - positiveButtonText = positiveButtonText, - onPositiveClick = onPositiveAction, - negativeButtonText = negativeBtnTitle, - onNegativeClick = onNegativeAction, - cancelable = cancelable, - onCancelAction = onCancelAction) - } - } - - private fun setupAlertDialog( - dialog: AlertDialog, - title: String? = null, - message: String? = null, - positiveButtonText: String, - onPositiveClick: (() -> Unit)? = null, - negativeButtonText: String? = null, - onNegativeClick: (() -> Unit)? = null, - cancelable: Boolean = true, - onCancelAction: () -> Unit = {} - ) { - dialog.setCancelable(cancelable) - dialog.setOnDismissListener { onCancelAction() } - dialog.findViewById(R.id.alert_title)?.setTextOrGone(title) - dialog.findViewById(R.id.alert_message)?.setTextOrGone(message) - dialog.findViewById(R.id.alert_positive_button)?.let { buttonView -> - setupButton(dialog, buttonView, positiveButtonText, onPositiveClick) - } - dialog.findViewById(R.id.alert_negative_button)?.let { buttonView -> - setupButton(dialog, buttonView, negativeButtonText, onNegativeClick) - } - } -} diff --git a/alerts/src/main/res/layout/dialog_alert.xml b/alerts/src/main/res/layout/dialog_alert.xml index 2d8797e..6aec6ce 100644 --- a/alerts/src/main/res/layout/dialog_alert.xml +++ b/alerts/src/main/res/layout/dialog_alert.xml @@ -10,13 +10,9 @@ - + + + + + +