locked
Custom TabbedRenderer to set tab text color on Android RRS feed

  • Question

  • User3331 posted

    I found an iOS render:

    • http://forums.xamarin.com/discussion/17811/tabbedpage-tabbar-background-color-tint

    but I can't seem to find a similar Android rendered to set to set the tab text color. I found a bunch of posts that reference things like background color:

    • http://forums.xamarin.com/discussion/25491/tabbed-page-action-bar-rendering#latest

    but nothing for tab text color.

    // http://forums.xamarin.com/discussion/comment/80381/#Comment_80381       
    public class CustomTabRenderer : TabbedRenderer
    {
        private Activity activity;
        private bool isFirstDesign = true;
    
        protected override void OnElementPropertyChanged(object sender, PropertyChangedEventArgs e)
        {
            base.OnElementPropertyChanged(sender, e);
            activity = this.Context as Activity;
        }
    
        protected override void OnWindowVisibilityChanged(ViewStates visibility)
        {
            base.OnWindowVisibilityChanged(visibility);
            if (isFirstDesign)
            {
                ActionBar actionBar = activity.ActionBar;
    
                ColorDrawable colorDrawable = new ColorDrawable(Color.White);
                actionBar.SetStackedBackgroundDrawable(colorDrawable);
    
                // TODO: set tab text color
    
                isFirstDesign = false; 
            }
        }
    }
    
    Wednesday, November 19, 2014 3:36 AM

Answers

  • User37696 posted

    Hi @RonGrabowski?!

    I think it would be more appropriate to use Android Themes and Styles for this.

    You add a Styles.xml to your Resources -> values folder and put this in there:

        <?xml version="1.0" encoding="utf-8"?>
        <resources>
            <style name="MyTheme"
                   parent="@android:style/Theme.Holo">
                <item name="android:actionBarTabTextStyle">@style/MyActionBarTabText</item>
            </style>
    
            <style name="MyActionBarTabText"
                   parent="@android:style/Widget.Holo.ActionBar.TabText">
                <item name="android:textColor">#FF3300</item>
            </style>
        </resources>
    

    Next, use the theme we created above in your MainActivity in the Android App project. Modify the class attribute on MainActivity and add the Theme attribute:

    [Activity(Label = "MyApp.Droid", Icon = "@drawable/icon", MainLauncher = true, Theme = "@style/MyTheme", ConfigurationChanges = ConfigChanges.ScreenSize | ConfigChanges.Orientation)]
    

    Notice the Theme = "@style/MyTheme"

    I changed the text color to red (FF3300):

    Hope that helps!

    • Marked as answer by Anonymous Thursday, June 3, 2021 12:00 AM
    Thursday, November 20, 2014 12:37 AM

All replies

  • User37696 posted

    Hi @RonGrabowski?!

    I think it would be more appropriate to use Android Themes and Styles for this.

    You add a Styles.xml to your Resources -> values folder and put this in there:

        <?xml version="1.0" encoding="utf-8"?>
        <resources>
            <style name="MyTheme"
                   parent="@android:style/Theme.Holo">
                <item name="android:actionBarTabTextStyle">@style/MyActionBarTabText</item>
            </style>
    
            <style name="MyActionBarTabText"
                   parent="@android:style/Widget.Holo.ActionBar.TabText">
                <item name="android:textColor">#FF3300</item>
            </style>
        </resources>
    

    Next, use the theme we created above in your MainActivity in the Android App project. Modify the class attribute on MainActivity and add the Theme attribute:

    [Activity(Label = "MyApp.Droid", Icon = "@drawable/icon", MainLauncher = true, Theme = "@style/MyTheme", ConfigurationChanges = ConfigChanges.ScreenSize | ConfigChanges.Orientation)]
    

    Notice the Theme = "@style/MyTheme"

    I changed the text color to red (FF3300):

    Hope that helps!

    • Marked as answer by Anonymous Thursday, June 3, 2021 12:00 AM
    Thursday, November 20, 2014 12:37 AM
  • User135696 posted

    How should I change it if I want to change the bbackground color?

    Wednesday, June 17, 2015 2:59 PM
  • User103333 posted

    @BrunoApellido using @JohnMiller Example just modify the following:

    <style name="MyTheme" parent="@android:style/Theme.Holo"> <item name="android:actionBarTabStyle">@style/MyActionBarTabBack</item> <item name="android:actionBarTabTextStyle">@style/MyActionBarTabText</item> </style>

    And add:

    <style name="MyActionBarTabBack" parent="@android:style/Widget.Holo.ActionBar.TabView"> <item name="android:background">#00FFFF</item> </style>

    Now the background color of the tabs will be teal (00FFFF)

    Tuesday, July 7, 2015 3:58 AM
  • User120795 posted

    I´ve changed the background color of my tabs in the Style.xml ( to blue) but now the selected indicator is not visible (i think it has the same color as the background), do you know how to change its color?

    Monday, July 27, 2015 2:20 PM
  • User52679 posted

    +1, I need to change the color of the selected tab

    Tuesday, August 11, 2015 7:56 PM
  • User60022 posted

    @JohnMiller how is it "more appropriate" to have to style an application in two places, once in the PCL (or shared project) and again for portions of android?

    Isn't the point of Xamarin Forms Styling and Xamarin Forms in general to be able to do the majority of the interface design within the PCL and then customize as necessary through Custom Renderers?

    This styling approach is the way to style an application through the PCL, as per your own documentation for Xamarin Forms: https://developer.xamarin.com/guides/cross-platform/xamarin-forms/working-with/styles/

    How does it make any sense to have to customize portions of the application through Android specific styling? Doesn't that defeat the entire purpose of Xamarin Forms and the global styling?

    If, for unimaginable reasons, Xamarin hasn't fully implimented app styling in the PCL shouldn't that be included in the documentation or at least admitted at some point? And if that is the case then please help us in Custom Rendering the TabbedPages so we can work out how to pass the PCL styling down to the custom renderer and not be styling an application in two different ways in two different places.

    This kind of disjointed approach to something as critical as styling an application is what takes a phenomenal concept such as Xamarin Forms and makes it a mediocre hack that we are paying a premium price for.

    Thanks M

    Wednesday, September 2, 2015 5:29 PM
  • User37696 posted

    @MikeRowley403,

    Sorry for any confusion. My comment was from a while ago (November 2014), so I am not sure the Styles API was out for Forms yet.

    Isn't the point of Xamarin Forms Styling and Xamarin Forms in general to be able to do the majority of the interface design within the PCL and then customize as necessary through Custom Renderers?

    That sounds reasonable. To me, it's easier to use the native features available to customize things that are not yet customizable in Forms. On Android, it was easier for me to customize this with a Theme/Style XML file because that is how the platform suggests doing it. I am sure you could do this programmatically in a custom renderer if you wanted to - at the time the only info I found to programmatically do this looked nasty.

    I don't think we currently document every missing feature, I'll suggest we make a note in the documentation. I'll also ask what the recommended practice is related to this too, as my suggestion was just my opinion.

    What specifically do you want to customize on Android in a TabbedPage? If we can figure out how to do it natively, we will be closer to making a custom renderer to do it.

    Wednesday, September 2, 2015 7:07 PM
  • User60022 posted

    Thanks @JohnMiller for the reply, I believe you might be correct as the stable 1.3 came out the following month, my mistake on the timeline of that release, it was the pre-release that came out in November.

    I am trying to customize the ActionBar and specifically the Tabs, however Android.App.ActionBar.Tab is obsolete so I am at a loss for how to customize this using Global Styles (which would be the ideal solution) or a Custom Renderer.

    Ideally I am looking to customize Tabs in the exact same way as in this article using the setter in C# code, even if that means a Custom Renderer built to support the style changes I need. https://developer.xamarin.com/guides/cross-platform/xamarin-forms/working-with/styles/

    I think Xamarin developers would greatly appreciate a deficiency list for things like this, especially for new developers to Xamarin like myself, it is exceedingly difficult to determine if a feature gap like this is simply a knowledge gap or actually a feature gap and having no direct support from Xamarin is very frustrating.

    We either need better and complete documentation or how to support like Telerik offers, where you can purchase support contracts and be able to ask tech support questions about how to use the products features to solve a specific problem.

    Right now we have neither and it is increasingly difficult to use Xamarin products on production timelines.

    Thanks again for your assistance. M

    Wednesday, September 2, 2015 7:52 PM
  • User86859 posted

    @JohnMiller and @MiguelCervantes greate samples, worked for me. Tanks

    Monday, September 7, 2015 7:22 AM
  • User114763 posted

    Xamarin.Forms. seem to ignore theme changes to the tab (action bar) header background and tint color when set in native theme so to get a complete experience it seems like to have to use both native theming and custom renderers

    Tuesday, September 15, 2015 7:02 AM
  • User60022 posted

    This may be related to the current gap in Xamarin.Forms support for Material Design. Without specifics it would be hard to say but I can tell you there is currently no support for Material Design features in Forms.

    Tuesday, September 15, 2015 3:27 PM
  • User60022 posted

    @JohnMiller any chance you have some information for me about customizing the tabs in custom renderers instead of Android themes? I never heard back from you or Keith Ballinger who I thought was going to follow up on this with you after I spoke with him.

    Thanks M

    Tuesday, September 15, 2015 4:01 PM
  • User37696 posted

    @MikeRowley403,

    I did play with this for a little to see what I could come up with. I made a basic proof of concept using the techniques discussed in this forum post.

    Basically, you will need to extend TabbedPage to have some bindable properties that it does not currently have to style things you want. For example, I added a new bindable property to my CustomTabbedPage:

    ``` public class CustomTabbedPage : TabbedPage { public static readonly BindableProperty TabTextColorProperty = BindableProperty.Create (p => p.TabTextColor, default(Color));

    public Color TabTextColor {
        get { return (Color)GetValue (TabTextColorProperty); }
        set { SetValue (TabTextColorProperty, value); }
    }
    

    } ```

    Now, you can set a style for it:

    ``` var tabbed = new CustomTabbedPage(); tabbed.Children.Add(new ContentPage() { Title = "Tab 1" });

    var tabbedStyle = new Style(typeof(CustomTabbedPage)) { Setters = { new Setter {Property = CustomTabbedPage.TabTextColorProperty, Value = Color.Red} } };

    tabbed.Style = tabbedStyle;

    MainPage = tabbed; ```

    And to make all this work, the Renderer needs to do something with that property. Below is a basic implementation. It's nothing Forms specific. The real question to answer is "How do we customize ActionBar in Android programmatically". From my research, it's ugly. Maybe someone with more Android experience has a better solution. This is what I found to work:

    ``` public class CustomTabbedPageRenderer : TabbedRenderer { Activity _activity;

    protected override void OnElementChanged (ElementChangedEventArgs<TabbedPage> e)
    {
        base.OnElementChanged (e);
    
        _activity = Context as Activity;
    }
    
    protected override void OnWindowVisibilityChanged (Android.Views.ViewStates visibility)
    {
        base.OnWindowVisibilityChanged (visibility);
    
        UpdateTabTextColor();
    }
    
    void UpdateTabTextColor ()
    {
        var actionBar = _activity.ActionBar;
    
        for (int i = 0; i < actionBar.TabCount; i++) {
    
            var tab = actionBar.GetTabAt(i);
            var textView = new TextView(Context) {
                TextFormatted = tab.TextFormatted,
                Gravity = Android.Views.GravityFlags.Center,
                LayoutParameters = new LayoutParams(LayoutParams.WrapContent, LayoutParams.MatchParent)
            };
    
            var tabbed = Element as CustomTabbedPage;
            textView.SetTextColor(tabbed.TabTextColor.ToAndroid());
    
            tab.SetCustomView(textView);
        }
    }
    

    } ```

    The above is basic, and should be extended if tabs are added at runtime or something. You can probably do something smart in OnElementChanged and call UpdateTabTextColor() there too. I found no way to customize the text color of the existing things in the ActionBar text. Instead, all suggestions related to using a CustomView with a TextView. This also lost the default styling that the built in Themes of Android use, so I am not sure how to fix that yet.

    This is why I preferred Android Styles/Themes - it's documented better. However, I'm guessing these things can be done, I have just not found the info on how to do it natively yet. I hope this helps!

    Wednesday, September 16, 2015 4:07 PM
  • User204471 posted

    @JohnMiller I am using OnWindowVisibilityChanged method to customise my Tab View for tabs added into Tabbed Page. I am setting flag to change tab custom view only once. But problem is my UI(Added in Page content) is getting distracted and does not loads properly. Can you please tell me exact place where I can change Tab custom view ?

    Thursday, April 14, 2016 4:40 PM
  • User37696 posted

    Hi YogeshPatil,

    It would be better to start a new post, and provide a sample on what's not working for you. This post is 7 months old and I don't want to keep surfacing it. I'm not too familiar with what you are doing, so some more code might help me.

    Thursday, April 14, 2016 6:25 PM
  • User184899 posted

    I was getting an error like No resource found that matches the given name (at 'theme' with value '@style/MyTheme')

    The fix is to set the Styles.xml property Build action to AndroidResource

    Saturday, January 21, 2017 1:00 AM
  • User297645 posted

    Hello everyone,

    I need to change the background color of my tabs.. I am new to Xamarin as well. Please help

    I just need to change the background color of tabbed pages :(

    Thursday, February 16, 2017 11:34 AM
  • User357575 posted

    @DarshanS said: Hello everyone,

    I need to change the background color of my tabs.. I am new to Xamarin as well. Please help

    I just need to change the background color of tabbed pages :(

    public tabbedPage() { InitializeComponent(); this.BarBackgroundColor = Color.FromHex("#54386B"); }

    little late.

    Thursday, May 31, 2018 4:42 PM
  • User364101 posted

    @JohnMiller said: Hi @RonGrabowski?!

    I think it would be more appropriate to use Android Themes and Styles for this.

    You add a Styles.xml to your Resources -> values folder and put this in there:

      <?xml version="1.0" encoding="utf-8"?>
      <resources>
          <style name="MyTheme"
                 parent="@android:style/Theme.Holo">
              <item name="android:actionBarTabTextStyle">@style/MyActionBarTabText</item>
          </style>
    
          <style name="MyActionBarTabText"
                 parent="@android:style/Widget.Holo.ActionBar.TabText">
              <item name="android:textColor">#FF3300</item>
          </style>
      </resources>
    

    Next, use the theme we created above in your MainActivity in the Android App project. Modify the class attribute on MainActivity and add the Theme attribute:

    [Activity(Label = "MyApp.Droid", Icon = "@drawable/icon", MainLauncher = true, Theme = "@style/MyTheme", ConfigurationChanges = ConfigChanges.ScreenSize | ConfigChanges.Orientation)]
    

    Notice the Theme = "@style/MyTheme"

    I changed the text color to red (FF3300):

    Hope that helps!

    Hi @JohnMiller , I am sharing my styles.xml page. I have changed the navigation bar color but unable to find the way in which I can change the color of tabText color.

     <item name="colorPrimary">#49C6C5</item>
    <!-- colorPrimaryDark is used for the status bar -->
    <item name="colorPrimaryDark">#000000</item>
    <!-- colorAccent is used as the default value for colorControlActivated
         which is used to tint widgets -->
    <item name="colorAccent">#F6694A</item>
    

    the code you have shared previously is fine but I am unable to use that. I want to change the color of navigation bar as well as tabbartextcolor. Please help.

    Tuesday, June 5, 2018 10:25 AM