Chandramouli
Chandramouli

Reputation: 422

.NET MAUI TabbedPage customization for required style themes

MY EXPECTATION I want to change the colors of the tabbed page themes as per my need.

Default tabbed page theme

enter image description here

Tabbed page theme I want

enter image description here

Environment .NET MAUI, C#, .NET 8

WHAT I HAVE TRIED I tried adding below two configurations in TabbedPage

BarBackgroundColor = UIHelper.DarkBackgroundColor;
BarTextColor = Colors.White;

which gave below result. But here there is NO difference in between selected tab and unselected tab. I want clear difference between selected vs unselected tabs. please suggest

enter image description here

Upvotes: 0

Views: 431

Answers (3)

Chandramouli
Chandramouli

Reputation: 422

I am able to fix this by using below two changes

C# code in TabbedPage related class

BarBackgroundColor = UIHelper.DarkBackgroundColor;
UnselectedTabColor = Color.FromRgb(208, 208, 208);
SelectedTabColor = UIHelper.SecondaryAppColor;

Styles.xml file changes

<style name="Maui.MainTheme" parent="Theme.MaterialComponents.DayNight">
    <item name="tabStyle">@style/CustomTabTabStyle</item>
</style>

<!-- Custom Tab style -->
<style name="CustomTabTabStyle" parent="Widget.MaterialComponents.TabLayout">
    <item name="tabIndicatorColor">#ED7E03</item>
    <item name="tabIndicatorAnimationMode">elastic</item>
    <item name="tabIndicatorAnimationDuration">300</item>
    <item name="android:transition">@android:drawable/ic_menu_slideshow</item>
    <item name="android:windowContentTransitions">true</item>
</style>

Upvotes: 0

Jianwei Sun - MSFT
Jianwei Sun - MSFT

Reputation: 4332

.NET MAUI TabbedPage customization for required style themes

You can modify it by using platform native code. Add the following code in your TabbedPage code behind:

    protected override void OnHandlerChanged()
    {
        base.OnHandlerChanged();
#if ANDROID
        FieldInfo tabbedPageManagerFieldInfo = typeof(TabbedPage).GetField("_tabbedPageManager", BindingFlags.NonPublic | BindingFlags.Instance);
        object tabbedPageManager = tabbedPageManagerFieldInfo?.GetValue(this);
        FieldInfo tabLayoutFieldInfo = tabbedPageManager?.GetType().GetField("_tabLayout", BindingFlags.NonPublic | BindingFlags.Instance);
        var tablayout = tabLayoutFieldInfo?.GetValue(tabbedPageManager) as Google.Android.Material.Tabs.TabLayout;
        if (tablayout != null)
        {
            tablayout.SetSelectedTabIndicatorColor(Android.Graphics.Color.ParseColor("#000000"));
        }
#endif
    }

Use Reflection to get TabbedPageManager(cause it is internal class) and TabLayout. Then call SetSelectedTabIndicatorColor method to set Indicator Color. I set it to black color.

Upvotes: 0

Mustafa Mutasim
Mustafa Mutasim

Reputation: 608

As requested to change theme by code only:

  • Create SharedClass

Enum_TabbedPage_Theme | TabbedPageTheme_1 | TabbedPageTheme_2 | Update_TabbedPageTheme

  • Usage for testing (From Code-Behind of TabbedPage)
SharedClass.Update_TabbedPageTheme(this, SharedClass.Enum_TabbedPage_Theme.TabbedPageTheme_1);

enter image description here

Or

SharedClass.Update_TabbedPageTheme(this, SharedClass.Enum_TabbedPage_Theme.TabbedPageTheme_2);

enter image description here

public static class SharedClass
{
    public enum Enum_TabbedPage_Theme
    {
        TabbedPageTheme_1, TabbedPageTheme_2
    }
    //------------------------------------------------
    public static TabbedPage_Theme TabbedPageTheme_1 =
       new TabbedPage_Theme()
       {
           BarBackgroundColor = Colors.Blue,
           UnselectedTabColor = Colors.Green,
           SelectedTabColor = Colors.Red
       };
    //------------------------------------------------
    public static TabbedPage_Theme TabbedPageTheme_2 =
       new TabbedPage_Theme()
       {
           BarBackgroundColor = Colors.Orange,
           UnselectedTabColor = Colors.Blue,
           SelectedTabColor = Colors.Fuchsia
       };
    //------------------------------------------------
    public static void Update_TabbedPageTheme(TabbedPage Source_TabbedPage, Enum_TabbedPage_Theme Selected_Theme)
    {
        switch (Selected_Theme)
        {
            case Enum_TabbedPage_Theme.TabbedPageTheme_1:
                Source_TabbedPage.BarBackgroundColor = TabbedPageTheme_1.BarBackgroundColor;
                Source_TabbedPage.UnselectedTabColor = TabbedPageTheme_1.UnselectedTabColor;
                Source_TabbedPage.SelectedTabColor = TabbedPageTheme_1.SelectedTabColor;
                break;
            case Enum_TabbedPage_Theme.TabbedPageTheme_2:
                Source_TabbedPage.BarBackgroundColor = TabbedPageTheme_2.BarBackgroundColor;
                Source_TabbedPage.UnselectedTabColor = TabbedPageTheme_2.UnselectedTabColor;
                Source_TabbedPage.SelectedTabColor = TabbedPageTheme_2.SelectedTabColor;
                break;
            default:
                break;
        }
    }
}

public class TabbedPage_Theme
{
    public Color BarBackgroundColor { get; set; } = Colors.White;
    public Color UnselectedTabColor { get; set; } = Colors.Grey;
    public Color SelectedTabColor { get; set; } = Colors.Yellow;
}

For General theme changing | Follow this structure

It will guide you how to access and use colors in .Xaml file, it is accessible in all platforms.


Define default colors: Main_1_Color | Main_2_Color | Main_3_Color

Colors 1: ThemeDark_Main_1_Color | ThemeDark_Main_2_Color | ThemeDark_Main_3_Color

Colors 2: ThemeLight_Main_1_Color | ThemeLight_Main_2_Color | ThemeLight_Main_3_Color

*** NOTE: YOU CAN ADD MORE [Follow Default & Color 1,2 ] ***

Colors 3 : ThemeXXX_Main_1_Color | ThemeXXX_Main_2_Color | ThemeXXX_Main_3_Color | ThemeXXX_Main_4_Color ...

Usage:

<Style TargetType="Label">
    <Setter Property="TextColor" Value="{DynamicResource Main_1_Color}" />
</Style>

OR

 <Border StrokeShape="RoundRectangle 20" BackgroundColor="{StaticResource Main_3_Color}">

To change the theme you can call the static function with the prefix name as a parameter

UpdateThemeColor("ThemeLight");
UpdateThemeColor("ThemeDark");


[ProjectName]\Resources\Styles\Colors.xaml

<?xml version="1.0" encoding="UTF-8" ?>
<?xaml-comp compile="true" ?>
<ResourceDictionary 
    xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
    xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml">

<Color x:Key="Main_1_Color">#2b2b44</Color>
<Color x:Key="Main_2_Color">#343453</Color>
<Color x:Key="Main_3_Color">#42426a</Color>

<Color x:Key="ThemeDark_Main_1_Color">#2b2b44</Color>
<Color x:Key="ThemeDark_Main_2_Color">#343453</Color>
<Color x:Key="ThemeDark_Main_3_Color">#42426a</Color>

<Color x:Key="ThemeLight_Main_1_Color">#bdb1ae</Color>
<Color x:Key="ThemeLight_Main_2_Color">#F8E1D4</Color>
<Color x:Key="ThemeLight_Main_3_Color">#d2d3db</Color>

</ResourceDictionary>

Static class.cs

#region Themes
public static void UpdateThemeColor(string themeName)
{
    ICollection<ResourceDictionary> mergedDictionaries = Application.Current.Resources.MergedDictionaries;

    if (mergedDictionaries is not null)
    {
        foreach (ResourceDictionary dictionaries in mergedDictionaries)
        {
            var Main_1_Color = dictionaries.TryGetValue(themeName + "_" + "Main_1_Color", out var out_Main_1_Color);
            if (Main_1_Color)
            {
                dictionaries["Main_1_Color"] = out_Main_1_Color;
            }

            var Main_2_Color = dictionaries.TryGetValue(themeName + "_" + "Main_2_Color", out var out_Main_2_Color);
            if (Main_2_Color)
            {
                dictionaries["Main_2_Color"] = out_Main_2_Color;
            }

            var Main_3_Color = dictionaries.TryGetValue(themeName + "_" + "Main_3_Color", out var out_Main_3_Color);
            if (Main_3_Color)
            {
                dictionaries["Main_3_Color"] = out_Main_3_Color;
            }
        }

        Preferences.Default.Set("themeName", themeName);
    }
}
#endregion

Upvotes: 2

Related Questions