Предположим, вы хотите использовать вкладки панели действий в качестве основной формы навигации верхнего уровня в вашем приложении. К сожалению, API-интерфейсы ActionBar
доступны только в Android 3.0 или более поздних версиях (уровень API 11+). Таким образом, если вы хотите распространить свое приложение на устройства, на которых работают более ранние версии платформы, вам необходимо предоставить реализацию, которая поддерживает новый API, а также предоставляет резервный механизм, использующий старые API.
В этом классе вы создаете компонент пользовательского интерфейса (UI) с вкладками, который использует абстрактные классы с реализациями для конкретной версии для обеспечения обратной совместимости. В этом уроке описывается, как создать уровень абстракции для API новых вкладок в качестве первого шага к созданию компонента вкладки.
Готовьтесь к абстракции
Абстракция в языке программирования Java предполагает создание одного или нескольких интерфейсов или абстрактных классов, чтобы скрыть детали реализации. В случае новых API-интерфейсов Android вы можете использовать абстракцию для создания компонентов с учетом версии, которые используют текущие API-интерфейсы на новых устройствах, и откатиться к более старым, более совместимым API-интерфейсам на старых устройствах.
При использовании этого подхода вы сначала определяете, какие новые классы вы хотите использовать с обратной совместимостью, а затем создаете абстрактные классы на основе общедоступных интерфейсов новых классов. При определении интерфейсов абстракции вам следует максимально отразить новый API. Это максимизирует прямую совместимость и упрощает удаление уровня абстракции в будущем, когда в нем больше нет необходимости.
После создания абстрактных классов для этих новых API можно создать и выбрать любое количество реализаций во время выполнения. В целях обратной совместимости эти реализации могут различаться в зависимости от требуемого уровня API. Таким образом, одна реализация может использовать недавно выпущенные API, а другие — старые API.
Создайте абстрактный интерфейс вкладок
Чтобы создать обратно совместимую версию вкладок, вам следует сначала определить, какие функции и конкретные API требуются вашему приложению. В случае вкладок разделов верхнего уровня предположим, что у вас есть следующие функциональные требования:
- Индикаторы вкладок должны отображать текст и значок.
- Вкладки могут быть связаны с экземпляром фрагмента.
- Действие должно иметь возможность прослушивать изменения вкладок.
Предварительная подготовка этих требований позволяет вам контролировать объем вашего уровня абстракции. Это означает, что вы можете потратить меньше времени на создание нескольких реализаций вашего уровня абстракции и раньше начать использовать новую обратно совместимую реализацию.
Ключевые API для вкладок находятся в ActionBar
и ActionBar.Tab
. Это API-интерфейсы, которые необходимо абстрагировать, чтобы ваши вкладки учитывали версии. Требования к этому примерному проекту требуют обеспечения совместимости с Eclair (уровень API 5) и одновременного использования преимуществ новых функций вкладок в Honeycomb (уровень API 11). Диаграмма структуры классов для поддержки этих двух реализаций и их абстрактных базовых классов (или интерфейсов) показана ниже.
Аннотация ActionBar.Tab
Начните создавать уровень абстракции вкладок, создав абстрактный класс, представляющий вкладку, который отражает интерфейс ActionBar.Tab
:
Котлин
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 ... }
Ява
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()
:
Котлин
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) ... }
Ява
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
, которые будут работать как на старых, так и на новых версиях платформы.