Teach you to understand fragment

Source: Internet
Author: User
Tags android sdk manager

Defined

Fragment represents the behavior or part of the user interface in activity. We can combine multiple fragments in one activity to build a multi-window UI and reuse a fragment in multiple activity. A fragment can be thought of as a modular component of Activity, has its own life cycle, can receive its own input events, and you can add or remove fragments when the activity runs (a bit like a "child activity" that is reused in different activity).

Fragments must always be embedded in the activity, whose life cycle is directly affected by the host activity life cycle. For example, when activity is paused, all of its fragments are also paused, and all fragments are destroyed when the activity is destroyed. However, when Activity is running (in the restored life cycle state), we can manipulate each fragment independently, such as adding or removing them. When performing such fragment transactions, it is also possible to add it to each return stack entry in the return stack-activity managed by Activity as a record of a fragment transaction that has occurred. The return stack allows the user to undo the fragment transaction (back) by pressing the back button.

When we add a fragment as part of the activity layout, it exists inside one of the viewgroup of the Activity view hierarchy, and the fragment defines its own view layout. We can insert it using the app code by declaring the fragment in the activity's layout file, inserting it as an element into your activity layout, or by adding it to an existing viewgroup. However, fragments do not have to be part of the activity layout; we can also use fragments that do not have their own UI as invisible worker threads for activity.

This article describes how to use fragments when developing our app, including how to keep a fragment in the activity's return stack, how to share events with activity and other fragments in activity, how to work with activity's action bar, and so on.

Design principle

Android has introduced fragments in Android 3.0 (API level 11), primarily to support a more dynamic and flexible UI design on large screens such as tablets. Because your tablet's screen is much larger than your phone screen, you can use it to combine and swap UI components more space. When implementing this type of design with fragments, we do not need to manage complex changes to the view hierarchy. By dividing the activity layout into fragments, we can modify the appearance of the activity at run time and keep those changes in the return stack managed by the activity.

For example, a news app can use one fragment to display a list of articles on the left, and another fragment to display an article on the right-two fragments are displayed alongside one Activity, each with its own set of lifecycle callback methods and each handling its own user input events. Thus, instead of using one activity to select an article and then using another activity to read the article, the user can select the article and read it within the same activity, as shown in the 1 tablet layout.

We should design each fragment as a reusable modular Activity component. In other words, since each fragment defines its own layout and behavior through its own lifecycle callback, we can add a fragment to multiple activities, so we should use a reusable design to avoid directly manipulating another fragment directly from one fragment. This is especially important because modular fragments allow us to adapt the combination of fragments to different screen sizes. When designing apps that can support both tablets and phones, we can reuse the written fragments in different layout configurations to optimize the user experience based on the available screen space. For example, on a phone, if you can't store multiple clips within the same Activity, you might have to use a separate fragment to implement a single-pane UI.

Figure 1. For an example of how the two UI modules defined by a fragment fit into a different design: adapt to the tablet design by combining them into one Activity, and use individual fragments to adapt to the phone's design.

For example-still using the news app as an example-when running on a tablet-sized device, the app can embed two clips in activity A. However, on a phone-sized screen, there is not enough space to store two clips, so activity A only includes fragments for displaying the list of articles, and when the user selects the article, it launches activity B, which includes a second fragment for reading the article. As a result, apps can be used to support both tablets and phones by reusing different combinations of fragments, as shown in 1.

Create fragment

To create a fragment, we must create a subclass of Fragment (or already have its subclasses). The code for the Fragment class is very similar to Activity. It contains callback methods similar to Activity, such as OnCreate (), OnStart (), OnPause (), and OnStop (). In fact, if we were to convert an existing Android app to use a fragment, we might simply move the code from the Activity's callback method into the corresponding callback method of the fragment.

In general, you should implement at least the following life cycle methods:

OnCreate ()
The system calls this method when the fragment is created. We should initialize the required fragment components in the implementation that we intend to retain when the fragment is paused or stopped.
Oncreateview ()
This method is called when the fragment first draws its user interface. To draw the UI for your fragment, the view that we return from this method must be the root view of the fragment layout. If the fragment does not provide a UI, we can return null.
OnPause ()
The system calls this method as the first signal of the user leaving the fragment (but does not always mean that the fragment will be destroyed). In this method, we should usually confirm any changes that are still valid after the end of the current user session (because the user may not return).
Most applications should implement these three methods at least for each fragment, but we should also use several other callback methods to handle each stage of the fragment's life cycle. Understand the Fragment Lifecycle section for specific lookup APIs for all life cycle callbacks.

Sometimes we may also want to extend several subclasses, rather than Fragment base classes:

Dialogfragment
Displays the floating dialog box. Use this class to create a dialog box that effectively overrides the dialog helper method in the activity class, because you can include the Fragment dialog box in the return stack of fragments managed by the activity, allowing the user to return to the purged fragment.
Listfragment
Displays a series of projects managed by adapters such as Simplecursoradapter, similar to listactivity. It provides several ways to manage the list view, such as the Onlistitemclick () callback for handling click events.
Preferencefragment
Displays a hierarchical structure of Preference objects in a list, similar to preferenceactivity. This is useful when creating "set up" Activity for our app.

Add user interface

Fragments are often used as part of the activity user interface to incorporate their own layouts into activity.

To provide a layout for a fragment, we must implement the Oncreateview () callback method, which is called by the Android system when the fragment needs to draw its layout. The view returned for the implementation of this method must be the root view of the fragment layout.

Note: If the fragment we are using is a subclass of Listfragment, the default implementation returns a ListView from Oncreateview (), so there is no need to implement it.

To return the layout from Oncreateview (), we can extend the layout through the layout resources defined in the XML. To help us do this, Oncreateview () provides a Layoutinflater object.

For example, this Fragment subclass loads the layout from the Example_fragment.xml file:

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 to Oncreateview () is the parent viewgroup (from the Activity's layout) to which our fragment layout will be inserted. The Savedinstancestate parameter is a Bundle that provides data about an instance of a segment when recovering a fragment.

The inflate () method has three parameters:

The resource ID of the layout we want to extend;
The viewgroup that will be the parent of the extended layout. Passing container is important for the system to apply layout parameters to the root view of the extended layout (specified by the parent view to which it belongs).
A Boolean value that indicates whether the extended layout should be attached to ViewGroup (the second parameter) during the extension. (In this case, the value is false because the system has inserted the extended layout into container-to pass a true value to create an extra view group in the final layout.) )
Now, we've learned how to create a fragment that provides a layout. Next, you need to add the fragment to your Activity.

Add a fragment to an activity

Typically, fragments contribute a portion of the UI to the host activity and are embedded in the activity as part of the activity's overall view hierarchy. There are two ways to add a fragment to the Activity layout:

    • Declare a fragment within the Activity's layout file
      In this case, we can use the fragment as a view to specify layout properties for it. For example, here is a layout file with an Activity of two fragments:
<?xml version= "1.0" encoding= "Utf-8"?><LinearLayoutXmlns:android="Http://schemas.android.com/apk/res/android"android:orientation="Horizontal"Android:layout_width="Match_parent"android:layout_height="Match_parent" ><FragmentAndroid: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 property in specifies the Fragment class to instantiate in the layout.

When the system creates this Activity layout, each fragment specified in the layout is instantiated, and the Oncreateview () method is called for each fragment to retrieve the layout of each fragment. The system will insert the View returned by the fragment directly to replace the element.

Note: Each fragment requires a unique identifier that the system can use to recover the fragment when the Activity is restarted (you can also use the identifier to capture a fragment to perform certain transactions, such as deleting it). There are three ways to provide an ID for a fragment:
-Provide a unique ID for the Android:id property
-Provides a unique string for the Android:tag property
-If you do not provide a value for the above two attributes, the system uses the ID of the container view

    • Or dynamically add fragments to an existing viewgroup programmatically
      We can add fragments to the activity layout at any time while the activity is running.
      We just need to specify which viewgroup to put the fragment into.
      To perform fragment transactions in our Activity (such as adding, deleting, or replacing fragments), we must use the APIs in Fragmenttransaction. We can get a fragmenttransaction instance from Activity like this:
FragmentManager fragmentManager = getFragmentManager()FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction();

You can then use the Add () method to add a fragment, specify which fragment to add, and which view to insert. For example:

ExampleFragment fragment = new ExampleFragment();fragmentTransaction.add(R.id.fragment_container, fragment);fragmentTransaction.commit();

The first parameter passed to add () is ViewGroup, which is the location where the fragment should be placed, specified by the resource ID, and the second parameter is the fragment to be added.
Once you have made changes through fragmenttransaction, you must call commit () for the changes to take effect.

What's the use of fragment without a UI?

Example shows how to add fragments to our Activity to provide the UI. However, we can also use fragments to provide background behavior for activity without displaying extra UI.

To add a fragment without a UI, add a fragment from Activity using Add (Fragment, String) (provides a unique string "tag" for the fragment, not a view ID). This adds a fragment, but it does not receive a call to Oncreateview () because it is not associated with a view in the Activity layout. Therefore, we do not need to implement this method.

Not only can you provide string markers for non-UI fragments-we can also provide a string tag for fragments with UI-but if the fragment does not have a UI, the string token will be the only way to identify it. If we want to get fragments from the Activity later, we need to use Findfragmentbytag ().

To see a sample Activity that uses a fragment that does not have a UI as a background worker, see the Fragmentretaininstance.java sample, which is included in the SDK sample (provided through the Android SDK Manager) to/apidemos/ap The P/src/main/java/com/example/android/apis/app/fragmentretaininstance.java form is located in your system.

Managing Fragments

To manage the fragments of our Activity, we need to use Fragmentmanager. To get it, please call Getfragmentmanager () from our Activity.

The actions we can perform with Fragmentmanager include:

Get the fragments that exist in the activity through Findfragmentbyid () (for fragments that provide UI in the activity layout) or Findfragmentbytag () (for fragments that provide or do not provide UI)
Eject a fragment from the return stack via Popbackstack () (Impersonate the user's back command)
Registers a listener that listens for changes to the stack via Addonbackstackchangedlistener ()
For more information about these methods and other methods, see the Fragmentmanager class documentation.

As shown above, we can also use Fragmentmanager to open a fragmenttransaction to perform certain transactions, such as adding and deleting fragments.

Performing fragment Transactions

One of the great advantages of using fragments in Activity is that they can be used to perform additions, deletions, substitutions, and other actions based on user behavior. Each set of changes we submit to the Activity is called a transaction, and we can use the API in Fragmenttransaction to execute a transaction. We can also save each transaction to the return stack managed by the Activity, allowing the user to fallback the fragment changes (similar to fallback Activity).

We can get a fragmenttransaction instance from Fragmentmanager like this:

FragmentManager fragmentManager = getFragmentManager();FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction();

Each transaction is a set of changes that you want to execute at the same time. We can use the Add (), remove (), and replace () methods to set all the changes we want to make for a given transaction. Then, to apply the transaction to the Activity, we must call commit ().

However, before we call commit (), we may want to call Addtobackstack () to add the transaction to the fragment transaction return stack. The return stack is managed by the Activity, allowing the user to return to the previous segment state by pressing the "Back" button.

For example, the following example shows how to replace one fragment with another, and how to retain the previous state on the return stack:

//Create New Fragmentandtransactionfragment 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 Stacktransaction. Replace (R.id.fragment_container, newfragment); Transaction.addtobackstack (null);//< Span class= "Hljs-keyword" >commit the transactiontransaction . commit ();             

In the example above, Newfragment replaces any fragment (if any) that is currently in the layout container identified by the R.id.fragment_container ID. by calling Addtobackstack (), you can save the replacement transaction to the return stack so that the user can undo the transaction and fall back to the previous segment by pressing the Back button.

If we add more than one change to a transaction (such as another add () or remove ()) and call Addtobackstack (), all changes applied before the call to commit () are added to the return stack as a single transaction, and the back button undoes them.

The order in which changes are added to fragmenttransaction is irrelevant, but:

We must finally call commit ()
If we want to add multiple fragments to the same container, the order in which the fragments are added determines the order in which they appear in the view hierarchy
If we do not call Addtobackstack () when executing a transaction that deletes a fragment, the fragment is destroyed when the transaction commits and the user cannot fall back to the fragment. However, if we call Addtobackstack () when we delete a fragment, the system stops the fragment and restores it when the user rolls back.

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

Calling commit () does not immediately execute the transaction, but instead schedules the activity's UI thread (the "primary" thread) to perform the operation when it is scheduled to run on its thread. However, if necessary, we can also call Executependingtransactions () from the UI thread to immediately execute a commit () COMMIT transaction. Typically, you do not have to do this unless the jobs in other threads depend on the transaction.

Note: We can only commit a transaction using commit () before the activity saves its state (the user leaves the activity). If you attempt to commit after that point in time, an exception is thrown. This is because if the Activity is to be resumed, the state after the commit may be lost. Use Commitallowingstateloss () for missing commits that do not matter.

Communicating with Activity

Although Fragment is implemented as an activity-independent object and can be used within multiple activity, a given instance of a fragment is bound directly to the activity that contains it.

Specifically, fragments can access activity instances through getactivity () and easily perform tasks such as finding views in the activity layout.

View listView = getActivity().findViewById(R.id.list);

Likewise, our Activity can use Findfragmentbyid () or Findfragmentbytag () to invoke a method in a fragment by obtaining a reference to Fragment from Fragmentmanager. For example:

ExampleFragment fragment = (ExampleFragment) getFragmentManager().findFragmentById(R.id.example_fragment);

Process Fragment life cycle

Managing the Fragment life cycle is similar to managing the Activity life cycle. Like Activity, fragments exist in three different states:

Recovery

The fragment is visible in the Activity in the run.

Time out

The other activity is in the foreground and has the focus, but the activity of the fragment is still visible (the foreground activity is partially transparent or does not cover the entire screen).

Stop it

The fragment is not visible. The host Activity has stopped, or the fragment has been removed from the activity but has been added to the return stack. The stop fragment is still active (all state and member information is preserved). However, it is no longer visible to the user and will be terminated if the Activity is terminated.

As with activity, if the activity process is terminated and we need to restore the fragment state while rebuilding the activity, we can also use the Bundle to preserve the state of the fragment. We can save the state during the Onsaveinstancestate () callback of the fragment and restore the state during onCreate (), Oncreateview (), or onactivitycreated (). For more information about save status, see the activity documentation.

The most significant difference between the Activity life cycle and the fragment lifecycle is how they are stored in their respective return stacks. By default, when activity is stopped, it is put into the system-managed activity return stack (so that the user can fall back to the activity via the "Back" button, which is described by the task and return stack). However, the system will place the fragment into the return stack managed by the host Activity only when we explicitly request that the instance be saved by calling Addtobackstack () during the transaction execution of the deleted fragment.

In other respects, managing the fragment life cycle is very similar to managing the Activity life cycle. Therefore, the practice of managing the Activity life cycle also applies to fragments. But we also need to understand the impact of the Activity's life cycle on the fragment life cycle.

Note: If you want a context object within the Fragment, you can call Getactivity (). Note, however, that you only call getactivity () when a fragment is attached to an Activity. Getactivity () returns null if the fragment has not been attached or is detached during the end of its life cycle

Teach you to understand fragment

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.