在MVVM架构中从ViewModel添加片段

4

我正在使用 DataBinding 并遵循 MVVM 架构,现在我卡在了如何从 ViewModel 中添加新的 fragment,因为我们需要在 ViewModel 上定义点击事件。这是我的 MainViewModel 类:

public class MainViewModel {
    private Context context;

    public MainViewModel (Context context) {
        this.context = context;
    }
    public void onClick(View v) {

    }
}

这是我的XML文件,我在其中定义了点击事件:

<layout xmlns:android="http://schemas.android.com/apk/res/android">

    <data>
        <variable
            name="viewmodel"
            type="com.example.MainViewModel" />
    </data>

    <RelativeLayout
        android:layout_width="match_parent"
        android:layout_height="match_parent">
         <TextView
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:onClick="@{viewmodel::onClick}"
            android:text="click me"/>
    </RelativeLayout>
</layout>

现在我该如何从我的ViewModel类中获取supportFragmentManagerchildFragmentManager? 我已经尝试使用activity.getSupportFragmentManager()activity.getChildFragmentManager(),但是它们没有这种方法。

我知道我们可以使用以下代码添加fragment:

getActivity().getSupportFragmentManager().beginTransaction()
            .setCustomAnimations(android.R.anim.fade_in, android.R.anim.fade_out, android.R.anim.fade_in, android.R.anim.fade_out).
            add(R.id.container, fragment, "").addToBackStack("main").commit();

但是在 ViewModel 类中如何实现呢?

2个回答

3

既然您已经有了Context,那么您有两种可能性:

public class MainViewModel {
    private Context context;

    public MainViewModel (Context context) {
        this.context = context;
    }

    public void onClick(View v) {
        //use context:
        ((AppCompatActivity) context).getSupportFragmentManager();

        //OR use the views context:
        if(v.getContext() instanceof AppCompatActivity) {
            ((AppCompatActivity) v.getContext()).getSupportFragmentManager();
        }            
    }    
}

在调用任何方法之前,检查上下文是否是你的活动实例(例如MainActivity)或AppCompatActivity,或者它是否为null可能是有用的。


6
在ViewModel中隐瞒View的上下文是不良实践。 - kazimad
@kazimad 你说得对,这就是为什么 MVVM 首先被创建的原因,不要在 ViewModel 中保存与 Android(视图)相关的内容的引用。 - Mehdi Kazemi
@MeHdi我有一个类似的问题,你会有什么建议呢? - Sorry
@LeNguyenDuyAnh,您能否再解释一下?您想要将某些片段添加到返回堆栈中吗? - Mehdi Kazemi

0

我不知道这是否可能,但这是我的建议:

定义一个接口,让Activity或Fragment实现此接口

public interface FragmentProvider {
    void showFragment(...);
}

将FragmentProvider的实例传递到您的ViewModel中。
public class MainViewModel {
    private Context context;
    private FragmentProvider provider;

    public MainViewModel (FragmentProvider provider) {
        this.provider = provider;
   }

   public void onClick(View v) {
        // delegate the action
        provider.showFragment(...);
   }

}


是的,这是一种可行的方式,但我不确定在使用MVVM时是否是一个好主意。 - Ravi
我想采用EventBus这种思路,这比这里第一个被接受的答案更好。 - Jileshl
我想采用EventBus这种思路,这比这里第一个被接受的答案更好。 - Jileshl

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接