Android 如何根据屏幕旋转连接视图和视图模型?
ViewModel的一个承诺是,它可以在屏幕旋转等情况下生存。我仍在努力想办法在实践中组织起来 在模型的某些事件上,视图应该更新。有两个主要的选择:Android 如何根据屏幕旋转连接视图和视图模型?,android,android-viewmodel,Android,Android Viewmodel,ViewModel的一个承诺是,它可以在屏幕旋转等情况下生存。我仍在努力想办法在实践中组织起来 在模型的某些事件上,视图应该更新。有两个主要的选择: ViewModel将更新视图 视图观察ViewModel并更新自身 在第一种情况下,ViewModel需要指向视图的链接。我可以将视图注入ViewModel,但我的感觉是将VieModel注入视图会更好 加入他们最好的方式是什么 然后在旋转之后,再次调用onCreate()方法,再次触发ViewModel的初始化。我需要检查这一点,否则我将面临两次
什么样的好模式可以以干净的标准方式处理此问题?Soo。。你真的不必连接ViewModel和“关于屏幕旋转”的活动/片段,你可以免费获得它——这是一个额外的好处 这个官员真的很好 您可以在
onCreate()
中通过以下方式将ViewModel连接到视图
public class MyActivity extends AppCompatActivity {
public void onCreate(Bundle savedInstanceState) {
MyViewModel model = ViewModelProviders.of(this).get(MyViewModel.class);
model.getUsers().observe(this, users -> {
updateUI()
});
}
}
虽然正如您所说,方向更改将再次触发onCreate()
,但这不会创建新的ViewModel。MyViewModel
仅在onCreate
中第一次创建。重新创建的活动接收由第一个活动创建的相同的MyViewModel
实例。这甚至适用于引用同一ViewModel的不同片段/活动
永远不要将视图注入ViewModel。这相当于溺水的小狗。如果需要ViewModel中的上下文,请扩展AndroidViewModel
(并将其传递给应用程序
)
您要做的是创建一个保存所有状态的ViewModel。并处理从网络或磁盘或其他地方获取数据。所有与UI无关的内容都会进入ViewModel(根据经验)。所有视图更新内容都进入活动/片段
上面示例中的ViewModel可能如下所示
public class MyViewModel extends ViewModel {
private MutableLiveData<List<User>> users;
public LiveData<List<User>> getUsers() {
if (users == null) {
users = new MutableLiveData<List<Users>>();
loadUsers();
}
return users;
}
private void loadUsers() {
// Do an asynchronous operation to fetch users.
}
}
公共类MyViewModel扩展了ViewModel{
私有可变LiveData用户;
公共LiveData getUsers(){
如果(用户==null){
用户=新的可变LiveData();
loadUsers();
}
返回用户;
}
私有void loadUsers(){
//执行异步操作以获取用户。
}
}
这通常意味着可能应该将单击事件传递到ViewModel中,以便它能够对数据进行处理。视图只会对更新的(经过处理的)数据做出反应 Soo。。你真的不必连接ViewModel和“关于屏幕旋转”的活动/片段,你可以免费获得它——这是一个额外的好处 这个官员真的很好 您可以在
onCreate()
中通过以下方式将ViewModel连接到视图
public class MyActivity extends AppCompatActivity {
public void onCreate(Bundle savedInstanceState) {
MyViewModel model = ViewModelProviders.of(this).get(MyViewModel.class);
model.getUsers().observe(this, users -> {
updateUI()
});
}
}
虽然正如您所说,方向更改将再次触发onCreate()
,但这不会创建新的ViewModel。MyViewModel
仅在onCreate
中第一次创建。重新创建的活动接收由第一个活动创建的相同的MyViewModel
实例。这甚至适用于引用同一ViewModel的不同片段/活动
永远不要将视图注入ViewModel。这相当于溺水的小狗。如果需要ViewModel中的上下文,请扩展AndroidViewModel
(并将其传递给应用程序
)
您要做的是创建一个保存所有状态的ViewModel。并处理从网络或磁盘或其他地方获取数据。所有与UI无关的内容都会进入ViewModel(根据经验)。所有视图更新内容都进入活动/片段
上面示例中的ViewModel可能如下所示
public class MyViewModel extends ViewModel {
private MutableLiveData<List<User>> users;
public LiveData<List<User>> getUsers() {
if (users == null) {
users = new MutableLiveData<List<Users>>();
loadUsers();
}
return users;
}
private void loadUsers() {
// Do an asynchronous operation to fetch users.
}
}
公共类MyViewModel扩展了ViewModel{
私有可变LiveData用户;
公共LiveData getUsers(){
如果(用户==null){
用户=新的可变LiveData();
loadUsers();
}
返回用户;
}
私有void loadUsers(){
//执行异步操作以获取用户。
}
}
这通常意味着可能应该将单击事件传递到ViewModel中,以便它能够对数据进行处理。视图只会对更新的(经过处理的)数据做出反应 你好!!它不是第二次创建的。观察员被第二次注册。根据
getUsers().observe()
的实现,回调updateUI()
可能在第一次旋转后调用两次,在第二次旋转后调用三次。然后调用.getUsers()
将模型的逻辑绘制到视图中。这是第二个原因,为什么我认为这是官方文件中一个相当糟糕的例子。在我看来,他们教坏习惯。现在,我们需要找出最佳实践,至少是更好的实践。哦,如果我误解了,对不起。但我看不出有什么问题。如果您旋转屏幕,您的活动将通过其onDestroy
。因此,您当然希望再次注册观察者,以便获得数据以再次更新UI—因为没有更多的UI。或者您是说您正在连续获得3次更新?我不明白您使用的意思。getUsers()
将模型的逻辑绘制到视图中。观察者只应画入(观察)待观察模型的一部分