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:
-
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.
-
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.
-
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.
-
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.
-
onStart()
Callback when the Fragment is started, the Fragment is visible
-
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
-
onPause()
Called when Fragemnt becomes inactive and loses focus. Note that the Fragment is still visible, but not interacting with the user
-
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
-
onDestroyView()
Called when the layout in the Fragment is removed
-
onDestroy()
Called when the Fragment is destroyed
-
onDetach()
Called when the Fragment and Activity are disassociated
Use of fragments
1. Add fragments statically
- 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.
- 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
- 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
- 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:
- 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
- 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 ` ฅ)