首页 > 解决方案 > 在 ViewModel 和 Fragment/Activity 交互和通信之间应用 MVVM

问题描述

我投入了大量时间来正确理解架构组件以及一切如何适应 MVVM 模式。到目前为止,这是我的看法(没有进行 Dagger 注入,因为我还没有做到这一点):

a)UserEntity是一个带有@Entity注释的类,用于处理Room的表创建

@Entity(tableName="users")
public class Users{
   private long id;
   private String name;
}

b)User模型中的 pojo 类以在应用程序周围使用它,并根据需要具有补充字段。

public class User{
   private long id;
   private String name;
   private List<Role> roles;
   private Preferences preferences;
}

除此之外,根据我对 db 的需要,可以有不同的 pojo,例如,UserWithRoles

c)UserDao负责在房间数据库中获取或插入/更新信息。在这里,对于@Insert@Update我可以使用,UserEntity但是对于@Query我也可以使用 pojo 类

@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 的理解,视图应该只负责显示信息,因此在片段或活动中没有实际的逻辑甚至处理。在这一点上,我有两个问题:

  1. 通常,我会创建一个接口,例如onFragmentAction并在activity. 然后fragment当我想通知活动做某事时,我会做callback.onFragmentAction(params)onFragmentAction活动中的 会触发并采取相应的行动。这种情况在 MVVM 中是如何处理的?片段如何与其父活动对话?
  2. 在常规方式中,我将在片段内部onCreateView,膨胀布局,用于findViewById获取视图并使用,例如 textView.setText() 或 button.setOnClickListener()。如何在 MVVM 中做到这一点?使用数据绑定?

标签: androidmvvmandroid-architecture-componentsandroid-viewmodelandroid-mvvm

解决方案


通常,我会创建一个接口,例如 onFragmentAction 并在活动中实现它。然后在片段上,当我想通知活动做某事时,我会做 callback.onFragmentAction(params) 并且活动中的 onFragmentAction 会触发并采取相应的行动。这种情况在 MVVM 中是如何处理的?片段如何与其父活动对话?

对于交互,您可以创建在和ViewModel之间共享的。在这种情况下,您有一个抽象,您将一些数据推送到它获取事件的地方,无论谁监听相同。FragmentActivityViewModel LiveDataViewModel

例如,这种方法推荐用于通信,但我认为它也适合.FragmentFragmentFragmentActivity

在常规方式中,我将在片段的 onCreateView 中,膨胀布局,使用 findViewById 获取视图并使用,例如 textView.setText() 或 button.setOnClickListener()。如何在 MVVM 中做到这一点?使用数据绑定?

您可以使用 DataBinding 或Kotlin Android Extension,两者都可以使用 MVVM。通过 DataBinding 应该会更好,因为它会减少样板。但我个人觉得 Kotlin Android Extensions 也很干净。


推荐阅读