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

עכשיו, אחרי שיש לך שתי הטמעות של 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).