Z tej lekcji dowiesz się, jak tworzyć klasyfikacje abstrakcyjne CompatTab i TabHelper oraz jak używać nowych interfejsów API. Twoja aplikacja może korzystać z tej implementacji na urządzeniach z obsługiwaną wersją platformy.
Wdrażanie kart przy użyciu nowych interfejsów API
Konkretne klasy dla CompatTab i TabHelper, które używają nowszych interfejsów API, są implementacją proxy. Klasy abstrakcyjne zdefiniowane w poprzedniej lekcji odzwierciedlają nowe interfejsy API (struktura klas, podpisy metod itp.), dlatego konkretne klasy korzystające z nowszych interfejsów API po prostu pośredniczą w wywołaniach metod i ich wynikach.
W tych konkretnych klasach możesz używać nowszych interfejsów API i nie powodować awarii na wcześniejszych urządzeniach z powodu leniwego wczytywania klas. Klasy są wczytywane i inicjowane przy pierwszym dostępie – inicjuje je lub uzyskuje dostęp do jednego z jej statycznych pól bądź metod. Jeśli więc nie utworzysz instancji implementacji typowej dla Honeycomb na urządzeniach sprzed Honeycomb, maszyna wirtualna Dalvik nie zgłosi żadnych wyjątków VerifyError.
Dobrą konwencją nazewnictwa w tej implementacji jest dodanie nazwy kodu poziomu interfejsu API lub wersji platformy do interfejsów API wymaganych przez konkretne klasy. Na przykład implementację karty natywnej mogą zapewnić klasy CompatTabHoneycomb i TabHelperHoneycomb, ponieważ bazują one na interfejsach API dostępnych w Androidzie 3.0 (poziom API 11) lub nowszym.
Rysunek 1. Schemat klasy implementacji kart w Honeycomb.
Wdrażanie CompatTabHoneycomb
CompatTabHoneycomb to implementacja klasy abstrakcyjnej CompatTab, której TabHelperHoneycomb używa do odwoływania się do poszczególnych kart. CompatTabHoneycomb po prostu przekierowuje wszystkie wywołania metod do zawartego w niej obiektu ActionBar.Tab.
Rozpocznij implementację CompatTabHoneycomb przy użyciu nowych interfejsów API ActionBar.Tab:
Kotlin
class CompatTabHoneycomb internal constructor(val activity: Activity, tag: String) : CompatTab(tag) { ... // The native tab object that this CompatTab acts as a proxy for. private var mTab: ActionBar.Tab = // Proxy to new ActionBar.newTab API activity.actionBar.newTab() override fun setText(@StringRes textId: Int): CompatTab { // Proxy to new ActionBar.Tab.setText API mTab.setText(textId) return this } ... // Do the same for other properties (icon, callback, etc.) }
Java
public class CompatTabHoneycomb extends CompatTab { // The native tab object that this CompatTab acts as a proxy for. ActionBar.Tab mTab; ... protected CompatTabHoneycomb(FragmentActivity activity, String tag) { ... // Proxy to new ActionBar.newTab API mTab = activity.getActionBar().newTab(); } public CompatTab setText(int resId) { // Proxy to new ActionBar.Tab.setText API mTab.setText(resId); return this; } ... // Do the same for other properties (icon, callback, etc.) }
Implementacja TabHelperHoneycomb
TabHelperHoneycomb to implementacja klasy abstrakcyjnej TabHelper, która pośredniczy w wywołaniach metody w rzeczywistym obiekcie ActionBar uzyskanym z zawartego w niej elementu Activity.
Zaimplementuj wywołania metody TabHelperHoneycomb przez serwer proxy do interfejsu API ActionBar:
Kotlin
class TabHelperHoneycomb internal constructor(activity: FragmentActivity) : TabHelper(activity) { private var mActionBar: ActionBar? = null override fun setUp() { mActionBar = mActionBar ?: mActivity.actionBar.apply { navigationMode = ActionBar.NAVIGATION_MODE_TABS } } override fun addTab(tab: CompatTab) { // Tab is a CompatTabHoneycomb instance, so its // native tab object is an ActionBar.Tab. mActionBar?.addTab(tab.getTab() as ActionBar.Tab) } }
Java
public class TabHelperHoneycomb extends TabHelper { ActionBar actionBar; ... protected void setUp() { if (actionBar == null) { actionBar = activity.getActionBar(); actionBar.setNavigationMode( ActionBar.NAVIGATION_MODE_TABS); } } public void addTab(CompatTab tab) { ... // Tab is a CompatTabHoneycomb instance, so its // native tab object is an ActionBar.Tab. actionBar.addTab((ActionBar.Tab) tab.getTab()); } // The other important method, newTab() is part of // the base implementation. }