Overview and use of fragments

  • Small knowledge, big challenge! This article is participating in the creation activity of “Essential Tips for Programmers”.

Since version 3.0, Android has introduced the concept of fragmentation to make interfaces better displayed on tablets, enabling more dynamic and flexible UI designs.

What is a fragment

Fragments are UI fragments that can be embedded in an activity to allow applications to take advantage of the larger screen space

Fragment represents a reusable part of an application interface. Fragments define and manage their own layout, have their own life cycle, and can handle their own input events. A Fragment cannot exist on its own, but must be hosted by an Activity or another Fragment. The Fragment view hierarchy becomes part of, or is attached to, the host view hierarchy.

Fragment life cycle

Like activities, fragments have their own life cycle, and it is very similar to the life cycle of activities.

The Fragment lifecycle:

  1. onAttach()

    OnAttach () is called after the Fragment is associated with the Activity. Note that the fragment initialization parameters are available from getArguments(), but you can’t call setArguments() again when the fragment is attached to the Activity. So you can’t add to initialization parameters at any time except at the beginning.

  2. onCreate()

    Called when fragment is first created. Although it looks like the OnCreate() function of the Activity, this is just used to create the Fragment. The Activity has not yet been created because our Fragment is part of the Activity creation. So if you retrieve the current fragment control, it will not be retrieved. If you want to get the resource associated with your Activity, you must get it in onActivityCreated.

  3. onCreateView()

    Called when the Fragment view is created and loaded

        @Nullable
        @Override
        public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
            // The first parameter is the layout file
            // The second argument is ViewGroup root, indicating the parent window. If null is returned, indicating that there is no parent window, the Fragment cannot be displayed
            // The third parameter, attchToRoot, if true, indicates that the root of the XML Fragment is the root of the Activity, and the other components of the Acrtivity are not displayed.
            View view = inflater.inflate(R.layout.fragment1, container, false);
            return view;
        }
    Copy the code

View creation is accomplished by binding the XML file with the Inflate () method of the LayoutInflater

Note: This method is called the first time the Fragment’s UI is drawn. This method returns a View, or null if the Fragment does not provide a UI. If you inherit from a ListFragment, the default implementation of onCreateView() returns a ListView, so you don’t need to implement it yourself.

  1. onActivityCreated()

This method is called after the Activity’s onCreate () method ends. Only the Activity has been created.

Note: OnActivityCreated (), because this method is called after the onCreate method in the Activity has been executed, the Activity’s onCreate might not have been executed before onActivityCreated() was called, So instead of doing activity-related UI operations in onCreateView(), you should do activity-related UI operations in onActivityCreated(), whereas onCreateView only does UI display operations.

  1. onStart()

    Callback when the Fragment is started, the Fragment is visible

  2. onResume()

    The time the Fragment becomes active and gets focus is a callback, when the Fragment is fully in the foreground and can interact with the user

  3. onPause()

Called when Fragemnt becomes inactive and loses focus. Note that the Fragment is still visible, but not interacting with the user

  1. onStop()

Called when Fragment becomes invisible. At this point the Fragment is still alive, but it may not be added to the Fragment’s rollback stack

  1. onDestroyView()

Called when the layout in the Fragment is removed

  1. onDestroy()

Called when the Fragment is destroyed

  1. onDetach()

Called when the Fragment and Activity are disassociated

Use of fragments

1. Add fragments statically

  1. Create two Fragment classes, Fragment1 and Fragment2

You can create a Fragment in this way, or you can manually create a Fragment class, inherit the Fragment class, and override the required methods to create the corresponding layout.

  1. The first Fragment1 class, I created manually
public class Fragment1 extends Fragment {

    @Override
    public void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
    }

    @Nullable
    @Override
    public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
        // The first parameter is the layout file
        // The second argument is ViewGroup root, indicating the parent window. If null is returned, indicating that there is no parent window, the Fragment cannot be displayed
        // The third parameter, attchToRoot, if true, indicates that the root of the XML Fragment is the root of the Activity, and the other components of the Acrtivity are not displayed.
        View view = inflater.inflate(R.layout.fragment_1, container, false);
        return view;
    }


    @Override
    public void onPause(a) {
        super.onPause(); }}Copy the code

Corresponds to the fragment_1.xml layout file


      
<LinearLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent">

    <TextView
        android:layout_gravity="center"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:text="I'm the first fragment." />

</LinearLayout>
Copy the code
  1. The first Fragment2 class is created automatically
public class Fragment2 extends Fragment {

    // TODO: Rename parameter arguments, choose names that match
    // the fragment initialization parameters, e.g. ARG_ITEM_NUMBER
    private static final String ARG_PARAM1 = "param1";
    private static final String ARG_PARAM2 = "param2";

    // TODO: Rename and change types of parameters
    private String mParam1;
    private String mParam2;

    public Fragment2(a) {
        // Required empty public constructor
    }

    /**
     * Use this factory method to create a new instance of
     * this fragment using the provided parameters.
     *
     * @param param1 Parameter 1.
     * @param param2 Parameter 2.
     * @return A new instance of fragment Fragment2.
     */
    // TODO: Rename and change types and number of parameters
    public static Fragment2 newInstance(String param1, String param2) {
        Fragment2 fragment = new Fragment2();
        Bundle args = new Bundle();
        args.putString(ARG_PARAM1, param1);
        args.putString(ARG_PARAM2, param2);
        fragment.setArguments(args);
        return fragment;
    }

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        if(getArguments() ! =null) { mParam1 = getArguments().getString(ARG_PARAM1); mParam2 = getArguments().getString(ARG_PARAM2); }}@Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
        // Inflate the layout for this fragment
        return inflater.inflate(R.layout.fragment_2, container, false); }}Copy the code

Corresponds to the fragment_2.xml layout file


      
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".Fragment2"
    android:background="#ffff00">

    <! --TODO: Update blank fragment layout -->
    <TextView
        android:layout_gravity="center"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:text="I am the second fragment." />

</FrameLayout>
Copy the code
  1. Write the activity_main.xml layout file

      
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".MainActivity">


<fragment
    android:id="@+id/fragment1"
    android:layout_width="0dp"
    android:layout_height="match_parent"
    android:layout_weight="1"
    android:name="com.mq.fragmentdemo.Fragment1"/>
    <fragment
        android:id="@+id/fragment2"
        android:layout_width="0dp"
        android:layout_height="match_parent"
        android:layout_weight="1"
        android:name="com.mq.fragmentdemo.Fragment2"/>

</LinearLayout>
Copy the code

Operation effect:

The Android: Name attribute in the Fragment specifies the fragment class to instantiate the Activity Layout. You can also use the class attribute to do the same. When the system creates an Activity Layout, it instantiates each fragment class in the Layout and calls the onCreateView() method in the Fragment, Return and get the root layout view of the fragment, and then insert the root layout view into the fragment. Note that each fragment needs a unique identifier that can be used to restore the fragment object state when the Activity restarts. Android currently provides three ways to provide a unique identifier for a fragment: 1. 2. Provide a unique character for Android :tag; 3. If neither of the preceding two methods is provided, the system uses the ID of the fragment container by default.

2. Dynamically add fragments

Dynamic addition, as the name implies, is the dynamic addition of fragments to the program at run time according to different conditions

FragmentTransaction and FragmentManager analysis are introduced before Fragment dynamics.

1, FragmentManager

FragmentManager is the Fragment manager. It is used to manage the fragments in an Activity, such as obtaining Fragmen transactions and executing unstack rollback.

Commonly used method

The method name role
beginTransaction() Gets the FragmentTransaction object
findFragmentById( int id) Obtain the corresponding Fragment based on the ID
findFragmentByTag(String tag) Obtain the corresponding Fragment based on the tag
2, FragmentTransaction

FragmentTransaction is a Fragment transaction class that performs Fragment operations on activities, such as add, remove, replace, hide, and show.

The transaction is finally committed via commit.

Project Structure:

  1. Create four fragments: Message_Fragment, Directories_Fragment, Find_Fragment, Me_Fragment, and the corresponding layout

There is a Message_Fragment and the layout shown here, and the rest are the same. Just change the layout to suit your needs. I’m going to show you a picture here

public class Message_Fragment extends Fragment {

    @Nullable
    @Override
    public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
        // The first parameter is the layout file
        // The second argument is ViewGroup root, indicating the parent window. If null is returned, indicating that there is no parent window, the Fragment cannot be displayed
        // The third parameter, attchToRoot, if true, indicates that the root of the XML Fragment is the root of the Activity, and the other components of the Acrtivity are not displayed.
        View view = inflater.inflate(R.layout.message_fragment, container, false);
        return view;
    }
Copy the code

Message_fragment. XML Layout file


      
<FrameLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent">

<TextView
        android:textColor="#ff0033"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="My first fragment"
        android:layout_gravity="center_horizontal"/>
    <ImageView
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:src="@drawable/touxiang"/>

</FrameLayout>
Copy the code
  1. Write the activity_main.xml layout file for the main activity

      
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".MainActivity"
    android:orientation="vertical">


<FrameLayout
    android:id="@+id/fl_content"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:layout_above="@+id/ll_imv"
    android:name="com.mq.fragmentdemo.Message_Fragment"/>

    <LinearLayout
        android:id="@+id/ll_imv"
        android:layout_width="match_parent"
        android:layout_height="100dp"
        android:layout_alignParentBottom="true"
        android:orientation="horizontal">

        <ImageView
            android:id="@+id/image1"
            android:layout_width="0dp"
            android:layout_weight="1"
            android:layout_height="match_parent"
            android:padding="30dp"
            android:src="@drawable/msg"/>
        <ImageView
            android:id="@+id/image2"
            android:layout_width="0dp"
            android:layout_weight="1"
            android:layout_height="match_parent"
            android:padding="20dp"
            android:src="@drawable/directories"/>
        <ImageView
            android:id="@+id/image3"
            android:layout_width="0dp"
            android:layout_weight="1"
            android:layout_height="match_parent"
            android:padding="30dp"
            android:src="@drawable/find"/>
        <ImageView
            android:id="@+id/image4"
            android:layout_width="0dp"
            android:layout_weight="1"
            android:layout_height="match_parent"
            android:padding="20dp"
            android:src="@drawable/me"/>
    </LinearLayout>

</RelativeLayout>
Copy the code

Write MainActivity code with comments in the code

public class MainActivity extends AppCompatActivity {

    private ImageView imageView1,imageView2,imageView3,imageView4;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        imageView1 = (ImageView) findViewById(R.id.image1);// Get the first navigation image of the layout file
        imageView2 = (ImageView) findViewById(R.id.image2);// Get the second navigation image of the layout file
        imageView3 = (ImageView) findViewById(R.id.image3);// Get the third navigation image of the layout file
        imageView4 = (ImageView) findViewById(R.id.image4);// Get the fourth navigation image of the layout file
        imageView1.setOnClickListener(mClickListener);// Add a standalone event for the first navigation image
        imageView2.setOnClickListener(mClickListener);// Add a standalone event for the second navigation image
        imageView3.setOnClickListener(mClickListener);// Add a standalone event for the third navigation image
        imageView4.setOnClickListener(mClickListener);// Add a standalone event for the fourth navigation image

        FragmentManager fm=getSupportFragmentManager();// Get the Fragment manager
        FragmentTransaction transaction = fm.beginTransaction();// Start a transaction
        transaction.add(R.id.fl_content,new Message_Fragment()).commit();// Set the initial fragment
    }

    // Create a standalone event listener
    View.OnClickListener mClickListener =new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            FragmentManager fm=getSupportFragmentManager();// Get the Fragment manager
            FragmentTransaction transaction = fm.beginTransaction();// Start a transaction
            Fragment fragment=null;
            switch (v.getId()) {    // Determine which image was clicked by getting the click id
                case R.id.image1:
                    fragment = new Message_Fragment(); // Create the first Fragment
                    break;
                case R.id.image2:
                    fragment = new Directories_Fragment();// Create second Fragment
                    break;
                case R.id.image3:
                    fragment = new Find_Fragment();// Create a third Fragment
                    break;
                case R.id.image4:
                    fragment = new Me_Fragment();// Create fourth Fragment
                    break;
                default:
                    break;
            }
            transaction.replace(R.id.fl_content, fragment); / / replace fragments
            transaction.commit(); // Commit the transaction}}; }Copy the code

Click the following four buttons to switch the corresponding fragment.

Here I put only one image for each fragment.

Here is a brief introduction to the Fragment life cycle and use. Complex use of nested fragments, Fragment+ViewPager, etc.

Come on, yard farmers! (ฅ ´ omega ` ฅ)