Implementierung mit älteren APIs erstellen

In dieser Lektion erfahren Sie, wie Sie eine Implementierung erstellen, die neuere APIs widerspiegelt und gleichzeitig ältere Geräte unterstützt.

Die schwierigste Aufgabe bei der abwärtskompatiblen Nutzung neuerer UI-Funktionen besteht darin, sich für eine ältere (Fallback-)Lösung für ältere Plattformversionen zu entscheiden und diese zu implementieren. In vielen Fällen ist es möglich, den Zweck dieser neueren UI-Komponenten mithilfe älterer UI-Framework-Funktionen zu erfüllen. Beispiel:

  • Aktionsleisten können mithilfe eines horizontalen LinearLayout mit Bildschaltflächen implementiert werden, entweder als benutzerdefinierte Titelleisten oder als Ansichten in Ihrem Aktivitätslayout. Überlaufaktionen können unter der Geräteschaltfläche Menü angezeigt werden.

  • Tabs in der Aktionsleiste können mit einer horizontalen LinearLayout mit Schaltflächen oder mit dem UI-Element TabWidget implementiert werden.

  • NumberPicker- und Switch-Widgets können mit Spinner- bzw. ToggleButton-Widgets implementiert werden.

  • ListPopupWindow- und PopupMenu-Widgets können mithilfe von PopupWindow-Widgets implementiert werden.

Im Allgemeinen gibt es keine Universallösung für das Backporting neuerer UI-Komponenten auf ältere Geräte. Achten Sie auf die User Experience: Auf älteren Geräten sind die Nutzenden möglicherweise nicht mit neueren Designmustern und UI-Komponenten vertraut. Überlegen Sie, wie die gleiche Funktionalität mit vertrauten Elementen umgesetzt werden kann. In vielen Fällen ist dies weniger problematisch – wenn neuere UI-Komponenten im Anwendungssystem (z. B. in der Aktionsleiste) hervorgehoben sind oder das Interaktionsmodell sehr einfach und intuitiv ist (z. B. Swipe-Ansichten mit einem ViewPager).

Tabs mit älteren APIs implementieren

Wenn Sie eine ältere Implementierung von Aktionsleisten-Tabs erstellen möchten, können Sie TabWidget und TabHost verwenden. Alternativ können Sie aber auch horizontal angeordnete Button-Widgets verwenden. Implementieren Sie dies in den Klassen TabHelperEclair und CompatTabEclair, da für diese Implementierung APIs verwendet werden, die spätestens mit Android 2.0 (Eclair) eingeführt wurden.

Klassendiagramm für die Eclair-Implementierung von Tabs.

Abbildung 1. Klassendiagramm für die Eclair-Implementierung von Tabs.

In der CompatTabEclair-Implementierung werden Tab-Eigenschaften wie der Tab-Text und das Symbol in Instanzvariablen gespeichert, da kein ActionBar.Tab-Objekt zum Verwalten dieses Speichers verfügbar ist:

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

Die TabHelperEclair-Implementierung verwendet Methoden im TabHost-Widget zum Erstellen von TabHost.TabSpec-Objekten und Tab-Indikatoren:

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

Sie haben jetzt zwei Implementierungen von CompatTab und TabHelper: eine für Geräte mit Android 3.0 oder höher, auf der neue APIs verwendet werden, die andere, die auf Geräten mit Android 2.0 oder höher funktioniert und ältere APIs verwendet. In der nächsten Lektion erfahren Sie, wie Sie diese Implementierungen in Ihrer Anwendung verwenden.