Vòng đời của Fragment

Một phần của tài liệu Bài giảng lập trình di động android (Trang 93 - 105)

Cũng giống như activity, vòng đời của một fragment xảy ra khi trạng thái của nó thay đổi. Một sự kiện trong vòng đời của Fragment xảy ra khi chúng ta có thể nhìn thấy fragment đang hoạt động, hoặc là khi fragment không sử dụng được hoặc bị destroy. Và cũng giống với Activity, bạn có thể override các hàm trong vòng đời fragment như: onCreate(), onAttach(), onCreateView()… để thực hiện những tác vụ mong muốn

Dưới đây là sơ đồ minh họa về vòng đời của Fragment

Giải thích sơ đồ:

Khi fragment được tạo và chạy, sẽ thực hiện theo thứ tự như sau:

onAttach(): Fragment được gắn vào activity. Mỗi Fragment muốn chạy được thì nó phải thuộc vào một activity nào đó.

onCreate(): Khi một fragment mới được khởi tạo (hàm này luôn được gọi sau khi fragment được attach vào Activity)

onCreateView(): Hàm này dùng để tạo giao diện cho fragment. onActivityCreated(): Khi activity của fragment đã khởi tạo xong.

onStart(): Khi fragment hiển thị. Một fragment chỉ start sau khi Activity start và thường là nó start ngay lập tức khi Activity start xong.

ThS. Bùi Trung Úy 94

Các s kin khi bn hoc h thng destroy mt fragment:

onPause(): Khi fragment không còn tương tác (có thể vẫn hiển thị). Điều này xảy ra ngay cả khi fragment bị gỡ bỏ hoặc bị thay thế, hoặc là khi activity của fragment bị tạm dừng.

onStop(): Khi fragment không còn hiển thị. Điều này xảy ra ngay sau khi fragment bị gỡ bỏ hoặc thay thế, hoặc là khi activity của fragment bị tạm dừng.

onDestroyView(): Khi các view hay resource được tạo trong onCreateView bị remove khỏi activity và destroy.

onDestroy(): Khi fragment kết thúc việc dọn dẹp. onDetach(): Khi fragment bị tách khỏi Activity của nó.

Bạn có thể thấy vòng đời của fragment được đan xen với vòng đời của activity. Tuy nhiên, vòng đời của Fragment có nhiều sự kiện trong vòng đời hơn so với Activity. Để hiểu rõ hơn vòng đời của một Frament, chúng ta có thể ghi đè các hàm sự kiện tương ứng và ghi ra log:

package com.example.helloandroid; import android.content.Context;

import android.support.v4.app.Fragment; import android.os.Bundle;

import android.util.Log;

public class DetailsFragment extends Fragment { @Override

public void onAttach(Context context) { super.onAttach(context);

Log.d("Fragment", "onAttach"); }

@Override

public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState);

Log.d("Fragment", "onCreate"); }

@Override

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

log.d("Fragment", "onCreateView"); return null;

}

@Override

public void onActivityCreated(Bundle savedInstanceState) { super.onActivityCreated(savedInstanceState);

Log.d("Fragment", "onActivityCreated"); }

@Override

public void onStart() { super.onStart();

ThS. Bùi Trung Úy 95 Log.d("Fragment", "onStart");

}

@Override

public void onResume() { super.onResume();

Log.d("Fragment", "onResume"); }

@Override

public void onPause() { super.onPause();

Log.d("Fragment", "onPause"); }

@Override

public void onStop() { super.onStop();

Log.d("Fragment", "onStop"); }

@Override

public void onDestroyView() { super.onDestroyView();

Log.d("Fragment", "onDestroyView"); }

@Override

public void onDestroy() { super.onDestroy();

Log.d("Fragment", "onDestroy"); }

@Override

public void onDetach() { super.onDetach();

Log.d("Fragment", "onDetach"); }

}

Chạy ứng dụng trên thiết bị Android, thực hiện các thao tác bấm phím Home, Back, mở ứng dụng khác… bạn sẽ thấy hiển thị log về các sự kiện xảy ra trong vòng đời của các Fragment:

11-03 23:24:29.398: D/Fragment (11354): onAttach 11-03 23:24:29.398: D/Fragment (11354): onCreate 11-03 23:24:29.398: D/Fragment (11354): onCreateView 11-03 23:24:29.398: D/Fragment (11354): onActivityCreated 11-03 23:24:29.398: D/Fragment (11354): onStart 11-03 23:24:29.398: D/Fragment (11354): onResume 11-03 23:24:33.835: D/Fragment (11354): onPause 11-03 23:24:33.835: D/Fragment (11354): onStop 11-03 23:24:33.835: D/Fragment (11354): onDestroyView 11-03 23:24:33.835: D/Fragment (11354): onDestroy 11-03 23:24:33.835: D/Fragment (11354): onDetach

ThS. Bùi Trung Úy 96

Thc hành vi Fragment:

Tạo dự án với bố cục giao diện như sau (với các hình ảnh như ví dụtrước).

Các bước thực hiện:

ThS. Bùi Trung Úy 97

B2. Tiếp theo chúng ta tạo file top_fragment.xml:

Trên Android Studio chọn: „File/New/Layout resource file‟

Nhập thông tin như sau:

Thiết kế giao diện trên top_fragment.xml, có được xml 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:gravity="center_horizontal" > <TextView android:id="@+id/text1" android:layout_width="wrap_content" android:layout_height="wrap_content" android:textSize="20dp" android:textColor="#FF0000" android:layout_marginTop="10dp" android:layout_gravity="center"

android:text="Image of 4 cities in Vietnam" />

ThS. Bùi Trung Úy 98 <RadioGroup android:id="@+id/rdGpCities" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_marginTop="10dp" android:orientation="horizontal" > <RadioButton android:id="@+id/rdDalat" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="Dalat" /> <RadioButton android:id="@+id/rdDanang" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="Danang" /> <RadioButton android:id="@+id/rdHanoi" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="Hanoi" /> <RadioButton android:id="@+id/rdbSaigon" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="Saigon" /> </RadioGroup> <Button android:id="@+id/btApply" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="Apply" /> </LinearLayout>

Tương tự tạo file bottom_fragment.xml, có XML 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="match_parent" android:layout_height="match_parent"> <TextView android:id="@+id/textView" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_gravity="center" android:textSize="25dp" android:textColor="#0000FF" android:layout_marginTop="20dp" android:text=""/> <ImageView

ThS. Bùi Trung Úy 99 android:id="@+id/cityView" android:layout_width="fill_parent" android:layout_height="fill_parent" android:scaleType="fitCenter" /> </LinearLayout>

Mỗi Fragment sẽ tương ứng với một lớp trong Java. Lớp này mở rộng từ lớp Fragment. Tạo 2 lớp TopFragment.java và BottomFragment.java và sửa code của nó như sau. TopFragment.java package com.example.helloandroid; import android.support.v4.app.Fragment; import android.os.Bundle; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup;

public class TopFragment extends Fragment { @Override

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

// Đọc file xml tạo ra đối tượng View.

View view = inflater.inflate(R.layout.top_fragment, container, false); return view; } } BottomFragment.java package com.example.helloandroid; import android.support.v4.app.Fragment; import android.os.Bundle; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup;

ThS. Bùi Trung Úy 100 @Override

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

// Đọc file xml tạo ra đối tượng View.

View view= inflater.inflate(R.layout.bottom_fragment, container, false); return view;

} }

Và bây giờ, bạn cần bố trí các fragment trên giao diện chính của FragmentActivity. Mở file activity_fragment.xml, kéo thẻ <fragment> vào giao diện và chọn TopFragment.java

Tương tự với BottomFragment.java, ta có nội dung file activity_fragment.xml:

<?xml version="1.0" encoding="utf-8"?> <LinearLayout 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" android:orientation="vertical"> <fragment android:id="@+id/fragTop" android:name="com.example.helloandroid.TopFragment" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_gravity="center" /> <fragment android:id="@+id/fragBottom"

ThS. Bùi Trung Úy 101 android:name="com.example.helloandroid.BottomFragment"

android:layout_width="match_parent" android:layout_height="match_parent" /> </LinearLayout>

Sửa file AndroidManifest.xml cho FragmentActivity là activity chính như sau:

<?xml version="1.0" encoding="utf-8"?> <manifest xmlns:android="http://schemas.android.com/apk/res/android" package="com.example.helloandroid"> <application android:allowBackup="true" android:icon="@mipmap/ic_launcher" android:label="@string/app_name" android:roundIcon="@mipmap/ic_launcher_round" android:supportsRtl="true" android:theme="@style/AppTheme"> <activity android:name=".FragmentActivity"> <intent-filter> <action android:name="android.intent.action.MAIN" /> <category android:name="android.intent.category.LAUNCHER" /> </intent-filter> </activity> <activity android:name=".MainActivity" /> </application> </manifest> Chạy thửứng dụng, ta có kết quả:

Tiếp theo, bạn cần phải viết code cho 3 lớp FragmentActivity.java,

TopFragment.java, BottomFragment.java để xử lý các sự kiện.

TopFragment.java package com.example.helloandroid; import android.app.Activity; import android.content.Context; import android.support.v4.app.Fragment; import android.os.Bundle; import android.util.Log; import android.view.LayoutInflater; import android.view.View;

ThS. Bùi Trung Úy 102 import android.view.ViewGroup;

import android.widget.Button; import android.widget.RadioGroup; import android.widget.Toast;

public class TopFragment extends Fragment { private int imageCityId;

private String cityName = ""; private FragmentActivity mActivity; @Override

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

// Đọc file xml tạo ra đối tượng View.

View view = inflater.inflate(R.layout.top_fragment, container, false); // Đăng ký sự kiện khi RadioGroup Cities có thay đổi.

RadioGroup rdGpCities = (RadioGroup) view.findViewById(R.id.rdGpCities);

rdGpCities.setOnCheckedChangeListener(new RadioGroup.OnCheckedChangeListener() { @Override

public void onCheckedChanged(RadioGroup group, int checkedId) { doOnCitiesChanged(group, checkedId);

} });

Button applyButton = (Button) view.findViewById(R.id.btApply); applyButton.setOnClickListener(new View.OnClickListener() { @Override

public void onClick(View v) { applyChange(); } }); return view; }

// Phương thức này được gọi sau khi Fragment được gắn vào Activity. @Override

public void onAttach(Context context) { super.onAttach(context);

Log.d("Fragment", "onAttach");

if (context instanceof FragmentActivity) { this.mActivity = (FragmentActivity) context; }

}

// Khi radio group "Cities" có thay đổi.

private void doOnCitiesChanged(RadioGroup group, int checkedId) { int checkedRadioId = group.getCheckedRadioButtonId();

if(checkedRadioId== R.id.rdDalat) { imageCityId = R.drawable.dalat; cityName = "City: Dalat";

} else if(checkedRadioId== R.id.rdDanang ) { imageCityId = R.drawable.danang;

ThS. Bùi Trung Úy 103 cityName = "City: Danang";

} else if(checkedRadioId== R.id.rdHanoi) { imageCityId = R.drawable.hanoi; cityName = "City: Ha Noi";

} else if(checkedRadioId== R.id.rdbSaigon) { imageCityId = R.drawable.saigon; cityName = "City: Saigon"; }

Toast.makeText(mActivity, "You choose:" + cityName, Toast.LENGTH_SHORT).show(); }

private void applyChange() {

mActivity.showCityImage(cityName, imageCityId); } } BottomFragment.java package com.example.helloandroid; import android.support.v4.app.Fragment; import android.os.Bundle; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; import android.widget.ImageView; import android.widget.TextView;

public class BottomFragment extends Fragment { private TextView textView;

private ImageView cityView; @Override

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

// Đọc file xml tạo ra đối tượng View.

View view = inflater.inflate(R.layout.bottom_fragment, container, false); textView = (TextView) view.findViewById(R.id.textView);

cityView = (ImageView) view.findViewById(R.id.cityView); return view;

}

public void showCity(String cityName, int imageId) { textView.setText(cityName); cityView.setImageResource(imageId); } } FragmentActivity.java package com.example.helloandroid;

ThS. Bùi Trung Úy 104 import android.support.v4.app.FragmentManager;

import android.support.v7.app.AppCompatActivity; import android.os.Bundle;

public class FragmentActivity extends AppCompatActivity { @Override

protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState);

setContentView(R.layout.activity_fragment); }

public void showCityImage(String cityName, int imageId) {

FragmentManager fragManager = this.getSupportFragmentManager(); BottomFragment bottomFragment

= (BottomFragment)fragManager.findFragmentById(R.id.fragBottom); bottomFragment.showCity(cityName, imageId);

} }

ThS. Bùi Trung Úy 105

Một phần của tài liệu Bài giảng lập trình di động android (Trang 93 - 105)