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

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

Решение

Короткий ответ: вы ничего не упускаете. 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() совсем нехорошо...

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

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

См. Мой пост с примером кода, касающимся настраиваемых вкладок 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);

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

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

Мы можем использовать поток, посмотрите эту ссылку

http://groups.google.com/group/android-developers/browse_thread/thread/ef3bdebcb715b385
Другие вопросы по тегам