Giờ đây, bạn đã có 2 cách triển khai TabHelper và CompatTab (một cho Android 3.0 trở lên và một cho các phiên bản cũ hơn của nền tảng này). Đã đến lúc bạn cần làm gì đó với những cách triển khai này. Bài học này thảo luận về việc tạo logic để chuyển đổi giữa các cách triển khai này, tạo bố cục nhận biết phiên bản và cuối cùng là sử dụng thành phần giao diện người dùng có khả năng tương thích ngược.
Thêm logic chuyển đổi
Lớp trừu tượng TabHelper đóng vai trò là một nhà máy để tạo các thực thể TabHelper và CompatTab phù hợp với phiên bản, dựa trên phiên bản nền tảng của thiết bị hiện tại:
Kotlin
sealed class TabHelper(protected val mActivity: FragmentActivity, protected val tag: String) { abstract fun setUp() abstract fun addTab(tab: CompatTab) // Usage is tabHelper.newTab("tag") fun newTab(tag: String): CompatTab = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB) { CompatTabHoneycomb(mActivity, tag) } else { CompatTabEclair(mActivity, tag) } companion object { // Usage is TabHelper.createInstance(activity) fun createInstance(activity: FragmentActivity): TabHelper = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB) { TabHelperHoneycomb(activity) } else { TabHelperEclair(activity) } } }
Java
public abstract class TabHelper { ... // Usage is TabHelper.createInstance(activity) public static TabHelper createInstance(FragmentActivity activity) { if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB) { return new TabHelperHoneycomb(activity); } else { return new TabHelperEclair(activity); } } // Usage is tabHelper.newTab("tag") public CompatTab newTab(String tag) { if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB) { return new CompatTabHoneycomb(mActivity, tag); } else { return new CompatTabEclair(mActivity, tag); } } ... }
Tạo bố cục hoạt động nhận biết phiên bản
Bước tiếp theo là cung cấp bố cục cho hoạt động của bạn để có thể hỗ trợ 2 cách triển khai thẻ. Đối với cách triển khai cũ (TabHelperEclair), bạn cần đảm bảo rằng bố cục hoạt động của bạn chứa TabWidget và TabHost, cùng với một vùng chứa cho nội dung thẻ:
res/layout/main.xml:
<!-- This layout is for API level 5-10 only. --> <TabHost xmlns:android="http://schemas.android.com/apk/res/android" android:id="@android:id/tabhost" android:layout_width="match_parent" android:layout_height="match_parent"> <LinearLayout android:orientation="vertical" android:layout_width="match_parent" android:layout_height="match_parent" android:padding="5dp"> <TabWidget android:id="@android:id/tabs" android:layout_width="match_parent" android:layout_height="wrap_content" /> <FrameLayout android:id="@android:id/tabcontent" android:layout_width="match_parent" android:layout_height="0dp" android:layout_weight="1" /> </LinearLayout> </TabHost>
Đối với việc triển khai TabHelperHoneycomb, bạn chỉ cần một FrameLayout để chứa nội dung thẻ, vì các chỉ báo thẻ do ActionBar cung cấp:
res/layout-v11/main.xml:
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android" android:id="@android:id/tabcontent" android:layout_width="match_parent" android:layout_height="match_parent" />
Trong thời gian chạy, Android sẽ quyết định phiên bản bố cục main.xml nào sẽ mở rộng tuỳ thuộc vào phiên bản nền tảng. Đây là logic tương tự như logic được trình bày trong phần trước để xác định nên sử dụng cách triển khai TabHelper nào.
Sử dụng TabHelper trong hoạt động của bạn
Trong phương thức onCreate() của hoạt động, bạn có thể lấy một đối tượng TabHelper và thêm các thẻ bằng mã sau:
Kotlin
override fun onCreate(savedInstanceState: Bundle?) { ... setContentView(R.layout.main) TabHelper.createInstance(this).apply { setUp() newTab("photos") .setText(R.string.tab_photos) .also { photosTab -> addTab(photosTab) } newTab("videos") .setText(R.string.tab_videos) .also { videosTab -> addTab(videosTab) } } }
Java
@Override public void onCreate(Bundle savedInstanceState) { setContentView(R.layout.main); TabHelper tabHelper = TabHelper.createInstance(this); tabHelper.setUp(); CompatTab photosTab = tabHelper .newTab("photos") .setText(R.string.tab_photos); tabHelper.addTab(photosTab); CompatTab videosTab = tabHelper .newTab("videos") .setText(R.string.tab_videos); tabHelper.addTab(videosTab); }
Khi chạy ứng dụng, mã này sẽ mở rộng bố cục hoạt động chính xác và tạo bản sao của đối tượng TabHelperHoneycomb hoặc TabHelperEclair. Lớp cụ thể thực sự được dùng là lớp mờ đối với hoạt động, vì chúng dùng chung giao diện TabHelper.
Hai ảnh chụp màn hình sau đây cho thấy quá trình triển khai này đang chạy trên thiết bị Android 2.3 và Android 4.0.
Hình 1. Ảnh chụp màn hình ví dụ về các thẻ tương thích ngược đang chạy trên thiết bị Android 2.3 (sử dụng TabHelperEclair) và thiết bị Android 4.0 (sử dụng TabHelperHoneycomb).