【问题标题】:Add fragment from ViewModel in MVVM architecture在 MVVM 架构中从 ViewModel 添加片段
【发布时间】:2017-02-26 10:45:10
【问题描述】:

我使用DataBinding 并遵循MVVM 架构,现在我被困在如何从ViewModel 添加新片段,因为我们需要在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(),但是没有那种方法。

我知道我们可以使用以下代码添加片段

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 类中做到这一点

【问题讨论】:

    标签: android android-fragments mvvm android-databinding android-mvvm


    【解决方案1】:

    既然你有你的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 可能很有用。

    【讨论】:

    • 在 ViewModel 中保留视图的上下文是不好的做法
    • @kazimad 你是对的,这就是为什么首先创建 MVVM,而不是在 ViewModel 中保存与 android(视图)相关的东西的引用。
    • @MeHdi 我也有类似的问题,那你有什么建议?
    • @LeNguyenDuyAnh 你能解释一下吗?您想将一些片段添加到 backstack 中吗?
    【解决方案2】:

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

    定义一个接口,让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 时这是否是个好主意。
    • 我想采用 EventBus 的想法,这是比这里第一个接受的答案更好的解决方案。
    • 我想采用 EventBus 的想法,这是比这里第一个接受的答案更好的解决方案。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2017-10-24
    • 1970-01-01
    • 2018-08-23
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-07-28
    相关资源
    最近更新 更多