• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2015 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 package android.app;
18 
19 import android.annotation.Nullable;
20 import android.content.Context;
21 import android.content.res.Configuration;
22 import android.os.Bundle;
23 import android.os.Parcelable;
24 import android.util.ArrayMap;
25 import android.util.AttributeSet;
26 import android.view.Menu;
27 import android.view.MenuInflater;
28 import android.view.MenuItem;
29 import android.view.View;
30 
31 import java.io.FileDescriptor;
32 import java.io.PrintWriter;
33 import java.util.List;
34 
35 /**
36  * Provides integration points with a {@link FragmentManager} for a fragment host.
37  * <p>
38  * It is the responsibility of the host to take care of the Fragment's lifecycle.
39  * The methods provided by {@link FragmentController} are for that purpose.
40  */
41 public class FragmentController {
42     private final FragmentHostCallback<?> mHost;
43 
44     /**
45      * Returns a {@link FragmentController}.
46      */
createController(FragmentHostCallback<?> callbacks)47     public static final FragmentController createController(FragmentHostCallback<?> callbacks) {
48         return new FragmentController(callbacks);
49     }
50 
FragmentController(FragmentHostCallback<?> callbacks)51     private FragmentController(FragmentHostCallback<?> callbacks) {
52         mHost = callbacks;
53     }
54 
55     /**
56      * Returns a {@link FragmentManager} for this controller.
57      */
getFragmentManager()58     public FragmentManager getFragmentManager() {
59         return mHost.getFragmentManagerImpl();
60     }
61 
62     /**
63      * Returns a {@link LoaderManager}.
64      */
getLoaderManager()65     public LoaderManager getLoaderManager() {
66         return mHost.getLoaderManagerImpl();
67     }
68 
69     /**
70      * Returns a fragment with the given identifier.
71      */
72     @Nullable
findFragmentByWho(String who)73     public Fragment findFragmentByWho(String who) {
74         return mHost.mFragmentManager.findFragmentByWho(who);
75     }
76 
77     /**
78      * Attaches the host to the FragmentManager for this controller. The host must be
79      * attached before the FragmentManager can be used to manage Fragments.
80      * */
attachHost(Fragment parent)81     public void attachHost(Fragment parent) {
82         mHost.mFragmentManager.attachController(
83                 mHost, mHost /*container*/, parent);
84     }
85 
86     /**
87      * Instantiates a Fragment's view.
88      *
89      * @param parent The parent that the created view will be placed
90      * in; <em>note that this may be null</em>.
91      * @param name Tag name to be inflated.
92      * @param context The context the view is being created in.
93      * @param attrs Inflation attributes as specified in XML file.
94      *
95      * @return view the newly created view
96      */
onCreateView(View parent, String name, Context context, AttributeSet attrs)97     public View onCreateView(View parent, String name, Context context, AttributeSet attrs) {
98         return mHost.mFragmentManager.onCreateView(parent, name, context, attrs);
99     }
100 
101     /**
102      * Marks the fragment state as unsaved. This allows for "state loss" detection.
103      */
noteStateNotSaved()104     public void noteStateNotSaved() {
105         mHost.mFragmentManager.noteStateNotSaved();
106     }
107 
108     /**
109      * Saves the state for all Fragments.
110      */
saveAllState()111     public Parcelable saveAllState() {
112         return mHost.mFragmentManager.saveAllState();
113     }
114 
115     /**
116      * Restores the saved state for all Fragments. The given Fragment list are Fragment
117      * instances retained across configuration changes.
118      *
119      * @see #retainNonConfig()
120      *
121      * @deprecated use {@link #restoreAllState(Parcelable, FragmentManagerNonConfig)}
122      */
123     @Deprecated
restoreAllState(Parcelable state, List<Fragment> nonConfigList)124     public void restoreAllState(Parcelable state, List<Fragment> nonConfigList) {
125         mHost.mFragmentManager.restoreAllState(state,
126                 new FragmentManagerNonConfig(nonConfigList, null));
127     }
128 
129     /**
130      * Restores the saved state for all Fragments. The given FragmentManagerNonConfig are Fragment
131      * instances retained across configuration changes, including nested fragments
132      *
133      * @see #retainNestedNonConfig()
134      */
restoreAllState(Parcelable state, FragmentManagerNonConfig nonConfig)135     public void restoreAllState(Parcelable state, FragmentManagerNonConfig nonConfig) {
136         mHost.mFragmentManager.restoreAllState(state, nonConfig);
137     }
138 
139     /**
140      * Returns a list of Fragments that have opted to retain their instance across
141      * configuration changes.
142      *
143      * @deprecated use {@link #retainNestedNonConfig()} to also track retained
144      *             nested child fragments
145      */
146     @Deprecated
retainNonConfig()147     public List<Fragment> retainNonConfig() {
148         return mHost.mFragmentManager.retainNonConfig().getFragments();
149     }
150 
151     /**
152      * Returns a nested tree of Fragments that have opted to retain their instance across
153      * configuration changes.
154      */
retainNestedNonConfig()155     public FragmentManagerNonConfig retainNestedNonConfig() {
156         return mHost.mFragmentManager.retainNonConfig();
157     }
158 
159     /**
160      * Moves all Fragments managed by the controller's FragmentManager
161      * into the create state.
162      * <p>Call when Fragments should be created.
163      *
164      * @see Fragment#onCreate(Bundle)
165      */
dispatchCreate()166     public void dispatchCreate() {
167         mHost.mFragmentManager.dispatchCreate();
168     }
169 
170     /**
171      * Moves all Fragments managed by the controller's FragmentManager
172      * into the activity created state.
173      * <p>Call when Fragments should be informed their host has been created.
174      *
175      * @see Fragment#onActivityCreated(Bundle)
176      */
dispatchActivityCreated()177     public void dispatchActivityCreated() {
178         mHost.mFragmentManager.dispatchActivityCreated();
179     }
180 
181     /**
182      * Moves all Fragments managed by the controller's FragmentManager
183      * into the start state.
184      * <p>Call when Fragments should be started.
185      *
186      * @see Fragment#onStart()
187      */
dispatchStart()188     public void dispatchStart() {
189         mHost.mFragmentManager.dispatchStart();
190     }
191 
192     /**
193      * Moves all Fragments managed by the controller's FragmentManager
194      * into the resume state.
195      * <p>Call when Fragments should be resumed.
196      *
197      * @see Fragment#onResume()
198      */
dispatchResume()199     public void dispatchResume() {
200         mHost.mFragmentManager.dispatchResume();
201     }
202 
203     /**
204      * Moves all Fragments managed by the controller's FragmentManager
205      * into the pause state.
206      * <p>Call when Fragments should be paused.
207      *
208      * @see Fragment#onPause()
209      */
dispatchPause()210     public void dispatchPause() {
211         mHost.mFragmentManager.dispatchPause();
212     }
213 
214     /**
215      * Moves all Fragments managed by the controller's FragmentManager
216      * into the stop state.
217      * <p>Call when Fragments should be stopped.
218      *
219      * @see Fragment#onStop()
220      */
dispatchStop()221     public void dispatchStop() {
222         mHost.mFragmentManager.dispatchStop();
223     }
224 
225     /**
226      * Moves all Fragments managed by the controller's FragmentManager
227      * into the destroy view state.
228      * <p>Call when the Fragment's views should be destroyed.
229      *
230      * @see Fragment#onDestroyView()
231      */
dispatchDestroyView()232     public void dispatchDestroyView() {
233         mHost.mFragmentManager.dispatchDestroyView();
234     }
235 
236     /**
237      * Moves all Fragments managed by the controller's FragmentManager
238      * into the destroy state.
239      * <p>Call when Fragments should be destroyed.
240      *
241      * @see Fragment#onDestroy()
242      */
dispatchDestroy()243     public void dispatchDestroy() {
244         mHost.mFragmentManager.dispatchDestroy();
245     }
246 
247     /**
248      * Lets all Fragments managed by the controller's FragmentManager know the multi-window mode of
249      * the activity changed.
250      * <p>Call when the multi-window mode of the activity changed.
251      *
252      * @see Fragment#onMultiWindowModeChanged
253      * @deprecated use {@link #dispatchMultiWindowModeChanged(boolean, Configuration)}
254      */
255     @Deprecated
dispatchMultiWindowModeChanged(boolean isInMultiWindowMode)256     public void dispatchMultiWindowModeChanged(boolean isInMultiWindowMode) {
257         mHost.mFragmentManager.dispatchMultiWindowModeChanged(isInMultiWindowMode);
258     }
259 
260     /**
261      * Lets all Fragments managed by the controller's FragmentManager know the multi-window mode of
262      * the activity changed.
263      * <p>Call when the multi-window mode of the activity changed.
264      *
265      * @see Fragment#onMultiWindowModeChanged
266      */
dispatchMultiWindowModeChanged(boolean isInMultiWindowMode, Configuration newConfig)267     public void dispatchMultiWindowModeChanged(boolean isInMultiWindowMode,
268             Configuration newConfig) {
269         mHost.mFragmentManager.dispatchMultiWindowModeChanged(isInMultiWindowMode, newConfig);
270     }
271 
272     /**
273      * Lets all Fragments managed by the controller's FragmentManager know the picture-in-picture
274      * mode of the activity changed.
275      * <p>Call when the picture-in-picture mode of the activity changed.
276      *
277      * @see Fragment#onPictureInPictureModeChanged
278      * @deprecated use {@link #dispatchPictureInPictureModeChanged(boolean, Configuration)}
279      */
280     @Deprecated
dispatchPictureInPictureModeChanged(boolean isInPictureInPictureMode)281     public void dispatchPictureInPictureModeChanged(boolean isInPictureInPictureMode) {
282         mHost.mFragmentManager.dispatchPictureInPictureModeChanged(isInPictureInPictureMode);
283     }
284 
285     /**
286      * Lets all Fragments managed by the controller's FragmentManager know the picture-in-picture
287      * mode of the activity changed.
288      * <p>Call when the picture-in-picture mode of the activity changed.
289      *
290      * @see Fragment#onPictureInPictureModeChanged
291      */
dispatchPictureInPictureModeChanged(boolean isInPictureInPictureMode, Configuration newConfig)292     public void dispatchPictureInPictureModeChanged(boolean isInPictureInPictureMode,
293             Configuration newConfig) {
294         mHost.mFragmentManager.dispatchPictureInPictureModeChanged(isInPictureInPictureMode,
295                 newConfig);
296     }
297 
298     /**
299      * Lets all Fragments managed by the controller's FragmentManager
300      * know a configuration change occurred.
301      * <p>Call when there is a configuration change.
302      *
303      * @see Fragment#onConfigurationChanged(Configuration)
304      */
dispatchConfigurationChanged(Configuration newConfig)305     public void dispatchConfigurationChanged(Configuration newConfig) {
306         mHost.mFragmentManager.dispatchConfigurationChanged(newConfig);
307     }
308 
309     /**
310      * Lets all Fragments managed by the controller's FragmentManager
311      * know the device is in a low memory condition.
312      * <p>Call when the device is low on memory and Fragment's should trim
313      * their memory usage.
314      *
315      * @see Fragment#onLowMemory()
316      */
dispatchLowMemory()317     public void dispatchLowMemory() {
318         mHost.mFragmentManager.dispatchLowMemory();
319     }
320 
321     /**
322      * Lets all Fragments managed by the controller's FragmentManager
323      * know they should trim their memory usage.
324      * <p>Call when the Fragment can release allocated memory [such as if
325      * the Fragment is in the background].
326      *
327      * @see Fragment#onTrimMemory(int)
328      */
dispatchTrimMemory(int level)329     public void dispatchTrimMemory(int level) {
330         mHost.mFragmentManager.dispatchTrimMemory(level);
331     }
332 
333     /**
334      * Lets all Fragments managed by the controller's FragmentManager
335      * know they should create an options menu.
336      * <p>Call when the Fragment should create an options menu.
337      *
338      * @return {@code true} if the options menu contains items to display
339      * @see Fragment#onCreateOptionsMenu(Menu, MenuInflater)
340      */
dispatchCreateOptionsMenu(Menu menu, MenuInflater inflater)341     public boolean dispatchCreateOptionsMenu(Menu menu, MenuInflater inflater) {
342         return mHost.mFragmentManager.dispatchCreateOptionsMenu(menu, inflater);
343     }
344 
345     /**
346      * Lets all Fragments managed by the controller's FragmentManager
347      * know they should prepare their options menu for display.
348      * <p>Call immediately before displaying the Fragment's options menu.
349      *
350      * @return {@code true} if the options menu contains items to display
351      * @see Fragment#onPrepareOptionsMenu(Menu)
352      */
dispatchPrepareOptionsMenu(Menu menu)353     public boolean dispatchPrepareOptionsMenu(Menu menu) {
354         return mHost.mFragmentManager.dispatchPrepareOptionsMenu(menu);
355     }
356 
357     /**
358      * Sends an option item selection event to the Fragments managed by the
359      * controller's FragmentManager. Once the event has been consumed,
360      * no additional handling will be performed.
361      * <p>Call immediately after an options menu item has been selected
362      *
363      * @return {@code true} if the options menu selection event was consumed
364      * @see Fragment#onOptionsItemSelected(MenuItem)
365      */
dispatchOptionsItemSelected(MenuItem item)366     public boolean dispatchOptionsItemSelected(MenuItem item) {
367         return mHost.mFragmentManager.dispatchOptionsItemSelected(item);
368     }
369 
370     /**
371      * Sends a context item selection event to the Fragments managed by the
372      * controller's FragmentManager. Once the event has been consumed,
373      * no additional handling will be performed.
374      * <p>Call immediately after an options menu item has been selected
375      *
376      * @return {@code true} if the context menu selection event was consumed
377      * @see Fragment#onContextItemSelected(MenuItem)
378      */
dispatchContextItemSelected(MenuItem item)379     public boolean dispatchContextItemSelected(MenuItem item) {
380         return mHost.mFragmentManager.dispatchContextItemSelected(item);
381     }
382 
383     /**
384      * Lets all Fragments managed by the controller's FragmentManager
385      * know their options menu has closed.
386      * <p>Call immediately after closing the Fragment's options menu.
387      *
388      * @see Fragment#onOptionsMenuClosed(Menu)
389      */
dispatchOptionsMenuClosed(Menu menu)390     public void dispatchOptionsMenuClosed(Menu menu) {
391         mHost.mFragmentManager.dispatchOptionsMenuClosed(menu);
392     }
393 
394     /**
395      * Execute any pending actions for the Fragments managed by the
396      * controller's FragmentManager.
397      * <p>Call when queued actions can be performed [eg when the
398      * Fragment moves into a start or resume state].
399      * @return {@code true} if queued actions were performed
400      */
execPendingActions()401     public boolean execPendingActions() {
402         return mHost.mFragmentManager.execPendingActions();
403     }
404 
405     /**
406      * Starts the loaders.
407      */
doLoaderStart()408     public void doLoaderStart() {
409         mHost.doLoaderStart();
410     }
411 
412     /**
413      * Stops the loaders, optionally retaining their state. This is useful for keeping the
414      * loader state across configuration changes.
415      *
416      * @param retain When {@code true}, the loaders aren't stopped, but, their instances
417      * are retained in a started state
418      */
doLoaderStop(boolean retain)419     public void doLoaderStop(boolean retain) {
420         mHost.doLoaderStop(retain);
421     }
422 
423     /**
424      * Destroys the loaders and, if their state is not being retained, removes them.
425      */
doLoaderDestroy()426     public void doLoaderDestroy() {
427         mHost.doLoaderDestroy();
428     }
429 
430     /**
431      * Lets the loaders know the host is ready to receive notifications.
432      */
reportLoaderStart()433     public void reportLoaderStart() {
434         mHost.reportLoaderStart();
435     }
436 
437     /**
438      * Returns a list of LoaderManagers that have opted to retain their instance across
439      * configuration changes.
440      */
retainLoaderNonConfig()441     public ArrayMap<String, LoaderManager> retainLoaderNonConfig() {
442         return mHost.retainLoaderNonConfig();
443     }
444 
445     /**
446      * Restores the saved state for all LoaderManagers. The given LoaderManager list are
447      * LoaderManager instances retained across configuration changes.
448      *
449      * @see #retainLoaderNonConfig()
450      */
restoreLoaderNonConfig(ArrayMap<String, LoaderManager> loaderManagers)451     public void restoreLoaderNonConfig(ArrayMap<String, LoaderManager> loaderManagers) {
452         mHost.restoreLoaderNonConfig(loaderManagers);
453     }
454 
455     /**
456      * Dumps the current state of the loaders.
457      */
dumpLoaders(String prefix, FileDescriptor fd, PrintWriter writer, String[] args)458     public void dumpLoaders(String prefix, FileDescriptor fd, PrintWriter writer, String[] args) {
459         mHost.dumpLoaders(prefix, fd, writer, args);
460     }
461 }
462