استخدام المكوِّن الإضافي للإصدار

بعد أن أصبح لديك عمليتان تنفيذيتان للفئتَين TabHelper وCompatTab، إحداهما للإصدار 3.0 من Android والإصدارات الأحدث والأخرى للإصدارات السابقة من النظام الأساسي، حان الوقت للاستفادة من هاتَين العمليتَين التنفيذيتَين. يناقش هذا الدرس إنشاء منطق للتبديل بين هاتَين العمليتَين التنفيذيتَين، وإنشاء تنسيقات متوافقة مع الإصدار، وأخيرًا استخدام مكوّن واجهة المستخدم المتوافق مع الإصدارات السابقة.

إضافة منطق التبديل

تعمل الفئة المجردة 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 في نشاطك

في طريقة 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)