在 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个问题:

  1. 按照常规方式,我会创建一个接口,例如 onFragmentAction 并在 activity 中实现它。然后在 fragment 上,当我想通知 activity 做某事时,我会做 callback.onFragmentAction(params) 并且 activity 中的 onFragmentAction 会触发并采取相应行动。这种情况在 MVVM 中是如何处理的?片段如何与其父片段对话 activity?
  2. 按照常规方式,我会在片段的 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?

为了互动,您可以创建 FragmentActivity 共享的 ViewModel。在那种情况下,你有一个抽象,你将一些数据推送到 ViewModel LiveData 中,它会得到一个监听相同 ViewModel 的事件。

例如this method is recommended用于FragmentFragment的通信,但我认为它也适合FragmentActivity

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 也很干净。