Reputation: 474
I just want to get a reference in my Fragment (extends Fragment) to my ViewModel.class (extends from AndroidViewModel). This is how it is described everywhere:
UserModel userModel = ViewModelProviders.of(getActivity()).get(UserModel.class);
description on Android Developer
..., but ViewModelProviders is deprecated since long ago.
*This class was deprecated in API level 1.1.0. *
I can't import the class with: android.arch.lifecycle.[ViewModelProviders]
it just offers ViewModelProvider and other stuff.
How am I able to get an instance of my UserModel.class?
Upvotes: 3
Views: 9211
Reputation: 680
After digging around I solved my similiar problem by adding the following method to my Activities:
protected final <T extends ViewModel> T obtainViewModel(@NonNull AppCompatActivity activity, @NonNull Class<T> modelClass) {
ViewModelProvider.AndroidViewModelFactory factory = ViewModelProvider.AndroidViewModelFactory.getInstance(activity.getApplication());
return new ViewModelProvider(activity, factory).get(modelClass);
}
And then I did this in my Fragments:
protected final <T extends ViewModel> T obtainFragmentViewModel(@NonNull FragmentActivity fragment, @NonNull Class<T> modelClass) {
ViewModelProvider.AndroidViewModelFactory factory = ViewModelProvider.AndroidViewModelFactory.getInstance(fragment.getApplication());
return new ViewModelProvider(fragment, factory).get(modelClass);
}
I already had some abstract super classes for menu purposes so I hid the methods away there so I don't have to repeat it in every activity. That's why they are protected. I believe they could be private if you put them in every activity or fragment that you need them in.
To be as clear as possible I would then call the methods to assign my view model in onCreate() in my activity and it would look something like this
private MyViewModel myViewModel;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
myViewModel = obtainViewModel(this, MyViewModel.class);
}
or in fragment
private MyViewModel myViewModel;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
if (getActivity() != null) {
myViewModel = obtainFragmentViewModel(getActivity(), MyViewModel.class);
}
}
Upvotes: 0
Reputation: 11726
Kotlin version of BeirDav's answer is
val vm = ViewModelProvider(requireActivity()).get(MyViewModel::class.java)
Upvotes: 0
Reputation: 1007584
but ViewModelProviders is deprecated since long ago
ViewModelProviders
is not deprecated. So, use ViewModelProviders
:
ViewModelProviders.of(yourFragment).get(UserModel.class)
There are pieces of ViewModelProviders
that are deprecated, such as its constructor, but the class overall is not.
UPDATE: 2020-05-28 Now ViewModelProviders
is deprecated. In Kotlin, use by viewModels()
and related property delegates. In Java, use new ViewModelProvider(...).get(UserModel.class)
(for various values of ...
depending on the scope of those viewmodels).
Upvotes: 2
Reputation: 1424
The class ViewModelProviders
is deprecated!
Use ViewModelProvider
understood.
MyViewModel viewModel = new ViewModelProvider(this).get(MyViewModel.class);
Happy coding :)
Upvotes: 0
Reputation: 166
Using Kotlin with the latest Android architecture components you should use the by viewModels()
Kotlin property delegate like so:
class YourFragment : Fragment() {
private val viewModel by viewModels<YourViewModel>()
}
More info here
Upvotes: 3
Reputation: 468
Here's how to write a ViewModel
public class MyViewModel extends ViewModel {
private MutableLiveData<List<User>> users;
public LiveData<List<User>> getUsers() {
if (users == null) {
users = new MutableLiveData<List<User>>();
loadUsers();
}
return users;
}
private void loadUsers() {
// Do an asynchronous operation to fetch users.
}
}
And then to use it in your actctivity do something like this
public class MyActivity extends AppCompatActivity {
public void onCreate(Bundle savedInstanceState) {
// Create a ViewModel the first time the system calls an activity's onCreate() method.
// Re-created activities receive the same MyViewModel instance created by the first activity.
MyViewModel model = ViewModelProviders.of(this).get(MyViewModel.class);
model.getUsers().observe(this, users -> {
// update UI
});
}
}
Upvotes: 1