在 ViewModel 和 Fragment/Activity 交互和通信之间应用 MVVM
Applying MVVM between ViewModel and Fragment/Activity interactions and communication
我投入了大量时间来正确理解架构组件以及一切如何适应 MVVM 模式。到目前为止,这是我的看法(没有进行 Dagger 注入,因为我还没有做到这一点):
a) UserEntity
是一个带有 @Entity
注释的 class 来处理 Room
的 table 创建
@Entity(tableName="users")
public class Users{
private long id;
private String name;
}
b) User
模型中的 pojo class 以在应用程序周围使用它,并根据需要提供补充字段。
public class User{
private long id;
private String name;
private List<Role> roles;
private Preferences preferences;
}
除此之外,根据我对数据库的需求,可以有不同的 pojos,例如,UserWithRoles
c) UserDao
负责获取或 inserting/updating 房间数据库中的信息。在这里,对于 @Insert
、@Update
我可以使用 UserEntity
但是对于 @Query
我也可以使用 pojo classes
@Dao
public abstract class UserDao{
@Insert
public abstract long insertUser(User user)
@Query("Select someFields from inner joined tables")
public abstract LiveData<List<UserRoles> getUsersWithRoles();
}
d) 将 RepositoryUser
作为 ViewModel 和 Dao 之间的存储库
public class RepositoryUser{
private UserDao userDao;
public RepositoryUser(Application app){
Database db = Databaase.getDatabase(app.getApplicationContext);
userDao = db.userDao();
}
public LiveData<List<UserWithRoles>> getUsersWithRoles(){
return userDao.getUsersWithRoles()
}
}
e) UserWithRolesViewModel
可用于显示包含用户及其角色的列表的片段
public class UserWithRolesViewModel extends AndroidViewModel{
private RepositoryUser repositoryUser;
public UserWithRolesViewModel(Application app){
super(app);
repositoryUser = new RepositoryUser(app);
}
public LiveData<List<UserWithRoles>> getUsersWithRoles(){
return repositoryUser.getUsersWithRoles()
}
}
f) 在我的片段中我可以做类似的事情:
public void onCreate(...){
viewModel = ViewModelProviders.of(this).get(UserWithRolesViewModel.class);
}
public View onCreateView(...){
viewModel.getUsersWithRoles().observe(...)
public void onChanged(...){
adapter.setData(...);
}
}
但是,有些部分缺失了。根据我对 MVVM 的理解,视图应该只负责显示信息,因此在片段或 activity 内部没有实际的逻辑甚至处理。此时我有2个问题:
- 按照常规方式,我会创建一个接口,例如
onFragmentAction
并在 activity
中实现它。然后在 fragment
上,当我想通知 activity 做某事时,我会做 callback.onFragmentAction(params)
并且 activity 中的 onFragmentAction
会触发并采取相应行动。这种情况在 MVVM 中是如何处理的?片段如何与其父片段对话 activity?
- 按照常规方式,我会在片段的
onCreateView
内填充布局,使用 findViewById
获取视图并使用,例如 textView.setText() 或 button.setOnClickListener()。这如何在 MVVM 中完成?使用数据绑定?
On the regular way, I would create an interface, for instance
onFragmentAction and implement it in activity. Then on fragment when I
wanted to inform the activity to do something, I would do
callback.onFragmentAction(params) and the onFragmentAction in the
activity would fire and act accordingly. How is this scenario handled
in MVVM? How does a fragment talk to it's parent activity?
为了互动,您可以创建 Fragment
和 Activity
共享的 ViewModel
。在那种情况下,你有一个抽象,你将一些数据推送到 ViewModel
LiveData
中,它会得到一个监听相同 ViewModel
的事件。
例如this method is recommended用于Fragment
到Fragment
的通信,但我认为它也适合Fragment
到Activity
。
On the regular way I would have inside the fragment's onCreateView,
inflate the layout, use findViewById to get the views and use, for
instance textView.setText() or button.setOnClickListener(). How can
this be done in MVVM? Use DataBinding?
您可以使用 DataBinding 或 Kotlin Android Extension,两者都应该适用于 MVVM。
通过 DataBinding 应该更好,因为它会减少样板文件。
但我个人觉得 Kotlin Android Extensions 也很干净。
我投入了大量时间来正确理解架构组件以及一切如何适应 MVVM 模式。到目前为止,这是我的看法(没有进行 Dagger 注入,因为我还没有做到这一点):
a) UserEntity
是一个带有 @Entity
注释的 class 来处理 Room
的 table 创建
@Entity(tableName="users")
public class Users{
private long id;
private String name;
}
b) User
模型中的 pojo class 以在应用程序周围使用它,并根据需要提供补充字段。
public class User{
private long id;
private String name;
private List<Role> roles;
private Preferences preferences;
}
除此之外,根据我对数据库的需求,可以有不同的 pojos,例如,UserWithRoles
c) UserDao
负责获取或 inserting/updating 房间数据库中的信息。在这里,对于 @Insert
、@Update
我可以使用 UserEntity
但是对于 @Query
我也可以使用 pojo classes
@Dao
public abstract class UserDao{
@Insert
public abstract long insertUser(User user)
@Query("Select someFields from inner joined tables")
public abstract LiveData<List<UserRoles> getUsersWithRoles();
}
d) 将 RepositoryUser
作为 ViewModel 和 Dao 之间的存储库
public class RepositoryUser{
private UserDao userDao;
public RepositoryUser(Application app){
Database db = Databaase.getDatabase(app.getApplicationContext);
userDao = db.userDao();
}
public LiveData<List<UserWithRoles>> getUsersWithRoles(){
return userDao.getUsersWithRoles()
}
}
e) UserWithRolesViewModel
可用于显示包含用户及其角色的列表的片段
public class UserWithRolesViewModel extends AndroidViewModel{
private RepositoryUser repositoryUser;
public UserWithRolesViewModel(Application app){
super(app);
repositoryUser = new RepositoryUser(app);
}
public LiveData<List<UserWithRoles>> getUsersWithRoles(){
return repositoryUser.getUsersWithRoles()
}
}
f) 在我的片段中我可以做类似的事情:
public void onCreate(...){
viewModel = ViewModelProviders.of(this).get(UserWithRolesViewModel.class);
}
public View onCreateView(...){
viewModel.getUsersWithRoles().observe(...)
public void onChanged(...){
adapter.setData(...);
}
}
但是,有些部分缺失了。根据我对 MVVM 的理解,视图应该只负责显示信息,因此在片段或 activity 内部没有实际的逻辑甚至处理。此时我有2个问题:
- 按照常规方式,我会创建一个接口,例如
onFragmentAction
并在activity
中实现它。然后在fragment
上,当我想通知 activity 做某事时,我会做callback.onFragmentAction(params)
并且 activity 中的onFragmentAction
会触发并采取相应行动。这种情况在 MVVM 中是如何处理的?片段如何与其父片段对话 activity? - 按照常规方式,我会在片段的
onCreateView
内填充布局,使用findViewById
获取视图并使用,例如 textView.setText() 或 button.setOnClickListener()。这如何在 MVVM 中完成?使用数据绑定?
On the regular way, I would create an interface, for instance onFragmentAction and implement it in activity. Then on fragment when I wanted to inform the activity to do something, I would do callback.onFragmentAction(params) and the onFragmentAction in the activity would fire and act accordingly. How is this scenario handled in MVVM? How does a fragment talk to it's parent activity?
为了互动,您可以创建 Fragment
和 Activity
共享的 ViewModel
。在那种情况下,你有一个抽象,你将一些数据推送到 ViewModel
LiveData
中,它会得到一个监听相同 ViewModel
的事件。
例如this method is recommended用于Fragment
到Fragment
的通信,但我认为它也适合Fragment
到Activity
。
On the regular way I would have inside the fragment's onCreateView, inflate the layout, use findViewById to get the views and use, for instance textView.setText() or button.setOnClickListener(). How can this be done in MVVM? Use DataBinding?
您可以使用 DataBinding 或 Kotlin Android Extension,两者都应该适用于 MVVM。 通过 DataBinding 应该更好,因为它会减少样板文件。 但我个人觉得 Kotlin Android Extensions 也很干净。