Обновление значков вкладки Android

У меня есть действие, в котором есть TabHost, содержащий набор TabSpecs, каждый со списком, содержащим элементы, которые будут отображаться на вкладке. Когда создается каждый 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();

Есть ли способ заменить отображаемый значок без удаления и повторного создания всех вкладок?


person lnediger    schedule 31.08.2008    source источник


Ответы (5)


Короткий ответ: вы ничего не упускаете. Android SDK не предоставляет прямого метода изменения индикатора TabHost после его создания. TabSpec используется только для создания вкладки, поэтому изменение TabSpec после факта не будет иметь никакого эффекта.

Я думаю, что есть обходной путь. Позвоните mTabs.getTabWidget(), чтобы получить объект TabWidget. Это просто подкласс ViewGroup, поэтому вы можете вызывать getChildCount() и getChildAt() для доступа к отдельным вкладкам в TabWidget. Каждая из этих вкладок также является представлением, а в случае вкладки с графическим индикатором и текстовой меткой это почти наверняка какая-то другая ViewGroup (может быть LinearLayout, но это не имеет значения), содержащая ImageView и TextView . Итак, немного повозившись с отладчиком или Log.i, вы сможете найти рецепт, чтобы получить ImageView и изменить его напрямую.

Недостатком является то, что если вы не будете осторожны, точное расположение элементов управления на вкладке может измениться, и ваше приложение может сломаться. Ваше первоначальное решение, возможно, более надежное, но опять же оно может привести к другим нежелательным побочным эффектам, таким как мерцание или проблемы с фокусировкой.

person dmazzoni    schedule 15.09.2008

Просто чтобы подтвердить ответ доминика, вот его решение в коде (которое действительно работает):

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() совсем нехорошо...

person srakyi    schedule 02.02.2009
comment
Небольшое улучшение - используйте: TabWidget.getChildTabViewAt(..) вместо getChildAt(...) - person tonys; 07.10.2010

См. мой пост с примером кода, касающимся настраиваемых вкладок Android.

спасибо

person Community    schedule 04.02.2009
comment
Здорово! Именно то, что я искал. Спасибо! - person Fedor; 02.11.2009

Это то, что я сделал, и это работает для меня. Я создал эту функцию в действии, которое простирается от 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);
person Mohit    schedule 08.07.2011
comment
Просто для информации: если вы используете макет вкладок материалов, обновите первую строку метода до ViewGroup идентифицируйтеView = (ViewGroup) tabLayout.getTabAt(0).getCustomView(); Удачного кодирования :) - person Mamta Kaundal; 10.01.2019

Попробуй это:

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));
        }
    }
});
person Gautam Vasoya    schedule 04.08.2012