Comments (4)
This is what I did:
abstract class BaseActivity : BaseMvRxActivity(), MvRxView {
override val mvrxViewModelStore by lazy { MvRxViewModelStore(viewModelStore) }
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
mvrxViewModelStore.restoreViewModels(this, savedInstanceState)
}
override fun onSaveInstanceState(outState: Bundle) {
super.onSaveInstanceState(outState)
mvrxViewModelStore.saveViewModels(outState)
}
override fun onStart() {
super.onStart()
// This ensures that invalidate() is called for static screens that don't
// subscribe to a ViewModel.
postInvalidate()
}
}
inline fun <T, reified VM : BaseMvRxViewModel<S>, reified S : MvRxState> T.activityViewModel(
viewModelClass: KClass<VM> = VM::class,
noinline keyFactory: () -> String = { viewModelClass.java.name }
) where T : AppCompatActivity, T : MvRxView = lifecycleAwareLazy(this) {
val stateFactory: () -> S = { _activityViewModelInitialStateProvider(keyFactory) }
if (this !is MvRxViewModelStoreOwner) throw IllegalArgumentException("Your Activity must be a MvRxViewModelStoreOwner!")
MvRxViewModelProvider.get(viewModelClass.java, this, keyFactory(), stateFactory)
.apply { subscribe(this@activityViewModel, subscriber = { postInvalidate() }) } //red line here
}
@Suppress("FunctionName")
inline fun <reified S : MvRxState, T : AppCompatActivity> T._activityViewModelInitialStateProvider(keyFactory: () -> String): S {
val args: Any? = intent.getBundleExtra(MvRx.KEY_ARG)
if (this is MvRxViewModelStoreOwner) {
this.mvrxViewModelStore._saveActivityViewModelArgs(keyFactory(), args)
} else {
throw IllegalArgumentException("Your Activity must be a MvRxViewModelStoreOwner!")
}
return _initialStateProvider(S::class.java, args)
}
from mavericks.
@aneophyte You can use the subscribe methods exposed in MvRxView
, so just delete this@activityViewModel
.
However -- we haven't been consistent on this -- but all the methods named starting with _
are also not meant to be publicly used.
I feel like a solution here is to change MvRxExtensions.viewModel
to apply a subscribe call if the receiver is a MvRxView
.
However, I would be hesitant to make this change without first understanding a bit more about what your refactoring to MvRx looks like. One of MvRx opinion's is that activities are just shells for fragments. It makes sense that this is different than may exist in applications which want to switch to MvRx. However I would imagine you will already need to refactor your activity to confirm to the invalidate
model, and am curious how much extra work it would be to pull it into a fragment?
from mavericks.
I haven't used any subscribe method outside the extension function. The subscribe
method in question came because it was part of the activityViewModel
method. This is the method, I believe, that is used to create view model under the activity scope. It leads me to another question that if that subscribe method were to be removed, would persistence and lifecycle related stuff work?
MvRxExtensions.viewModel
is definitely the better option, though the restriction is still there. I tried to make an extension function around it.
inline fun <T, reified VM : BaseMvRxViewModel<S>, reified S : MvRxState> T.activityViewModel(
viewModelClass: KClass<VM> = VM::class,
noinline keyFactory: () -> String = { viewModelClass.java.name }
) where T : BaseActivity, T : MvRxView = lifecycleAwareLazy(this) {
viewModel(viewModelClass, keyFactory).run{this.value}.apply {
subscribe(this@activityViewModel, subscriber = { postInvalidate() })
}
}
This is how I'm using activityViewModel
currently.
class SimpleActivity : BaseActivity() {
val viewModel by activityViewModel(ActivitySplashViewModel::class)
override fun invalidate() {
withState(viewModel) {
}
}
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_simple)
}
}
The problem with refactoring to Fragment
s, here in my case, is a lot has been written already and would require quite a lot of changing. And moving from Activity
based flow to Fragment
one, I suppose would require using the Navigation library from the AndroidX family. I'm a bit hesitant with that because it's currently in experimental state, also I did not have pleasant experience in using Fragment
s as a prominent thing in previous projects.
Having said all this, maybe applying your solution would allow Activity
s to be used as View
s, would make the library more open for developers choosing to use Activity
, but to be honest, I don't really want my requirements to affect the conventions that MvRx has opted for.
Thanks for the input! I apologize for responding late.
from mavericks.
@aneophyte I'm going to close this for now because we don't plan on adding support for Activities out of the box but you can also make your base activity implement MvRxView.
Fragments are also not tied in any way to jetpack navigation.
from mavericks.
Related Issues (20)
- # [Codecov](https://codecov.io/gh/airbnb/mavericks/pull/639?src=pr&el=h1&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=airbnb) Report
- How to go about unit testing onEach events in Viewmodel HOT 1
- setState fast multiple times, app will anr HOT 1
- The link on the Threading documentation page is broken.
- App is crashing when network call returns HTTP 400. Am I implementing this incorrectly? HOT 3
- How to inject SavedStateHandle with hilt?
- Getting state from multiple flows with combine is causing recomposition HOT 3
- How to create ViewModels in dynamic feature?
- Is there a way to get the MavericksViewModel to refresh when returning to a Fragment? HOT 4
- Dagger in a single activity compose app (no fragment)
- Build doesn't work on JDK 17: `Unrecognized VM option 'CMSClassUnloadingEnabled'`
- MavericksLauncherMockActivity crashes if there's no App.Theme or if fragments are Hilt fragments HOT 1
- Feature Request: avoid shipping MockableMavericksView with release builds
- Feature Request - Allow retainValue parameter of type S.() -> Async<T> in MavericksRepository HOT 1
- Calling `mavericksActivityViewModel` in fragment, not working properly HOT 1
- Type com.airbnb.mvrx.AndroidStrictModeExtensionsKt is defined multiple times HOT 1
- possible incompatibility with Kotlin coroutines 1.7.0 HOT 2
- Using androidx.lifecycle:lifecycle-runtime-ktx:2.6.1 problems HOT 13
- Fail State call twice and make error HOT 2
- how to use stateflow in MavericksViewModel HOT 2
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from mavericks.