Как получить ViewModel?
Я просто хочу получить ссылку в моем фрагменте (расширяет фрагмент) на мой ViewModel.class (расширяется от AndroidViewModel). Вот как это описано везде:
UserModel userModel = ViewModelProviders.of(getActivity()).get(UserModel.class);
..., но ViewModelProviders давно устарела.
* Этот класс устарел на уровне API 1.1.0. *
Я не могу импортировать класс с помощью: android.arch.lifecycle.[ViewModelProviders]
он просто предлагает ViewModelProvider и другие вещи.
Как я могу получить экземпляр моего UserModel.class?
6 ответов
но ViewModelProviders устарела давно
ViewModelProviders
не считается устаревшим Итак, используйте ViewModelProviders
:
ViewModelProviders.of(yourFragment).get(UserModel.class)
Есть кусочки ViewModelProviders
которые устарели, такие как его конструктор, но класс в целом - нет.
Используя Kotlin с новейшими компонентами архитектуры Android, вы должны использовать by viewModels()
Делегат свойства Kotlin следующим образом:
class YourFragment : Fragment() {
private val viewModel by viewModels<YourViewModel>()
}
Больше информации здесь
Вот как написать 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.
}
}
И затем, чтобы использовать это в своей деятельности, сделайте что-то вроде этого
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
});
}
}
Класс ViewModelProviders
устарела! ИспользоватьViewModelProvider
понял.
MyViewModel viewModel = new ViewModelProvider(this).get(MyViewModel.class);
Удачного кодирования:)
Покопавшись, я решил аналогичную проблему, добавив к своим действиям следующий метод:
protected final <T extends ViewModel> ViewModel obtainViewModel(@NonNull AppCompatActivity activity, @NonNull Class<T> modelClass) {
ViewModelProvider.AndroidViewModelFactory factory = ViewModelProvider.AndroidViewModelFactory.getInstance(activity.getApplication());
return new ViewModelProvider(activity, factory).get(modelClass);
}
А потом я сделал это в своих фрагментах:
protected final <T extends ViewModel> ViewModel obtainFragmentViewModel(@NonNull FragmentActivity fragment, @NonNull Class<T> modelClass) {
ViewModelProvider.AndroidViewModelFactory factory = ViewModelProvider.AndroidViewModelFactory.getInstance(fragment.getApplication());
return new ViewModelProvider(fragment, factory).get(modelClass);
}
У меня уже было несколько абстрактных суперклассов для целей меню, поэтому я спрятал там методы, чтобы не повторять их в каждом действии. Вот почему они защищены. Я считаю, что они могут быть личными, если вы поместите их в каждое действие или фрагмент, в котором они вам нужны.
Чтобы быть как можно более ясным, я бы затем вызвал методы для назначения моей модели представления в onCreate() в моей деятельности, и это выглядело бы примерно так
private MyViewModel myViewModel;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
myViewModel = (MyViewModel) obtainViewModel(this, MyViewModel.class);
}
или во фрагменте
private MyViewModel myViewModel;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
if (getActivity() != null) {
myViewModel = (MyViewModel) obtainFragmentViewModel(getActivity(), MyViewModel.class);
}
}
Вроде пока работает нормально. Если у кого-то есть способ лучше, дайте нам знать!
Котлин версия ответа BeirDav в это
val vm = ViewModelProvider(requireActivity()).get(MyViewModel::class.java)