Proxy para as novas APIs

Esta lição mostra como colocar as classes abstratas CompatTab e TabHelper em subclasses e usar novas APIs. Seu aplicativo pode usar essa implementação em dispositivos que executam uma versão de plataforma que seja compatível com eles.

Implementar guias usando novas APIs

As classes concretas para CompatTab e TabHelper que usam APIs mais recentes são uma implementação do proxy. Como as classes abstratas definidas na lição anterior espelham as novas APIs (estrutura de classe, assinaturas de métodos etc.), as classes concretas que usam essas APIs mais recentes simplesmente colocam em proxy chamadas de método e os resultados delas.

É possível usar de forma direta APIs mais novas nessas classes concretas (sem falhas em dispositivos mais antigos) devido ao carregamento lento da classe. As classes são carregadas e inicializadas no primeiro acesso: a classe é instanciada ou um dos campos estáticos ou métodos é acessado pela primeira vez. Assim, desde que você não instancie as implementações específicas do Honeycomb em dispositivos anteriores a ele, a VM Dalvik não gerará nenhuma exceção VerifyError.

Uma boa convenção de nomenclatura para essa implementação é anexar o nome do código da versão da plataforma ou do nível de API correspondente às APIs exigidas pelas classes concretas. Por exemplo, a implementação da guia nativa pode ser fornecida pelas classes CompatTabHoneycomb e TabHelperHoneycomb, uma vez que elas dependem de APIs disponíveis no Android 3.0 (API de nível 11) ou versões posteriores.

Diagrama de classes para a implementação de guias do Honeycomb.

Figura 1. Diagrama de classes para a implementação de guias do Honeycomb.

Implementar CompatTabHoneycomb

CompatTabHoneycomb é a implementação da classe abstrata CompatTab que o TabHelperHoneycomb usa para fazer referência a guias individuais. O CompatTabHoneycomb simplesmente envia proxies de todas as chamadas de método para o objeto ActionBar.Tab contido.

Comece a implementar CompatTabHoneycomb usando as novas APIs ActionBar.Tab:

Kotlin

class CompatTabHoneycomb internal constructor(val activity: Activity, tag: String) :
        CompatTab(tag) {
    ...
    // The native tab object that this CompatTab acts as a proxy for.
    private var mTab: ActionBar.Tab =
            // Proxy to new ActionBar.newTab API
            activity.actionBar.newTab()

    override fun setText(@StringRes textId: Int): CompatTab {
        // Proxy to new ActionBar.Tab.setText API
        mTab.setText(textId)
        return this
    }

    ...
    // Do the same for other properties (icon, callback, etc.)
}

Java

public class CompatTabHoneycomb extends CompatTab {
    // The native tab object that this CompatTab acts as a proxy for.
    ActionBar.Tab mTab;
    ...

    protected CompatTabHoneycomb(FragmentActivity activity, String tag) {
        ...
        // Proxy to new ActionBar.newTab API
        mTab = activity.getActionBar().newTab();
    }

    public CompatTab setText(int resId) {
        // Proxy to new ActionBar.Tab.setText API
        mTab.setText(resId);
        return this;
    }

    ...
    // Do the same for other properties (icon, callback, etc.)
}

Implementar TabHelperHoneycomb

TabHelperHoneycomb é a implementação da classe abstrata TabHelper que envia proxies das chamadas de método para um ActionBar recebido a partir da Activity contida.

Implementar o TabHelperHoneycomb, enviando proxy das chamadas de método para a API ActionBar:

Kotlin

class TabHelperHoneycomb internal constructor(activity: FragmentActivity) : TabHelper(activity) {

    private var mActionBar: ActionBar? = null

    override fun setUp() {
        mActionBar = mActionBar ?: mActivity.actionBar.apply {
            navigationMode = ActionBar.NAVIGATION_MODE_TABS
        }
    }

    override fun addTab(tab: CompatTab) {
        // Tab is a CompatTabHoneycomb instance, so its
        // native tab object is an ActionBar.Tab.
        mActionBar?.addTab(tab.getTab() as ActionBar.Tab)
    }
}

Java

public class TabHelperHoneycomb extends TabHelper {
    ActionBar actionBar;
    ...

    protected void setUp() {
        if (actionBar == null) {
            actionBar = activity.getActionBar();
            actionBar.setNavigationMode(
                    ActionBar.NAVIGATION_MODE_TABS);
        }
    }

    public void addTab(CompatTab tab) {
        ...
        // Tab is a CompatTabHoneycomb instance, so its
        // native tab object is an ActionBar.Tab.
        actionBar.addTab((ActionBar.Tab) tab.getTab());
    }

    // The other important method, newTab() is part of
    // the base implementation.
}

Leia também