Android Getting Started Tutorial | Fragment Basic Concepts

insert image description here

What are Fragments?

Fragment, literally translated as "fragment", "fragment". Fragment represents the behavior or part of the interface in FragmentActivity. You can combine multiple fragments in one Activity to build a multi-pane interface and reuse a fragment in multiple Activities. Fragments can be thought of as modular components of an Activity that have their own life cycle, receive their own input events, and can be added or removed while the Activity is running (it's a bit like a " Child Activity").

Fragments must always be hosted in an Activity, and their lifecycle is directly affected by the host Activity's lifecycle. For example, when the Activity is paused, all fragments of the Activity are also paused; when the Activity is destroyed, all fragments are also destroyed.

However, while the Activity is running (in the resumed lifecycle state), each fragment can be manipulated independently, such as adding or removing fragments. When such a fragment transaction is executed, it is also added to the back stack managed by the Activity—each back stack entry in the Activity is a record that a fragment transaction has occurred. With the back stack, the user can undo the fragment transaction (back) by pressing the back button.

Advantages of Fragments

  • Fragment loading is flexible and easy to replace. Customize your UI, create a suitable UI on screens of different sizes, and improve user experience.
  • Reusable, the page layout can use multiple Fragments, and different controls and content can be distributed on different Fragments.
  • Using Fragment, you can use less Activity. An Activity can govern multiple Fragments.

Fragment life cycle

img

The code for the Fragment class is very similar to the Activity. It contains callback methods similar to Activity, such as onCreate(), onStart(), onPause(), and onStop(). In fact, if you're converting an existing Android app to use fragments, you might just need to move the code from the Activity's callback method into the fragment's corresponding callback method.

Typically, at least the following lifecycle methods should be implemented :

  • onCreate() The system calls this method when the fragment is created. If you want to preserve the basic components of a fragment after the fragment has been paused or stopped and then resumed, you should initialize it in your implementation.
  • onCreateView() The system calls this method when the fragment draws its interface for the first time. To draw the interface for a fragment, the View returned from this method must be the root view of the fragment's layout. May return null if the fragment does not provide an interface.
  • onPause() The system calls this method as the first signal that the user leaves the fragment (but does not always mean that the fragment will be destroyed). In general, any changes that persist after the current user session ends (since the user may not return) should be acknowledged within this method.

You may also want to extend several subclasses other than the Fragment base class :

  • DialogFragment displays a floating dialog. Using this class to create a dialog is an effective alternative to using the dialog helper methods in the Activity class, because you can place the fragment dialog on the fragment back stack managed by the Activity, allowing the user to return to a cleared fragment.
  • ListFragment displays a collection of items managed by an adapter such as SimpleCursorAdapter, similar to ListActivity. This class provides several methods for managing the list view, such as the onListItemClick() callback for handling click events. (Note that the preferred way to display a list is to use a RecyclerView, not a ListView. In this case, create a fragment that contains the RecyclerView in the list layout. See Creating a List with a RecyclerView to learn how)
  • PreferenceFragmentCompat displays a hierarchy of Preference objects in list form. This class is used to create settings screens for the application.
Create Fragment, use custom interface

Fragments are typically used as part of an Activity's interface and will incorporate their own layout into the Activity.

To provide layout for a fragment, you must implement onCreateView()the callback method that the Android system calls when the fragment needs to draw its layout. The View returned by an implementation of this method must be the root view of the fragment layout.

To return a layout from onCreateView(), the layout can be extended by a layout resource defined in XML. To help you do this, onCreateView() provides a LayoutInflater object.

For example, the following Fragment subclass example_fragment.xmlloads the layout from a 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) into which the fragment's layout will be inserted. The savedInstanceState parameter is the Bundle that provides data related to the previous fragment instance when the fragment is restored (the section dealing with the fragment life cycle explains in detail the restoration state).

The inflate() method takes three parameters :

  • The resource ID of the layout you want to extend.
  • The ViewGroup that will be the parent of the extended layout. Passing a container has significance for the system to apply layout parameters to the root view (specified by the parent view it belongs to) of the extended layout.
  • A boolean indicating whether an expanded layout should be attached to the ViewGroup (second parameter) during expansion. (In this case, the value is false because the system has already inserted the expanded layout into the container, and passing a value of true would have created a redundant viewgroup in the final layout.)

Next, you need to add this fragment to your Activity.

Add Fragment to Activity

Typically, fragments contribute a portion of the interface to the host Activity, embedded in the Activity as part of the Activity's overall view hierarchy. There are two ways to add fragments to the Activity layout (the code snippets below are not complete).

static way

Declare fragments within the Activity's layout file. In this case, you can specify layout properties for a fragment as if it were a view. For example, here is the layout file for an Activity with two fragments:

<?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>

<fragment>The attribute in android:namespecifies the Fragment class to instantiate in the layout.

When this activity layout is created, the system instantiates each fragment specified in the layout and calls onCreateView()the method for each fragment to retrieve each fragment's layout. The View returned by the fragment is inserted directly in place of <fragment>the element.

Note: Each fragment requires a unique identifier that the system can use to restore the fragment when the activity is restarted (or to capture the fragment to perform certain transactions, such as removing it). There are two ways to provide an ID for a fragment: Provide a unique ID for the android:id attribute. Provide a unique string for the android:tag attribute.

Java code loads Fragment

Alternatively, programmatically add the fragment to an existing ViewGroup. You can add fragments to the activity layout at any time while the activity is running. You just specify which ViewGroup you want to put the fragment into.

To perform fragment transactions (such as adding, removing, or replacing fragments) in an Activity, you must use the APIs in FragmentTransaction. A FragmentTransaction instance can be obtained from FragmentActivity as follows:

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

You can then add()add a fragment using the method, specifying which fragment to add and which view to insert it into. For example:

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

The first parameter passed to add()is the ViewGroup where the fragment should be placed, specified by the resource ID, and the second parameter is the fragment to add. Once changes have been made via a FragmentTransaction, must be called commit()for the changes to take effect.

Manage Fragments

To manage the fragments in the Activity, you need to use FragmentManager. To get it, call it from the Activity getSupportFragmentManager().

Operations that can be performed using FragmentManager include :

  • findFragmentById()Get the fragments present in the Activity via (for fragments that provide an interface in the Activity layout) or findFragmentByTag() (for fragments that provide or do not provide an interface).
  • popBackStack()Pop the fragment off the back stack by (simulating a return command issued by the user).
  • addOnBackStackChangedListener()Register a listener for changes to the return stack via .

FragmentManager can also be used to open a FragmentTransaction, through which to perform certain transactions, such as adding and removing fragments.

Execute Fragment transaction

One of the great things about using fragments in an Activity is that you can add, remove, replace, and do other things with the fragment in response to user interaction. Each set of changes committed to an Activity is called a transaction, and APIs in FragmentTransaction can be used to perform a transaction. Each transaction can also be saved to a back stack managed by the Activity, allowing the user to roll back fragment changes (similar to rolling back the Activity).

A FragmentTransaction instance can be obtained from the FragmentManager as follows:

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

Each transaction is a set of changes that you want to perform concurrently. You can use methods such as add(), remove(), and replace() to set all the changes you want to perform for a given transaction. Then, to apply the transaction to the Activity, you must call commit().

However, before calling commit(), you may wish to call addToBackStack() to add the transaction to the fragment transaction back stack. This back stack is managed by the Activity and allows the user to return to the previous fragment state by pressing the back button.

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

// Create new fragment and transaction
Fragment newFragment = new ExampleFragment();
FragmentTransaction transaction = getSupportFragmentManager().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
transaction.commit();

In this case, newFragment replaces any fragment (if any) currently in the layout container identified by the R.id.fragment_container ID. By calling addToBackStack(), a replacement transaction can be saved to the back stack so that the user can undo the transaction and roll back to the previous fragment by pressing the back button.

FragmentActivity then automatically retrieves the fragment from the back stack via onBackPressed().

If you add multiple changes to a transaction (such as yet another add() or remove()), and call addToBackStack(), all changes applied before calling commit() will be added to the back stack as a single transaction, and the back button will Undo them all.

The order in which you add changes to FragmentTransaction doesn't matter, though:

commit() must be called last. If you are adding multiple fragments to the same container, the order in which you add the fragments will determine the order in which they appear in the view hierarchy. If addToBackStack() is not called during the transaction that deletes the fragment, the fragment will be destroyed when the transaction commits, and the user will not be able to roll back to the fragment. However, if addToBackStack() is called while the fragment is being deleted, the system stops the fragment and then resumes it when the user goes back.

Calling commit() does not execute the transaction immediately, but instead schedules the transaction to run on the thread when the Activity's UI thread (the "main" thread) is available to do so. However, if necessary, executePendingTransactions() can also be called from the UI thread to execute commit() committed transactions immediately. Usually you don't have to do this unless jobs in other threads depend on the transaction.

Note: You can only use commit() to commit a transaction before the Activity saves its state (when the user leaves the Activity). An exception will be thrown if an attempt is made to commit after that point. This is because the submitted state may be lost if the Activity needs to be resumed. For cases where missing commits don't matter, use commitAllowingStateLoss().

life cycle changes

When Fragment is created

It goes through the following states

onAttach()
onCreate()
onCreateView()
onActivityCreated()

When the Fragment is visible to the user

It goes through the following states

onStart()
onResume()

When Fragment enters "background mode"

It goes through the following states

onPause()
onStop()

Fragment is destroyed (or the activity holding it is destroyed)

It goes through the following states

onPause()
onStop()
onDestroyView()
onDestroy()
onDetach()

Different life cycles between Fragment and Activity

Most of the state of Fragment is similar to Activity, but Fragment has some new states.

Fragment is different from the life cycle of Activity

  • onAttached()—— Called when the fragment is added to the activity (in this method, the activity where it is located can be obtained).
  • onCreateView()—— When the activity wants to get the layout of the fragment, this method is called, and the fragment creates its own layout (interface) in it.
  • onActivityCreated()—— This method is called after the activity's onCreated() method returns
  • onDestroyView()- This method is called when the view in the fragment is removed.
  • onDetach()—— This method is called when the fragment and activity are separated.

Once the activity enters the resumed state (that is, the running state), you can freely add and remove fragments. Therefore, only when the activity is in the resumed state, the life cycle of the fragment can run independently, and other times it depends on the change of the life cycle of the activity.

Handle the Fragment lifecycle

Managing the fragment lifecycle is very similar to managing the Activity lifecycle. Like Activities, Fragments exist in three states:

  • Restored: The fragment is visible in the running Activity.
  • Paused: Another Activity is in the foreground and has focus, but the Activity in which this fragment resides is still visible (the foreground Activity is partially transparent, or does not cover the entire screen).
  • Stopped: The fragment is not visible. The host Activity has been stopped, or the fragment has been removed from the Activity but added to the back stack. A stopped fragment is still active (all state and membership information is preserved). However, it is no longer visible to the user and terminates with the termination of the Activity. As with Activities, you can also use a combination of onSaveInstanceState(Bundle), ViewModel, and persistent local storage to preserve a fragment's UI state across configuration changes and process termination. To learn more about preserving UI state, see Saving UI State.

For the Activity life cycle and the fragment life cycle, the most significant difference between the two is the storage method in their respective return stacks. By default, when an Activity stops, it is placed on the system-managed Activity Back Stack. However, the system places the fragment on the back stack managed by the host Activity only when an instance is explicitly requested to be saved by calling addToBackStack() during the transaction that removed the fragment.

In other respects, managing the fragment lifecycle is very similar to managing the Activity lifecycle; the same approach can be taken here.

img

Note: If you need a Context object in the Fragment, you can call getContext(). Note, however, that getContext() only needs to be called when the fragment is attached to an Activity. If the fragment has not been attached, or it was detached during end-of-lifetime, getContext() returns null.

Fragment related interview questions:

1. How to switch fragement (without re-instantiation)

Looking through the official Android Doc and the source code of some components, I found that the replace() method is just a convenient method when the previous Fragment is no longer needed.

The correct switching method is add(), hide() when switching, and add() another Fragment; when switching again, just hide() the current one and show() the other one. In this way, multiple Fragment switches can be achieved without re-instantiation:

2. Advantages of Fragment

  • Fragments enable you to separate an activity into multiple reusable components, each with its own life cycle and UI.
  • Fragments can easily create dynamic and flexible UI designs that can adapt to different screen sizes. From phone to tablet.
  • Fragment is an independent module, tightly bound together with activity. It can be dynamically removed, added, exchanged, etc. during operation.
  • Fragments provide a new way for you to unify your UI across different Android devices.
  • Fragment solves the problem of unsmooth switching between activities and lightweight switching.
  • Fragment replaces TabActivity for navigation and has better performance.
  • Fragment adds a nested fragment usage method in version 4.2., which can generate better interface effects.

3. How does Fragment achieve the push and pop effects similar to the Activity stack

Fragment's thing manager maintains a doubly linked list structure inside, which can record the Fragment we add and replace Fragment each time, and then when we click the back button, it will automatically help us realize the unstack operation.

4. The difference between the replace and add methods of Fragment

Fragment itself does not have replace and add methods. The understanding here should be the difference between using FragmentManager's replace and add methods to switch Fragments.

One of the architectures we often use is to switch Fragments through RadioGroup, and each Fragment is a functional module.

The container of the Fragment is a FrameLayout. When adding, all the Fragments are superimposed on the FrameLayout layer by layer. When replacing, first remove the other Fragments in the container and then add the current Fragment to the container.

Only one type of Fragment can be added to a Fragment container. If it is added multiple times, an exception will be reported and the program will terminate. However, it does not matter for replace, just switch at will.

Because each Fragment added by the add method can only be added once, so if you want to achieve the switching effect, you need to use the combination of the Fragment's hide and show methods. Show the ones to be displayed and hide others. The Fragment life cycle has not changed in this process. Switching Fragments by replace will execute the onDestroyView of the previous Fragment and the onCreateView, onStart, and onResume methods of the new Fragment every time.

Based on the above different characteristics, the use we are using must be combined with the life cycle to operate our views and data.

5. How to pass value between Fragment and Activity

  • Activity passes value to Fragment:

Put the value to be passed into the bundle object; Create the fragment object fragment of the Fragment in the Activity, and pass it to the fragment by calling fragment.setArguments(); Get the bundle object by calling getArguments() in the Fragment, and you can get the inside value.

  • Fragment passes value to Activity:

Call getFragmentManager() in Activity to get fragmentManager, call findFragmentByTag(tag) or pass findFragmentById(id) FragmentManager fragmentManager = getFragmentManager(); Fragment fragment = fragmentManager.findFragmentByTag(tag);

Through callback, define an interface (can be defined in the Fragment class), there is an empty method in the interface, the method of the interface is called when needed in the fragment, the value can be placed in this method as a parameter, and then let the Activity implement This interface will inevitably rewrite this method, so that the value is passed to the Activity.

6. Fragment life cycle

  • onAttach(Contextcontext): Called when Fragment and Activity are associated, and only called once. In this callback, we can convert the context into an Activity and save it, thereby avoiding the situation of frequently calling getAtivity() to obtain the Activity later, and avoiding the exception that getAtivity() is empty in some cases (when the Activity and Fragment are separated) . At the same time, the incoming Arguments can also be extracted and parsed in the callback. Here, it is strongly recommended to pass parameters to Fragment through setArguments, because Fragment will not save related properties when the application is recycled by the system.
  • onCreate: It will be called when the Fragment is initially created, similar to Activity's onCreate.
  • View onCreateView(LayoutInflater inflater, ViewGroup container,Bundle savedInstanceState): Called when the Fragment interface is ready to be drawn, the return value is the root view of the Fragment to draw the layout, of course, it can also return null. Note that attachToRoot must be specified as false when using the inflater to build a View, because Fragment will automatically add the view to the container, and attachToRoot will repeatedly add an error if it is true. onCreateView is not necessarily called, it will not be called when adding a Fragment without an interface, such as calling the add(Fragment fragment, String tag) method of FragmentTransaction.
  • onActivityCreated: It will be called when the Activity's onCreated is executed.
  • onStart(): Called when the Fragment is visible to the user, provided that the Activity has been started.
  • onResume(): It will be called when the Fragment and the user can interact before, provided that the Activity has resumed.
  • onPause(): It will be called when the Fragment and the user cannot interact with each other before.
  • onStop(): Called when the Fragment is not visible.
  • onDestroyView(): Called when the Fragment-related view hierarchy is removed.
  • onDestroy(): It will be called when the Fragment state is finally cleared.
  • onDetach(): Called when Fragment and Activity are disassociated.

7. The impact of ViewPager on Fragment life cycle

ViewPager+Fragment is a relatively common combination, generally used with ViewPager's FragmentPagerAdapter or FragmentStatePagerAdapter. However, ViewPager has a caching mechanism in order to prevent sliding from freezing. By default, ViewPager will create and cache pages (such as Fragments) on the left and right sides of the current page. At this time, the left and right Fragments will execute the life cycle from onAttach->….->onResume. Obviously the Fragment has not been displayed but has reached onResume. In some cases, problems will occur. For example, the timing of loading data, judging whether the Fragment is visible, etc.

last share

[Tencent technical team produced] Android zero-based entry to proficiency, Android Studio installation tutorial + a full set of Android basic tutorials

Android programming tutorial

Java language basics from entry to familiarity

insert image description here

Kotlin language basics from entry to familiarity

insert image description here

Android technology stack from entry to familiarity

insert image description here

Android Jetpack family bucket comprehensive learning

insert image description here

For novices, it may be difficult to install Android Studio. You can watch the following video and learn to install and run step by step.

Android Studio installation tutorial

insert image description here

With the learning of the Java stage, it is recommended to focus on video learning at this stage and supplement it with books to check for omissions. If you focus on books, you can type codes based on book explanations, supplemented by teaching videos to check for omissions. If you encounter problems, you can go to Baidu. Generally, many people will encounter problems when getting started, and they will give better answers.

It is necessary to master basic knowledge points, such as how to use the four major components, how to create a Service, how to layout, simple custom View, animation, network communication and other common technologies.

A full set of zero-based tutorials has been prepared for you, if you need it, you can add the QR code below to get it for free

A full set of Android basic tutorials

insert image description here

insert image description here

insert image description here

insert image description here
insert image description here
insert image description here
insert image description here

Guess you like

Origin blog.csdn.net/Android23333/article/details/132467377