diff --git a/reactiveviewmodel/build.gradle b/reactiveviewmodel/build.gradle index 3d2e15b..226f320 100644 --- a/reactiveviewmodel/build.gradle +++ b/reactiveviewmodel/build.gradle @@ -45,7 +45,7 @@ afterEvaluate { release(MavenPublication) { from components.release groupId = 'com.alexdeww.reactiveviewmodel' - version = '2.4.8' + version = '2.4.9' } } } diff --git a/reactiveviewmodel/src/main/java/com/alexdeww/reactiveviewmodel/core/RvmViewComponent.kt b/reactiveviewmodel/src/main/java/com/alexdeww/reactiveviewmodel/core/RvmViewComponent.kt index 8297332..be2087d 100644 --- a/reactiveviewmodel/src/main/java/com/alexdeww/reactiveviewmodel/core/RvmViewComponent.kt +++ b/reactiveviewmodel/src/main/java/com/alexdeww/reactiveviewmodel/core/RvmViewComponent.kt @@ -1,5 +1,6 @@ package com.alexdeww.reactiveviewmodel.core +import android.app.Dialog import android.widget.CompoundButton import android.widget.EditText import android.widget.RatingBar @@ -63,10 +64,10 @@ interface RvmViewComponent { ) fun DialogControl.bindTo( - createDialog: ActionCreateDialog + dialogFactory: DialogFactory ) = bindTo( rvmViewComponent = this@RvmViewComponent, - createDialog = createDialog + dialogFactory = dialogFactory ) fun InputControl.bindTo( diff --git a/reactiveviewmodel/src/main/java/com/alexdeww/reactiveviewmodel/widget/DialogControl.kt b/reactiveviewmodel/src/main/java/com/alexdeww/reactiveviewmodel/widget/DialogControl.kt index 0fd9205..ca47b86 100644 --- a/reactiveviewmodel/src/main/java/com/alexdeww/reactiveviewmodel/widget/DialogControl.kt +++ b/reactiveviewmodel/src/main/java/com/alexdeww/reactiveviewmodel/widget/DialogControl.kt @@ -1,6 +1,7 @@ package com.alexdeww.reactiveviewmodel.widget import android.app.Dialog +import androidx.lifecycle.LiveData import androidx.lifecycle.MediatorLiveData import androidx.lifecycle.Observer import com.alexdeww.reactiveviewmodel.core.RvmViewComponent @@ -71,51 +72,88 @@ fun dialogControl(): DialogControl = DialogControl() fun dialogControlWithResult(): DialogControl = DialogControl() -typealias ActionCreateDialog = (data: T, dc: DialogControlResult) -> Dialog +fun interface DialogFactory { + fun createDialog(data: T, dc: DialogControlResult): D +} -fun DialogControl.bindTo( +fun DialogControl.bindToEx( rvmViewComponent: RvmViewComponent, - createDialog: ActionCreateDialog + dialogFactory: DialogFactory, + dialogLiveDataProvider: (control: DialogControl, dialogFactory: DialogFactory) -> DialogLiveDataMediator ) { - val liveData = DialogLiveDataMediator( - control = this, - createDialog = createDialog - ) + val liveData = dialogLiveDataProvider(this, dialogFactory) rvmViewComponent.run { liveData.observe { /* empty */ } } } -private class DialogLiveDataMediator( +fun DialogControl.bindTo( + rvmViewComponent: RvmViewComponent, + dialogFactory: DialogFactory +) = bindToEx(rvmViewComponent, dialogFactory, ::DialogLiveDataMediatorDialog) + +abstract class DialogLiveDataMediator( control: DialogControl, - createDialog: ActionCreateDialog + dialogFactory: DialogFactory ) : MediatorLiveData>() { - private var dialog: Dialog? = null + private var dialog: D? = null init { addSource(control.displayed.liveData) { displayData -> value = displayData when (displayData) { is DialogControl.Display.Displayed -> { - dialog = createDialog(displayData.data, DialogControlResult(control)) - dialog?.setOnDismissListener { control.dismiss() } - dialog?.show() + dialog = dialogFactory + .createDialog( + data = displayData.data, + dc = DialogControlResult(control) + ).also { + setupOnDismiss(it) { control.dismiss() } + showDialog(it) + } } DialogControl.Display.Absent -> closeDialog() } } } - override fun removeObserver(observer: Observer>) { + final override fun addSource(source: LiveData, onChanged: Observer) { + super.addSource(source, onChanged) + } + + final override fun removeObserver(observer: Observer>) { super.removeObserver(observer) closeDialog() } + protected abstract fun setupOnDismiss(dialog: D, dismissAction: () -> Unit) + + protected abstract fun showDialog(dialog: D) + + protected abstract fun onCloseDialog(dialog: D) + private fun closeDialog() { - dialog?.apply { - setOnDismissListener(null) - dismiss() - } + dialog?.let { onCloseDialog(it) } dialog = null } } + +private class DialogLiveDataMediatorDialog( + control: DialogControl, + dialogFactory: DialogFactory +) : DialogLiveDataMediator(control, dialogFactory) { + + override fun setupOnDismiss(dialog: Dialog, dismissAction: () -> Unit) { + dialog.setOnDismissListener { dismissAction() } + } + + override fun showDialog(dialog: Dialog) { + dialog.show() + } + + override fun onCloseDialog(dialog: Dialog) { + dialog.setOnDismissListener(null) + dialog.dismiss() + } + +}