Merge branch 'master' into code_confirm

This commit is contained in:
Anastasiya97 2022-09-16 13:23:02 +03:00
commit c33b02c8ea
10 changed files with 384 additions and 0 deletions

1
alerts/.gitignore vendored Normal file
View File

@ -0,0 +1 @@
/build

75
alerts/README.md Normal file
View File

@ -0,0 +1,75 @@
Alerts
=====
### Общее описание
Модуль содержит:
`AlertDialogManager` - служит для демонстрации AlertDialog с использованием View, необходимо вызвать метод `showAlertDialog`, который
в качестве агруметов может принимать:
* `context`,
* `style` - стиль для элементов дефолтного диалога (по умолчанию R.style.AlertDialogDefault),
* `title` - Заголовок диалога,
* `message` - дополнительное сообщение,
* `positiveButtonText` - текст правой кнопки (по умолчанию "ОК"),
* `onPositiveAction` - колбэк при нажатии на правую кнопку,
* `negativeBtnTitle` - текст левой кнопки (по умолчаннию null - в этом случаи не отображается),
* `onNegativeAction` - колбэк при нажатии на левую кнопку,
* `dialogLayout` - id кастомного layout (по умолчанию R.layout.dialog_alert).
---
`ComposableAlertDialog` - служит для демонстрации AlertDialog с использованием Jetpack Compose, необходимо вызвать метод `ShowAlertDialog`, который
в качестве агруметов может принимать:
* `isDialogOpen` - индикатор состояния диалога,
* `title` - Заголовок диалога,
* `message` - дополнительное сообщение,
* `positiveButtonText` - текст правой кнопки,
* `onPositiveAction` - колбэк при нажатии на правую кнопку,
* `negativeBtnTitle` - текст левой кнопки (по умолчаннию null - в этом случаи не отображается),
* `onNegativeAction` - колбэк при нажатии на левую кнопку.
Кастомизация Compose версии происходит по средствам инициализации полей: customTitle, customMessage, customConfirmBtn, customNegativeBtn
### Примеры
View версия (ViewableAlertDialog) ok/cancel диалога:
```kotlin
alertDialogManager.showAlertDialog(
context = activity,
title = "Ой, что-то пошло не так",
message = "Попробуйте ещё раз",
positiveButtonText = "Ещё раз",
onPositiveAction = { retryConnection() },
negativeBtnTitle = "Отмена"
)
```
View версия (ViewableAlertDialog) ok диалога:
```kotlin
alertDialogManager.showOkDialog(
context = 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)}
....
//Создание диалога
ComposableAlertDialog
.apply { customTitle = { Text(text = "Ой, что-то пошло не так", color = Color.Blue) } }
.ShowAlertDialog(isDialogOpen, message = "Проблемы с сетью", positiveButtonText = "ОК")
....
//Отображение диалога
isDialogOpen.value = true
```

47
alerts/build.gradle Normal file
View File

@ -0,0 +1,47 @@
apply from: "../android-configs/lib-config.gradle"
ext {
composeVersion = '1.1.1'
}
android {
buildFeatures {
viewBinding true
}
}
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"
implementation "androidx.compose.ui:ui:$composeVersion"
implementation "androidx.compose.foundation:foundation:$composeVersion"
implementation "androidx.compose.foundation:foundation-layout:$composeVersion"
implementation "androidx.compose.material:material:$composeVersion"
implementation "androidx.compose.runtime:runtime-livedata:$composeVersion"
implementation "androidx.compose.ui:ui-tooling:$composeVersion"
implementation "com.google.android.material:compose-theme-adapter:1.1.9"
constraints {
implementation("androidx.core:core-ktx") {
version {
require '1.0.0'
}
}
implementation("androidx.constraintlayout:constraintlayout") {
version {
require '2.2.0-alpha03'
}
}
implementation("com.google.android.material:material") {
version {
require '1.1.0'
}
}
}
}

View File

@ -0,0 +1,2 @@
<manifest
package="ru.touchin.roboswag.alerts"/>

View File

@ -0,0 +1,54 @@
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<Boolean>,
title: String? = null,
message: String? = null,
positiveButtonText: String? = null,
onPositiveAction: (() -> Unit)? = null,
negativeBtnTitle: String? = null,
onNegativeAction: (() -> Unit)? = null
) {
if (!isDialogOpen.value) return
AlertDialog(
onDismissRequest = { isDialogOpen.value = false },
title = customTitle ?: { Text(title.orEmpty()) },
text = customMessage ?: { Text(message.orEmpty()) },
confirmButton = customConfirmBtn ?: createButton(positiveButtonText.orEmpty()) {
onPositiveAction?.invoke()
isDialogOpen.value = false
},
dismissButton = when {
customNegativeBtn != null -> customNegativeBtn
negativeBtnTitle != null -> createButton(negativeBtnTitle) {
onNegativeAction?.invoke()
isDialogOpen.value = false
}
else -> null
}
)
}
@Composable
private fun createButton(text: String, onClickAction: () -> Unit): @Composable (() -> Unit) =
{
TextButton(onClick = onClickAction) {
Text(text)
}
}
}

View File

@ -0,0 +1,85 @@
package ru.touchin.roboswag.viewable_dialog
import android.content.Context
import android.view.LayoutInflater
import android.widget.TextView
import androidx.appcompat.app.AlertDialog
import androidx.appcompat.view.ContextThemeWrapper
import com.google.android.material.dialog.MaterialAlertDialogBuilder
import ru.touchin.roboswag.alerts.R
class AlertDialogManager {
@SuppressWarnings("detekt.LongParameterList")
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()
.setupAlertDialog(
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 AlertDialog.setupAlertDialog(
title: String? = null,
message: String? = null,
positiveButtonText: String,
onPositiveClick: (() -> Unit)? = null,
negativeButtonText: String? = null,
onNegativeClick: (() -> Unit)? = null,
cancelable: Boolean = true,
onCancelAction: () -> Unit = {}
) {
setCancelable(cancelable)
setOnDismissListener { onCancelAction() }
findViewById<TextView>(R.id.alert_title)?.setTextOrGone(title)
findViewById<TextView>(R.id.alert_message)?.setTextOrGone(message)
findViewById<TextView>(R.id.alert_positive_button)?.let { buttonView ->
setupButton(this, buttonView, positiveButtonText, onPositiveClick)
}
findViewById<TextView>(R.id.alert_negative_button)?.let { buttonView ->
setupButton(this, buttonView, negativeButtonText, onNegativeClick)
}
}
}

View File

@ -0,0 +1,19 @@
package ru.touchin.roboswag.viewable_dialog
import android.widget.TextView
import androidx.appcompat.app.AlertDialog
import androidx.core.view.isVisible
import ru.touchin.extensions.setOnRippleClickListener
fun setupButton(alertDialog: AlertDialog, buttonView: TextView, text: String?, onButtonClick: (() -> Unit)?) {
buttonView.setTextOrGone(text)
buttonView.setOnRippleClickListener {
onButtonClick?.invoke()
alertDialog.dismiss()
}
}
fun TextView.setTextOrGone(text: CharSequence?) {
isVisible = !text.isNullOrEmpty()
setText(text)
}

View File

@ -0,0 +1,57 @@
<?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="wrap_content"
android:paddingTop="22dp"
android:paddingBottom="8dp">
<TextView
android:id="@+id/alert_title"
style="?attr/materialAlertDialogTitleTextStyle"
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
tools:text="Header" />
<TextView
android:id="@+id/alert_message"
style="?attr/materialAlertDialogBodyTextStyle"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_below="@id/alert_title"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/alert_title"
tools:text="Text" />
<TextView
android:id="@+id/alert_positive_button"
style="?attr/buttonBarPositiveButtonStyle"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_below="@id/alert_message"
android:layout_alignParentEnd="true"
android:layout_alignParentRight="true"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toBottomOf="@id/alert_message"
tools:text="OK" />
<TextView
android:id="@+id/alert_negative_button"
style="?attr/buttonBarNegativeButtonStyle"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_below="@id/alert_message"
android:layout_marginEnd="8dp"
android:layout_toStartOf="@id/alert_positive_button"
android:layout_toLeftOf="@id/alert_positive_button"
app:layout_constraintRight_toLeftOf="@id/alert_positive_button"
app:layout_constraintTop_toBottomOf="@id/alert_message"
tools:text="Cancel" />
</androidx.constraintlayout.widget.ConstraintLayout>

View File

@ -0,0 +1,5 @@
<?xml version="1.0" encoding="utf-8"?>
<resources>
<string name="positive_btn">OK</string>
<string name="negative_btn">Cancel</string>
</resources>

View File

@ -0,0 +1,39 @@
<?xml version="1.0" encoding="utf-8"?>
<resources>
<style name="AlertDialogDefault" parent="ThemeOverlay.MaterialComponents.MaterialAlertDialog">
<item name="colorSurface">#FFFFFF</item>
<item name="materialAlertDialogTitleTextStyle">@style/MaterialAlertDialog.MaterialComponents.Title.Text.Default</item>
<item name="buttonBarPositiveButtonStyle">@style/MaterialAlertDialog.MaterialComponents.Button.Default</item>
<item name="buttonBarNegativeButtonStyle">@style/MaterialAlertDialog.MaterialComponents.Button.Default</item>
<item name="materialAlertDialogBodyTextStyle">@style/MaterialAlertDialog.MaterialComponents.Body.Text.Default</item>
</style>
<style name="MaterialAlertDialog.MaterialComponents.Title.Text.Default" parent="MaterialAlertDialog.MaterialComponents.Title.Text">
<item name="android:textColor">#383838</item>
<item name="android:textSize">15sp</item>
<item name="android:layout_marginLeft">24dp</item>
<item name="android:layout_marginRight">24dp</item>
<item name="android:paddingBottom">16dp</item>
</style>
<style name="MaterialAlertDialog.MaterialComponents.Body.Text.Default" parent="MaterialAlertDialog.MaterialComponents.Body.Text">
<item name="android:textColor">#383838</item>
<item name="android:textSize">12sp</item>
<item name="android:layout_marginLeft">24dp</item>
<item name="android:layout_marginRight">24dp</item>
<item name="android:paddingBottom">28dp</item>
<item name="android:lineSpacingExtra">8dp</item>
</style>
<style name="MaterialAlertDialog.MaterialComponents.Button.Default" parent="Widget.MaterialComponents.Button.TextButton.Dialog">
<item name="android:textColor">#383838</item>
<item name="android:minWidth">56dp</item>
<item name="android:gravity">center</item>
<item name="android:textAllCaps">true</item>
<item name="android:textSize">14sp</item>
<item name="android:paddingTop">11dp</item>
<item name="android:paddingBottom">9dp</item>
<item name="android:layout_marginTop">8dp</item>
<item name="android:layout_marginRight">8dp</item>
</style>
</resources>