43

我有一个活动,它有一个包含一组 TabSpecs 的 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();

有没有办法在不删除和重新创建所有选项卡的情况下替换正在显示的图标?

4

5 回答 5

37

简短的回答是,你不会错过任何东西。Android SDK 不提供TabHost在创建后更改 a 指示器的直接方法。TabSpec仅用于构建选项卡,因此事后更改将TabSpec无效。

不过,我认为有一个解决方法。调用mTabs.getTabWidget()以获取TabWidget对象。这只是 的子类ViewGroup,因此您可以调用getChildCount()getChildAt()访问TabWidget. 这些选项卡中的每一个也是一个视图,对于带有图形指示器和文本标签的选项卡,几乎可以肯定是其他一些ViewGroup(可能是 a LinearLayout,但没关系)包含 anImageView和 a TextView。因此,稍微摆弄一下调试器或Log.i,您应该能够找出一个方法来获取ImageView并直接更改它。

不利的一面是,如果您不小心,选项卡中控件的确切布局可能会发生变化,并且您的应用程序可能会中断。您最初的解决方案可能更健壮,但又可能导致其他不需要的副作用,例如闪烁或焦点问题。

于 2008-09-15T23:59:28.807 回答
30

只是为了确认多米尼克斯的答案,这是他的代码解决方案(实际上有效):

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() 中使用这些直接索引一点都不好......

于 2009-02-02T17:19:26.177 回答
6

请参阅我的帖子,其中包含有关Customized Android Tabs的代码示例。

谢谢 spct

于 2009-02-04T05:41:23.260 回答
5

这就是我所做的,它对我有用。我在从 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);
于 2011-07-08T17:13:58.257 回答
4

试试这个:

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));
        }
    }
});
于 2012-08-04T12:48:59.833 回答