抽象化新的 API

假设您想使用操作栏标签页作为应用中顶层导航的主要形式。遗憾的是,ActionBar API 仅适用于 Android 3.0 或更高版本(API 级别 11+)。因此,如果您想将应用分发到运行早期平台版本的设备,则需要提供一个支持新 API 的实现,同时提供一个使用旧 API 的备用机制。

在本课程中,您将构建一个使用抽象类和特定版本实现的标签页用户界面 (UI) 组件,以提供向下兼容性。本课介绍如何为新的标签页 API 创建一个抽象层,作为构建标签页组件的第一步。

准备进行抽象

Java 编程语言中的抽象涉及创建一个或多个接口或抽象类来隐藏实现细节。对于较新的 Android API,您可以使用抽象来构建版本感知组件,以便在较新的设备上使用当前 API,并在较旧的设备上回退到旧的、更兼容的 API。

使用这种方法时,首先确定您希望以向下兼容的方式使用哪些较新的类,然后基于较新类的公共接口创建抽象类。在定义抽象接口时,应尽可能地模仿较新的 API。这样可以最大程度地实现向前兼容性,并在将来不再需要抽象层时更容易移除它。

为这些新 API 创建抽象类后,可以在运行时创建并选择任意数量的实现。为了实现向下兼容性,这些实现可以根据所需的 API 级别而有所不同。因此,一种实现可以使用最近发布的 API,而其他实现则可以使用旧的 API。

创建抽象标签页接口

为了创建标签页的向下兼容版本,您应首先确定您的应用需要哪些功能和特定的 API。对于顶层部分标签页,假设您有以下功能需求

  1. 标签页指示器应显示文本和图标。
  2. 标签页可以与 Fragment 实例关联。
  3. Activity 应能够监听标签页更改。

提前准备好这些需求可以帮助您控制抽象层的范围。这意味着您可以花费更少的时间创建抽象层的多个实现,并更快地开始使用新的向下兼容实现。

标签页的关键 API 位于 ActionBarActionBar.Tab 中。这些是需要进行抽象的 API,以使您的标签页具有版本感知能力。此示例项目要求兼容 Eclair(API 级别 5),同时利用 Honeycomb(API 级别 11)中的新标签页功能。下面显示了支持这两种实现及其抽象基类(或接口)的类结构图。

Class diagram of abstract base classes and version-specific implementations.

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

您可以在此处使用抽象类代替接口,以简化常见功能的实现,例如将标签页对象与 Activity 关联(未在代码片段中显示)的功能。

抽象化 ActionBar 标签页方法

接下来,定义一个抽象类,用于创建标签页并将其添加到 Activity 中,例如 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);

    ...
}

在接下来的课程中,您将创建适用于旧平台版本和新平台版本的 TabHelperCompatTab 实现。

您还应阅读