Skip to content

Commit 210b92a

Browse files
authored
Use ActivityViewModelContext for activity scope (#676)
* Use ActivityViewModelContext for activity scope * Update MavericksComposeExtensions.kt * Add tests
1 parent 115c8c3 commit 210b92a

File tree

3 files changed

+121
-1
lines changed

3 files changed

+121
-1
lines changed

mvrx-compose/src/main/kotlin/com/airbnb/mvrx/compose/MavericksComposeExtensions.kt

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -66,7 +66,11 @@ inline fun <reified VM : MavericksViewModel<S>, reified S : MavericksState> mave
6666
val view = LocalView.current
6767

6868
val viewModelContext = remember(scope, activity, viewModelStoreOwner, savedStateRegistry) {
69-
val parentFragment = scope as? Fragment ?: findFragmentFromView(view)
69+
val parentFragment = when (scope) {
70+
is Fragment -> scope
71+
is ComponentActivity -> null
72+
else -> findFragmentFromView(view)
73+
}
7074

7175
if (parentFragment != null) {
7276
val args = argsFactory?.invoke() ?: parentFragment.arguments?.get(Mavericks.KEY_ARG)

mvrx-compose/src/test/AndroidManifest.xml

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,13 @@
88
tools:ignore="GoogleAppIndexingWarning"
99
android:theme="@style/Theme.AppCompat.NoActionBar"
1010
android:allowBackup="false">
11+
<activity android:name="com.airbnb.mvrx.compose.LifecycleOwnerScopeTestActivity" android:exported="false" >
12+
<intent-filter>
13+
<action android:name="android.intent.action.MAIN" />
14+
15+
<category android:name="android.intent.category.LAUNCHER" />
16+
</intent-filter>
17+
</activity>
1118
<activity android:name="com.airbnb.mvrx.compose.FragmentArgsTestActivity" android:exported="false" >
1219
<intent-filter>
1320
<action android:name="android.intent.action.MAIN" />
Lines changed: 109 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,109 @@
1+
package com.airbnb.mvrx.compose
2+
3+
import android.os.Bundle
4+
import android.view.LayoutInflater
5+
import android.view.View
6+
import android.view.ViewGroup
7+
import android.widget.LinearLayout
8+
import androidx.appcompat.app.AppCompatActivity
9+
import androidx.compose.ui.platform.ComposeView
10+
import androidx.compose.ui.test.junit4.createAndroidComposeRule
11+
import androidx.fragment.app.Fragment
12+
import androidx.fragment.app.FragmentContainerView
13+
import com.airbnb.mvrx.Mavericks
14+
import org.junit.Assert.assertNotNull
15+
import org.junit.Before
16+
import org.junit.Rule
17+
import org.junit.Test
18+
import org.junit.runner.RunWith
19+
import org.robolectric.RobolectricTestRunner
20+
21+
@RunWith(RobolectricTestRunner::class)
22+
class LifecycleOwnerScopeTest {
23+
@get:Rule
24+
val composeTestRule = createAndroidComposeRule<LifecycleOwnerScopeTestActivity>()
25+
26+
@Before
27+
fun setUp() {
28+
Mavericks.initialize(composeTestRule.activity)
29+
}
30+
31+
@Test
32+
fun `activity_viewModel and activity_activityScopedViewModel are the same`() {
33+
assertNotNull(composeTestRule.activity.viewModel)
34+
assertNotNull(composeTestRule.activity.activityScopedViewModel)
35+
assert(composeTestRule.activity.viewModel === composeTestRule.activity.activityScopedViewModel)
36+
}
37+
38+
@Test
39+
fun `fragment_viewModel and fragment_activityScopedViewModel are different`() {
40+
assertNotNull(composeTestRule.activity.fragment.viewModel)
41+
assertNotNull(composeTestRule.activity.fragment.activityScopedViewModel)
42+
assert(composeTestRule.activity.fragment.viewModel !== composeTestRule.activity.fragment.activityScopedViewModel)
43+
}
44+
45+
@Test
46+
fun `activity_viewModel and fragment_activityScopedViewModel are the same`() {
47+
assertNotNull(composeTestRule.activity.viewModel)
48+
assertNotNull(composeTestRule.activity.fragment.activityScopedViewModel)
49+
assert(composeTestRule.activity.viewModel === composeTestRule.activity.fragment.activityScopedViewModel)
50+
}
51+
52+
@Test
53+
fun `fragment_viewModel and activity_activityScopedViewModel are different`() {
54+
assertNotNull(composeTestRule.activity.fragment.viewModel)
55+
assertNotNull(composeTestRule.activity.activityScopedViewModel)
56+
assert(composeTestRule.activity.fragment.viewModel !== composeTestRule.activity.activityScopedViewModel)
57+
}
58+
}
59+
60+
class LifecycleOwnerScopeTestActivity : AppCompatActivity() {
61+
lateinit var fragment: LifecycleOwnerScopeTestFragment
62+
lateinit var viewModel: CounterViewModel
63+
lateinit var activityScopedViewModel: CounterViewModel
64+
65+
override fun onCreate(savedInstanceState: Bundle?) {
66+
super.onCreate(savedInstanceState)
67+
68+
val fragmentId = 123
69+
val fragmentContainerView = FragmentContainerView(this).apply {
70+
id = fragmentId
71+
}
72+
val composeView = ComposeView(this).apply {
73+
setContent {
74+
this@LifecycleOwnerScopeTestActivity.viewModel = mavericksViewModel<CounterViewModel, CounterState>()
75+
this@LifecycleOwnerScopeTestActivity.activityScopedViewModel = mavericksActivityViewModel<CounterViewModel, CounterState>()
76+
}
77+
}
78+
79+
setContentView(
80+
LinearLayout(this).apply {
81+
addView(fragmentContainerView)
82+
addView(composeView)
83+
}
84+
)
85+
86+
fragment = LifecycleOwnerScopeTestFragment()
87+
88+
supportFragmentManager.beginTransaction()
89+
.add(
90+
fragmentId,
91+
fragment
92+
)
93+
.commit()
94+
}
95+
}
96+
97+
class LifecycleOwnerScopeTestFragment : Fragment() {
98+
lateinit var viewModel: CounterViewModel
99+
lateinit var activityScopedViewModel: CounterViewModel
100+
101+
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View {
102+
return ComposeView(requireContext()).apply {
103+
setContent {
104+
this@LifecycleOwnerScopeTestFragment.viewModel = mavericksViewModel<CounterViewModel, CounterState>()
105+
this@LifecycleOwnerScopeTestFragment.activityScopedViewModel = mavericksActivityViewModel<CounterViewModel, CounterState>()
106+
}
107+
}
108+
}
109+
}

0 commit comments

Comments
 (0)