Implementierung mit älteren APIs erstellen

In dieser Lektion erfahren Sie, wie Sie eine Implementierung erstellen, die neuere APIs spiegelt, aber auch ältere Geräte unterstützt.

Für eine Ersatzlösung entscheiden

Die schwierigste Aufgabe bei der abwärtskompatiblen Nutzung neuerer UI-Funktionen ist die Entscheidung für eine ältere (Fallback-)Lösung für ältere Plattformversionen. In vielen Fällen ist es möglich, den Zweck dieser neueren UI-Komponenten mithilfe von älteren UI-Framework-Funktionen zu erfüllen. Beispiele:

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

  • Tabs für Aktionsleisten können mit einem horizontalen LinearLayout mit Schaltflächen oder mit dem TabWidget-UI-Element implementiert werden.

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

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

Im Allgemeinen gibt es keine Universallösung für die Rückportierung neuerer UI-Komponenten auf ältere Geräte. Achten Sie auf die User Experience: Auf älteren Geräten sind Nutzende mit neueren Designmustern und UI-Komponenten möglicherweise nicht vertraut. Überlegen Sie, wie dieselbe Funktionalität mithilfe vertrauter Elemente bereitgestellt werden kann. In vielen Fällen ist dies weniger bedenklich, wenn neuere UI-Komponenten im App-Ökosystem hervorstechen (z. B. die Aktionsleiste) oder wo das Interaktionsmodell extrem einfach und intuitiv ist (z. B. Wischvorgänge mit einem ViewPager).

Tabs mit älteren APIs implementieren

Wenn du eine ältere Implementierung von Tabs für Aktionsleisten erstellen möchtest, kannst du TabWidget und TabHost verwenden. Alternativ kannst du auch horizontal angeordnete Button-Widgets verwenden. Implementieren Sie dies in Klassen namens TabHelperEclair und CompatTabEclair, da diese Implementierung APIs verwendet, die ab 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

Die CompatTabEclair-Implementierung speichert Tabeigenschaften wie den Tabtext und das Symbol in Instanzvariablen, da kein ActionBar.Tab-Objekt für diesen Speicher verfügbar ist:

Kotlin

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

Java

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 nutzt die Methoden im TabHost-Widget zum Erstellen von TabHost.TabSpec-Objekten und Tab-Indikatoren:

Kotlin

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

Java

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

Es gibt jetzt zwei Implementierungen von CompatTab und TabHelper: eine für Geräte mit Android 3.0 oder höher und neuen APIs, die andere für Geräte mit Android 2.0 oder höher und älteren APIs. In der nächsten Lektion wird beschrieben, wie Sie diese Implementierungen in Ihrer Anwendung verwenden.