Trang chủHướng dẫnVòng đời của Fragment trong Android – Hướng dẫn chi tiết cho lập trình viên
Android

Vòng đời của Fragment trong Android – Hướng dẫn chi tiết cho lập trình viên

CyStack blog 6 phút để đọc
CyStack blog23/09/2025
Locker Avatar

Chris Pham

Technical Writer

Locker logo social
Reading Time: 6 minutes

Hôm nay, chúng ta sẽ tìm hiểu về vòng đời của Fragment trong Android (Fragment lifecycle Android) và cách triển khai một class Activity (class đại diện cho một cửa sổ tương tác với người dùng) đơn giản chứa hai fragment trong một ứng dụng Android.

Vòng đời của Fragment trong Android

Fragment trong Android

Class Fragment trong Android được dùng để xây dựng các giao diện người dùng (UI) động. Fragment nên được sử dụng bên trong Activity. Ưu điểm lớn nhất của fragment là giúp đơn giản hóa việc tạo UI cho nhiều kích thước màn hình khác nhau. Một Activity có thể chứa không giới hạn số lượng fragment.

Một fragment trong Android không phải là subclass (class con) trực tiếp của View như hầu hết các thành phần UI khác. Thay vào đó, một fragment chứa một view bên trong nó. Chính view này sẽ được hiển thị trong activity chứa fragment đó.

Vì fragment không phải là một view, việc thêm nó vào activity sẽ hơi khác so với việc thêm một view (ví dụ như TextView). Fragment được thêm vào một ViewGroup bên trong activity, và view của fragment sẽ được hiển thị trong ViewGroup này.

Sơ đồ sau đây mô tả quá trình một fragment được thêm vào một activity:

Sơ đồ vòng đời của Fragment

Đầu tiên, activity lấy tham chiếu đến fragment. Sau đó, nó lấy tham chiếu đến ViewGroup nơi mà view của fragment sẽ được hiển thị. Tiếp theo, activity thêm fragment vào. Fragment sau đó sẽ tạo ra view của nó và trả về cho activity. Cuối cùng, view này được chèn vào ViewGroup cha, và fragment bắt đầu đi vào hoạt động.

Vòng đời của Fragment

Vòng đời của một fragment trong Android được minh họa trong hình dưới đây.

Sơ đồ vòng đời của Fragment

Đây là danh sách các phương thức trong vòng đời của fragment.

  1. onAttach() là phương thức này sẽ được gọi đầu tiên, ngay cả trước onCreate(), để cho chúng ta biết rằng fragment đã được gắn vào một activity. Phương thức này nhận tham số là Activity sẽ chứa fragment của bạn.
  2. onCreateView() là callback hệ thống gọi khi đến lúc fragment vẽ UI của nó lần đầu tiên. Để vẽ UI cho fragment, ta phải trả về một thành phần View từ phương thức này, đây chính là root (thành tử gốc) của layout của fragment. Ta có thể trả về null nếu fragment không cung cấp UI.
  3. onViewCreated() sẽ được gọi sau onCreateView(). Phương thức này đặc biệt hữu ích khi ta kế thừa lại việc triển khai onCreateView() nhưng cần cấu hình các view sau khi chúng được tạo (như với ListFragment khi cần thiết lập một adapter).
  4. onActivityCreated() sẽ được gọi sau onCreate()onCreateView() để báo hiệu rằng phương thức onCreate() của activity đã hoàn tất. Nếu có bất kỳ thứ gì cần được khởi tạo trong fragment mà phụ thuộc vào việc onCreate() của activity đã chạy xong, ta có thể dùng onActivityCreated() để thực hiện công việc khởi tạo đó.
  5. onStart() là Phương thức onStart() được gọi khi fragment bắt đầu được hiển thị với người dùng.
  6. onPause() được gọi bởi hệ thống để tạo dấu hiệu đầu tiên cho thấy người dùng đang rời khỏi fragment. Đây thường là nơi bạn nên lưu lại (commit) bất kỳ thay đổi nào cần được duy trì sau phiên làm việc hiện tại của người dùng.
  7. onStop() được gọi khi dừng fragment.
  8. onDestroyView() được gọi trước onDestroy(). Đây là phương thức đối ngược với onCreateView() (nơi ta thiết lập UI). Nếu có những thứ liên quan đến UI cần được dọn dẹp, chúng có thể được đặt trong onDestroyView().
  9. onDestroy() được gọi để thực hiện việc dọn dẹp cuối cùng trạng thái của fragment. Lưu ý nó không được đảm bảo sẽ luôn được gọi bởi Android.
  10. onDetach() được gọi sau onDestroy() để thông báo rằng fragment đã được tách khỏi activity chứa nó.

Các class Fragment

Fragment được thêm vào Android API từ phiên bản Honeycomb (API 11).

  1. android.app.Fragment: Class cơ sở cho mọi định nghĩa fragment.
  2. android.app.FragmentManager: Class để tương tác với các đối tượng fragment bên trong một activity.
  3. android.app.FragmentTransaction: Class để thực hiện một tập hợp các thao tác fragment một cách nguyên tử (atomic).

Khi sử dụng thư viện tương thích (compatibility package) do Google cung cấp, các class sau sẽ được dùng để triển khai:

  • android.support.v4.app.FragmentActivity: Class cơ sở cho tất cả các activity sử dụng các tính năng fragment (và loader) dựa trên thư viện tương thích.
  • android.support.v4.app.Fragment
  • android.support.v4.app.FragmentManager
  • android.support.v4.app.FragmentTransaction

Phương thức onCreateView()

Dưới đây là một ví dụ về fragment triển khai bằng onCreateView():

public class SampleFragment extends Fragment {

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup parentViewGroup,
                             Bundle savedInstanceState) {

        View rootView = inflater.inflate(R.layout.fragment_sample, parentViewGroup, false);
        return rootView;
    }
}

Phương thức onCreateView() nhận các tham số là LayoutInflater, ViewGroup, và Bundle. LayoutInflater là một component có thể tạo ra các thực thể của View dựa trên các file XML layout. Như bạn thấy trong ví dụ, nó thực hiện điều này bằng cách gọi inflater.inflate().

Phương thức inflate() nhận ba tham số: ID của một file XML layout (bên trong R.layout), một ViewGroup cha nơi View của fragment sẽ được chèn vào, và một giá trị boolean thứ ba cho biết liệu View của fragment được tạo từ file XML layout có nên được chèn vào ViewGroup cha hay không.

Trong trường hợp này, ta truyền giá trị falseView sẽ được gắn vào ViewGroup cha ở một nơi khác (bởi một đoạn code khác của Android chúng ta đã gọi). Khi bạn truyền false làm tham số cuối cùng cho inflate(), ViewGroup cha vẫn được sử dụng để tính toán layout cho View được tạo ra, vì vậy bạn không thể truyền null cho tham số ViewGroup cha.

Tham số ViewGroup của onCreateView() là ViewGroup cha nơi View của fragment sẽ được chèn vào. Đây là một ViewGroup bên trong activity sẽ chứa (host) fragment.

Tham số Bundle của onCreateView() là một đối tượng Bundle mà fragment có thể dùng để lưu trữ dữ liệu, tương tự như trong một Activity.

Ví dụ sử dụng Fragment trong Android

Đây là cấu trúc một ví dụ sử dụng fragment trong Android. Nó bao gồm một activity duy nhất chứa hai fragment là TextFragment và MenuFragment.

Cấu trúc ứng dụng ví dụ

Code của ví dụ

MainActivity chứa hai fragment là TextFragment và MenuFragment. Hãy bắt đầu bằng cách định nghĩa các fragment trong layout XML với file activity_main.xml.

<LinearLayout xmlns:android="<https://schemas.android.com/apk/res/android>"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="horizontal"
    android:weightSum="1.0">

    <fragment
        android:layout_height="match_parent"
        android:layout_width="match_parent"
        class="journaldev.com.fragments.fragments.MenuFragment"
        android:id="@+id/fragment"
        android:layout_weight="0.5"/>
    <fragment
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        class="journaldev.com.fragments.fragments.TextFragment"
        android:id="@+id/fragment2"
        android:layout_weight="0.5"/>
</LinearLayout>

Như ta thấy, các file class của fragment thuộc activity này được định nghĩa là class=“journaldev.com.fragments.fragments.TextFragment”. Các class fragment và layout của chúng được định nghĩa như trong các đoạn code dưới đây.

package journaldev.com.fragments.fragments;

import android.app.Fragment;
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.TextView;

import journaldev.com.fragments.R;
public class TextFragment extends Fragment {
    TextView text,vers;

    @Override

    public View onCreateView(LayoutInflater inflater,ViewGroup container, Bundle savedInstanceState) {

        View view = inflater.inflate(R.layout.text_fragment, container, false);
        text= (TextView) view.findViewById(R.id.AndroidOs);
        vers= (TextView)view.findViewById(R.id.Version);

        return view;

    }
    public void change(String txt, String txt1){
        text.setText(txt);
        vers.setText(txt1);

    }
}

text_fragment.xml

<?xml version="1.0" encoding="utf-8"?>

<LinearLayout xmlns:android="<https://schemas.android.com/apk/res/android>"
    android:orientation="vertical"
    android:layout_width="match_parent"
    android:gravity="center"
    android:background="#5ba4e5"
    android:layout_height="match_parent">

    <TextView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:textSize="40px"
        android:textColor="#ffffff"
        android:layout_gravity="center"
        android:id="@+id/AndroidOs"/>
    <TextView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_gravity="center"
        android:textColor="#ffffff"
        android:textSize="30px"
        android:id="@+id/Version"/>

</LinearLayout>

TextFragment bao gồm các TextView chứa tên và số hiệu phiên bản Android.

package journaldev.com.fragments.fragments;

import android.app.ListFragment;
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ArrayAdapter;
import android.widget.ListView;

import journaldev.com.fragments.R;
public class MenuFragment extends ListFragment {
    String[] AndroidOS = new String[] { "Cupcake","Donut","Eclair","Froyo","Gingerbread","Honeycomb","Ice Cream SandWich","Jelly Bean","KitKat" };
    String[] Version = new String[]{"1.5","1.6","2.0-2.1","2.2","2.3","3.0-3.2","4.0","4.1-4.3","4.4"};
    @Override

    public View onCreateView(LayoutInflater inflater,ViewGroup container, Bundle savedInstanceState) {
        View view =inflater.inflate(R.layout.list_fragment, container, false);
        ArrayAdapter<String> adapter = new ArrayAdapter<String>(getActivity(),
                android.R.layout.simple_list_item_1, AndroidOS);
        setListAdapter(adapter);

        return view;

    }
    @Override
    public void onListItemClick(ListView l, View v, int position, long id) {
        TextFragment txt = (TextFragment)getFragmentManager().findFragmentById(R.id.fragment2);
        txt.change(AndroidOS[position],"Version : "+Version[position]);
        getListView().setSelector(android.R.color.holo_blue_dark);
    }
}

list_fragment.xml

<?xml version="1.0" encoding="utf-8"?>

<LinearLayout xmlns:android="<https://schemas.android.com/apk/res/android>"
    android:orientation="vertical"
    android:layout_width="match_parent"
    android:layout_height="match_parent">
    <ListView
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:id="@android:id/list" />
</LinearLayout>

MenuFragment hiển thị một ListView. Ở đây, layout của ListView là layout mặc định simple_list_item_1, khác với layout tùy chỉnh mà chúng ta đã tạo cho ListView trong bài viết trước. MainActivity chỉ có gọi setContentView từ phương thức onCreate. Các fragment được gọi từ file XML.

Ngoài ra, chúng ta có thể thêm các fragment từ class activity bằng cách sử dụng FragmentManager như trong đoạn code dưới đây:

getFragmentManager()
                  .beginTransaction()
                  .add(R.id.fragmentParentViewGroup, new MyFragment())
                  .commit();

Ở đây, ID fragmentParentViewGroup thuộc về FrameLayout như bên dưới:

<FrameLayout xmlns:android="<https://schemas.android.com/apk/res/android>"
             xmlns:tools="<https://schemas.android.com/tools>"
             android:id="@+id/fragmentParentViewGroup"
             android:layout_width="match_parent"
             android:layout_height="match_parent"
             tools:context=".MyActivity"
             tools:ignore="MergeRootFrame" />

Bên dưới là ứng dụng cuối cùng. Bạn có thể thấy có hai fragment. Khi bạn chọn một mục trong fragment bên trái, dữ liệu tương ứng sẽ được hiển thị ở fragment bên phải.

Ứng dụng ví dụ

Bạn có thể tải xuống toàn bộ ví dụ mẫu ở trên từ liên kết này.

0 Bình luận

Đăng nhập để thảo luận

Chuyên mục Hướng dẫn

Tổng hợp các bài viết hướng dẫn, nghiên cứu và phân tích chi tiết về kỹ thuật, các xu hướng công nghệ mới nhất dành cho lập trình viên.

Đăng ký nhận bản tin của chúng tôi

Hãy trở thành người nhận được các nội dung hữu ích của CyStack sớm nhất

Xem chính sách của chúng tôi Chính sách bảo mật.

Đăng ký nhận Newsletter

Nhận các nội dung hữu ích mới nhất