Android – Fragment


Được đăng vào ngày 12/05/2016 | 0 bình luận
Đánh giá bài viết

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 ActivityJFrame.

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ác Fragment để dễ dàng quản lý và sửa đổi code.
  • Có thể dùng một Fragment cho nhiều Activity, do đó khi tạo một Activity 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ác Fragment đã 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ó.

fragment_lifecycle

  • onAttach: phương thức này sẽ gắn Fragment vào một Activity
  • onCreate: sau khi đã được gắn vào Activity, phương thức onCreate() sẽ tạo một đối tượng mới thuộc lớp Fragment.
  • onCreateView: sau đó phương thức onCreateView() sẽ tạo giao diện cho Fragment và gắn giao diện này vào giao diện chính của Activity.
  • onActivityCreated: phương thức này được gọi sau khi phương thức onCreate() của Activity đã 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ủa Activity được gọi.
  • onPause: phương thức này được gọi khi Fragment bị ẩn, hoặc khi Activity đ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ởi Fragment khác, hoặc khi Activity gọi phương thức onStop().
  • onDestroyView: sau khi gọi phương thức onStop() thì phương thức onDestroyView() được gọi để xóa và gỡ giao diện ra khỏi Activity.
  • 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ỏi Activity.

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 onClickselectFragment().

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.

Capture

Click vào nút Fragment 2 để hiển thị giao diện khác.

Capture







Trả lời


Lưu ý: bọc code trong cặp thẻ [code language="x"][/code] để highlight code.


Ví dụ:


[code language="cpp"]


    std::cout << "Hello world";


[/code]



Các ngôn ngữ được hỗ trợ gồm: actionscript3, bash, clojure, coldfusion, cpp, csharp, css, delphi, diff, erlang, fsharp, go, groovy, html, java, javafx, javascript, latex, matlab, objc, perl, php, powershell, python, r, ruby, scala, sql, text, vb, xml.

Thư điện tử của bạn sẽ không được hiển thị công khai. Các trường bắt buộc được đánh dấu *