我正在学习MVVM模式,现在遇到了一个问题。我有一个活动A,上面有imageview,还有一个活动B,上面有相同的imageview,但在另一个地方更大。当在活动A中我点击imageview时,我想开始活动B,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(视图视图(等方法创建接口,并在活动中实现它,并将其设置为字段,例如viewModelListener。然后我可以写一些类似的东西:
public void onAvatarClick(View view) {
viewModelListener.startActivityB(view);
}
但在这种情况下,我的视图模型将引用视图,它打破了MVVM的主要思想,对吧?
那么,使用MVVM体系结构使用共享元素启动新活动的正确方法是什么呢?
这可以通过Android中的Live Data完成。因为您可以观察实时数据的变化,并相应地导航到其他活动。
此处的示例
在您单击按钮的xml文件中
android:onClick="@{()->homeActivityViewModel.openNewActivity()}"
在您的视图中模型类
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);
} });