I am trying to create a custom application theme in Windows Phone 7 but unfortunately faced the following problem: If I try to change a Style and some of the default colors, as a result the Style is applied correctly but for some reason the colors are not. I mean my new Style uses the default colors instead of the custom ones.
Here is what I am doing:
1.I created a folder named CustomTheme with two ResourceDictionaries:
Brushes.xaml
Styles.xaml
2.Next I added them into App.xaml in this way:
<Application.Resources>
<ResourceDictionary>
<ResourceDictionary.MergedDictionaries>
<ResourceDictionary Source="CustomTheme/Brushes.xaml"/>
<ResourceDictionary Source="CustomTheme/Styles.xaml"/>
</ResourceDictionary.MergedDictionaries>
</ResourceDictionary>
</Application.Resources>
3. After that I tried to use a sample Style from Styles.xaml in this way:
<TextBox Style="{StaticResource SomeStyle}"/>
4.As a result the Style is applied as expected(I mean the ControlTemplate is changed) but with the default colors instead of these specified in Brushes.xaml
I managed to find a workaround of the problem by adding Brushes.xaml in my Styles.xaml file instead of in App.xaml:
<ResourceDictionary.MergedDictionaries>
<ResourceDictionary Source="Brushes.xaml"/>
</ResourceDictionary.MergedDictionaries>
I am asking for a suggestion. Is there a better solution of the problem? Why are the colors not merged correctly?
The solution that you have is the best that I know and is what we used when implementing RunKeeper, though we did also keep the equivalent of your Brushes.xaml in App.xaml, too.
Feels "broken" to be honest, but at least there's a usable workaround :)
Related
I had applied light theme and dark theme for Xamarin app via resource dictionary.
here is my resource samples
Light theme:
<ResourceDictionary xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
x:Class="App.Views.Themes.LightTheme"
xmlns:converters="clr-namespace:App.Services.Helper;assembly=App.Services">
<!-- bootm bar background color -->
<Color x:Key="BottomBar">#17a7a7</Color>
</ResourceDictionary>
Dark Theme :
<ResourceDictionary xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
x:Class="App.Views.Themes.DarkTheme"
xmlns:converters="clr-namespace:App.Services.Helper;assembly=App.Services">
<!-- bootm bar background color -->
<Color x:Key="BottomBar">#292a2a</Color>
</ResourceDictionary>
Both themes are working fine , But i need to change only the bottom bar color according the user level.Its only for the light theme.
The condition is:
if(memeberlevel =="Basic"){
//need to change bottom bar color as green
}
else if(memeberlevel =="Intermediate")
{
//need to change bottom bar color as silver
}
else
{
//need to change bottom bar color as gold
}
How i apply this condition inside the Light theme resource dictionary for
<Color x:Key="BottomBar">#17a7a7</Color>
Here i need to set green, silver and gold for x:Key="BottomBar" according to user level
Appreciate a quick help. Thanks in advance
You can do it in your code, not in resource dictionary by conditionally binding color to your viewmodel. Example how to access resource color:
(Color)Application.Current.Resources["BottomBar"]
You can define several colors that will reflect remember level in your resource dictionary. If you need it only for dark theme then define them as different colors in dark theme resource dictionary and leave them the same in light theme.
I think you can change it like
App.Current.Resources["BottomBar"] = Color.Green;
Long ago I searched on Internet for a SVG image plugin and found that one, which is almost broken, outdated and thus unusable. Is there any other plugin that I might miss that allows to show SVG images and works fine with recent Nativescript version?
For anyone still struggling with this, there is another route you could take. What ended up doing was converting my svg files into a font file (.tff). My svg files were simple, so I'm not sure if this will work for every case, but at least it works for using icons. It's really easy to convert svg files to a .ttf file. I used this online tool converter, then I added the file into my nativescript app/fonts folder. Now I can use a label like this to display the svg files:
<label
style="font-family: yourFontFileName;"
text="A" //This will show the icon mapping to the letter 'A'
></label>
It's also worth noting that since it's a font, you can change stroke color, and size.
Note: Android uses the file name as the font name, while IOS has its own font name. To find the font name you can just open your .ttf file, and it should open a window showing the letters (icons) and the font name as the title
There is an updated fork from teammaestro
<Page xmlns="http://schemas.nativescript.org/tns.xsd"
xmlns:svg="#teammaestro/nativescript-svg" loaded="pageLoaded">
<StackLayout>
<svg:SVGImage src="~/image/nativescript.svg" height="100" />
<svg:SVGImage src="https://media4.giphy.com/media/3uyIgVxP1qAjS/200.svg" height="200" />
<svg:SVGImage src="res://somesvg" height="200" />
</StackLayout>
</Page>
As pointed out in this documentation -
https://developer.xamarin.com/guides/xamarin-forms/creating-mobile-apps-xamarin-forms/summaries/chapter05/, specifying a height of 1 will give you 1, 2 or 3 pixels depending on the iOS device.
I want to put a separator into my view similar to a hr in HTML. I've done this by adding either a BoxView or StackLayout with a height of 1 and the necessary width.
This means that depending on the device, the separator will not always render at 1px. Is there something I can do to ensure that I will always get 1px for any device?
At the moment all I can think of is to place my content into ListView cells and leverage the native separators provided.
I think you are interpreting it wrong. Although you might actually get 1, 2 or 3 pixels, the user will see the same thing. This is due to the retina screens. Density will be higher, but the end result will be the same.
This is the same reason that you need to supply all images with the #2x and #3x suffix. The images will physically be bigger, but on iOS they will appear the same.
Following similar steps to the answer here https://stackoverflow.com/a/26570933/2931055 I ended up defining a global style that uses a static variable set up in the startup of iOS and Android, then defined in my stylekit to programmatically determine the fraction of a point I need for any given device.
In my portable project App.xaml.cs I defined
public static double ScreenDensity { get; set; }
Which needs to get populated independently for iOS and Android.
For iOS, in AppDelegate.cs in FinishedLaunching()
App.ScreenDensity = UIScreen.MainScreen.Scale;
Then for Android, in MainActivity.cs in OnCreate()
App.ScreenDensity = Resources.DisplayMetrics.Density;
UIScreen.MainScreen.Scale and Resources.DisplayMetrics.Density will evaluate to 1.0, 2.0 or 3.0 depending on the device.
In my portable project StyleKit (myApp\Helpers\StyleKit\SytyleKit.cs) I created a static variable to later use in a global style
using Xamarin.Forms;
namespace myApp.Helpers.StyleKit
{
public class Sizes
{
public static double Hairline = 1 / App.ScreenDensity;
}
}
Then in my global styles (myApp\App.xaml) I create the global style
<?xml version="1.0" encoding="utf-8" ?>
<Application xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
x:Class="myApp.App"
xmlns:stylekit="clr-myApp.Helpers.StyleKit;assembly=myApp">
<Application.Resources>
<ResourceDictionary>
<Style x:Key="hairlineSeparator" TargetType="StackLayout">
<Setter Property="BackgroundColor" Value="#ddd" />
<Setter Property="HeightRequest" Value="{x:Static stylekit:Sizes.Hairline}" />
<Setter Property="HorizontalOptions" Value="FillAndExpand" />
</Style>
</ResourceDictionary>
</Application.Resources>
</Application>
And finally when I want to use one in a xaml page
<!-- some content -->
<StackLayout Style="{StaticResource hairlineSeparator}"></StackLayout>
<!-- some content -->
Successfully tested on iOS and Android.
I'd like to add some icons in my app especially in listviews using custom cell and specify the color to be rendered.
I don't want to edit each image in Photoshop; I want to apply an overlay color at runtime.
Is that possible with a custom renderer?
No it is not possible through standard Image class provided in Xamarin.Forms.
But you can use this amazing IconView custom renderer created by this guy. I use it all the time it is amazing.
IconView for Xamarin Forms
Usage
<?xml version="1.0" encoding="UTF-8"?>
<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
x:Class="IconApp.MyPage"
xmlns:controls="clr-namespace:IconApp;assembly=IconApp">
<controls:IconView Source="monkey"
Foreground="Red"
WidthRequest="100"
HeightRequest="100"
HorizontalOptions="Center"
VerticalOptions="Center" />
</ContentPage>
Just specify the Foreground="Red" property color
Now We got another way with Xamarin.CommunityToolkit. We can use its IconTintColorEffect.TintColor for changing Tint Color or Overlay of an Image.
<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
xmlns:xct="http://xamarin.com/schemas/2020/toolkit"
x:Class="MyLittleApp.MainPage">
<StackLayout>
<Image Source="monkey" xct:IconTintColorEffect.TintColor="Red" />
</StackLayout>
</ContentPage>
Xamarin.CommunityToolkit is handy and provides lot of features such as Shadows on any View, EventToCommandBehavior for MVVMifying lot of Events and Controls, it also has additional Converters, Extensions, Helpers, and Views that are not available in builtin Xamarin Forms yet.
Refer for more Documentation
I have decided to try Xamarin Forms, because I thought that I can make one design for all platforms or at least Android and iOS.
However a simple form like:
<?xml version="1.0" encoding="utf-8" ?>
<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
xmlns:app91="clr-namespace:App9;assembly=MasterDetail.Android"
x:Class="MasterDetail.CompetitorsListPage"
>
<StackLayout>
<Label Text="{Binding CurrentEvent.Name}"></Label>
<StackLayout Orientation="Horizontal">
<Button Text="By Place" Clicked="Button_OnClickedByPlace"></Button>
<Button Text="By Number" Clicked="Button_OnClickedByNumber"></Button>
<Button Text="By Rating" Clicked="Button_OnClickedByRating"></Button>
<Button Text="Change Event" Clicked="Button_OnClickedChangeEvent"></Button>
</StackLayout>
<ScrollView>
<ListView x:Name="couples" ItemSelected="Comps_OnItemSelected" ItemTapped="Couples_OnItemTapped">
<ListView.ItemTemplate>
<DataTemplate>
<ViewCell>
<ViewCell.View>
<StackLayout Orientation="Horizontal">
<Label Text="{Binding Round}"></Label>
<Label Text="{Binding Pos, StringFormat='({0}).'}"></Label>
<Label Text="{Binding Name}"></Label>
<Label Text="{Binding StartingNumber}" ></Label>
<Label Text="{Binding OldRating, StringFormat=' [{0}]'}"></Label>
<!--<Label Text="{Binding NewRating, StringFormat=' {0} ]'}"></Label>-->
</StackLayout>
</ViewCell.View>
</ViewCell>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
</ScrollView>
</StackLayout>
</ContentPage>
Looks completely different on Android and iOS. I do not mind colours, but font size? I do not set font anywhere in the code or xaml.
Any idea what am I doing wrong?
Here it is a picture showing both versions:
This is by design. Forms is intended to provide a native experience on each platform by using their respective UI standards. Android has a different default color scheme than iOS. iOS default buttons look different than Android.
You can override the default fonts, sizes, colors, etc if you like in order to provide a more consistent UI. Xamarin has also introduced Themes for Forms which help you provide a consistent UI between platforms.
Because Android has variety of screen sizes and different screen DPI as compared to standard dpi and font sizes across iOS devices, it is not possible to create same look. But you can certainly change Theme in the MainActivity of your Droid project and increase font size as per your convenience. Beware that your theme's font size may be too big for small devices and too small for big devices. You can add scaling factor for font size in your theme, but I have not been very successful, instead, I tried to design a UI that will automatically fit for the best.
As per Xamarin Evolve 2016, some questions were raised regarding font sizes, they said it is difficult, but they are trying to make some unified font sizing.
Although Xamarin.Forms has everything in Xaml and C#, you still need to use iOS assets and Android resources to customize look and feel.
For me, #Jason's answer and comments from #Egg and #Bill Reiss are spot-on.
Meanwhile, so often clients request "same font size" across platforms that something like this finds its way into base Styles or Theme to account for what seems to be "natively smaller" fonts on Android:
<OnPlatform x:TypeArguments="Font">
<OnPlatform.iOS>Bold,Medium</OnPlatform.iOS>
<OnPlatform.Android>Bold,Large</OnPlatform.Android>
<OnPlatform.WinPhone>Bold,Medium</OnPlatform.WinPhone>
</OnPlatform>
Something similar can also be expressed in code at or near app startup, for example as a base Label font added to global Styles dictionary.
Just wanted to give a concrete example of what others above alluded to.
Strange behavior on iOS - as you can see those are labels in StackLayout, while in Android they behave OK, in iOS second and third label behave more lithe they were in some kind of grid rather than stack –
You have put 5 labels in a horizontal stack, and haven't changed the layout options on any of them. This will 'stack' all 5 labels next to each other, then size them based on the amount of text to be displayed. There is not enough horizontal space to accommodate all of the text, so the labels are wrapping vertically. The longest labels show the most wrapping, but as they get longer other labels wrap as well, which is why the Pos and OldRating data raps in some labels. When I'm working out layouts like this I often add different background colors to each control so I can see how they are laying out.
There are different ways to solve this depending on your desired result. If you want the entire line of text to wrap you can concatenate the data behind the scenes and add it as one label. If you want the name to wrap and the other data to display without wrapping you can set WidthRequests on the labels.