У меня есть действие, в котором есть TabHost, содержащий набор TabSpec, каждый со списком, содержащим элементы, которые будут отображаться на вкладке. Когда создается каждый TabSpec, я устанавливаю значок, который будет отображаться в заголовке вкладки.
Спецификации вкладок создаются таким образом в методе setupTabs()
, который циклически создает соответствующее количество вкладок:
TabSpec ts = mTabs.newTabSpec("tab");
ts.setIndicator("TabTitle", iconResource);
ts.setContent(new TabHost.TabContentFactory(
{
public View createTabContent(String tag)
{
...
}
});
mTabs.addTab(ts);
Есть несколько случаев, когда я хочу иметь возможность изменить значок, который отображается на каждой вкладке во время выполнения моей программы. В настоящее время я удаляю все вкладки и снова вызываю приведенный выше код, чтобы воссоздать их.
mTabs.getTabWidget().removeAllViews();
mTabs.clearAllTabs(true);
setupTabs();
Есть ли способ заменить отображаемый значок без удаления и повторного создания всех вкладок?
Короткий ответ: вы ничего не упускаете. Android SDK не предоставляет прямого метода для изменения индикатора TabHost
после его создания. TabSpec
используется только для создания вкладки, поэтому изменение TabSpec
постфактум не повлияет.
Однако я думаю, что есть обходной путь. Позвоните в mTabs.getTabWidget()
, чтобы получить объект TabWidget
. Это всего лишь подкласс ViewGroup
, поэтому вы можете вызывать getChildCount()
и getChildAt()
для доступа к отдельным вкладкам в TabWidget
. Каждая из этих вкладок также является представлением, и в случае вкладки с графическим индикатором и текстовой меткой это почти наверняка какой-то другой ViewGroup
(возможно, LinearLayout
, но это не имеет значения), который содержит ImageView
и TextView
. . Итак, немного повозившись с отладчиком или Log.i
, вы сможете выяснить рецепт получения ImageView
и его непосредственного изменения.
Обратной стороной является то, что если вы не будете осторожны, точный макет элементов управления на вкладке может измениться, и ваше приложение может сломаться. Ваше первоначальное решение, возможно, более надежное, но опять же оно может привести к другим нежелательным побочным эффектам, таким как мерцание или проблемы с фокусировкой.
Чтобы подтвердить ответ Доминика, вот его решение в коде (которое действительно работает):
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));
}
}
});
Конечно, это совсем не доработано, и использование этих прямых индексов в getChildAt () совсем нехорошо ...
См. Мой пост с примером кода относительно Индивидуальные вкладки Android.
Спасибо Spct
Большой! Именно то, что я искал. Спасибо!
Это то, что я сделал, и у меня это работает. Я создал эту функцию в действии, которое простирается от TabBarActivity
public void updateTab(int stringID) {
ViewGroup identifyView = (ViewGroup)getTabWidget().getChildAt(0);
TextView v = (TextView)identifyView.getChildAt(identifyView.getChildCount() - 1);
v.setText(stringID);
}
Вы можете изменить эту функцию, чтобы изменить изображение вместо текста, или вы можете изменить оба, также вы можете изменить это, чтобы получить любую дочернюю вкладку. Меня особенно интересовало изменение текста первой вкладки во время выполнения.
Я вызвал эту функцию из соответствующего действия, используя этот вызов
getParent().updateTab(R.string.tab_bar_analyze);
Просто для информации: если вы используете макет вкладки материалов, обновите первую строку метода как ViewGroup identifyView = (ViewGroup) tabLayout.getTabAt (0) .getCustomView (); Удачного кодирования :)
Попробуй это:
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));
}
}
});
Незначительное улучшение - используйте: TabWidget.getChildTabViewAt (..) вместо getChildAt (...)