שימוש ברכיב לניהול גרסאות

עכשיו שיש לכם שתי הטמעות של TabHelper ושל CompatTab – אחת ל-Android 3.0 ואילך ואחת לגרסאות קודמות של הפלטפורמה – הגיע הזמן לעשות משהו עם ההטמעות האלה. בשיעור הזה נדון ביצירת הלוגיקה למעבר בין ההטמעות האלה, ביצירת פריסות שמתאימות לגרסה ובשימוש ברכיב ממשק משתמש שתואם לאחור.

הוספת לוגיקת המעבר

המחלקה המופשטת TabHelper פועלת כמפעל ליצירת מופעים של TabHelper ושל CompatTab שמתאימים לגרסה, על סמך גרסת הפלטפורמה הנוכחית של המכשיר:

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);
        }
    }
    ...
}

יצירת פריסת פעילות עם תמיכה בגרסאות

בשלב הבא צריך לספק פריסות לפעילות שלכם שיכולות לתמוך בשתי ההטמעות של הכרטיסיות. בגרסה הקודמת של ההטמעה (TabHelperEclair), צריך לוודא שפריסת הפעילות מכילה את הרכיבים TabWidget ו-TabHost, וגם מאגר לתוכן הכרטיסיות:

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>

כדי להטמיע את TabHelperHoneycomb, כל מה שצריך הוא FrameLayout שיכיל את תוכן הכרטיסייה, כי אינדיקטורים של הכרטיסיות מסופקים על ידי ActionBar:

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" />

בזמן הריצה, מערכת Android תחליט איזו גרסה של פריסת main.xml להרחיב בהתאם לגרסת הפלטפורמה. זהו אותו היגיון שמוצג בקטע הקודם כדי לקבוע באיזו הטמעה של TabHelper להשתמש.

שימוש ב-TabHelper בפעילות

ב-method onCreate() של הפעילות, אפשר לקבל אובייקט TabHelper ולהוסיף כרטיסיות באמצעות הקוד הבא:

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);
}

כשמריצים את האפליקציה, הקוד הזה מרחיב את פריסת הפעילות הנכונה ויוצר מופע של אובייקט TabHelperHoneycomb או TabHelperEclair. הפעילות לא יכולה לראות את המחלקה הקונקרטית שבה נעשה שימוש בפועל, כי הן חולקות את הממשק המשותף TabHelper.

בהמשך מוצגים שני צילומי מסך שבהם ההטמעה הזו פועלת במכשיר Android 2.3 ובמכשיר Android 4.0.

דוגמה לכרטיסיות שפועלות במכשיר Android 2.3 (באמצעות TabHelperEclair).
דוגמה לכרטיסיות שפועלות במכשיר Android 4.0 (באמצעות TabHelperHoneycomb).

איור 1. דוגמאות לצילומי מסך של כרטיסיות שתואמות לדורות קודמים שפועלות במכשיר Android 2.3 (באמצעות TabHelperEclair) ובמכשיר Android 4.0 (באמצעות TabHelperHoneycomb).