代码之家  ›  专栏  ›  技术社区  ›  Darthoo

使用MVVM体系结构的活动共享元素转换

  •  0
  • Darthoo  · 技术社区  · 6 年前

    我正在学习MVVM模式,现在有一个问题。我有一个活动A,上面有ImageView,还有一个活动B,上面有相同的ImageView,但是在另一个地方和更大的地方。在活动A中,我单击ImageView时,我想启动活动B,并且ImageView应该是共享元素,以通过良好的动画实现我想要的。

    使用我处理的数据绑定,在我的视图模型中单击ImageView:

    <de.hdodenhof.circleimageview.CircleImageView
                        android:layout_width="60dp"
                        android:layout_height="60dp"
                        android:onClick="@{(v) -> user.onAvatarClick(v)}"
                        android:scaleType="centerCrop"
                        android:src="@{user.photoUrl}"
                        android:transitionName="@string/avatar_transition" />
    

    在我的视图模型中,我应该这样写:

    public void onAvatarClick(View view) {
        Intent intent = new Intent(context, AvatarActivity.class);
        ActivityOptionsCompat options = ActivityOptionsCompat.makeSceneTransitionAnimation(activity, view, view.getTransitionName());
        context.startActivity(intent, options.toBundle());
    }
    

    但是,问题是我的视图模型对活动一无所知。我不知道该怎么做。

    一种可能的解决方案是使用StartActivityB(视图视图)等方法创建接口,并在Activity中实现它,并将其设置为Field,例如ViewModelListener。然后我可以写下:

    public void onAvatarClick(View view) {
        viewModelListener.startActivityB(view);
    }
    

    但在这种情况下,我的视图模型将引用视图,它打破了MVVM的主要思想,对吧?

    那么,使用MVVM体系结构的共享元素启动新活动的正确方法是什么?

    1 回复  |  直到 6 年前
        1
  •  0
  •   Rajat Beck    6 年前

    这可以通过Android中的实时数据来实现。因为您可以观察实时数据中的变化并相应地导航到其他活动。

    此处为示例

    在单击按钮的XML文件中

    android:onClick="@{()->homeActivityViewModel.openNewActivity()}"
    

    在ViewModel类中

    private final MutableLiveData<Boolean> openNewScreen = new MutableLiveData<>();
    
     //function that is binded to xml
    public void openNewActivity() {
        openNewScreen.setValue(true);
    }
    
    public MutableLiveData<Boolean> getNewScreen() {
        return openNewScreen;
    }
    

    在你的活动中

     homeActivityViewModel.getNewScreen().observe(this,
                start -> {
                    if (start) {
                        Intent intent = new Intent(this, NewActivity.class);
                        startActivity(intent);
                    } });