Atualizando ícones da guia Android
-
09-06-2019 - |
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?
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));
}
}
});