简体   繁体   中英

Add fragment from ViewModel in MVVM architecture

I am using DataBinding and following MVVM architecture , now i am stuck on how to add new fragment from ViewModel as we need defined click event on ViewModel . Here is my MainViewModel class

public class MainViewModel {
    private Context context;

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

    }
}

here is my xml where i have defined click event

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

now how can i get supportFragmentManager or childFragmentManager from my ViewModel class? I have tried to use activity.getSupportFragmentManager() and activity.getChildFragmentManager() but it doesn't have that kind of method.

I know we can add fragment with following code

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();

but how to do it in ViewModel class

Since you have your Context available, you have two possibilities:

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

It may be useful to check whether the context is an instance of your activity (like MainActivity ) or AppCompatActivity , or if it is null before calling any method.

I don't know if it's possible but here is what i suggest:

Define an interface and let the Activity or Fragment implement this interface

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

Pass an instance of FragmentProvider into your 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(...);
   }

}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM