Atlas of Beauties 02

Summary of fragments

Fragment is an Activity or part of the user interface in an Activity. It mainly supports dynamic display on the large screen and more flexible to combine or exchange UI components. By dividing the layout of the Activity into several fragments, you can edit the presentation of the Activity at runtime, and those changes are saved in the background stack managed by the Activity. A Fragment must always be embedded in an activity, and its life cycle is directly influenced by the life cycle of its host activity. You can think of a fragment as a modular part of an activity that has its own life cycle, receives its own input events, and can be added or removed while the activity is running. Each fragment should be designed as a modular and reusable activity component. That is, you can refer to the same fragment in multiple activities because the fragment defines its own layout and uses its own lifecycle callback behavior.

  • First look at the Fragment lifecycle diagram:





    Fragments periodogram

  • Look at the Fragment attached to the Activity’s life state diagram:





    Fragment and Activity life cycle synthesis diagram

So many methods in the Fragment life cycle, come and learn! go go go

Fragment lifecycle method meaning:
  • Public void onAttach(Context Context) onAttach() is called immediately after the Fragment is associated with the Activity window. From this method, you can get the Activtiy window object associated with the Fragment using the fragment.getActivity () method, but because the Fragment control is uninitialized, you cannot manipulate the control.
  • Public void onCreate(Bundle savedInstanceState) calls onCreate() immediately after onAttach() is executed, and retrieves some of the data passed in the Activity from the Bundle object. This method usually reads the saved transitions and gets or initializes some data. Do not perform time-consuming operations in this method or the Activity window will not display.
  • public View onCreateView(LayoutInflater inflater, ViewGroup Container,Bundle savedInstanceState) this method is an important part of the Fragment lifecycle because it creates views that the Fragment displays, and inflaters are used to load layout files. Container is the parent of the < Fragment > tag. The saveInstanceState parameter obtains the state saved in the fragment. If the state is not saved, the value is null.
  • Public void onViewCreated(View View,Bundle savedInstanceState) Android calls back this method immediately after the View object in the Fragment is created. The View argument is the view returned from onCreateView, and the Bundle object is used for general purposes.
  • Public void onActivityCreated(Bundle savedInstanceState) The Android system calls this method immediately after the Activity’s onCreate() method is executed. GetActivity ().findViewById(R.i.xx); To operate the View in your Activity.
  • Public void onStart() this is not much to say, but one detail to know is that when the system calls the method, the fragment is already displayed on the UI, but can’t interact yet because the onResume() method hasn’t finished executing.
  • Public void onResume() This method is the last method in the fragment’s life cycle from creation to display Android calls. When this method is called, the fragment can interact with the user.
  • Public void onPause() fragment The first callback method to be executed after the active state is changed to inactive. It is usually used to hold work in this method that needs to be temporarily paused. For example, save the music playback speed and then resume the music playback progress in the onResume() method.
  • Public void onStop() When onStop() returns, the fragment will disappear from the screen.
  • Public void onDestoryView() The call to this method means that all views created in onCreateView() will be removed.
  • Public void onDestroy() This method is called when Android is no longer using your Fragment. And you can get a Fragment object, but you can’t do anything with it.
  • Public void onDetach() is the last method in the Fragment lifecycle. After the method is executed, the Fragment is no longer associated with the Activity.
Fragment has several additional lifecycle callback methods than Activity:
  • OnAttach (Activity): Used when the Fragment is associated with the Activity.
  • OnCreateView (LayoutInflater, ViewGroup, Bundle) : create a view of the fragments
  • OnActivityCreate (Bundle): called when the Activity’s onCreate() method returns
  • OnDestoryView (): Corresponding to onCreateView, called when the Fragment view is removed
  • OnDetach (): corresponding to onAttach(), called when the Fragment and Activity association is removed note: If you override all methods except onCreateView(), you must call the parent class’s implementation of that method
Managing the Fragment life cycle is similar to managing the Activity life cycle

Like activities, fragments have three states:

  • Resumed Fragments are visible in running activities
  • Paused Another activity is in the foreground and in focus, but the Activtiy in which the fragment is located is still visible (the foreground activity is partially transparent or does not cover the full screen).
  • Stopped

    Fragment is not visible. Either the host activity has stopped, or the fragment has been removed from the activity but added to the background stack. A stopped fragment is still alive (all state and member information is still retained by the system). However, it is no longer visible to the user, and if the activity is killed, it is also killed.

    — — — — — — — — — — — — — — — —

    If the activity’s process is killed, you restore the fragment state when the activity is recreated. You can execute onSaveIntanceState() of the fragment to save the state (note: the fragment is restored in onCreate(),onCreateView() or onActivityCreate())).

    There is an important difference between activities and fragments in terms of life cycleThat’s how it’s stored in the respective backend stacks. whenThe activity stopsBy default, activities are placed in the system-managed activity background stack.fragmentOnly when a transaction is removed is the fragment placed on the backend stack managed by the host activity by explicitly calling addToBackStack() to request a saved instance.

    To create a fragment, you must create a subclass of the fragment. In general, you need to implement at least one of the following methods for the fragment lifecycle :onCreate(),onCreateView(),onPause()
    @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);
    }Copy the code

    The inflate() function takes the following three arguments:

    (1). The resource Id of the inflate layout

    (2). The parent ViewGroup of the synchronized layout

    (3). A Boolean value that indicates whether the ViewGroup (the second container) should be attached to a layout that is inflate during the constructorates. (False is passed in this case because the system has inserted the inflate layout into the container — passing true creates an extra ViewGroup in the final layout.)

Interaction between Fragments and activities:
  • You can add a Fragment to an activity by declaring the Fragment in the Activtiy layout file, inserting the Fragment into the activity layout with the Fragment tag, or adding it to an existing ViewGroup using the application source code. But fragments don’t have to be part of the activity layout; they can also work for activity stealth. (1). Declare a fragment in the activity’s layout file. You can assign layout attributes to the fragment just like a view does. The code is as follows:

      <?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.test.FragmentOne"
                  android:id="@+id/fo"
                  android:layout_width="match_parent"
                  android:layout_height="match_parent" />
      </LinearLayout>Copy the code

    The Android: Name attribute in the Fragment tag specifies that the Fragment class is instantiated in the layout. When the system creates the activity layout, it instantiates each fragment specified in the layout file and calls the onCeateView() function for them to get the layout of each fragment. The system inserts the View returned by the fragment directly at the element’s location. Note: Each fragment needs a unique identifier. If you restart the activity, the system can restore the fragment (and capture the fragment’s transactions, such as removing the fragment). There are three ways to provide ids for the fragment: 1:> Provides a unique identifier with the Android: ID attribute. 2:> provides a unique string with the Android :tag attribute. 3:> If neither of these attributes is present, the system uses the ID of its container view. (2). Add a Fragment to an existing ViewGroup by coding it. You can add a fragment to the activity layout at any time the activity is running. To manage fragments in an activity, use the FragmentManager. This can be obtained by calling getFragmentManager() in the activity. You can do the following things with FragmentManager, including: 1:> Use findFragmentById() (used to provide interface fragments in the activity layout or findFragmentByTag() to get existing fragments in the activity (with or without an interface)). 2:> Use popBackStack() (imitating the user’s Back command) to pop the fragment from the background stack. 3: > use addOnBackStackChangeListener () to register a stack to monitor background change listener. In Android, transactions on fragments are performed using FragmentTranSaction. Operations can be roughly divided into two types: 1:> show: add(), replace(), show(), attach() 2:> hide: remove(), hide(), detach() When the show() & hide() methods are called, the Fragment’s life-cycle methods are not executed, only the Fragment’s View is shown or hidden. Replace () (with at least two fragments) executes the onAttach() method of the second Fragment and the onPause() -ondetach () method of the first Fragment. Also containerView detach the first Fragment View. The add() method executes the life cycle of onAttach()-onResume(), and the relative remove() completes the rest of the onPause() -ondetach () cycle. You can get an instance of FragmentTransaction from your Activity like this:

    FragmentManager fragmentManager = getFragmentManager FragmentTransaction ()fragmentTransaction = fragmentManager
                                              .beginTransaction();Copy the code

    You can add a fragment using the add() function and specify which fragment to add and which view to insert it into (note the commit transaction) :

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

    (3). Add a fragment without an interface. You can also use the fragment to provide background actions for an activity without presenting an unnecessary user interface. To add a fragment without an interface, use Add (Fragment, String) (give the fragment a unique String “tag” instead of a view ID). This adds a fragment, but because the view is not associated with the activity layout, the onCreateView() call is not received. So you don’t need to implement this method. For a non-interface fragment, the string tag is the only way to identify it. If you later want to retrieve a fragment from your activity, you need to use findFragmentByTag().

  • Interaction between fragments and activities can be achieved with fragment.setarguments (Bundle args) and fragment.getarguments ().

Persistence of fragments:

Since an Activity’s configuration changes frequently, fragments attached to it need to store their state. There are two common ways to persist a Fragment state.

  • Methods a

    Can be achieved byprotected void onSaveInstanceState(Bundle outState),protected void onRestoreInstanceState(Bundle savedInstanceState)The methods of state saving and recovery persist the state.
  • Method 2 (more convenient, let Android automatically save Fragment state for us) <1>. We only need to save the Fragment as a variable in the Activity. As long as the Fragment is saved, the Fragment state is saved. Therefore, we can obtain the Fragment data through the following method.

    FragmentManager.putFragment(Bundle bundle, String key, Fragment 
    fragment) is a method to save fragments in an Activity.FragmentManager.getFragment(Bundle bundle, String Key is the method to retrieve the saved Frament in the Activity.Copy the code

    <2>. Obviously, the key in <1> is the id of the Fragment that you want to save the state on. This means that the FragmentManager holds fragments through the Bundle. However, this method can only save the state of the control in the Fragment, such as the text the user has entered in the EditText. The Fragment requires an ID value, otherwise Android will not save the state of the control for us), and variables that need to be persisted in the Fragment will still be lost, but there is still a solution: use method 1! <3>. Here is the code for a persistent instance of the state:

       /** The code in the Activity **/
       FragmentB fragmentB;
    
      @Override
      protected void onCreate(@Nullable Bundle savedInstanceState) {
          super.onCreate(savedInstanceState);
          setContentView(R.layout.fragment_activity);
          if( savedInstanceState ! =null ){
              fragmentB = (FragmentB) getSupportFragmentManager()
                          .getFragment(savedInstanceState,"fragmentB");
          }
          init();
      }
    
      @Override
      protected void onSaveInstanceState(Bundle outState) {
          if( fragmentB ! =null ){
             getSupportFragmentManager()
               .putFragment(outState,"fragmentB",fragmentB);
          }
          super.onSaveInstanceState(outState);
      }
    
      /** Fragment code to save variables **/
      @Nullable
      @Override
      public View onCreateView(LayoutInflater inflater, @Nullable 
          ViewGroup container, @Nullable Bundle savedInstanceState) {
          AppLog.e("onCreateView");
          if ( null! = savedInstanceState ){String savedString = savedInstanceState
                                   .getString("string");
              // Get the saved string
          }
          View root = inflater.inflate(R.layout.fragment_a,null);
          return root;
      }
    
      @Override
      public void onSaveInstanceState(Bundle outState) {
          outState.putString("string"."anAngryAnt");
          super.onSaveInstanceState(outState);
      }Copy the code
Use fragments statically

1. Integrate the Fragment and override onCreateView() to determine the layout of the Fragment 2. Declare the Fragment in the Activity, just like a normal View.

Fragment common API
  • Android. Support. The v4. App. Fragments: mainly used for defining fragments
  • Android. Support. The v4. App. FragmentManager: mainly used for operating fragments in the Activity, can be usedFragmentMagager. FindFragmentById () and FragmentMagager findFragmentByTag ()Etc to find a Fragment
  • Android. Support. The v4. App. FragmentTransaction: guarantee some fragments of atomic operation, familiar with the word affairs.
  • The main operations are FragmentTransaction methods (normally we use the Fragment in support-V4 for backwards compatibility).

    GetFragmentManager () / / fragments if use is support the v4 package, then use getSupportFragmentManager instead

Links: about getChildFragmentManager (), getFragmentManager (), getSupportFragmentManager (use of)

  • The main operations are the FragmentTransaction methods:

      FragmentTransaction transaction = fm.benginTransatcion();// Start a transaction
      // Add a Fragment to the Activity
      transaction.add() 
    
      transaction.remove(a)// Remove a Fragment from the Activity, if the removed Fragment is not added to the rollback stackThe Fragment instance will be destroyed. transaction.replace()// Replace the current Fragment with another Fragment, which is essentially a combination of remove() and add() ~
    
      transaction.hide()
      // Hide the current Fragment, just make it invisible, not destroyed
    
      transaction.show()
      // Display the previously hidden Fragment
    
      detach(a)// This method works the same as *remove()* when the fragment is added to the rollback stack,
      // Instead, this method simply removes the fragment from the view,
      // You can still reuse the fragment by * attaching ()*,
      // After calling the *remove()* method,
      // Not only will the Fragment be removed from the view, but the Fragment will no longer be available.
    
      attach(a)// Rebuild the view, attach it to the UI and display it.
    
      transatcion.commit()
      // Commit a transactionCopy the code

    Transactions can be added to the Fragment transaction stack (by calling addToBackStatck()) before calling commit(). The background stack is managed by the activity and allows the user to return to the previous fragment state by pressing the BACK key. The following code substitutes one fragment for another and keeps the previous fragment state in the background stack:

    Fragment newFragment = new ExampleFragment(a); FragmentTransaction transaction = getFragmentManager().beginTransaction(); transaction.replace(R.id.fragment_container,newFragment);
    transaction.addToBackStack(null);
    transaction.commit();Copy the code

    Note: If you add multiple change transactions (such as another add() or remove()) and call addToBackStack(), all applied changes prior to the commit() call are added to the background stack as a single transaction, and the BACK key can roll them BACK together. When removing a fragment, if addToBackStack() is called, the fragment is then stopped and restored if the user falls back. Calling commit() does not execute the transaction immediately. Instead, it takes the form of a reservation and runs as soon as the activity’s interface thread (the main thread) is ready. However, if necessary, you can start your interface thread calls executePendingTransations immediate execution by commit () () committed transaction. The transaction can only be committed with commit() before the activity saves state (when the user leaves the activity). If you try to commit after that time, an exception will be thrown. This is because if the activity needs to be resumed, the state after the submission will be lost. For this type of lost commit, use commitAllowingStateLoss()

Manage the Fragment rollback stack
  • Traces the status of the rollback

    We do this by implementingOnBackStackChangedListenerInterface to realize the state tracking of the rollback, the specific code is as follows:
    / / implements the interface
    public class XXX implements FragmentManager.OnBackStackChangedListener 
    // Implement the method to be implemented by the interface
    @Override
    public void onBackStackChanged() {
      //do whatevery you want
    }
    // Set the fallback stack listening interface
    getSupportFragmentManager().addOnBackStackChangedListener(this);Copy the code
  • Management back stack (1). FragmentTransaction. AddToBackStack (String) to add a Fragment just add to the back stack (2). GetSupportFragmentManager (.) getBackStackEntryCount () to get back the number of entities in the stack (3) getSupportFragmentManager () popBackStack (String Name, int flags) according to the name immediately pops up on the top of the stack fragments (4) getSupportFragmentManager () popBackStack (int id, Int flags) immediately pop the fragment at the top of the stack based on the ID

Conclusion: believe in yourself, you can be the person you want to be, come on! – upon

QQ: 2585085940

Email address: [email protected]

Welcome to my humble home.