From e7b6ec740a9d2ebe6e4010ce5870cabd972af881 Mon Sep 17 00:00:00 2001 From: Rinat Nurmukhametov Date: Mon, 16 Aug 2021 13:30:21 +0300 Subject: [PATCH] add mvi interface to mvi fragment --- .../ru/touchin/roboswag/mvi_arch/core/IMvi.kt | 80 +++++++++++++++++++ .../roboswag/mvi_arch/core/MviFragment.kt | 65 +-------------- 2 files changed, 82 insertions(+), 63 deletions(-) create mode 100644 mvi-arch/src/main/java/ru/touchin/roboswag/mvi_arch/core/IMvi.kt diff --git a/mvi-arch/src/main/java/ru/touchin/roboswag/mvi_arch/core/IMvi.kt b/mvi-arch/src/main/java/ru/touchin/roboswag/mvi_arch/core/IMvi.kt new file mode 100644 index 0000000..e30d1ed --- /dev/null +++ b/mvi-arch/src/main/java/ru/touchin/roboswag/mvi_arch/core/IMvi.kt @@ -0,0 +1,80 @@ +package ru.touchin.roboswag.mvi_arch.core + +import android.os.Parcelable +import android.view.View +import ru.touchin.extensions.setOnRippleClickListener +import ru.touchin.roboswag.mvi_arch.marker.ViewAction +import ru.touchin.roboswag.mvi_arch.marker.ViewState + +/** + * Interface with the main MVI methods and fields + */ +interface IMvi + where NavArgs : Parcelable, + State : ViewState, + Action : ViewAction, + VM : MviViewModel { + + /** + * Use [viewModel] extension to get an instance of your view model class. + */ + val viewModel: VM + + /** + * Use this method to subscribe on view state changes. + * + * You should render view state here. + * + * Must not be called before [onAttach] and after [onDetach]. + */ + fun renderState(viewState: State) {} + + /** + * Use this method to dispatch view actions to view model. + */ + fun dispatchAction(actionProvider: () -> Action) { + viewModel.dispatchAction(actionProvider.invoke()) + } + + /** + * Use this method to dispatch view actions to view model. + */ + fun dispatchAction(action: Action) { + viewModel.dispatchAction(action) + } + + fun addOnBackPressedCallback(actionProvider: () -> Action) { + addOnBackPressedCallback(actionProvider.invoke()) + } + + fun addOnBackPressedCallback(action: Action) + + /** + * Simple extension for dispatching view events to view model with on click. + */ + fun View.dispatchActionOnClick(actionProvider: () -> Action) { + setOnClickListener { dispatchAction(actionProvider) } + } + + /** + * Simple extension for dispatching view events to view model with on click. + */ + fun View.dispatchActionOnClick(action: Action) { + setOnClickListener { dispatchAction(action) } + } + + /** + * Simple extension for dispatching view events to view model with on ripple click. + */ + fun View.dispatchActionOnRippleClick(actionProvider: () -> Action) { + setOnRippleClickListener { dispatchAction(actionProvider) } + } + + /** + * Simple extension for dispatching view events to view model with on ripple click. + */ + fun View.dispatchActionOnRippleClick(action: Action) { + setOnRippleClickListener { dispatchAction(action) } + } + +} \ No newline at end of file diff --git a/mvi-arch/src/main/java/ru/touchin/roboswag/mvi_arch/core/MviFragment.kt b/mvi-arch/src/main/java/ru/touchin/roboswag/mvi_arch/core/MviFragment.kt index 2399f4d..d89714f 100644 --- a/mvi-arch/src/main/java/ru/touchin/roboswag/mvi_arch/core/MviFragment.kt +++ b/mvi-arch/src/main/java/ru/touchin/roboswag/mvi_arch/core/MviFragment.kt @@ -12,7 +12,6 @@ import androidx.fragment.app.Fragment import androidx.lifecycle.Observer import androidx.lifecycle.ViewModel import androidx.lifecycle.ViewModelProvider -import ru.touchin.extensions.setOnRippleClickListener import ru.touchin.roboswag.mvi_arch.di.ViewModelAssistedFactory import ru.touchin.roboswag.mvi_arch.di.ViewModelFactory import ru.touchin.roboswag.mvi_arch.marker.ViewAction @@ -47,7 +46,7 @@ import javax.inject.Inject */ abstract class MviFragment( @LayoutRes layout: Int -) : BaseFragment(layout) +) : BaseFragment(layout), IMvi where NavArgs : Parcelable, State : ViewState, Action : ViewAction, @@ -57,11 +56,6 @@ abstract class MviFragment( const val INIT_ARGS_KEY = "INIT_ARGS" } - /** - * Use [viewModel] extension to get an instance of your view model class. - */ - protected abstract val viewModel: VM - /** * Used for smooth view model injection to this class. */ @@ -86,34 +80,7 @@ abstract class MviFragment( viewModel.state.observe(viewLifecycleOwner, Observer(this::renderState)) } - /** - * Use this method to subscribe on view state changes. - * - * You should render view state here. - * - * Must not be called before [onAttach] and after [onDetach]. - */ - protected open fun renderState(viewState: State) {} - - /** - * Use this method to dispatch view actions to view model. - */ - protected fun dispatchAction(actionProvider: () -> Action) { - viewModel.dispatchAction(actionProvider.invoke()) - } - - /** - * Use this method to dispatch view actions to view model. - */ - protected fun dispatchAction(action: Action) { - viewModel.dispatchAction(action) - } - - protected fun addOnBackPressedCallback(actionProvider: () -> Action) { - addOnBackPressedCallback(actionProvider.invoke()) - } - - protected fun addOnBackPressedCallback(action: Action) { + override fun addOnBackPressedCallback(action: Action) { requireActivity().onBackPressedDispatcher.addCallback(viewLifecycleOwner, object : OnBackPressedCallback(true) { override fun handleOnBackPressed() { dispatchAction(action) @@ -137,32 +104,4 @@ abstract class MviFragment( ).get(ViewModel::class.java) } - /** - * Simple extension for dispatching view events to view model with on click. - */ - protected fun View.dispatchActionOnClick(actionProvider: () -> Action) { - setOnClickListener { dispatchAction(actionProvider) } - } - - /** - * Simple extension for dispatching view events to view model with on click. - */ - protected fun View.dispatchActionOnClick(action: Action) { - setOnClickListener { dispatchAction(action) } - } - - /** - * Simple extension for dispatching view events to view model with on ripple click. - */ - protected fun View.dispatchActionOnRippleClick(actionProvider: () -> Action) { - setOnRippleClickListener { dispatchAction(actionProvider) } - } - - /** - * Simple extension for dispatching view events to view model with on ripple click. - */ - protected fun View.dispatchActionOnRippleClick(action: Action) { - setOnRippleClickListener { dispatchAction(action) } - } - }