Dùng thành phần nhận biết phiên bản

Giờ đây, khi bạn đã có hai cách triển khai TabHelperCompatTab (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 lúc thực hiện các thao tác với những phương thức 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 phương thức 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 hoạt động như một nhà máy để tạo các thực thể TabHelperCompatTab 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 cho 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ó thể hỗ trợ việc triển khai 2 thẻ. Đối với cách triển khai cũ hơn (TabHelperEclair), bạn cần đảm bảo bố cục hoạt động chứa TabWidgetTabHost, 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>

Để triển khai TabHelperHoneycomb, bạn chỉ cần một FrameLayout để chứa nội dung thẻ, vì 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 sẽ tăng cường tuỳ thuộc vào phiên bản nền tảng. Logic này cũng tương tự như trong phần trước, giúp xác định phương thức triển khai TabHelper nào sẽ được sử dụng.

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 đố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ẽ tăng cường đúng bố cục hoạt động và tạo thực thể cho đối tượng TabHelperHoneycomb hoặc TabHelperEclair. Lớp cụ thể được sử dụng thực sự không rõ ràng đối với hoạt động, vì chúng có chung giao diện TabHelper.

Dưới đây là hai ảnh chụp màn hình của quá trình triển khai này chạy trên thiết bị chạy Android 2.3 và Android 4.0.

Ảnh chụp màn hình mẫu về các thẻ chạy trên thiết bị Android 2.3 (sử dụng TabHelperEclair). Ảnh chụp màn hình mẫu về các thẻ chạy trên thiết bị Android 4.0 (sử dụng TabHelperHoneycomb).

Hình 1. Ảnh chụp màn hình mẫu về các thẻ có khả năng tương thích ngược 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).