android - 在 ViewModel 和 Fragment/Activity 交互和通信之间应用 MVVM

标签 android mvvm android-architecture-components android-viewmodel android-mvvm

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

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;
}

除此之外,根据我对数据库的需求,可以有不同的 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 可用于显示用户及其角色列表的 fragment

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) 在我的 fragment 中我可以做类似的事情:

public void onCreate(...){
    viewModel = ViewModelProviders.of(this).get(UserWithRolesViewModel.class);
}

public View onCreateView(...){
  viewModel.getUsersWithRoles().observe(...)
          public void onChanged(...){
          adapter.setData(...);
       }
}

但是,有些部分缺失了。根据我对 MVVM 的理解, View 应该只负责显示信息,因此在 fragment 或 Activity 内部没有实际的逻辑甚至处理。此时我有两个问题:

  1. 通常,我会创建一个接口(interface),例如 onFragmentAction 并在 activity 中实现它。然后在 fragment 上,当我想通知 Activity 做某事时,我会在 Activity 中执行 callback.onFragmentAction(params)onFragmentAction会开火并采取相应行动。这种情况在 MVVM 中是如何处理的? fragment 如何与其父 Activity 对话?
  2. 按照常规方式,我会在 fragment 的 onCreateView 中展开布局,使用 findViewById 获取 View 并使用,例如 textView.setText() 或按钮.setOnClickListener()。这如何在 MVVM 中完成?使用数据绑定(bind)?

最佳答案

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

关于android - 在 ViewModel 和 Fragment/Activity 交互和通信之间应用 MVVM,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51210821/

相关文章:

java - 比较 2 个 ArrayList<HashMap<String, String>> 之间的字符串

android - 无法在 Release模式下构建应用程序 - keystore 被篡改或密码不正确

Android LiveData - 第二次更新时不会触发 switchMap

android - MediaPlayer seekTo 从头开始​​不一致地播放歌曲

android - 显示来自 Application 类的 Toast 消息

c# - 如何在不实例化新 ViewModel 的情况下设置 BindingContext

c# - WPF MVVM : EventTrigger is not working inside CheckBox

silverlight - 如何在我准备好之前防止 Silverlight RIA 实体附加到数据上下文

android - 我们如何在 ViewModel 中将 "assign"LiveData 从 Room 转移到 MutableLiveData

android - 如何在 Android 中填充 Room Persistence 数据库?