Tạo quá trình triển khai với các API cũ

Bài học này sẽ thảo luận cách tạo một phương thức triển khai phản ánh các API mới nhưng hỗ trợ các thiết bị cũ.

Quyết định một giải pháp thay thế

Nhiệm vụ khó khăn nhất trong việc sử dụng các tính năng giao diện người dùng mới hơn theo cách tương thích ngược là quyết định và triển khai một giải pháp (dự phòng) cũ hơn cho các phiên bản nền tảng cũ hơn. Trong nhiều trường hợp, bạn có thể thực hiện mục đích của các thành phần giao diện người dùng mới hơn bằng cách sử dụng các tính năng cũ của khung giao diện người dùng. Ví dụ:

  • Bạn có thể triển khai thanh thao tác bằng cách sử dụng LinearLayout ngang chứa các nút hình ảnh, dưới dạng thanh tiêu đề tuỳ chỉnh hoặc chế độ xem trong bố cục hoạt động. Bạn có thể thấy các hành động mục trong mục bổ sung bên dưới nút Trình đơn của thiết bị.

  • Bạn có thể triển khai các thẻ trên thanh thao tác bằng cách sử dụng một LinearLayout ngang chứa các nút hoặc dùng thành phần TabWidget trên giao diện người dùng.

  • Bạn có thể triển khai tiện ích NumberPickerSwitch bằng cách sử dụng tiện ích SpinnerToggleButton tương ứng.

  • Bạn có thể triển khai các tiện ích ListPopupWindowPopupMenu bằng cách sử dụng tiện ích PopupWindow.

Thường thì không có giải pháp nào đáp ứng mọi nhu cầu để điều chỉnh cho phiên bản cũ các thành phần giao diện người dùng mới hơn cho các thiết bị cũ. Lưu ý đến trải nghiệm người dùng: trên các thiết bị cũ, người dùng có thể chưa quen với các mẫu thiết kế và thành phần giao diện người dùng mới. Hãy suy nghĩ về cách phân phối cùng một chức năng bằng các thành phần quen thuộc. Trong nhiều trường hợp, bạn không cần quan tâm đến điều này – nếu các thành phần giao diện người dùng mới hơn nổi bật trong hệ sinh thái ứng dụng (chẳng hạn như thanh thao tác) hoặc khi mô hình tương tác cực kỳ đơn giản và trực quan (chẳng hạn như thành phần hiển thị vuốt sử dụng ViewPager).

Triển khai các thẻ bằng API cũ

Để tạo cách triển khai cũ hơn cho các thẻ trên thanh thao tác, bạn có thể sử dụng TabWidgetTabHost (mặc dù bạn có thể sử dụng các tiện ích Button được bố trí theo chiều ngang). Hãy triển khai việc này trong các lớp có tên là TabHelperEclairCompatTabEclair, vì cách triển khai này sử dụng các API được ra mắt từ Android 2.0 (Eclair).

Sơ đồ lớp để triển khai thẻ trong Eclair.

Hình 1. Sơ đồ lớp để triển khai thẻ trong Eclair.

Phương thức triển khai CompatTabEclair lưu trữ các thuộc tính thẻ (chẳng hạn như văn bản và biểu tượng thẻ) trong các biến thực thể, vì không có đối tượng ActionBar.Tab nào để xử lý bộ nhớ này:

Kotlin

class CompatTabEclair internal constructor(val activity: FragmentActivity, tag: String) :
        CompatTab(tag) {

    // Store these properties in the instance,
    // as there is no ActionBar.Tab object.
    private var text: CharSequence? = null
    ...

    override fun setText(resId: Int): CompatTab {
        // Our older implementation simply stores this
        // information in the object instance.
        text = activity.resources.getText(resId)
        return this
    }

    ...
    // Do the same for other properties (icon, callback, etc.)
}

Java

public class CompatTabEclair extends CompatTab {
    // Store these properties in the instance,
    // as there is no ActionBar.Tab object.
    private CharSequence text;
    ...

    public CompatTab setText(int resId) {
        // Our older implementation simply stores this
        // information in the object instance.
        text = activity.getResources().getText(resId);
        return this;
    }

    ...
    // Do the same for other properties (icon, callback, etc.)
}

Việc triển khai TabHelperEclair sử dụng các phương thức trên Tiện ích TabHost để tạo TabHost.TabSpec đối tượng và chỉ báo thẻ:

Kotlin

class TabHelperEclair internal constructor(activity: FragmentActivity) : TabHelper(activity) {

    private var tabHost: TabHost? = null
    ...

    override fun setUp() {
        // Our activity layout for pre-Honeycomb devices
        // must contain a TabHost.
        tabHost = tabHost ?: mActivity.findViewById<TabHost>(android.R.id.tabhost).apply {
            setup()
        }
    }

    override fun addTab(tab: CompatTab) {
        ...
        tabHost?.newTabSpec(tab.tag)?.run {
            setIndicator(tab.getText()) // And optional icon
            ...
            tabHost?.addTab(this)
        }
    }
    // The other important method, newTab() is part of
    // the base implementation.
}

Java

public class TabHelperEclair extends TabHelper {
    private TabHost tabHost;
    ...

    protected void setUp() {
        if (tabHost == null) {
            // Our activity layout for pre-Honeycomb devices
            // must contain a TabHost.
            tabHost = (TabHost) mActivity.findViewById(
                    android.R.id.tabhost);
            tabHost.setup();
        }
    }

    public void addTab(CompatTab tab) {
        ...
        TabSpec spec = tabHost
                .newTabSpec(tag)
                .setIndicator(tab.getText()); // And optional icon
        ...
        tabHost.addTab(spec);
    }

    // The other important method, newTab() is part of
    // the base implementation.
}

Bạn hiện có hai cách triển khai CompatTabTabHelper: một cách hoạt động trên thiết bị chạy Android 3.0 trở lên và sử dụng API mới, còn một cách hoạt động trên thiết bị chạy Android 2.0 trở lên và sử dụng API cũ. Bài học tiếp theo sẽ thảo luận về cách sử dụng các phương pháp triển khai này trong ứng dụng của bạn.