Создайте реализацию со старыми API.

В этом уроке обсуждается, как создать реализацию, отражающую новые API, но поддерживающую старые устройства.

Принятие решения о замене

Самая сложная задача при использовании новых функций пользовательского интерфейса с обратной совместимостью — это выбор и реализация старого (резервного) решения для старых версий платформы. Во многих случаях можно реализовать назначение этих новых компонентов пользовательского интерфейса, используя старые функции платформы пользовательского интерфейса. Например:

  • Панели действий можно реализовать с помощью горизонтального LinearLayout , содержащего кнопки изображений, либо в виде настраиваемых заголовков, либо в виде представлений в макете действий. Действия переполнения могут быть представлены под кнопкой « Меню устройства».

  • Вкладки панели действий можно реализовать с помощью горизонтального LinearLayout содержащего кнопки, или с помощью элемента пользовательского интерфейса TabWidget .

  • Виджеты NumberPicker и Switch можно реализовать с помощью виджетов Spinner и ToggleButton соответственно.

  • Виджеты ListPopupWindow и PopupMenu можно реализовать с помощью виджетов PopupWindow .

Как правило, не существует универсального решения для переноса новых компонентов пользовательского интерфейса на старые устройства. Помните о пользовательском опыте: на старых устройствах пользователи могут быть не знакомы с новыми шаблонами дизайна и компонентами пользовательского интерфейса. Подумайте, как можно реализовать ту же функциональность, используя знакомые элементы. Во многих случаях это не вызывает беспокойства, если в экосистеме приложения заметны новые компоненты пользовательского интерфейса (например, панель действий) или если модель взаимодействия чрезвычайно проста и интуитивно понятна (например, пролистывание представлений с помощью ViewPager ).

Реализация вкладок с использованием старых API

Чтобы создать более старую реализацию вкладок панели действий, вы можете использовать TabWidget и TabHost (хотя в качестве альтернативы можно использовать горизонтально расположенные виджеты Button ). Реализуйте это в классах TabHelperEclair и CompatTabEclair , поскольку эта реализация использует API, представленные не позднее Android 2.0 (Eclair).

Диаграмма классов для реализации вкладок в Eclair.

Рисунок 1. Диаграмма классов для реализации вкладок в Eclair.

Реализация CompatTabEclair сохраняет свойства вкладки, такие как текст и значок вкладки, в переменных экземпляра, поскольку для обработки этого хранилища не существует объекта ActionBar.Tab :

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.)
}
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.)
}

Реализация TabHelperEclair использует методы виджета TabHost для создания объектов TabHost.TabSpec и индикаторов вкладок:

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.
}
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.
}

Теперь у вас есть две реализации CompatTab и TabHelper : одна работает на устройствах под управлением Android 3.0 или более поздней версии и использует новые API, а другая работает на устройствах под управлением Android 2.0 или более поздней версии и использует старые API. В следующем уроке обсуждается использование этих реализаций в вашем приложении.