Fragment android – Xuan Loc Le

Fragment được sử dụng như một sub-activity. Các fragment không có file giao diện xml thường được gọi là headless fragments. Vòng đời của fragment bị ảnh hưởng trực tiếp bởi vòng đời của activity chứa nó.
Ví dụ, khi activity pause, tất cả fragment trong nó cũng pause,và khi activity destroyed, các fragment cũng vậy. Tuy nhiên, khi activity đang ở trạng thái resumed, ta có thể thêm hoặc xóa fragment. Các fragment transaction sẽ được lưu vào backstack.

Một Fragment có thể được sử dụng trong nhiều Activitiy, fragment được thêm vào từ API 11, fragment sử dụng phương thức getActivity() để lấy ra Activity chứa nó, fragment được định nghĩa trong file xml của activity (static definition) hoặc có thể sửa đổi fragment khi đang chạy (dynamic definition)

1. Fragment lifecycle

onAttach(1 time) được gọi đầu tiên

=> onCreate(1 time): nơi khởi tạo các thành phần của fragment dể dùng lại khi stop hoặc pause

=> onCreateView: nơi vẽ UI

=> onActivityCreated: Thông báo activity chứa fragment đã load xong

=> onStart: Người dùng bắt đầu nhìn thấy, chưa nhận tương tác

=> onResume: Người dùng nhìn thấy hoàn toàn và nhận tương tác

=> onPause: Callback này cho thấy rằng người dùng đang rời khỏi Fragment hiện tại.

=> onStop: Fragment chính thức không còn được thấy nữa

=> onDestroyView: đối tượng View sẽ bị hủy ở callback này. Các khởi tạo view ở onCreateView() sẽ nhanh chóng không còn nữa. Nếu như Fragment được đưa vào Back Stack, thì khi được lấy ra lại sau đó, callback onCreateView() sẽ được gọi lại

=> onDestroy://…

=> onDetact: Callback này gọi đến báo hiệu Fragment sẽ được gỡ khỏi Activity đang chứa nó. Kết thúc vòng đời của Fragment.

Chú ý: Khi dùng getContext() trong fragment, phải chắc chắn là fragment đó đang được attact vào activity. Nếu fragment đó không attact hoặc đã từng attact nhưng đã detact thì getContext sẽ trả về null

2. Fragment Manager

Để quản lý các fragment trong activity, ta cần sử dụng FragmentManager. Gọi getSupportFragmentManager() từ activity chứa nó để lấy.

Một số chức năng của fragment manager:
Lấy các fragment tồn tại trong activity bằng findFragmentById (fragment có layout) hoặc findFragmentByTag( fragment không có layout)

— Lấy fragment ra từ backstack bằng popBackStack (tương tự như nút back)

— Đăng ký sự kiện lắng nghe thay đổi của backstack

Chúng ta cũng có thể dùng FragmentManager để mở một FragmentTransaction — cái mà dùng thực hiện thêm hoặc xóa fragments.

3. Fragment Transactions

Như đã đề cập, một lợi ích khi sử dụng fragment trong activity là nó có khả năng thêm, xóa, thay thế và thực hiện các hành động khác với nó thông qua tương tác của user.

Mỗi khi thay đổi, fragment sẽ được commit vào activity bằng cách gọi một transaction thông qua FragmentTransaction. Ta cũng có thể lưu transaction vào backstack của activity nhằm để cho phép quay lại bằng sự kiện back.

Mỗi transaction sẽ bao gồm một tập hợp những sự thay đổi của fragment. Ta có thể thực hiện add, remove, replace. Sau đó, để apply transaction, ta phải commit. Trước khi commit, bạn có thể add vào backstack trạng thái hiện tại, sẽ giúp user có thể sử dụng nút back để trở lại.

Ví dụ: đây là cách ta thay thế một fragment bằng một fragment khác và duy trì trạng thái trước đó trong backstack:

// 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();

Tip: Đối với mỗi FragmentTransaction, ta có thể áp dụng animation bằng cách gọi setTransition() trước khi bạn commit.

Lưu ý: Bạn chỉ có thể commit transaction trước khi activity saving its state (khi user rời khỏi activity). Nếu bạn cố gắng commit sau thời điểm đó, một exception sẽ được throw. Điều này là do trạng thái sau khi commit có thể bị mất nếu activity cần được khôi phục. Đối với các trường hợp bị mất commit, hãy sử dụng commitAllowingStateLoss().