hartk1213
hartk1213

Reputation: 33

changing xamarin.forms colors at runtime

i am making an app using xamarin.forms and i have set up a color scheme that i want to be able to change within the settings to either a dark style or a light style right now it all works except i have to restart the app everytime after i select a different color scheme.

here is where i am trying to change it at runtime

   private void DarkThemeClick(object sender, EventArgs e)
    {
        database.DropTable(new StyleModel());
        database.CreateTable(new StyleModel());
        database.SaveItem(new StyleModel() { ThemeNum = 1 });
        App.ActiveStyle = new DarkStyle();
    }

    private void LightThemeClick(object sender, EventArgs e)
    {
        database.DropTable(new StyleModel());
        database.CreateTable(new StyleModel());
        database.SaveItem(new StyleModel() { ThemeNum = 0 });
        App.ActiveStyle = new LightStyle();
    }

here is an example of an item that im using that i want to change the colors on

    using System;
using TestXamForms.Style;
using Xamarin.Forms;

namespace TestXamForms.Helpers
{
class EntryValueCell : StackLayout
{

    public EntryValueCell(string key,int FieldIdx, string value = "",  bool isNumber = false)
    {
        Entry entry;
        Label label = new Label()
        {
            TextColor = App.ActiveStyle.LabelTextColor,
            Text = key,
            HorizontalOptions = LayoutOptions.End
        };
        if (isNumber)
        {
            entry = new Entry()
            {
                ClassId = FieldIdx.ToString(),
                TextColor = App.ActiveStyle.LabelTextColor,
                HorizontalOptions = LayoutOptions.FillAndExpand,
                Keyboard = Keyboard.Numeric,
                Text = value, 


            };
        }
        else
        {
            entry = new Entry()
            {
                ClassId = FieldIdx.ToString(),
                TextColor = App.ActiveStyle.LabelTextColor,
                HorizontalOptions = LayoutOptions.FillAndExpand,
                Keyboard = Keyboard.Text,
                Text = value
            };
        }

        BackgroundColor = App.ActiveStyle.StackLayoutBackground;
        Orientation = StackOrientation.Horizontal;
        VerticalOptions = LayoutOptions.FillAndExpand;
        Children.Add(label);
        Children.Add(entry);
    }
}
}

here is an example of one of the color schemes

    using Xamarin.Forms;

   namespace TestXamForms.Style
 {
     public  class LightStyle : StyleBase
    {
       public LightStyle()
        {
        LabelTextColor = Color.Black;
        ButtonColor = Color.FromHex("337ab7");
        StackLayoutBackground = Color.FromHex("eff0f1");
        InputBackgroundColor = Color.White;
        PlaceHolderColor = Color.Gray;
        TableColor = Color.FromHex("e6e6e6");
        StacklayoutBorderColor = Color.Black;
       }
      }
     }

here is styleBase that the file above is inheriting

using TestXamForms.Models;
using Xamarin.Forms;

namespace TestXamForms.Style
{
public class StyleBase : ModelBase
{
    public enum ThemeNum : int
    {
        Light = 0, Dark = 1
    }
    public Color LabelTextColor { get; set; }
    public Color ButtonColor { get; set; }
    public Color StackLayoutBackground { get; set; }
    public Color InputBackgroundColor { get; set; }
    public Color PlaceHolderColor { get; set; }

    public Color StacklayoutBorderColor { get; set; }

    public Color TableColor { get; set; }

    public int ThemeNums { get; set; }

}
}

here is the part of App.cs file that loads the color scheme when the app starts

    static StyleBase activeStyle { get; set; }


    public static StyleBase ActiveStyle
    {
        get
        {
            if (activeStyle == null)
            {
                StyleModel styleBase = database.GetItems(new     StyleModel()).First();
                if (styleBase == null)
                {
                    database.SaveItem(new StyleModel() { ThemeNum = 0 }); //sets the default color scheme to light style 
                    styleBase = database.GetItems(new StyleModel()).First();
                }
                int themeNum = styleBase.ThemeNum;
                switch (themeNum)
                {
                    case (int)StyleBase.ThemeNum.Dark:
                        activeStyle = new DarkStyle();
                        break;
                    case (int)StyleBase.ThemeNum.Light:
                        activeStyle = new LightStyle();
                        break;
                }
            }
            return activeStyle;
        }
        set { } }

Upvotes: 3

Views: 6312

Answers (2)

Rohit Vipin Mathews
Rohit Vipin Mathews

Reputation: 11787

The problem you are facing is that everything is already rendered and you have not bound to any property which will re render the changes you made in the code to the UI. You can take the MVVM approach and create properties and bind to them and notify when they are changed in the UI thread.

If you are interested only in dark and light themes then you can use the in built Light Theme and Dark Theme. You can also create Custom Themes.

A theme is added to a Xamarin.Forms application by including the Xamarin.Forms.Theme.Base Nuget package, plus an additional package that defines a specific theme (eg. Xamarin.Forms.Theme.Light) or else a local theme can be defined for the application.

In addition to automatically styling the common controls the Light and Dark themes currently support the following classes that can be applied by setting the StyleClass on these controls:

  • BoxView - HorizontalRule, Circle, Rounded

  • Image - Circle, Rounded, Thumbnail

  • Button - Default, Primary, Success, Info, Warning, Danger, Link, Small, Large

  • Label - Header, Subheader, Body, Link, Inverse

To add a theme to your application, do the following :

  1. Add the Nuget packages to your project.

  2. Add theme to Resource Dictionary in App.xaml

  3. Use the Style class to apply predefined style classes in the theme.

    <Button Text="Button Class Default" StyleClass="Default" />
    <Button Text="Button Class Primary" StyleClass="Primary" />
    <Button Text="Button Class Success" StyleClass="Success" />
    

Read more about themes here.

Upvotes: 1

AllDayer
AllDayer

Reputation: 993

Have a look at this blog post. Particularly the bit about DynamicResources and Styles.

<Application
    xmlns="http://xamarin.com/schemas/2014/forms"
    xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
    x:Class="Your.App">
    <Application.Resources>
        <ResourceDictionary>
            <Color x:Key="backgroundColor">#33302E</Color>
            <Color x:Key="textColor">White</Color>
        </ResourceDictionary>
    </Application.Resources>
</Application>

Now set your resources

<Label Text="{Binding Name}" FontSize="Medium" FontAttributes = "Bold" TextColor = "{DynamicResource textColor}" LineBreakMode="NoWrap"/>
<Label Text="{Binding Text}" FontSize="Small" LineBreakMode="WordWrap" TextColor = "{DynamicResource textColor}"/>

Now in code you can change your resource on the fly

App.Current.Resources ["backgroundColor"] = Color.White;
App.Current.Resources ["textColor"] = Color.Black;

If you're using 2.3 you could also try the built in themes

Upvotes: 3

Related Questions