Bài học này sẽ thảo luận cách tạo một phương thức triển khai phản ánh các API mới nhưng hỗ trợ các thiết bị cũ.
Quyết định một giải pháp thay thế
Nhiệm vụ khó khăn nhất trong việc sử dụng các tính năng giao diện người dùng mới hơn theo cách tương thích ngược là quyết định và triển khai một giải pháp (dự phòng) cũ hơn cho các phiên bản nền tảng cũ hơn. Trong nhiều trường hợp, bạn có thể thực hiện mục đích của các thành phần giao diện người dùng mới hơn bằng cách sử dụng các tính năng cũ của khung giao diện người dùng. Ví dụ:
-
Bạn có thể triển khai thanh thao tác bằng cách sử dụng
LinearLayout
ngang chứa các nút hình ảnh, dưới dạng thanh tiêu đề tuỳ chỉnh hoặc chế độ xem trong bố cục hoạt động. Bạn có thể thấy các hành động mục trong mục bổ sung bên dưới nút Trình đơn của thiết bị. -
Bạn có thể triển khai các thẻ trên thanh thao tác bằng cách sử dụng một
LinearLayout
ngang chứa các nút hoặc dùng thành phầnTabWidget
trên giao diện người dùng. -
Bạn có thể triển khai tiện ích
NumberPicker
vàSwitch
bằng cách sử dụng tiện íchSpinner
vàToggleButton
tương ứng. -
Bạn có thể triển khai các tiện ích
ListPopupWindow
vàPopupMenu
bằng cách sử dụng tiện íchPopupWindow
.
Thường thì không có giải pháp nào đáp ứng mọi nhu cầu để điều chỉnh cho phiên bản cũ các thành phần giao diện người dùng mới hơn cho các thiết bị cũ. Lưu ý đến trải nghiệm người dùng: trên các thiết bị cũ, người dùng có thể chưa quen với các mẫu thiết kế và thành phần giao diện người dùng mới. Hãy suy nghĩ về cách phân phối cùng một chức năng bằng các thành phần quen thuộc. Trong nhiều trường hợp, bạn không cần quan tâm đến điều này – nếu các thành phần giao diện người dùng mới hơn nổi bật trong hệ sinh thái ứng dụng (chẳng hạn như thanh thao tác) hoặc khi mô hình tương tác cực kỳ đơn giản và trực quan (chẳng hạn như thành phần hiển thị vuốt sử dụng ViewPager
).
Triển khai các thẻ bằng API cũ
Để tạo cách triển khai cũ hơn cho các thẻ trên thanh thao tác, bạn có thể sử dụng TabWidget
và TabHost
(mặc dù bạn có thể sử dụng các tiện ích Button
được bố trí theo chiều ngang). Hãy triển khai việc này trong các lớp có tên là TabHelperEclair
và CompatTabEclair
, vì cách triển khai này sử dụng các API được ra mắt từ Android 2.0 (Eclair).
![Sơ đồ lớp để triển khai thẻ trong Eclair.](https://developer.android.com/static/images/training/backward-compatible-ui-classes-eclair.png?authuser=9&hl=vi)
Hình 1. Sơ đồ lớp để triển khai thẻ trong Eclair.
Phương thức triển khai CompatTabEclair
lưu trữ các thuộc tính thẻ (chẳng hạn như văn bản và biểu tượng thẻ) trong các biến thực thể, vì không có đối tượng ActionBar.Tab
nào để xử lý bộ nhớ này:
Kotlin
class CompatTabEclair internal constructor(val activity: FragmentActivity, tag: String) : CompatTab(tag) { // Store these properties in the instance, // as there is no ActionBar.Tab object. private var text: CharSequence? = null ... override fun setText(resId: Int): CompatTab { // Our older implementation simply stores this // information in the object instance. text = activity.resources.getText(resId) return this } ... // Do the same for other properties (icon, callback, etc.) }
Java
public class CompatTabEclair extends CompatTab { // Store these properties in the instance, // as there is no ActionBar.Tab object. private CharSequence text; ... public CompatTab setText(int resId) { // Our older implementation simply stores this // information in the object instance. text = activity.getResources().getText(resId); return this; } ... // Do the same for other properties (icon, callback, etc.) }
Việc triển khai TabHelperEclair
sử dụng các phương thức trên
Tiện ích TabHost
để tạo TabHost.TabSpec
đối tượng và chỉ báo thẻ:
Kotlin
class TabHelperEclair internal constructor(activity: FragmentActivity) : TabHelper(activity) { private var tabHost: TabHost? = null ... override fun setUp() { // Our activity layout for pre-Honeycomb devices // must contain a TabHost. tabHost = tabHost ?: mActivity.findViewById<TabHost>(android.R.id.tabhost).apply { setup() } } override fun addTab(tab: CompatTab) { ... tabHost?.newTabSpec(tab.tag)?.run { setIndicator(tab.getText()) // And optional icon ... tabHost?.addTab(this) } } // The other important method, newTab() is part of // the base implementation. }
Java
public class TabHelperEclair extends TabHelper { private TabHost tabHost; ... protected void setUp() { if (tabHost == null) { // Our activity layout for pre-Honeycomb devices // must contain a TabHost. tabHost = (TabHost) mActivity.findViewById( android.R.id.tabhost); tabHost.setup(); } } public void addTab(CompatTab tab) { ... TabSpec spec = tabHost .newTabSpec(tag) .setIndicator(tab.getText()); // And optional icon ... tabHost.addTab(spec); } // The other important method, newTab() is part of // the base implementation. }
Bạn hiện có hai cách triển khai CompatTab
và TabHelper
: một cách hoạt động trên thiết bị chạy Android 3.0 trở lên và sử dụng API mới, còn một cách hoạt động trên thiết bị chạy Android 2.0 trở lên và sử dụng API cũ. Bài học tiếp theo sẽ thảo luận về cách sử dụng các phương pháp triển khai này trong ứng dụng của bạn.