Pergunta

Eu tenho uma atividade que possui um TabHost contendo um conjunto de TabSpecs, cada um com um listview contendo os itens a serem exibidos pela guia.Quando cada TabSpec é criado, defino um ícone para ser exibido no cabeçalho da guia.

Os TabSpecs são criados desta forma dentro de um setupTabs() método que faz um loop para criar o número apropriado de guias:

TabSpec ts = mTabs.newTabSpec("tab");
ts.setIndicator("TabTitle", iconResource);

ts.setContent(new TabHost.TabContentFactory(
{
    public View createTabContent(String tag)
    {
        ... 
    }            
});
mTabs.addTab(ts);

Há alguns casos em que desejo alterar o ícone exibido em cada guia durante a execução do meu programa.Atualmente estou excluindo todas as guias e chamando o código acima novamente para recriá-las.

mTabs.getTabWidget().removeAllViews();
mTabs.clearAllTabs(true);
setupTabs();

Existe uma maneira de substituir o ícone que está sendo exibido sem excluir e recriar todas as guias?

Foi útil?

Solução

A resposta curta é: você não está perdendo nada.O Android SDK não fornece um método direto para alterar o indicador de um TabHost depois de criado.O TabSpec é usado apenas para construir a guia, portanto, alterando o TabSpec após o fato não terá efeito.

Acho que há uma solução alternativa, no entanto.Chamar mTabs.getTabWidget() para obter um TabWidget objeto.Esta é apenas uma subclasse de ViewGroup, então você pode ligar getChildCount() e getChildAt() para acessar guias individuais dentro do TabWidget.Cada uma dessas guias também é uma Visualização e, no caso de uma guia com um indicador gráfico e um rótulo de texto, é quase certo que seja alguma outra. ViewGroup (talvez um LinearLayout, mas isso não importa) que contém um ImageView e um TextView.Então, mexendo um pouco no depurador ou Log.i, você deve ser capaz de descobrir uma receita para obter o ImageView e altere-o diretamente.

A desvantagem é que, se você não tomar cuidado, o layout exato dos controles em uma guia poderá mudar e seu aplicativo poderá quebrar.Sua solução inicial talvez seja mais robusta, mas pode levar a outros efeitos colaterais indesejados, como cintilação ou problemas de foco.

Outras dicas

Apenas para confirmar a resposta de Dominic, aqui está a solução dele em código (que realmente funciona):

tabHost.setOnTabChangedListener(new OnTabChangeListener() {
    public void onTabChanged(String tabId) {
        if (TAB_MAP.equals(tabId)) {
            ImageView iv = (ImageView) tabHost.getTabWidget().getChildAt(0).findViewById(android.R.id.icon);
            iv.setImageDrawable(getResources().getDrawable(R.drawable.tab_map_black));
            iv = (ImageView) tabHost.getTabWidget().getChildAt(1).findViewById(android.R.id.icon);
            iv.setImageDrawable(getResources().getDrawable(R.drawable.tab_list_white));
        } else if (TAB_LIST.equals(tabId)) {
            ImageView iv = (ImageView) tabHost.getTabWidget().getChildAt(0).findViewById(android.R.id.icon);
            iv.setImageDrawable(getResources().getDrawable(R.drawable.tab_map_white));
            iv = (ImageView) tabHost.getTabWidget().getChildAt(1).findViewById(android.R.id.icon);
            iv.setImageDrawable(getResources().getDrawable(R.drawable.tab_list_black));
        }
    }
});

É claro que não é nada polido e usar esses índices diretos em getChildAt() não é nada legal...

Pode ser um pouco tarde, mas você pode querer dar uma olhada neste tópico

http://groups.google.com/group/android-developers/browse_thread/thread/ef3bdebcb715b385

Veja minha postagem com exemplo de código sobre Guias Android personalizadas.

Obrigado spct

Isso é o que eu fiz e funciona para mim.Criei esta função na atividade que se estende de TabBarActivity

public void updateTab(int stringID) {
    ViewGroup identifyView = (ViewGroup)getTabWidget().getChildAt(0);
    TextView v =  (TextView)identifyView.getChildAt(identifyView.getChildCount() - 1);
    v.setText(stringID);
}

Você pode modificar esta função para alterar a imagem em vez do texto ou pode alterar ambos, também pode modificar isso para obter qualquer guia filho.Eu estava particularmente interessado em modificar o texto da primeira aba em tempo de execução.

Chamei esta função da atividade relevante usando esta chamada

getParent().updateTab(R.string.tab_bar_analyze);

Experimente isto:

tabHost.setOnTabChangedListener(new OnTabChangeListener() {
    public void onTabChanged(String tabId) {
        if (TAB_MAP.equals(tabId)) {
            ImageView iv = (ImageView) tabHost.getTabWidget().getChildAt(0).findViewById(android.R.id.icon);
            iv.setImageDrawable(getResources().getDrawable(R.drawable.tab_map_black));
            iv = (ImageView) tabHost.getTabWidget().getChildAt(1).findViewById(android.R.id.icon);
            iv.setImageDrawable(getResources().getDrawable(R.drawable.tab_list_white));
        } else if (TAB_LIST.equals(tabId)) {
            ImageView iv = (ImageView) tabHost.getTabWidget().getChildAt(0).findViewById(android.R.id.icon);
            iv.setImageDrawable(getResources().getDrawable(R.drawable.tab_map_white));
            iv = (ImageView) tabHost.getTabWidget().getChildAt(1).findViewById(android.R.id.icon);
            iv.setImageDrawable(getResources().getDrawable(R.drawable.tab_list_black));
        }
    }
});
Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top