package org.robolectric.android.controller; import android.app.Activity; import android.app.Fragment; import android.content.Intent; import android.os.Bundle; import android.widget.LinearLayout; import org.robolectric.Robolectric; import org.robolectric.ShadowsAdapter; import org.robolectric.util.FragmentTestUtil; /** * Controller class for driving fragment lifecycles, similar to {@link ActivityController}. Only * necessary if more complex lifecycle management is needed, otherwise {@link FragmentTestUtil} * should be sufficient. */ public class FragmentController<F extends Fragment> extends org.robolectric.util.FragmentController<F> { private final F fragment; private final ActivityController<? extends Activity> activityController; public static <F extends Fragment> FragmentController<F> of(F fragment) { return of(fragment, FragmentControllerActivity.class, null); } public static <F extends Fragment> FragmentController<F> of(F fragment, Class<? extends Activity> activityClass) { return of(fragment, activityClass, null); } public static <F extends Fragment> FragmentController<F> of(F fragment, Intent intent) { return new FragmentController<>(Robolectric.getShadowsAdapter(), fragment, FragmentControllerActivity.class, intent); } public static <F extends Fragment> FragmentController<F> of(F fragment, Class<? extends Activity> activityClass, Intent intent) { return new FragmentController<>(Robolectric.getShadowsAdapter(), fragment, activityClass, intent); } private FragmentController(ShadowsAdapter shadowsAdapter, F fragment, Class<? extends Activity> activityClass, Intent intent) { super(shadowsAdapter, fragment, intent); this.fragment = fragment; this.activityController = Robolectric.buildActivity(activityClass, intent); } /** * @deprecated This is a no-op, it's safe to remove this call. * * This method will be removed in Robolectric 3.4. */ @Deprecated @Override public FragmentController<F> attach() { return this; } /** * Creates the activity with {@link Bundle} and adds the fragment to the view with ID {@code contentViewId}. */ public FragmentController<F> create(final int contentViewId, final Bundle bundle) { shadowMainLooper.runPaused(new Runnable() { @Override public void run() { activityController.create(bundle).get().getFragmentManager().beginTransaction().add(contentViewId, fragment).commit(); } }); return this; } /** * Creates the activity with {@link Bundle} and adds the fragment to it. Note that the fragment will be added to the view with ID 1. */ public FragmentController<F> create(Bundle bundle) { return create(1, bundle); } @Override public FragmentController<F> create() { return create(null); } @Override public FragmentController<F> destroy() { shadowMainLooper.runPaused(new Runnable() { @Override public void run() { activityController.destroy(); } }); return this; } public FragmentController<F> start() { shadowMainLooper.runPaused(new Runnable() { @Override public void run() { activityController.start(); } }); return this; } public FragmentController<F> resume() { shadowMainLooper.runPaused(new Runnable() { @Override public void run() { activityController.resume(); } }); return this; } public FragmentController<F> pause() { shadowMainLooper.runPaused(new Runnable() { @Override public void run() { activityController.pause(); } }); return this; } public FragmentController<F> visible() { shadowMainLooper.runPaused(new Runnable() { @Override public void run() { activityController.visible(); } }); return this; } public FragmentController<F> stop() { shadowMainLooper.runPaused(new Runnable() { @Override public void run() { activityController.stop(); } }); return this; } public FragmentController<F> saveInstanceState(final Bundle outState) { shadowMainLooper.runPaused(new Runnable() { @Override public void run() { activityController.saveInstanceState(outState); } }); return this; } /** * @deprecated Use {@link org.robolectric.Robolectric#buildFragment(Class, Class, Intent)} instead. * * This method will be removed in Robolectric 3.4. */ @Deprecated @Override public FragmentController<F> withIntent(final Intent intent) { shadowMainLooper.runPaused(new Runnable() { @Override public void run() { activityController.withIntent(intent); } }); return this; } private static class FragmentControllerActivity extends Activity { @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); LinearLayout view = new LinearLayout(this); view.setId(1); setContentView(view); } } }