Xem mẫu
- Bài giảng Lập Trình Di Động - Android
Chương 4. FRAGMENT VÀ GIAO DIỆN NÂNG CAO
Trong chương này, chúng ta sẽ tìm hiểu về khái niệm phân mảnh giao diện, cách
sử dụng chúng để tạo những giao diện phức tạp và một số đối tượng điều kiển hộp
thoại và điều kiển hiển thị dạng danh sách.
4.1. Android Fragment
4.1.1. Fragment là gì?
Trong phần trước chúng ta đã tìm hiểu qua Activty cơ bản là giao diện của một
“màn hình” ứng dụng, mỗi màn hình là một Activity. Tuy nhiên khi các máy tính bảng
ra đời với màn hình lớn hơn rất nhiều so với điện thoại truyền thống, cho phép thiết kế
với nhiều loại view khác nhau, và phát sinh nhu cầu dùng lại các view này trên các
màn hình khác nhau (điện thoại và máy tính bảng). Khái niệm fragment được sinh ra
nhằm phục vụ nhu cầu đó.
Có thể hiểu fragment như các “tiểu Activity”, chứa tập hợp các view khác bên
trong nó. Fragment luôn luôn được chứa trong một Activity hoặc một fragment khác,
mỗi Activity có thể chứa một hoặc nhiều fragment . Một ví dụ điển hình của việc sử
dụng fragment là trường hợp thiết kế “master-detail”, bao gồm 2 view: view tổng
quan chứa danh sách các đối tượng (danh sách tiêu đề các bài báo chẳng hạn), và view
chi tiết, hiển thị nội dung của đối tượng (bài báo) đang được chọn. Mỗi view như vậy
được đặt trong 1 fragment. Trên màn hình điện thoại, do kích thước hạn chế, 2
fragment này sẽ nằm trong 2 activity khác nhau, trong khi đối với màn hình máy tính
bảng, 2 fragment này nằm trên cùng một Activity. Thiết kế này giúp việc dùng lại
code được tối đa, logic của ứng dụng nằm trong 2 fragment, được dùng lại cho cả điện
thoại và máy tính bảng, còn Activity chỉ là khung chứa tối thiểu mã nguồn.
ThS. Bùi Trung Úy 90
- Bài giảng Lập Trình Di Động - Android
Khái niệm fragment mới được đưa vào từ phiên bản Android 3.0 HoneyComb, tuy
nhiên tính năng này cũng được Google bổ sung cho các API thấp hơn (từ Level 4)
thông qua thư viện hỗ trợ Android Support Library v4.
Yếu tố chính trong việc sử dụng Fragment là nó có thể giúp chúng ta xây dựng các
giao diện một cách chủ động và linh hoạt để có thể thích ứng với các kiểu màn hình có
kích thước khác nhau từ điện thoại cho đến máy tính bảng, nói chính xác hơn là tối ưu
hóa giao diện cho từng loại thiết bị, kích thước và độ phân giải khác nhau.
Mỗi Fragment là một module độc lập có ràng buộc chặt chẽ vào Activity mà nó
gắn vào. Fragment có thể được tái sử dụng trong nhiều Activity, và trong một activity
có thể được gắn vào nhiều Fragment.
Dưới đây là một số ưu điểm nổi bật mà Fragment mang lại:
Module hóa (modularity): Với các Activity phức tạp thì code sẽ được implement ở
các Fragment. Mỗi Fragment là một module độc lập. Điều này sẽ làm cho code dễ tổ
chức và bảo trì tốt hơn.
Tái sử dụng (reusability): Viết code implement các tương tác với người dùng hoặc
các phần UI vào fragment để có thể chia sẻ chúng với các Activity khác.
Hỗ trợ đa màn hình: Fragment cung cấp cách thức để trình bày giao diện người
dùng (UI) phù hợp và tối ưu cho các loại thiết bị Android có kích thước màn hình và
mật độ điểm ảnh khác nhau.
4.1.2. Sử dụng Fragment
* Tạo mới Fragment
Để tạo một fragment mới, bạn tạo lớp và thừa kế từ lớp Fragment. Thiết lập giao
diện và implement các chức năng đóng gói của nó.
ThS. Bùi Trung Úy 91
- Bài giảng Lập Trình Di Động - Android
Để thiết lập giao diện cho fragment, bạn ghi đè phương thức onCreateView() và
thực hiện gắn UI cho fragment, phương thức này được hệ thống Android gọi khi đến
khi fragment vẽ layout của nó.
public class DetailsFragment 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.details_fragment, container, false);
return view;
}
}
Không giống như Activity, fragment không cần phải khai báo trong Manifest bởi
vì Fragment chỉ tồn tại khi nhúng nó vào một Activity và vòng đời sống cũng phụ
thuộc Activity này.
* Gắn fragment vào Activity
Cách 1: Thực hiện tham chiếu Fragment từ giao diện XML của Activity
Để gắn fragment vào giao diện của Activity, ta sử dụng thẻ như sau:
Cách 2: Dùng mã nguồn Java
Mỗi Activity có một FragmentManager để quản lý các fragment bên trong nó.
FragmentManager cung cấp các phương thức sử dụng để truy cập vào fragment hiện
tại đã được gắn vào Activity:
FragmentManager fragManager = getFragmentManager();
Sử dụng FragmentTransaction để thêm fragment vào Activity:
FragmentTransaction fragTransaction = fragManager.beginTransaction();
fragTransaction.add(R.id.details_fragment, new DetailsFragment());
fragTransaction.commit();
Ngoài ra, FragmentTransaction cũng có các thao tác khác như thêm, xóa hay thay
thế fragment, các thao tác này được gọi là một giao dịch. Mỗi giao dịch có thể gồm
nhiều thao tác thực hiện tại cùng thời điểm.
FragmentTransaction fragTransaction = fragManager.beginTransaction();
Fragment fragment = fragManager.findFragmentById(R.id.list_fragment);
fragTransaction.remove(fragment);
fragTransaction.commit();
ThS. Bùi Trung Úy 92
- Bài giảng Lập Trình Di Động - Android
4.1.3. Vòng đời của Fragment
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.
onResume(): Khi fragment hiển thị và có thể tương tác
ThS. Bùi Trung Úy 93
- Bài giảng Lập Trình Di Động - Android
Các sự kiện khi bạn hoặc hệ thống destroy một 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 94
- Bài giảng Lập Trình Di Động - Android
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 95
- Bài giảng Lập Trình Di Động - Android
Thực hành với 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:
1. Tạo mới một Activity có tên là FragmentActvity.java
ThS. Bùi Trung Úy 96
- Bài giảng Lập Trình Di Động - Android
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:
ThS. Bùi Trung Úy 97
- Bài giảng Lập Trình Di Động - Android
Tương tự tạo file bottom_fragment.xml, có XML như sau:
- Bài giảng Lập Trình Di Động - Android
android:id="@+id/cityView"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:scaleType="fitCenter">
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;
public class BottomFragment extends Fragment {
ThS. Bùi Trung Úy 99
- Bài giảng Lập Trình Di Động - Android
@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ẻ 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:
- Bài giảng Lập Trình Di Động - Android
android:name="com.example.helloandroid.BottomFragment"
android:layout_width="match_parent"
android:layout_height="match_parent">
Sửa file AndroidManifest.xml cho FragmentActivity là activity chính như sau:
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 101
- Bài giảng Lập Trình Di Động - Android
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 102
- Bài giảng Lập Trình Di Động - Android
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 103
- Bài giảng Lập Trình Di Động - Android
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);
}
}
Chạy ứng dụng, thực hiện chọn city và nhấn nút „Apply‟ ta có kết quả:
ThS. Bùi Trung Úy 104
- Bài giảng Lập Trình Di Động - Android
4.2. Trình đơn (menu) và hộp thoại (dialog)
4.2.1. Sử dụng trình đơn (menu)
Trình đơn dùng để hiển thị các hành động thường ít dùng hơn và không hiển thị
trực tiếp lên màn hình. Trong Android có 2 loại trình đơn:
- Trình đơn chính (options menu) – hiển thị các hành động liên quan đến toàn bộ
Activity hiện tại. Trong Android, để kích hoạt trình đơn này, ta bấm phím Menu của
thiết bị (phím cứng hoặc phím ảo trên màn hình)
- Trình đơn ngữ cảnh (context menu) – hiển thị các hành động liên quan đến một
view cụ thể trên màn hình, trình đơn này được kích hoạt bằng cách bấm và giữ (long
tap) trên view để kích hoạt trình đơn ngữ cảnh.
Về mặt lập trình, 2 loại menu này sử dụng cùng một lớp (android.view.Menu) và
chứa các đối tượng giống nhau (android.view.MenuItem), vì vậy ta tạo sẵn 2 phương
thức để dùng chung cho 2 loại menu này. Để tạo menu với các item bên trong và xử lý
sự kiện bấm vào từng item như dưới đây:
Hàm createMenu() dùng để thêm 7 items vào menu có sẵn:
private void createMenu(Menu menu)
{
menu.setQwertyMode(true);
MenuItem mnu1 = menu.add(0, 0, 0, "Item 1");
mnu1.setAlphabeticShortcut('a');
MenuItem mnu2 = menu.add(0, 1, 1, "Item 2");
mnu2.setAlphabeticShortcut('b');
MenuItem mnu3 = menu.add(0, 2, 2, "Item 3");
mnu3.setAlphabeticShortcut('c');
mnu3.setIcon(R.mipmap.ic_launcher);
menu.add(0, 3, 3, "Item 4");
menu.add(0, 4, 4, "Item 5");
menu.add(0, 5, 5, "Item 6");
menu.add(0, 6, 6, "Item 7");
}
Hàm menuChoice để xử lý sự kiện tương ứng với menu item được lựa chọn
(truyền vào dạng tham số). Với mục đích minh họa, khi một menu item được chọn, ta
chỉ đơn gian hiển thị tên của item đó dưới dạng Toast.
private boolean menuChoice(MenuItem item) {
switch (item.getItemId()) {
case 0:
Toast.makeText(this, "You choose on Item 1", Toast.LENGTH_LONG).show();
default:
Toast.makeText(this, "You click Item id = " + item.getItemId(), Toast.LENGTH_LONG).show();
return true;
}
}
ThS. Bùi Trung Úy 105
- Bài giảng Lập Trình Di Động - Android
Trình đơn chính (options menu)
Để hiển thị trình đơn chính, ta nạp chồng hàm onCreateOptionMenu() của Activity
và thêm các menu item vào đối tượng menu (trong tham số của hàm):
@Override
public boolean onCreateOptionsMenu(Menu menu) {
super.onCreateOptionsMenu(menu);
// Tạo menu
createMenu(menu);
return true;
}
Để hiển thị menu này lúc chạy ứng dụng, ta bấm phím MENU của thiết bị hoặc nút
More (3 chấm đứng) trên Actionbar.
Để xử lý sự kiện khi chọn một item trong menu, ta cần nạp chồng hàm:
@Override
public boolean onOptionsItemSelected(MenuItem item)
{
return menuChoice(item);
}
Trình đơn ngữ cảnh (context menu)
Để hiển thị trình đơn ngữ cảnh, ta nạp chồng hàm onCreateContextMenu() và
thêm các menu item vào đối tượng menu (trong tham số của hàm):
@Override
public void onCreateContextMenu(ContextMenu menu, View view, ContextMenuInfo menuInfo)
{
super.onCreateContextMenu(menu, view, menuInfo);
createMenu(menu);
}
Để xử lý sự kiện chọn một item trong menu, ta cần nạp chồng hàm sau:
ThS. Bùi Trung Úy 106
- Bài giảng Lập Trình Di Động - Android
@Override
public boolean onContextItemSelected (MenuItem item)
{
return menuChoice(item);
}
Để gắn menu ngữ cảnh này cho một đối tượng (chẳng hạn, nút bấm button), ta
thêm code sau vào hàm onCreate của activity:
Button btn = (Button) findViewById(R.id.button1);
btn.setOnCreateContextMenuListener(this);
Để hiển thị menu này lúc chạy ứng dụng, ta nhấn và giữ lên trên đối tượng, trình
đơn hiện ra như hình bên dưới:
4.2.2. Sử dụng hộp thoại (dialog)
Trong rất nhiều trường hợp chúng ta cần hiển thị thông báo, hỏi xác nhận của
người dùng, hiển thị trạng thái chờ… ở dạng hộp thoại nhanh hiện lên trên Activity
hiện tại, mà không cần mở ra Activity mới, khi đó ta cần nạp chồng hàm
onCreateDialog() của Activity.
Ví dụ dưới đây mô tả cách tạo một hộp thoại cơ bản như vậy:
CharSequence[] items = { "Google", "Apple", "Microsoft" };
boolean[] itemsChecked = new boolean [items.length];
@Override
protected Dialog onCreateDialog(int id) {
switch (id) {
case 0:
return new AlertDialog.Builder(this)
.setIcon(R.mipmap.ic_launcher)
.setTitle("This is a dialog")
.setPositiveButton("OK",
new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int whichButton) {
ThS. Bùi Trung Úy 107
- Bài giảng Lập Trình Di Động - Android
Toast.makeText(getBaseContext(), "OK clicked!",
Toast.LENGTH_SHORT).show();
}
})
.setNegativeButton("Cancel",
new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int whichButton) {
Toast.makeText(getBaseContext(), "Cancel clicked!",
Toast.LENGTH_SHORT).show();
}
})
.setMultiChoiceItems(items, itemsChecked,
new DialogInterface.OnMultiChoiceClickListener() {
public void onClick(DialogInterface dialog, int
which, boolean isChecked) {
Toast.makeText(getBaseContext(), items[which] +
(isChecked ? " checked!":" unchecked!"), Toast.LENGTH_SHORT).show();
}
}).create();
}
return null;
}
Để hiển thị dialog ta viết sự kiện cho một nút bấm và gọi hàm showDialog(id). Kết
quả chạy ứng dụng và bấm vào nút, hộp thoại như hình bên dưới sẽ hiện ra:
Trong ví dụ trên ta đã nạp chồng phương thức onCreateDialog(int id) để hiển thị
hộp thoại khi có yêu cầu. Trong Activity có thể hiển thị nhiều hộp thoại khác nhau tùy
vào ngữ cảnh xử lý như hộp thoại thông báo, hộp thoại xác nhận, hộp thoại tiến
trình…, tham số id trong phương thức onCreateDialog là để phân biệt hộp thoại nào
cần được hiện lên.
Để kích hoạt yêu cầu mở hộp thoại, ta gọi phương thức showDialog(id). Trong
hàm onCreateDialog, tùy thuộc vào id truyền vào mà ta hiển thị hộp thoại tương ứng,
trong ví dụ trên là hộp thoại có id = 0. Trong trường hợp này ta sử dụng loại hộp thoại
đơn giản nhất là AlertDialog, để tạo ra một hộp thoại loại này, ta tạo ra một object của
class AlertDialog.Builder và gọi phương thức create() của nó. Đoạn code trên thiết lập
ThS. Bùi Trung Úy 108
- Bài giảng Lập Trình Di Động - Android
2 nút bấm cho hộp thoại cho trường hợp đồng ý (nút “OK” – setPositiveButton) và
hủy bỏ (nút “Cancel” – setNegativeButton), cũng như thiết lập các ô checkbox
(setMultiChoiceItems)
Các hàm xử lý sự kiện trong Dialog trong ví dụ chỉ đơn giản là hiển thị lên màn
hình dòng thông báo dạng text trong một khoảng thời gian ngắn. Dạng thông báo này
trong Android gọi là Toast - là đoạn chữ hiển thị ở giữa, phía dưới màn hình trong
khoảng vài giây. Toast thường được dùng để hiển thị các loại thông báo ngắn, ít quan
trọng như thông báo SMS, lưu dữ liệu thành công,…
4.3. Các điều khiển hiển thị dạng danh sách
4.3.1. Sử dụng ListView
ListView là một view group, hiển thị các thành phần (elements) theo một danh
sách, có thể cuộn được theo chiều thẳng đứng. ListView là một view quan trọng, nó
được sử dụng rộng rãi trong các ứng dụng Android.
Một ví dụ đơn giản của ListView là danh bạ liên lạc, nơi bạn có một danh sách các
số điện thoại liên lạc hiển thị trong một ListView.
Các bước để tạo và sử dụng
* Bước 1: Khai báo ListView trong giao diện
Tương tự như các view khác, có thể dùng kéo-thả hoặc viết trong XML:
* Bước 2: Xác định cách hiển thỉ các phần tử (List-item)
Một ListView được tạo từ một danh sách các list-item. List-item là một dòng (row)
riêng lẻ trong listview nơi mà dữ liệu sẽ được hiển thị. Bất kỳ dữ liệu nào trong
listview chỉ được hiển thị thông qua list-item.
* Bước 3: Xây dựng nguồn cấp dữ liệu (Adapter)
Sau khi có một adapter cần thiết lập cho ListView, trong onCreate của Activity, ta
gán Adapter này cho listView như sau:
ThS. Bùi Trung Úy 109
nguon tai.lieu . vn