Android fragments (Chinese Version of Android official documentation)

Source: Internet
Author: User

From: http://blog.sina.com.cn/s/blog_69a4fbd70100r5j4.html

 

 

Overview

Fragment represents an action or part of the UI in an activity. multiple fragment can be combined and placed in a single activity to create a multi-Interface UI, and a fragment can be reused in multiple activities. think of fragment as a modular area of an activity. It has its own life cycle, receives input events belonging to it, and can be added and deleted during activity running.

Fragment must always be embedded into an activity, and their lifecycles are directly affected by the lifecycles of the activity to which it belongs. for example, when an activity is paused, all fragment in the activity is also paused. When the activity is destroyed, all fragment affiliated to the activity is also destroyed. however, when an activity is running (in the resumed state), we can operate on each fragment independently, such as adding or deleting them. when processing such a fragment transaction, you can also add it to the back stack managed by activity --
The back stack entity in each activity is a record of a fragment transaction that has occurred. Back stack allows you to press the back button to return from a fragment transaction (navigation back ).

When a fragment is added as part of the activity layout, it is located in the viewgroup in the view hierarchy of the activity, and its own view layout is defined. insert a fragment to your activity layout by declaring fragment in the activity layout file, or you can write code to add it to an existing viewgroup. however, fragment does not have to be part of the activity layout. You can also use fragment as a hidden background worker of the activity.

This document describes how to use fragment to create your application, including how fragment maintains its status after being added to the back stack of the activity. share events with activity and other fragment in activity. construct the action bar to the activity. and more.

Design Philosophy
Android 3.0 introduces the fragments concept, which is mainly used on large screen devices, such as tablets, to support more dynamic and flexible uidesign. the screen size of a tablet is much larger than that of a mobile phone. More space is available for more UI components, and more interaction is generated between these components. fragment allows such a design, without the need for you to personally manage the complex changes of view hierarchy. by spreading the activity layout to fragment, you can modify the activity appearance at runtime and save the changes in the back stack managed by the activity.


 
For example, a news application can use a fragment on the left side of the screen to display a list of articles, then, use another fragment on the right side of the screen to display an article-2 fragment are displayed side by side in the same activity, and each fragment has its own set of lifecycle callback methods, and process their own user input events. therefore, instead of using one activity to select an article, and the other activity to read the article, you can select an article in the same activity and read it ,:

Fragment should be a modular and reusable component in your application. that is, because fragment defines its own layout and uses its own lifecycle callback method to define its own behavior, you can include fragment into multiple activities. this is especially important because it allows you to adapt your user experience to different screen sizes. for example, you may only include multiple fragment in an activity when the screen size is large enough. If this is not the case, another independent one will be started, use different fragment activities.

Continue with the previous news example-when running on a very large screen (such as a tablet), the app can embed two fragment entries in activity. however, on a normal screen (such as a mobile phone), there is not enough space for two fragment at the same time. Therefore, activity a only contains the fragment of the article list, when you select an article, Activity B is started, which contains the fragment for reading the article. therefore, the application supports two design modes in Figure 1 at the same time.

Create Fragment

To create a fragment, you must create a fragment subclass (or inherit from an existing subclass ). the code of the fragment class looks like activity. it contains callback methods similar to activity, such as oncreate (), onstart (), onpause, and onstop (). in fact, if you want to convert a ready-made Android app to fragment, you may simply move the code from the callback function of your activity to the callback method of your fragment.

Generally, the following lifecycle methods should be implemented at least:
Oncreate ()
This method is called when fragment is created.
In the implementation code, you should initialize the necessary components that you want to maintain in fragment. After the fragment is paused or stopped, it can be restored.
Oncreateview ()
When fragment draws its user interface for the first time, the system will call this method. to draw the fragment UI, this method must return a view, which is the root view of your fragment layout. if fragment does not provide the UI, null can be returned.
Onpause ()
When the user is about to leave fragment, the system calls this method as the first indication (however, it does not always mean that fragment will be destroyed .) before the end of the current user session, you should submit any persistent changes here (because the user may not return ).
Most applications should implement at least these three methods for each fragment, but there are other callback methods you should also use to process various stages of the fragment lifecycle. all lifecycle callback methods will be discussed in handling the fragment lifecycle.

In addition to inheriting the base class fragment, you may inherit some subclasses:
Dialogfragment
A floating dialog box is displayed.
Using this class to create a dialog box is a good choice outside the toolmethods of the activity class dialog box,
Because you can merge a fragment dialog box into the fragment back stack of activity management, allowing users to return to a previously abandoned fragment.
Listfragment
Displays a list of projects managed by an adapter (such as simplecursoradapter), similar to listactivity.
It provides some methods to manage a list view, such as onlistitemclick () callback to handle click events.
Preferencefragment
Displays a list of preference object hierarchies, similar to preferenceactivity.
This is useful when creating a "set" activity for your application.

Add a user interface

Fragment is usually used as a part of the user interface of an activity and provides its layout to the activity. to provide a layout for a fragment, you must implement the oncreateview () callback method. When the fragment draws its own layout, the android system calls it. the implementation code of this method must return the Root View of layout of your fragment.

NOTE: If your fragment is a subclass of listfragment, its default implementation is to return a listview from oncreateview (), so it generally does not have to be implemented.

The view returned from oncreateview () can also be read and generated from an XML layout resource file. To help you do so, oncreateview () provides a layoutinflater object.

For example, here is a subclass of fragment, which loads a layout from the file example_fragment.xml:
Public static class examplefragment extends fragment {
@ Override
Public View oncreateview (layoutinflater Inflater, viewgroup container, bundle savedinstancestate ){
// Inflate the layout for this fragment
Return Inflater. Inflate (R. layout. example_fragment, container, false );
}
}

The container parameter passed in oncreateview () is the parent viewgroup (from layout of activity) that your fragment layout will be inserted ). the savedinstancestate parameter is a bundle. If the fragment is recovered, it provides data about the previous fragment instance,

The inflate () method has three parameters:
The resource ID of the layout to be loaded.
Parent viewgroup of the loaded layout.
It is very important to pass in the container. The purpose is to allow the system to accept the layout parameter of the Root View to be loaded,
It specifies the parent view of the affiliated object.
A boolean value indicates whether the expanded layout should be attached to viewgroup during loading (the second parameter ).
(In this example, false is specified, because the system has inserted the expanded layout into the container-input true will create a redundant view group in the last layout .)

Add fragment to activity

Generally, fragment provides a part of the UI for the host activity and is embedded as part of the entire view hierarchy of the activity. You can add a fragment to the activity layout in two ways:

Declare fragment in the layout file of the activity
You can specify the layout attribute for fragment just like a view.
In this example, there are two fragment activities:

<? XML version = "1.0" encoding = "UTF-8"?>
<Linearlayout xmlns: Android = "http://schemas.android.com/apk/res/android"
Android: Orientation = "horizontal"
Android: layout_width = "match_parent"
Android: layout_height = "match_parent">
<Fragment Android: Name = "com. example. News. articlelistfragment"
Android: Id = "@ + ID/List"
Android: layout_weight = "1"
Android: layout_width = "0dp"
Android: layout_height = "match_parent"/>
<Fragment Android: Name = "com. example. News. articlereaderfragment"
Android: Id = "@ + ID/Viewer"
Android: layout_weight = "2"
Android: layout_width = "0dp"
Android: layout_height = "match_parent"/>
</Linearlayout>

The Android: Name attribute in <fragment> specifies the fragment class instantiated in layout.

When the system creates this activity layout, it instantiates each fragment specified in layout and calls the oncreateview () method on each to obtain the layout of each fragment. the system inserts the view returned from fragment directly to the location where the <fragment> element is located.

Note: Each fragment requires a unique identifier. If the activity restarts, the system can restore the fragment (and you can also capture the fragment to process the transaction, such as removing it .)

There are three methods to provide an identifier for a fragment:
Provides a unique ID for the Android: Id attribute.
Provides a unique string for the Android: Tag attribute.
If none of the above two items are provided, the system uses the ID of the container view.

Write code to add fragment to an existing viewgroup.

You can add fragment to activity layout at any time when the activity is running. you only need to specify a viewgroup for fragment. to operate fragment transactions (such as adding, removing, or replacing a fragment transaction) in your activity, you must use APIs from fragmenttransaction.

You can obtain a fragmenttransaction instance from your activity as follows:

Fragmentmanager = getfragmentmanager ();
Fragmenttransaction = fragmentmanager. begintransaction ();

Then you can use the add () method to add a fragment, specifying the fragment to be added and the view to be inserted.

Examplefragment fragment = new examplefragment (); fragmenttransaction. Add (R. Id. fragment_container, fragment );
Fragmenttransaction. Commit ();
The first parameter of add () is the viewgroup to be added by fragment, which is specified by the resource ID. The second parameter is the fragment to be added. once a change is made with fragmenttransaction, commit () must be called to make the change take effect ().

Add a fragment with no UI

The previous example shows how to add a fragment to the activity. However, you can also use fragment to provide background behavior for the activity without displaying additional UI.

To add a non-UI fragment, you need to use add (fragment, string) from the activity to add fragment (provide a unique string "tag" for fragment, rather than a view ID ). fragment is added in this way, but because it is not associated with a view in the activity layout, it will not receive oncreateview () calls. therefore, you do not need to implement this method.

Providing a string tag for fragment is not specifically for fragment without UI-you can also provide a string tag to fragment with UI-but if fragment does not have UI, this tag is the only way to identify it. if you want to obtain the fragment from the activity later, use findfragmentbytag ().

Manage Fragment
To manage fragment in an activity, you must use fragmentmanager to obtain its instance by calling getfragmentmanager () of the activity.

You can do something through fragmentmanager, including:
Use findfragmentbyid () (used to provide a UI fragment in activity layout) or findfragmentbytag () (applicable to fragment with or without a UI) to get the fragment existing in the activity
Pop up fragment from the background stack and use popbackstack () (simulate the user to press the back command ).
Use addonbackstackchangelistener () to register a listener that listens to background stack changes.

Handle fragment transactions
A strong feature of using fragment in an activity is to add, remove, replace, and execute fragment based on user interaction. each set of changes committed to the activity is called a transaction and can be processed using the API in fragmenttransaction. we can also save every transaction to a back stack managed by activity, allowing users to navigate back through the change in fragment (similar to navigation back through activity ).

Get an instance of fragmenttransaction from fragmentmanager:

Fragmentmanager = getfragmentmanager ();
Fragmenttransaction = fragmentmanager. begintransaction ();

Every transaction is a set of changes to be executed at the same time. you can set all the changes you want to execute in a given transaction, such as add (), remove (), and replace (). then, to apply the transaction to the activity, you must call commit ().

Before calling commit (), you may want to call addtobackstack () to add the transaction to the back stack of a fragment transaction. this back stack is managed by the activity and allows the user to return to the previous fragment status by pressing the back button.

For example, here is how to replace one fragment with another and keep the previous state in the background Stack:
// Create new fragment and transaction fragment newfragment = new examplefragment (); fragmenttransaction transaction = getfragmentmanager (). begintransaction (); // replace whatever is in the fragment_container view with this fragment, // and add the transaction
To the back stack transaction. Replace (R. Id. fragment_container, newfragment); transaction. addtobackstack (null); // commit the transaction. Commit ();

In this example, newfragment replaces. id. fragment_container ID. by calling addtobackstack (), the replace transaction is saved to the back stack. Therefore, you can roll back the transaction and press the back button to bring back the previous fragment.

If you add multiple changes to a transaction (such as add () or remove () and call addtobackstack (), then you call commit () all previous application changes will be added to the background stack as a single transaction, and the back button will roll them back together.

The order of adding changes to fragmenttransaction is not important, except for the following:
You must call commit ().
If multiple fragment entries are added to the same container, the order in which they are added determines the order they are displayed in view hierarchy.
If addtobackstack () is not called when a transaction is executed to remove fragment, the fragment will be destroyed after the transaction is committed, and the user cannot navigate back to it. in this case, if addtobackstack () is called when a fragment is removed, the fragment will be stopped. If the user returns the navigation, the fragment will be restored.

Tip: For each fragment transaction, you can apply a transaction animation by calling settransition () before committing the transaction.

Calling commit () does not execute transactions immediately. on the contrary, it schedules transactions. Once prepared, it runs on the UI thread of the activity (main thread ). if necessary, you can call executependingtransactions () from your UI thread to immediately execute the transactions committed by commit. however, this is usually unnecessary unless the transaction is a subordinate of the job in other threads.

Warning: You can only use commit () to submit a transaction before the activity saves its status (when the user leaves the activity.

If you try to submit after that point, an exception will be thrown. this is because the submitted status may be lost if the activity needs to be restored. use commitallowingstateloss ().

Communication with activity
Although fragment is implemented as an activity-independent object and can be used in multiple activities, a given fragment instance is directly bound to the activity containing it. in particular, fragment can use getactivity () to access the activity instance and easily execute a view task, for example, in activity layout.
View listview = getactivity (). findviewbyid (R. Id. List );
Similarly, the activity can obtain a reference to fragment from fragmentmanager to call the method in fragment, using findfragmentbyid () or findfragmentbytag ().

Examplefragment fragment = (examplefragment) getfragmentmanager (). findfragmentbyid (R. Id. example_fragment );

Create an Event Callback METHOD FOR THE ACTIVITY

In some cases, you may need a fragment to share the event with the activity. A good method is to define a callback interface in fragment and require the host activity to implement it. when an activity receives a callback through the interface, it can share information with other fragment in layout if necessary.

For example, if a new application has two fragment items in the activity-one for displaying the article list (framgent a) and the other for displaying the article content (fragment B) -Then framgent A must tell the activity when a list item is selected, and then it can tell fragment B to display the article.

In this example, the onarticleselectedlistener interface declares in fragment:

Public static class fragmenta extends listfragment {
...
// Container activity must implement this interface
Public interface onarticleselectedlistener {
Public void onarticleselected (URI articleuri );
}
...
}
Then, the fragment host activity implements the onarticleselectedlistener interface and overwrites onarticleselected () to notify fragment B of the events that come from fragment. to ensure that the host activity implements this interface, the onattach () callback method of fragment A (called by the system when fragment is added to the activity) passes in onattach () as a parameter () to instantiate an onarticleselectedlistener instance.

Public static class fragmenta extends listfragment {
Onarticleselectedlistener mlistener;
...
@ Override
Public void onattach (activity ){
Super. onattach (activity );
Try {
Mlistener = (onarticleselectedlistener) activity;
} Catch (classcastexception e ){
Throw new classcastexception (activity. tostring () + "must implement onarticleselectedlistener ");
}
}
...
}

If the activity does not implement an interface, fragment will throw a classcastexception. under normal circumstances, the mlistener member will keep a reference to the onarticleselectedlistener implementation of the activity. Therefore, fragment A can share the event to the activity by calling the method defined in the onarticleselectedlistener interface. for example, if fragment A is a subclass of listfragment, each time you click a list item, the system calls onlistitemclick () in fragment, and the latter calls
Onarticleselected () to allocate events to the activity.

Public static class fragmenta extends listfragment {
Onarticleselectedlistener mlistener;
...
@ Override
Public void onlistitemclick (listview L, view V, int position, long ID ){
// Append the clicked item's row ID with the content provider URI
Uri noteuri = contenturis. withappendedid (articlecolumns. content_uri, ID );
// Send the event and URI to the host activity
Mlistener. onarticleselected (noteuri );
}
...
}

The ID parameter passed to onlistitemclick () is the row ID of the item to be clicked, and activity (or other fragment) is used to obtain the article from the contentprovider of the application.

Add a project to action bar

Your fragment can provide the option menu for the activity by implementing oncreateoptionmenu () (similarly, the action bar ). to enable this method to receive calls, you must call sethasoptionsmenu () during oncreate () to indicate that fragment is willing to add items to the option menu (otherwise, fragment will not receive calls to oncreateoptionsmenu)

Any items added from fragment to the option menu will be appended to the end of the existing menu item. when a menu item is selected, fragment also receives a callback to onoptionsitemselected. you can also register a view in your fragment layout by calling registerforcontextmenu () to provide an environment menu. when you open the environment menu, fragment receives a call to oncreatecontextmenu. when you select a project, fragment receives a pair of oncontextitemselected ()
.

Note: although your fragment receives the callback after each menu item added to it is selected, the activity receives the corresponding callback first when you select a menu item. if the on-item-selected callback function of the activity does not process the selected project, the event will be passed to the fragment callback.

This rule applies to option menus and environment menus.

Process fragment Lifecycle

Managing the lifecycle of fragment is similar to managing the lifecycle of an activity in most cases. Like an activity, fragment can be in three states:
Resumed
Fragment is visible in the running activity.
Paused
The other activity is in the foreground and has focus, but the activity where the fragment is located is still visible (the foreground activity is partially transparent or does not cover the entire screen ).
Stopped
Either the host activity has been stopped or fragment has been removed from the activity but added to the background stack.
The fragment in the stopped state is still alive (all States and member information are kept by the system). However, it is invisible to the user and will be killed if the activity is killed.
Like activity, you can use bundle to maintain the fragment State. If the activity process is killed and the activity is re-created, you can use it to restore the fragment state. you can save the status during the onsaveinstancestate () of fragment and restore it during oncreate (), oncreateview (), or onactivitycreated.

The most important difference between activity and fragment in life cycle is how they are stored in their backend stacks. by default, an activity is placed in a background stack managed by the system to save the activity after it is stopped. (You can use the back button to navigate back to it ).

However, only when you remove fragment during a transaction and explicitly call addtobackstack () to save the instance is put into a background stack managed by the host activity.

In addition, the lifecycle of fragment management is very similar to that of activity management. therefore, the same practices in "managing the activity lifecycle" also apply to fragment. you need to understand how activity life affects fragment life.

Coordination with activity Lifecycle

The lifecycle of a fragment activity directly affects the lifecycle of fragment. The callback behavior of each activity will cause a similar callback in each fragment.

For example, when an activity receives onpause (), every fragment in the activity receives onpause ().

Fragment has some additional lifecycle callback methods that process the unique interaction with the activity and execute the UI actions such as creating and destroying fragment. These additional callback methods are:

Onattach ()
It is called when fragment is bound to activity (activity will be passed in .).
Oncreateview ()
It is called when the view hierarchy associated with fragment is created.
Onactivitycreated ()
Called when the oncreate () method of activity returns.
Ondestroyview ()
Called when the view hierarchy associated with fragment is being removed.
Ondetach ()
It is called when fragment disassociates from activity.
The fragment Lifecycle Process and the impact of the host activity on it are shown in figure 3. in this figure, we can see how each status of the activity determines the callback method that fragment may receive. for example, when an activity receives its oncreate (), fragment in the activity receives onactivitycreated () at most ().

Once the activity reaches the resumed state, you can freely add and remove fragment in the activity. Therefore, the fragment lifecycle can be changed only when the activity is in the resumed state.
In any case, when the activity leaves the resumed status, the fragment is pushed into its own Lifecycle Process by the activity again.
 

Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.