Esta lição aborda a criação de implementações que espelham APIs mais recentes e que ainda são compatíveis com dispositivos mais antigos.
Escolher uma solução alternativa
A tarefa mais desafiadora ao usar recursos de IU mais recentes de forma compatível com versões anteriores é decidir e implementar uma solução antiga (substituta) para versões de plataformas mais antigas. Em muitos casos, é possível atender a finalidade desses novos componentes da IU usando recursos de framework mais antigos dela. Exemplo:
-
As barras de ação podem ser implementadas usando um
LinearLayout
horizontal contendo botões de imagem, seja como barras de título personalizadas ou como visualizações no layout da atividade. É possível apresentar ações flutuantes sob o botão Menu do dispositivo. -
As guias de barras de ações podem ser implementadas usando um
LinearLayout
horizontal que contém botões ou usando o elementoTabWidget
da IU. -
Os widgets
NumberPicker
eSwitch
podem ser implementados usando os widgetsSpinner
eToggleButton
, respectivamente. -
Os widgets
ListPopupWindow
ePopupMenu
podem ser implementados usando widgetsPopupWindow
.
Geralmente, não há uma solução única para fazer retrocompatibilidade de componentes de IU mais recentes para dispositivos mais antigos. Pense sempre na experiência do usuário: em dispositivos mais antigos, os usuários podem não estar familiarizados com os padrões de design e componentes de IU mais recentes. Pense em como a mesma funcionalidade pode ser oferecida usando elementos conhecidos. Em muitos casos, isso é uma preocupação menor se os componentes da IU forem proeminentes no ecossistema de aplicativos, como a barra de ações, ou se o modelo de interação for extremamente simples e intuitivo, como deslizar visualizações usando um ViewPager
.
Implementar guias usando APIs mais antigas
Para criar uma implementação mais antiga de guias da barra de ações, você pode usar um TabWidget
e um TabHost
, embora também seja possível usar widgets Button
dispostos horizontalmente. Implemente isso em classes chamadas TabHelperEclair
e CompatTabEclair
, uma vez que essa implementação usa APIs introduzidas no máximo no Android 2.0 (Eclair).

Figura 1. Diagrama de classes para a implementação de guias do Eclair.
A implementação de CompatTabEclair
armazena propriedades da guia, como o texto e ícone dela em variáveis de instância, já que não há um objeto ActionBar.Tab
disponível para gerenciar esse armazenamento:
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.)
}
A implementação de TabHelperEclair
usa métodos no widget
TabHost
para criar objetos TabHost.TabSpec
e indicadores de guia:
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.
}
Agora, você tem duas implementações de CompatTab
e TabHelper
: uma que funciona em dispositivos que executam o Android 3.0 ou versões mais recentes e usa APIs novas, e outra que funciona em dispositivos que executam o Android 2.0 ou versões mais recentes e usa APIs mais antigas. A próxima lição aborda o uso dessas implementações no seu aplicativo.