แอบสแตรก API ใหม่

สมมติว่าคุณต้องการใช้ แท็บแถบการดำเนินการ เป็นรูปแบบหลักของการนำทางระดับบนสุดในแอปพลิเคชัน แต่ ActionBar API ใช้ได้ใน Android 3.0 ขึ้นไป (API ระดับ 11 ขึ้นไป) เท่านั้น ดังนั้นหากต้องการเผยแพร่แอปพลิเคชันไปยังอุปกรณ์ที่ใช้แพลตฟอร์มเวอร์ชันก่อนหน้า คุณต้องสร้างการใช้งานที่รองรับ API ใหม่กว่า ขณะเดียวกันก็มีกลไกการทำงานสำรองที่ใช้ API เก่ากว่า

ในคลาสนี้ คุณจะสร้างคอมโพเนนต์อินเทอร์เฟซผู้ใช้ (UI) แบบแท็บที่ใช้คลาสแบบนามธรรมพร้อมการใช้งานเฉพาะเวอร์ชันเพื่อมอบความเข้ากันได้แบบย้อนกลับ บทเรียนนี้จะอธิบายวิธีสร้างเลเยอร์การแยกส่วนสำหรับ API แท็บใหม่ ซึ่งเป็นขั้นตอนแรกในการสร้างคอมโพเนนต์แท็บ

เตรียมพร้อมสำหรับการแยกส่วน

การแยกส่วนในภาษาโปรแกรม Java เกี่ยวข้องกับการสร้างอินเทอร์เฟซหรือคลาสแบบนามธรรมอย่างน้อย 1 รายการเพื่อซ่อนรายละเอียดการใช้งาน ในกรณีของ Android API ใหม่กว่า คุณสามารถใช้การแยกส่วนเพื่อสร้างคอมโพเนนต์ที่ทราบเวอร์ชันซึ่งใช้ API ปัจจุบันในอุปกรณ์ใหม่กว่า และกลับไปใช้ API เก่ากว่าที่เข้ากันได้มากขึ้นในอุปกรณ์เก่ากว่า

เมื่อใช้วิธีนี้ ขั้นแรกให้กำหนดคลาสใหม่กว่าที่ต้องการใช้ในลักษณะที่เข้ากันได้แบบย้อนกลับ จากนั้นสร้างคลาสแบบนามธรรมตามอินเทอร์เฟซสาธารณะของคลาสใหม่กว่า ในการกำหนดอินเทอร์เฟซการแยกส่วน คุณควรจำลอง API ใหม่กว่าให้มากที่สุด ซึ่งจะเพิ่มความเข้ากันได้แบบไปข้างหน้าให้มากที่สุดและทำให้การนำเลเยอร์การแยกส่วนออกในอนาคตทำได้ง่ายขึ้นเมื่อไม่จำเป็นอีกต่อไป

หลังจากสร้างคลาสแบบนามธรรมสำหรับ API ใหม่เหล่านี้แล้ว คุณจะสร้างและเลือกการใช้งานได้ไม่จำกัดจำนวนในรันไทม์ การใช้งานเหล่านี้อาจแตกต่างกันไปตามระดับ API ที่จำเป็นเพื่อวัตถุประสงค์ด้านความเข้ากันได้แบบย้อนกลับ ดังนั้น การใช้งานหนึ่งอาจใช้ API ที่เพิ่งเปิดตัว ขณะที่การใช้งานอื่นๆ อาจใช้ API เก่ากว่า

สร้างอินเทอร์เฟซแท็บแบบนามธรรม

หากต้องการสร้างแท็บเวอร์ชันที่เข้ากันได้แบบย้อนกลับ คุณควรกำหนดฟีเจอร์และ API เฉพาะที่แอปพลิเคชันต้องการก่อน ในกรณีของแท็บส่วนระดับบนสุด สมมติว่าคุณมีข้อกำหนดด้านฟังก์ชันการทำงานต่อไปนี้

  1. ตัวบ่งชี้แท็บควรแสดงข้อความและไอคอน
  2. แท็บสามารถเชื่อมโยงกับอินสแตนซ์ของ Fragment ได้
  3. กิจกรรมควรสามารถฟังการเปลี่ยนแปลงแท็บได้

การเตรียมข้อกำหนดเหล่านี้ล่วงหน้าจะช่วยให้คุณควบคุมขอบเขตของเลเยอร์แอบสแตรกชันได้ ซึ่งหมายความว่าคุณจะใช้เวลาน้อยลงในการสร้างการใช้งานเลเยอร์การแยกส่วนหลายรายการ และเริ่มใช้การใช้งานใหม่ที่เข้ากันได้แบบย้อนกลับได้เร็วขึ้น

API หลักสำหรับแท็บอยู่ใน ActionBar และ ActionBar.Tab ซึ่งเป็น API ที่ต้องแยกส่วนเพื่อให้แท็บทราบเวอร์ชัน ข้อกำหนดสำหรับโปรเจ็กต์ตัวอย่างนี้กำหนดให้เข้ากันได้กับ Eclair (API ระดับ 5) ขณะเดียวกันก็ใช้ประโยชน์จากฟีเจอร์แท็บใหม่ใน Honeycomb (API ระดับ 11) แผนภาพโครงสร้างคลาสเพื่อรองรับการใช้งานทั้ง 2 รายการนี้และคลาสฐานแบบนามธรรม (หรืออินเทอร์เฟซ) มีดังนี้

คลาสฐานแบบนามธรรมและการติดตั้งใช้งานเฉพาะเวอร์ชัน
รูปที่ 1 แผนภาพคลาสของคลาสฐานแบบนามธรรมและการใช้งานเฉพาะเวอร์ชัน

แยกส่วน ActionBar.Tab

เริ่มต้นสร้างเลเยอร์การแยกส่วนแท็บโดยสร้างคลาสแบบนามธรรมที่แสดงแท็บ ซึ่งจำลองอินเทอร์เฟซ ActionBar.Tab ดังนี้

Kotlin

sealed class CompatTab(val tag: String) {
    ...
    abstract fun getText(): CharSequence
    abstract fun getIcon(): Drawable
    abstract fun getCallback(): CompatTabListener
    abstract fun getFragment(): Fragment

    abstract fun setText(text: String): CompatTab
    abstract fun setIcon(icon: Drawable): CompatTab
    abstract fun setCallback(callback: CompatTabListener): CompatTab
    abstract fun setFragment(fragment: Fragment): CompatTab
    ...
}

Java

public abstract class CompatTab {
    ...
    public abstract CompatTab setText(int resId);
    public abstract CompatTab setIcon(int resId);
    public abstract CompatTab setTabListener(
            CompatTabListener callback);
    public abstract CompatTab setFragment(Fragment fragment);

    public abstract CharSequence getText();
    public abstract Drawable getIcon();
    public abstract CompatTabListener getCallback();
    public abstract Fragment getFragment();
    ...
}

คุณสามารถใช้คลาสแบบนามธรรมแทนอินเทอร์เฟซที่นี่เพื่อลดความซับซ้อนในการใช้งานฟีเจอร์ทั่วไป เช่น การเชื่อมโยงออบเจ็กต์แท็บกับกิจกรรม (ไม่แสดงในข้อมูลโค้ด)

เมธอดแท็บ ActionBar แบบนามธรรม

จากนั้นกำหนดคลาสแบบนามธรรมที่ช่วยให้คุณสร้างและเพิ่มแท็บลงในกิจกรรมได้ เช่น ActionBar.newTab() และ ActionBar.addTab()

Kotlin

sealed class TabHelper(protected val activity: FragmentActivity) {
    ...

    abstract fun setUp()

    fun newTab(tag: String): CompatTab {
        // This method is implemented in a later lesson.
    }

    abstract fun addTab(tab: CompatTab)

    ...
}

Java

public abstract class TabHelper {
    ...

    public CompatTab newTab(String tag) {
        // This method is implemented in a later lesson.
    }

    public abstract void addTab(CompatTab tab);

    ...
}

ในบทเรียนถัดไป คุณจะสร้างการใช้งานสำหรับ TabHelper และ CompatTab ที่ทำงานได้ทั้งในแพลตฟอร์มเวอร์ชันเก่าและใหม่กว่า

สิ่งที่คุณควรอ่านเพิ่มเติม