Обновление значков вкладок Android - PullRequest
39 голосов
/ 31 августа 2008

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

TabSpecs создаются таким образом в методе 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();

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

Ответы [ 6 ]

32 голосов
/ 16 сентября 2008

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

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

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

30 голосов
/ 02 февраля 2009

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

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

10 голосов
/ 05 марта 2009

Возможно, немного поздно, но вы можете взглянуть на эту тему

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

6 голосов
/ 04 февраля 2009

См. Мой пост с примером кода относительно настраиваемых вкладок Android .

Спасибо SPCT

5 голосов
/ 08 июля 2011

Это то, что я сделал, и это работает для меня. Я создал эту функцию в упражнении, которое распространяется на 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);
4 голосов
/ 04 августа 2012

Попробуйте:

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));
        }
    }
});
...