studio room livedata example dependency data combine arch android mvvm viewmodel

room - Android ViewModel argumentos adicionales



view model android studio (3)

Debe tener una clase de fábrica para su ViewModel.

public class MyViewModelFactory implements ViewModelProvider.Factory { private Application mApplication; private String mParam; public MyViewModelFactory(Application application, String param) { mApplication = application; mParam = param; } @Override public <T extends ViewModel> T create(Class<T> modelClass) { return (T) new MyViewModel(mApplication, mParam); } }

Y al crear una instancia del modelo de vista, te gusta esto:

MyViewModel myViewModel = ViewModelProviders.of(this, new MyViewModelFactory(this.getApplication(), "my awesome param")).get(MyViewModel.class);

¿Hay alguna forma de pasar argumentos adicionales a mi constructor de AndroidViewModel personalizado, excepto el contexto de la aplicación? Ejemplo:

public class MyViewModel extends AndroidViewModel { private final LiveData<List<MyObject>> myObjectList; private AppDatabase appDatabase; public MyViewModel(Application application, String param) { super(application); appDatabase = AppDatabase.getDatabase(this.getApplication()); myObjectList = appDatabase.myOjectModel().getMyObjectByParam(param); } }

Y cuando quiero usar mi clase de ViewModel personalizada, uso este código en mi fragmento:

MyViewModel myViewModel = ViewModelProvider.of(this).get(MyViewModel.class)

Así que no sé cómo pasar un ViewModel String param argumento adicional a mi ViewModel personalizado. Solo puedo pasar el contexto de la aplicación, pero no argumentos adicionales. Realmente apreciaria cualquier ayuda. Gracias.

Edición: he añadido algún código. Espero que sea mejor ahora.


Escribí una biblioteca que debería hacer esto más sencillo y más limpio, sin necesidad de multibuntos o repeticiones de fábrica, mientras trabajo sin problemas con los argumentos de ViewModel que Dagger puede proporcionar como dependencias: https://github.com/radutopor/ViewModelFactory

@ViewModelFactory class UserViewModel(@Provided repository: Repository, userId: Int) : ViewModel() { val greeting = MutableLiveData<String>() init { val user = repository.getUser(userId) greeting.value = "Hello, $user.name" } }

En la vista:

class UserActivity : AppCompatActivity() { @Inject lateinit var userViewModelFactory2: UserViewModelFactory2 override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) setContentView(R.layout.activity_user) appComponent.inject(this) val userId = intent.getIntExtra("USER_ID", -1) val viewModel = ViewModelProviders.of(this, userViewModelFactory2.create(userId)) .get(UserViewModel::class.java) viewModel.greeting.observe(this, Observer { greetingText -> greetingTextView.text = greetingText }) } }


Para una fábrica compartida entre varios modelos de vista diferentes, extendería la respuesta de mlyko de esta manera:

public class MyViewModelFactory extends ViewModelProvider.NewInstanceFactory { private Application mApplication; private Object[] mParams; public MyViewModelFactory(Application application, Object... params) { mApplication = application; mParams = params; } @Override public <T extends ViewModel> T create(Class<T> modelClass) { if (modelClass == ViewModel1.class) { return (T) new ViewModel1(mApplication, (String) mParams[0]); } else if (modelClass == ViewModel2.class) { return (T) new ViewModel2(mApplication, (Integer) mParams[0]); } else if (modelClass == ViewModel3.class) { return (T) new ViewModel3(mApplication, (Integer) mParams[0], (String) mParams[1]); } else { return super.create(modelClass); } } }

Y instanciando modelos de vista:

ViewModel1 vm1 = ViewModelProviders.of(this, new MyViewModelFactory(getApplication(), "something")).get(ViewModel1.class); ViewModel2 vm2 = ViewModelProviders.of(this, new MyViewModelFactory(getApplication(), 123)).get(ViewModel2.class); ViewModel3 vm3 = ViewModelProviders.of(this, new MyViewModelFactory(getApplication(), 123, "something")).get(ViewModel3.class);

Con diferentes modelos de vista teniendo diferentes constructores.