Fragment
là một lớp trong Android cho phép thao tác với các View, Fragment
cũng có các phương thức khởi tạo, phục hồi, hủy… có thế nhận và xử lý sự kiện…v.v như một Activity,
nhìn chung thì chúng ta có thể coi Fragment
như một Activity
con vậy. Nhưng Fragment
không tồn tại một mình như Activity
mà một Fragment
phải được “gắn” với một Activity
nào đó, nếu Activity
bị hủy thì Fragment
cũng bị hủy, nếu Activity
được phục hồi thì Fragment
cũng được phục hồi.
Bản chất Fragment
cũng giống như một View
như Button, EditText
…v.v chỉ khác các View
ở chỗ là Fragment
lại được dùng để chứa các View
khác, có vòng đời của riêng nó và có thể xử lý sự kiện.
Nếu bạn đã từng lập trình GUI với Java Swing thì bạn có thể so sánh Fragment
giống như JPanel
vậy, còn Activity
là JFrame.
Thường thì chúng ta dùng Fragment
để phân chia công việc của Activity
ra cho dễ quản lý. Sử dụng Fragment
cho bạn những lợi thế sau:
- Có thể chia công việc của
Activity
cho cácFragment
để dễ dàng quản lý và sửa đổi code. - Có thể dùng một
Fragment
cho nhiềuActivity,
do đó khi tạo mộtActivity
chúng ta không cần phải thiết kế lại giao diện mà có thể dùng giao diện có sẵn từ cácFragment
đã tạo trước đó. - Có khả năng tùy biến giao diện ứng dụng một cách dễ dàng dựa theo nhiều kích thước màn hình khác nhau.
Vòng đời của một Fragment
Cũng giống như Activity,
một Fragment
cũng có các phương thức trạng thái của riêng nó.
- onAttach: phương thức này sẽ gắn
Fragment
vào mộtActivity
- onCreate: sau khi đã được gắn vào
Activity,
phương thứconCreate()
sẽ tạo một đối tượng mới thuộc lớpFragment.
- onCreateView: sau đó phương thức
onCreateView()
sẽ tạo giao diện choFragment
và gắn giao diện này vào giao diện chính củaActivity.
- onActivityCreated: phương thức này được gọi sau khi phương thức
onCreate()
củaActivity
đã chạy xong. - onStart: chỉ khi phương thức
onStart()
được gọi thìFragment
mới có thể thực hiện các tương tác với người dùng. - onResume: phương thức này được gọi sau khi phương thức
onResume()
củaActivity
được gọi. - onPause: phương thức này được gọi khi
Fragment
bị ẩn, hoặc khiActivity
đi vào trạng thái Paused. - onStop: phương thức này được gọi khi
Fragment
bị xóa hoặc bị thay thế bởiFragment
khác, hoặc khiActivity
gọi phương thứconStop().
- onDestroyView: sau khi gọi phương thức
onStop()
thì phương thứconDestroyView()
được gọi để xóa và gỡ giao diện ra khỏiActivity.
- onDestroy: phương thức này sẽ thực hiện các công việc dọn dẹp cuối cùng.
- onDetach: phương thức này sẽ gỡ
Fragment
ra khỏiActivity.
Nhìn chung thì vòng đời của một Fragment
cũng giống như của một Activity
nhưng có nhiều phương thức hơn.
Ví dụ
Chúng ta tạo một project như bình thường.
Trong file main.xml
chúng ta thiết kế như sau:
<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:orientation="vertical" android:layout_width="fill_parent" android:layout_height="fill_parent"> <Button android:id="@+id/button1" android:layout_width="fill_parent" android:layout_height="wrap_content" android:text="Fragment 1" android:onClick="selectFragment"/> <Button android:id="@+id/button2" android:layout_width="fill_parent" android:layout_height="wrap_content" android:text="Fragment 2" android:onClick="selectFragment" /> <fragment android:id="@+id/fragment_place" android:name="com.phocode.FragmentOne" android:layout_width="match_parent" android:layout_height="match_parent" /> </LinearLayout>
Giao diện chính của Activity
gồm 2 Button
và một thẻ fragment,
thẻ này mặc định sẽ dùng lớp FragmentOne
để tương tác với người dùng,
chúng ta sẽ viết lớp này ở dưới, thẻ fragment
này cũng có các thuộc tính width, height...
như các View
bình thường.
android:onClick="selectFragment"
Hai thẻ Button
sẽ có phương thức xử lý sự kiện onClick
là selectFragment().
Tiếp theo chúng ta định nghĩa 2 lớp Fragment,
các lớp Fragment
này cũng giống như các Activity
là sẽ có 1 file .java để xử lý sự kiện và một file .xml để thiết kế giao diện, tất nhiên nếu muốn bạn cũng có thể làm tất cả trong file .java luôn cũng được.
Chúng ta tạo 2 file .java như sau:
package com.phocode; import android.app.Fragment; import android.os.Build; import android.os.Bundle; import android.view.View; import android.view.ViewGroup; import android.view.LayoutInflater; public class FragmentOne extends Fragment { @Override public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { return inflater.inflate(R.layout.fragment_one, container, false); } }
package com.phocode; import android.app.Fragment; import android.os.Build; import android.os.Bundle; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; public class FragmentTwo extends Fragment { @Override public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { return inflater.inflate(R.layout.fragment_two, container, false); } }
Hai lớp này sẽ kế thừa từ lớp android.app.Fragment.
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { ... }
Đối với Activity
thì các công việc xây dựng giao diện được thực hiện trong phương thức onCreate(),
còn đối với Fragment
thì là phương thức onCreateView().
Phương thức này nhận vào một đối tượng LayoutInflater, ViewGroup
và một đối tượng Bundle.
return inflater.inflate(R.layout.fragment_two, container, false);
Phương thức LayoutInflater.inflate()
sẽ thiết kế giao diện cho lớp Fragment,
phương thức này nhận vào tên file layout, tham số thứ 2 là đối tượng chứa Fragment
này, trong ví dụ này là lớp LinearLayout,
tham số thứ 3 cho biết Fragment
có được gắn vào LinearLayout đó hay không, ở đây hai tham số sau cũng không quan trọng lắm vì trước sau gì chúng ta cũng gắn Fragment
vào LinearLayout.
Sau khi đã có 2 file .java của 2 Fragment
thì chúng ta tạo 2 file layout cho 2 Fragment
này như sau:
<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical" android:background="#00ffff"> <TextView android:id="@+id/textView1" android:layout_width="match_parent" android:layout_height="match_parent" android:layout_weight="1" android:text="Fragment number 1" android:textStyle="bold" /> </LinearLayout>
<?xml version="1.0" encoding="utf-8" ?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical" android:background="#ffff00"> <TextView android:id="@+id/textView2" android:layout_width="match_parent" android:layout_height="match_parent" android:text="Fragment number 2"/> </LinearLayout>
Các file layout này khá đơn giản, chỉ chứa một TextView.
android:background="#ffff00"
Thuộc tính android:background
sẽ quy định màu nền cho Fragment.
Cuối cùng là file MainActivity.java
package com.phocode; import android.app.Activity; import android.os.Bundle; import android.view.View; import android.app.Fragment; import android.app.FragmentManager; import android.app.FragmentTransaction; public class MainActivity extends Activity { /** Called when the activity is first created. */ @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main); } public void selectFragment(View view) { Fragment fr; if(view == findViewById(R.id.button2)) fr = new FragmentTwo(); else fr = new FragmentOne(); FragmentManager fm = getFragmentManager(); FragmentTransaction ft = fm.beginTransaction(); ft.replace(R.id.fragment_place, fr); ft.commit(); } }
Chúng ta định nghĩa phương thức selectFragment()
để xử lý sự kiện onClick()
của Button.
Fragment fr; if(view == findViewById(R.id.button2)) fr = new FragmentTwo(); else fr = new FragmentOne();
Ở đây chúng ta chỉ đơn giản là nếu ấn button Fragment
nào thì sẽ cho hiện ra file layout của Fragment
đó.
FragmentManager fm = getFragmentManager(); FragmentTransaction ft = fm.beginTransaction(); ft.replace(R.id.fragment_place, fr); ft.commit();
Để có thể thực hiện các thao tác với Fragment
thì chúng ta sử dụng đến lớp FragmentManager,
lớp này sẽ tạo một đối tượng FragmentTransaction,
đối tượng này cung cấp các phương thức để tạo, xóa, thay thế… các đối tượng Fragment.
Phương thức replace()
sẽ thay thế một Fragment
bằng Fragment
khác. Ngoài còn có một số phương thức khác như add()
có tác dụng gắn thêm một Fragment
mới vào giao diện.
Click vào nút Fragment 2 để hiển thị giao diện khác.