Compare commits

...

2 Commits

Author SHA1 Message Date
Kirill Nayduik ce65617ab8 MVI fix: expand flow component lifecycle 2021-07-01 12:54:13 +03:00
Kirill Nayduik b577e4d1d5 MVI fix: add another way of providing screen arguments 2021-07-01 12:50:43 +03:00
5 changed files with 68 additions and 8 deletions
@@ -0,0 +1,9 @@
package ru.touchin.roboswag.mvi_arch.core
import android.os.Parcelable
/**
* Used for setting arguments and initial state into Fragments
*/
fun <NavArgs : Parcelable, State, Action, VM, TFragment : MviFragment<NavArgs, State, Action, VM>>
TFragment.withArgs(navArgs: NavArgs) = apply { initArgs(navArgs) }
@@ -45,8 +45,7 @@ import javax.inject.Inject
* @author Created by Max Bachinsky and Ivan Vlasov at Touch Instinct.
*/
abstract class MviFragment<NavArgs, State, Action, VM>(
@LayoutRes layout: Int,
navArgs: NavArgs = EmptyState as NavArgs
@LayoutRes layout: Int
) : BaseFragment<FragmentActivity>(layout)
where NavArgs : Parcelable,
State : ViewState,
@@ -69,9 +68,11 @@ abstract class MviFragment<NavArgs, State, Action, VM>(
lateinit var viewModelMap: MutableMap<Class<out ViewModel>, ViewModelAssistedFactory<out ViewModel>>
init {
arguments?.putParcelable(INIT_ARGS_KEY, navArgs) ?: let {
arguments = bundleOf(INIT_ARGS_KEY to navArgs)
}
arguments = bundleOf(INIT_ARGS_KEY to EmptyState)
}
fun initArgs(navArgs: NavArgs) {
arguments?.putParcelable(INIT_ARGS_KEY, navArgs)
}
@CallSuper
+1
View File
@@ -7,4 +7,5 @@ dependencies {
implementation(Library.CICERONE)
fragment()
dagger(withAssistedInject = false)
androidX()
}
@@ -0,0 +1,20 @@
package ru.touchin.roboswag.navigation_cicerone.flow
import me.vponomarenko.injectionmanager.customlifecycle.StoredComponent
import ru.touchin.mvi_arch.di.FeatureScope
import javax.inject.Inject
@FeatureScope
class ComponentHolder<TComponent> @Inject constructor(){
private var storedComponent: StoredComponent<TComponent>? = null
fun setStoredComponent(storedComponent: StoredComponent<TComponent>) {
this.storedComponent = storedComponent
}
fun destroy() {
storedComponent?.lifecycle?.destroy()
}
}
@@ -3,14 +3,18 @@ package ru.touchin.roboswag.navigation_cicerone.flow
import android.os.Bundle
import android.view.View
import androidx.fragment.app.Fragment
import me.vponomarenko.injectionmanager.customlifecycle.StoredComponent
import ru.terrakok.cicerone.NavigatorHolder
import ru.terrakok.cicerone.Router
import ru.terrakok.cicerone.android.support.SupportAppScreen
import ru.touchin.mvi_arch.core_nav.R
import ru.touchin.mvi_arch.di.FeatureScope
import ru.touchin.roboswag.navigation_base.activities.BaseActivity
import ru.touchin.roboswag.navigation_base.activities.OnBackPressedListener
import ru.touchin.roboswag.navigation_cicerone.CiceroneTuner
import javax.inject.Inject
abstract class FlowFragment : Fragment(R.layout.fragment_flow) {
abstract class FlowFragment<TComponent> : Fragment(R.layout.fragment_flow), OnBackPressedListener {
@Inject
@FlowNavigation
@@ -20,15 +24,35 @@ abstract class FlowFragment : Fragment(R.layout.fragment_flow) {
@FlowNavigation
lateinit var router: Router
@Inject
@FeatureScope
lateinit var componentHolder: ComponentHolder<TComponent>
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
injectComponent()
if (!injectExistedComponent()) {
val storedComponent = injectComponent()
componentHolder.setStoredComponent(storedComponent)
}
if (childFragmentManager.fragments.isEmpty()) {
router.newRootScreen(getLaunchScreen())
}
}
abstract fun injectComponent()
override fun onResume() {
super.onResume()
(activity as? BaseActivity)?.addOnBackPressedListener(this)
}
override fun onStop() {
super.onStop()
(activity as? BaseActivity)?.removeOnBackPressedListener(this)
}
abstract fun injectComponent(): StoredComponent<TComponent>
abstract fun injectExistedComponent(): Boolean
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
@@ -42,5 +66,10 @@ abstract class FlowFragment : Fragment(R.layout.fragment_flow) {
)
}
override fun onBackPressed(): Boolean {
componentHolder.destroy()
return false
}
abstract fun getLaunchScreen(): SupportAppScreen
}