Bài học này thảo luận cách tạo quy trình triển khai phản ánh các API mới nhưng có hỗ trợ thiết bị cũ.
Quyết định 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 giải pháp cũ (dự phòng) 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 này bằng cách sử dụng các tính năng khung giao diện người dùng cũ. 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, có thể là thanh tiêu đề tuỳ chỉnh hoặc khung hiển thị trong bố cục hoạt động. Các thao tác bổ sung có thể hiển thị 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
LinearLayout
ngang chứa các nút hoặc dùng thành phần giao diện người dùngTabWidget
. -
Bạn có thể triển khai các tiện ích
NumberPicker
vàSwitch
bằng cách sử dụng các 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ác tiện íchPopupWindow
.
Thường thì không có giải pháp chung nào đáp ứng được mọi yêu 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 sang các thiết bị cũ. Hãy chú ý đế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 cân nhắc về cách có thể phân phối cùng một chức năng bằng các phần tử quen thuộc. Trong nhiều trường hợp, vấn đề này ít phải được quan tâm – nếu các thành phần giao diện người dùng mới hơn xuất hiệ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ư các khung hiển thị vuốt sử dụng ViewPager
).
Triển khai thẻ bằng API cũ
Để tạo cách triển khai cũ hơn cho các thẻ thanh thao tác, bạn có thể sử dụng TabWidget
và TabHost
(mặc dù người dùng có thể sử dụng tiện ích Button
được bố trí theo chiều ngang). Hãy triển khai trong các lớp có tên là TabHelperEclair
và CompatTabEclair
, vì quá trình triển khai này sử dụng các API được giới thiệu trước phiên bản Android 2.0 (Eclair).
Quá trình triển khai CompatTabEclair
lưu trữ các thuộc tính thẻ 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 đối tượng TabHost.TabSpec
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 khác hoạt động trên các 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 những cách triển khai này trong ứng dụng của bạn.