Omówienie nowych interfejsów API

Załóżmy, że chcesz używać kart na pasku działań jako podstawowej formy nawigacji najwyższego poziomu w aplikacji. Interfejsy API ActionBar są dostępne tylko na Androidzie 3.0 lub nowszym (poziom API 11 i nowszy). Dlatego, jeśli chcesz dystrybuować swoją aplikację na urządzeniach z wcześniejszymi wersjami platformy, musisz udostępnić implementację, która obsługuje nowszy interfejs API, a jednocześnie udostępnić mechanizm zastępczy, który korzysta ze starszych interfejsów API.

W ramach tych zajęć utworzysz komponent interfejsu z kartami, który wykorzystuje klasy abstrakcyjne z implementacjami związanymi z konkretną wersją, aby zapewnić zgodność wsteczną. Z tej lekcji dowiesz się, jak utworzyć warstwę abstrakcji dla interfejsów API nowych kart, aby utworzyć komponent karty.

Przygotowanie do abstrakcji

Streszczenie w języku programowania Java obejmuje utworzenie co najmniej jednego interfejsu lub klas abstrakcyjnych do ukrycia szczegółów implementacji. W przypadku nowszych interfejsów API Androida możesz wykorzystać abstrakcje, by tworzyć komponenty uwzględniające wersję, które korzystają z aktualnych interfejsów API na nowszych urządzeniach, a na starszych urządzeniach – użyć w zastępstwie starszych, bardziej zgodnych interfejsów API.

W przypadku tego podejścia najpierw trzeba określić, których nowszych klas chcesz używać w sposób zgodny wstecznie, a następnie utworzyć klasy abstrakcyjne na podstawie publicznych interfejsów nowszych klas. Przy definiowaniu interfejsów abstrakcji należy w jak największym stopniu powielać nowszy interfejs API. Maksymalizuje to zgodność z praktyką i ułatwia porzucenie warstwy abstrakcji w przyszłości, gdy nie jest już potrzebna.

Po utworzeniu klas abstrakcyjnych dla tych nowych interfejsów API można utworzyć i wybrać dowolną liczbę implementacji w czasie działania. Aby zapewnić zgodność wsteczną, implementacje te mogą się różnić w zależności od wymaganego poziomu interfejsu API. Dlatego w jednej z nich mogą być używane niedawno wydane interfejsy API, a inne – starsze.

Utwórz abstrakcyjny interfejs karty

Aby utworzyć wstecznie zgodną wersję kart, musisz określić, których funkcji i konkretnych interfejsów API potrzebuje Twoja aplikacja. W przypadku kart sekcji najwyższego poziomu załóżmy, że są spełnione następujące wymagania funkcjonalne:

  1. Wskaźniki kart powinny zawierać tekst i ikonę.
  2. Karty mogą być powiązane z instancją fragmentu.
  3. Aktywność powinna wykrywać zmiany na karcie.

Wcześniejsze przygotowanie tych wymagań pozwoli Ci kontrolować zakres warstwy abstrakcji. Oznacza to, że możesz poświęcać mniej czasu na tworzenie wielu implementacji warstwy abstrakcji i szybciej zacząć korzystać z nowej implementacji zgodnej wstecznie.

Najważniejsze interfejsy API kart znajdują się w językach ActionBar i ActionBar.Tab. To są interfejsy API, które należy wyodrębnić, aby określić wersję kart. Wymagania w tym przykładowym projekcie dotyczą zgodności z klasyfikacją Eclair (poziom interfejsu API 5) i korzystania z nowych funkcji kart w Honeycomb (poziom interfejsu API 11). Poniżej znajduje się diagram struktury klas, który obsługuje te 2 implementacje, oraz ich abstrakcyjne klasy podstawowe (czyli interfejsy).

Diagram klas abstrakcyjnych klas podstawowych i implementacji w konkretnej wersji.

Rysunek 1. Diagram klas abstrakcyjnych klas podstawowych i implementacji w konkretnej wersji.

Abstrakcyjny pasek działań.Tab

Zacznij tworzyć warstwę abstrakcji kart. Utwórz klasę abstrakcyjną reprezentującą kartę, która odzwierciedla interfejs 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();
    ...
}

Zamiast interfejsu możesz użyć klasy abstrakcyjnej, by uprościć implementację typowych funkcji, takich jak powiązanie obiektów kart z działaniami (niewidocznych we fragmencie kodu).

Abstrakcyjne metody korzystania z kart na pasku akcji

Następnie zdefiniuj klasę abstrakcyjną, która pozwoli Ci tworzyć i dodawać karty do aktywności, np. ActionBar.newTab() i 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);

    ...
}

Podczas następnych lekcji utworzysz implementacje dla systemów TabHelper i CompatTab, które będą działać zarówno na starszych, jak i nowszych wersjach platformy.

Przeczytaj też