Skip to content

Commit 187ef62

Browse files
author
Arkadiusz Pałka
committed
refactor: split implementation of mvi fragment with save instance state
to separate the minimal mvi implementation to extended implementation which handles that state can be restored after killing process by system.
1 parent b4f07c2 commit 187ef62

File tree

9 files changed

+92
-45
lines changed

9 files changed

+92
-45
lines changed

app/build.gradle

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -82,4 +82,5 @@ dependencies {
8282
implementation deps.androidx.material
8383
implementation deps.androidx.multidex
8484
implementation deps.androidx.annotation
85+
implementation "androidx.lifecycle:lifecycle-common:2.2.0"
8586
}

app/src/main/java/pl/valueadd/mvi/example/presentation/base/AbstractBackMviFragment.kt

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,13 +4,26 @@ import android.os.Bundle
44
import androidx.annotation.LayoutRes
55
import pl.valueadd.mvi.example.utility.dependencyinjection.DependencyUtil
66
import pl.valueadd.mvi.fragment.back.BackMviFragment
7+
import pl.valueadd.mvi.fragment.delegate.fragment.MviFragmentSaveInstanceStateDelegateImpl
78
import pl.valueadd.mvi.fragment.mvi.BaseMviPresenter
89
import pl.valueadd.mvi.fragment.mvi.IBaseView
910
import pl.valueadd.mvi.fragment.mvi.IBaseViewState
1011

1112
abstract class AbstractBackMviFragment<V : IBaseView<VS, *>, VS : IBaseViewState, VI : IBaseView.IBaseIntent, P : BaseMviPresenter<VS, *, *, V>>(@LayoutRes layoutId: Int) :
1213
BackMviFragment<V, VS, VI, P>(layoutId) {
1314

15+
protected val restoredViewState: VS?
16+
get() = mviDelegate.restoredViewState
17+
18+
@Suppress("UNCHECKED_CAST")
19+
override val mviDelegate: MviFragmentSaveInstanceStateDelegateImpl<V, VS>
20+
by lazy {
21+
MviFragmentSaveInstanceStateDelegateImpl(
22+
this as V,
23+
presenter
24+
)
25+
}
26+
1427
override fun onCreate(savedInstanceState: Bundle?) {
1528
DependencyUtil.inject(requireActivity(), this)
1629
super.onCreate(savedInstanceState)

app/src/main/java/pl/valueadd/mvi/example/presentation/base/AbstractBaseMviFragment.kt

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,13 +4,26 @@ import android.os.Bundle
44
import androidx.annotation.LayoutRes
55
import pl.valueadd.mvi.example.utility.dependencyinjection.DependencyUtil
66
import pl.valueadd.mvi.fragment.base.BaseMviFragment
7+
import pl.valueadd.mvi.fragment.delegate.fragment.MviFragmentSaveInstanceStateDelegateImpl
78
import pl.valueadd.mvi.fragment.mvi.BaseMviPresenter
89
import pl.valueadd.mvi.fragment.mvi.IBaseView
910
import pl.valueadd.mvi.fragment.mvi.IBaseViewState
1011

1112
abstract class AbstractBaseMviFragment<V : IBaseView<VS, *>, VS : IBaseViewState, VI : IBaseView.IBaseIntent, P : BaseMviPresenter<VS, *, *, V>>(@LayoutRes layoutId: Int) :
1213
BaseMviFragment<V, VS, VI, P>(layoutId) {
1314

15+
protected val restoredViewState: VS?
16+
get() = mviDelegate.restoredViewState
17+
18+
@Suppress("UNCHECKED_CAST")
19+
override val mviDelegate: MviFragmentSaveInstanceStateDelegateImpl<V, VS>
20+
by lazy {
21+
MviFragmentSaveInstanceStateDelegateImpl(
22+
this as V,
23+
presenter
24+
)
25+
}
26+
1427
override fun onCreate(savedInstanceState: Bundle?) {
1528
DependencyUtil.inject(requireActivity(), this)
1629
super.onCreate(savedInstanceState)

app/src/main/java/pl/valueadd/mvi/example/presentation/main/first/FirstFragment.kt

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -24,8 +24,6 @@ class FirstFragment :
2424
@Inject
2525
override lateinit var presenter: FirstPresenter
2626

27-
override val shouldSaveViewStateInSavedInstanceState = true
28-
2927
private val buttonDelay
3028
by lazy { resources.getInteger(R.integer.button_delay_100).toLong() }
3129

mvi-valueadd/src/main/java/pl/valueadd/mvi/fragment/base/BaseMviFragment.kt

Lines changed: 3 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -26,22 +26,9 @@ abstract class BaseMviFragment<V : IBaseView<VS, *>, VS : IBaseViewState, VI : I
2626
protected var disposables: CompositeDisposable =
2727
CompositeDisposable()
2828

29-
/*
30-
* View state which can be restored after killing process by system.
31-
*/
32-
protected val restoredViewState: VS?
33-
get() = mviDelegate.restoredViewState
34-
35-
protected open val shouldSaveViewStateInSavedInstanceState = false
36-
37-
private val mviDelegate: MviFragmentDelegate<VS>
38-
by lazy {
39-
@Suppress("UNCHECKED_CAST")
40-
MviFragmentDelegateImpl(
41-
shouldSaveViewStateInSavedInstanceState,
42-
this as V,
43-
presenter)
44-
}
29+
@Suppress("UNCHECKED_CAST")
30+
protected open val mviDelegate: MviFragmentDelegate
31+
by lazy { MviFragmentDelegateImpl(this as V, presenter) }
4532

4633
/* IBaseView */
4734

Lines changed: 3 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,19 +1,16 @@
11
package pl.valueadd.mvi.fragment.delegate.fragment
22

33
import android.os.Bundle
4-
import pl.valueadd.mvi.fragment.mvi.IBaseViewState
54

6-
interface MviFragmentDelegate<VS : IBaseViewState> {
7-
8-
val restoredViewState: VS?
5+
interface MviFragmentDelegate {
96

107
fun onCreate(savedInstanceState: Bundle?)
118

9+
fun onSaveInstanceState(outState: Bundle)
10+
1211
fun onStart()
1312

1413
fun onStop()
1514

1615
fun onDestroy()
17-
18-
fun onSaveInstanceState(outState: Bundle)
1916
}

mvi-valueadd/src/main/java/pl/valueadd/mvi/fragment/delegate/fragment/MviFragmentDelegateImpl.kt

Lines changed: 13 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -3,25 +3,23 @@ package pl.valueadd.mvi.fragment.delegate.fragment
33
import android.os.Bundle
44
import pl.valueadd.mvi.fragment.mvi.BaseMviPresenter
55
import pl.valueadd.mvi.fragment.mvi.IBaseView
6-
import pl.valueadd.mvi.fragment.mvi.IBaseViewState
76

8-
class MviFragmentDelegateImpl<V : IBaseView<VS, *>, VS : IBaseViewState>(
9-
private val shouldHandleSaveInstanceState: Boolean,
10-
private val fragment: V,
11-
private val presenter: BaseMviPresenter<VS, *, *, V>
12-
) : MviFragmentDelegate<VS> {
7+
/**
8+
* Minimal implementation of contract between fragment and presenter.
9+
*
10+
* This API requires call every fragment's lifecycle callback event defined at [MviFragmentDelegate].
11+
*/
12+
open class MviFragmentDelegateImpl<V : IBaseView<*, *>>(
13+
protected val fragment: V,
14+
protected val presenter: BaseMviPresenter<*, *, *, V>
15+
) : MviFragmentDelegate {
1316

14-
companion object {
15-
private const val VIEW_STATE_BUNDLE_KEY = "VIEW_STATE_BUNDLE_KEY"
17+
override fun onCreate(savedInstanceState: Bundle?) {
18+
// no-op
1619
}
1720

18-
override var restoredViewState: VS? = null
19-
private set
20-
21-
override fun onCreate(savedInstanceState: Bundle?) {
22-
if (shouldHandleSaveInstanceState) {
23-
this.restoredViewState = savedInstanceState?.getParcelable(VIEW_STATE_BUNDLE_KEY)
24-
}
21+
override fun onSaveInstanceState(outState: Bundle) {
22+
// no-op
2523
}
2624

2725
override fun onStart() {
@@ -32,12 +30,6 @@ class MviFragmentDelegateImpl<V : IBaseView<VS, *>, VS : IBaseViewState>(
3230
presenter.detachView()
3331
}
3432

35-
override fun onSaveInstanceState(outState: Bundle) {
36-
if (shouldHandleSaveInstanceState) {
37-
outState.putParcelable(VIEW_STATE_BUNDLE_KEY, presenter.currentState)
38-
}
39-
}
40-
4133
override fun onDestroy() {
4234
presenter.destroy()
4335
}
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
package pl.valueadd.mvi.fragment.delegate.fragment
2+
3+
import pl.valueadd.mvi.fragment.mvi.IBaseViewState
4+
5+
interface MviFragmentSaveInstanceStateDelegate<VS : IBaseViewState> {
6+
7+
val restoredViewState: VS?
8+
}
Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
package pl.valueadd.mvi.fragment.delegate.fragment
2+
3+
import android.os.Bundle
4+
import pl.valueadd.mvi.fragment.mvi.BaseMviPresenter
5+
import pl.valueadd.mvi.fragment.mvi.IBaseView
6+
import pl.valueadd.mvi.fragment.mvi.IBaseViewState
7+
8+
/**
9+
* Extended [implementation][MviFragmentDelegateImpl] of fragment's MVI which handles
10+
* that state can be restored after killing process by system.
11+
*
12+
* @see MviFragmentDelegateImpl
13+
*/
14+
class MviFragmentSaveInstanceStateDelegateImpl<V : IBaseView<VS, *>, VS : IBaseViewState>(
15+
fragment: V,
16+
presenter: BaseMviPresenter<VS, *, *, V>
17+
) : MviFragmentDelegateImpl<V>(fragment, presenter),
18+
MviFragmentSaveInstanceStateDelegate<VS> {
19+
20+
companion object {
21+
private const val VIEW_STATE_BUNDLE_KEY = "VIEW_STATE_BUNDLE_KEY"
22+
}
23+
24+
override var restoredViewState: VS? = null
25+
private set
26+
27+
override fun onCreate(savedInstanceState: Bundle?) {
28+
this.restoredViewState =
29+
savedInstanceState?.getParcelable(VIEW_STATE_BUNDLE_KEY)
30+
}
31+
32+
override fun onSaveInstanceState(outState: Bundle) {
33+
outState.putParcelable(
34+
VIEW_STATE_BUNDLE_KEY,
35+
presenter.currentState
36+
)
37+
}
38+
}

0 commit comments

Comments
 (0)