Forum Xamarin.Forms

Custom TabbedRenderer to set tab text color on Android

RonGrabowskiRonGrabowski USMember, University
edited November 2014 in Xamarin.Forms

I found an iOS render:

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:

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

Best Answer

Answers

  • BrunoApellidoBrunoApellido USMember

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

  • MiguelCervantesMiguelCervantes MXMember ✭✭✭
    edited July 2015

    @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)

  • Mariano.7927Mariano.7927 USMember

    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?

  • BrunoPasquiniBrunoPasquini USMember ✭✭

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

  • MikeRowley403MikeRowley403 CAMember ✭✭✭

    @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

  • JohnMillerJohnMiller USForum Administrator, Xamarin Team Xamurai

    @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.

  • MikeRowley403MikeRowley403 CAMember ✭✭✭

    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

  • AlinFrunzaAlinFrunza ROMember

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

  • 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

  • MikeRowley403MikeRowley403 CAMember ✭✭✭

    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.

  • MikeRowley403MikeRowley403 CAMember ✭✭✭

    @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

  • JohnMillerJohnMiller USForum Administrator, Xamarin Team Xamurai
    edited September 2015

    @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<CustomTabbedPage,Color> (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!

  • YogeshPatil.2761YogeshPatil.2761 USMember ✭✭
    edited April 2016

    @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 ?

  • JohnMillerJohnMiller USForum Administrator, Xamarin Team Xamurai
    edited April 2016

    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.

  • EnriqueZavaletaEnriqueZavaleta USMember ✭✭

    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

  • DarshanSDarshanS USMember ✭✭

    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 :(

  • Matt_PerleyMatt_Perley CAMember ✭✭

    @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.

  • shubham1shubham1 Member ✭✭✭

    @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.

Sign In or Register to comment.