根据应用主题修改ViewPager Tabs

Modifying ViewPager Tabs according to the theme of the application

我创建了一个简单的 ViewPager 标签视图。 tabview 有一个我设计的自定义主题。

选项卡视图如下所示:

tabview 的布局 XML 文件:

<?xml version="1.0" encoding="utf-8"?>
<android.support.v4.view.ViewPager
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/pager"
    android:layout_width="match_parent"
    android:layout_height="match_parent">
</android.support.v4.view.ViewPager>

我为ViewPager创建的自定义主题:

<?xml version="1.0" encoding="utf-8"?>


<resources>

    <style name="Theme.Custom_tab_theme" parent="@android:style/Theme.Holo.Light">
        <item name="android:actionBarItemBackground">@drawable/selectable_background_custom_tab_theme</item>
        <item name="android:popupMenuStyle">@style/PopupMenu.Custom_tab_theme</item>
        <item name="android:dropDownListViewStyle">@style/DropDownListView.Custom_tab_theme</item>
        <item name="android:actionBarTabStyle">@style/ActionBarTabStyle.Custom_tab_theme</item>
        <item name="android:actionDropDownStyle">@style/DropDownNav.Custom_tab_theme</item>
        <item name="android:actionBarStyle">@style/ActionBar.Solid.Custom_tab_theme</item>
        <item name="android:actionModeBackground">@drawable/cab_background_top_custom_tab_theme</item>
        <item name="android:actionModeSplitBackground">@drawable/cab_background_bottom_custom_tab_theme</item>
        <item name="android:actionModeCloseButtonStyle">@style/ActionButton.CloseMode.Custom_tab_theme</item>
        <item name="actionMenuTextColor">@color/white</item>
        <item name="android:actionMenuTextColor">@color/white</item>

    </style>


    <style name="TextAppearance">
        <item name="android:textColor">@android:color/white</item>
    </style>

    <style name="ActionBar.Solid.Custom_tab_theme" parent="@android:style/Widget.Holo.Light.ActionBar.Solid">
        <item name="android:background">@drawable/ab_solid_custom_tab_theme</item>
        <item name="android:backgroundStacked">@drawable/ab_stacked_solid_custom_tab_theme</item>
        <item name="android:backgroundSplit">@drawable/ab_bottom_solid_custom_tab_theme</item>
        <item name="android:progressBarStyle">@style/ProgressBar.Custom_tab_theme</item>
    </style>

    <style name="ActionBar.Transparent.Custom_tab_theme" parent="@android:style/Widget.Holo.Light.ActionBar">
        <item name="android:background">@drawable/ab_transparent_custom_tab_theme</item>
        <item name="android:progressBarStyle">@style/ProgressBar.Custom_tab_theme</item>
    </style>

    <style name="PopupMenu.Custom_tab_theme" parent="@android:style/Widget.Holo.Light.ListPopupWindow">
        <item name="android:popupBackground">@drawable/menu_dropdown_panel_custom_tab_theme</item>  
    </style>

    <style name="DropDownListView.Custom_tab_theme" parent="@android:style/Widget.Holo.Light.ListView.DropDown">
        <item name="android:listSelector">@drawable/selectable_background_custom_tab_theme</item>
    </style>

    <style name="ActionBarTabStyle.Custom_tab_theme" parent="@android:style/Widget.Holo.Light.ActionBar.TabView">
        <item name="android:background">@drawable/tab_indicator_ab_custom_tab_theme</item>
    </style>

    <style name="DropDownNav.Custom_tab_theme" parent="@android:style/Widget.Holo.Light.Spinner">
        <item name="android:background">@drawable/spinner_background_ab_custom_tab_theme</item>
        <item name="android:popupBackground">@drawable/menu_dropdown_panel_custom_tab_theme</item>
        <item name="android:dropDownSelector">@drawable/selectable_background_custom_tab_theme</item>
    </style>

    <style name="ProgressBar.Custom_tab_theme" parent="@android:style/Widget.Holo.Light.ProgressBar.Horizontal">
        <item name="android:progressDrawable">@drawable/progress_horizontal_custom_tab_theme</item>
    </style>

    <style name="ActionButton.CloseMode.Custom_tab_theme" parent="@android:style/Widget.Holo.Light.ActionButton.CloseMode">
        <item name="android:background">@drawable/btn_cab_done_custom_tab_theme</item>
    </style>

    <!-- this style is only referenced in a Light.DarkActionBar based theme -->
    <style name="Theme.Custom_tab_theme.Widget" parent="@android:style/Theme.Holo">
        <item name="android:popupMenuStyle">@style/PopupMenu.Custom_tab_theme</item>
        <item name="android:dropDownListViewStyle">@style/DropDownListView.Custom_tab_theme</item>
    </style>

</resources>

现在我想更多地自定义 TabView 以包含图标,并在选中时更改 ViewPager 的图标和文本颜色。

我想达到的目标:

所以,基本上我想做 3 件事:

  1. 将图片添加到选项卡
  2. 选中时更改选项卡的图片和文字颜色
  3. 更改选项卡文本的字体样式(删除粗体并使用自定义字体)

我应该怎么做才能实现同样的目标?是否应该修改自定义主题?

请从您的 PagerAdapter 尝试此操作。

private int[] imageResId = {
        R.drawable.ic_one,
        R.drawable.ic_two,
        R.drawable.ic_three
};

// ...

@Override
public CharSequence getPageTitle(int position) {
    // Generate title based on item position
    // return tabTitles[position];

    // getDrawable(int i) is deprecated, use getDrawable(int i, Theme theme) for min SDK >=21
    // or ContextCompat.getDrawable(Context context, int id) if you want support for older versions.
    // Drawable image = context.getResources().getDrawable(iconIds[position], context.getTheme());
    // Drawable image = context.getResources().getDrawable(imageResId[position]);

    Drawable image = ContextCompat.getDrawable(context, imageResId[position]);
    image.setBounds(0, 0, image.getIntrinsicWidth(), image.getIntrinsicHeight());
    SpannableString sb = new SpannableString(" ");
    ImageSpan imageSpan = new ImageSpan(image, ImageSpan.ALIGN_BOTTOM);
    sb.setSpan(imageSpan, 0, 1, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
    return sb;
}

试试这个

1) 将图片添加到选项卡

    // here you add an array of your icon   
 final int[] ICONS = new int[] {
                    R.drawable.ic_browse,
                    R.drawable.ic_start,
                    R.drawable.ic_collage,
            };

for (int i=0; i < tabs.length; i++)
        {
        actionBar.addTab(actionBar.newTab().setText(tabs[i])
                                 .setIcon(NewsFeedActivity.this.getResources().getDrawable(ICONS[i]))
                                 .setTabListener(this));
        }//endfor

2) 选中时更改选项卡的图片和文字颜色

您可以使用 activity 的 tabHost.getCurrentTab() onResume() 来检测您选择了哪个选项卡。

我假设您正在使用设计库中的 TabLayout(如果您不是,您可能应该使用它,因为它非常易于使用)。 class 文档解释了如何使用 ViewPager 对其进行设置,但这只会为选项卡提供标题而不是图标。之后您可以自己添加图标:

TabLayout tabLayout = (TabLayout) findViewById(...);
// normal setup, text-only tabs
tabLayout.setupWithViewPager(viewPager);
// add the icons
for (int i = 0; i < tabLayout.getTabCount(); i++) {
    TabLayout.Tab tab = tabLayout.getTabAt(i);
    tab.setIcon(R.drawable.tab_icon); // different icon per tab
}

要为图标着色,您可以使用 state list drawables to show a different colored icon for android:state_selected="true". You can do the same thing for the text by making a color state list 和相同的状态属性。

要使文本不加粗,您可以将自己的文本外观应用到 TabLayout。通过做一个样式声明来做到这一点(注意我在这里也应用了前面提到的颜色状态列表):

<!-- TextAppearance.Design.Tab is the default used in the Design Library -->
<style name="TabTextAppearance" parent="TextAppearance.Design.Tab">
    <item name="android:textColor">@color/tab_text_color_state_list</color>
    <item name="android:fontFamily">sans-serif</color>
</style>

然后在您的布局中使用它:

<LinearLayout 
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    ... >

    <android.support.design.widget.TabLayout
        android:id="@+id/pager"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:minHeight="?android:attr/actionBarSize"
        app:tabTextAppearance="@style/TabTextAppearance" />

    <android.support.v4.view.ViewPager
        android:id="@+id/pager"
        android:layout_width="match_parent"
        android:layout_height="0dp"
        android:layout_weight="1" />

</LinearLayout>