I search but I can't find if it's possible to change the StatusBar color for each platform, from my portable code? (for Android, iOS & WinPhone 8.1)
public App()
{
// Change the StatusBar color
MainPage = new MainPageUser();
}
I believe you would be better off writing a little bit of platform-specific code:
For Android:
On your MainActivity.cs on the Droid project, right after
LoadApplication(new App());
of the overriden OnCreate method, add:
Window.SetStatusBarColor(Android.Graphics.Color.Argb(255, 0, 0, 0));
Like so:
protected override void OnCreate(Bundle bundle)
{
TabLayoutResource = Resource.Layout.Tabbar;
ToolbarResource = Resource.Layout.Toolbar;
base.OnCreate(bundle);
global::Xamarin.Forms.Forms.Init(this, bundle);
LoadApplication(new App());
Window.SetStatusBarColor(Android.Graphics.Color.Argb(255, 0, 0, 0)); //here
}
I'm coming back to this answer years later to fix it because my answer had been wrong even though it had been accepted as the correct answer. I have now fixed it.
I had misread the question to want to change the navigation bar or that it worked differently in Android at that time.
I think at least this is a much better answer and should be better help to change the color of the navigationbar in Android and iOS.
Add this code to your Xamarin.Forms project
public interface IStatusBarPlatformSpecific
{
void SetStatusBarColor(Color color);
}
add this class to your Android project
[assembly: Dependency(typeof(MyDemo.Droid.CustomRenderers.Statusbar))]
namespace MyDemo.Droid.CustomRenderers
{
public class Statusbar : IStatusBarPlatformSpecific
{
public Statusbar()
{
}
public void SetStatusBarColor(Color color)
{
// The SetStatusBarcolor is new since API 21
if (Build.VERSION.SdkInt >= BuildVersionCodes.Lollipop)
{
var androidColor = color.AddLuminosity(-0.1).ToAndroid();
//Just use the plugin
CrossCurrentActivity.Current.Activity.Window.SetStatusBarColor(androidColor);
}
else
{
// Here you will just have to set your
// color in styles.xml file as shown below.
}
}
}
}
Add this CurrentActivityPlugin to your projects
Now you can change the color in your Forms project like this
var statusbar = DependencyService.Get<IStatusBarPlatformSpecific>();
statusbar.SetStatusBarColor(Color.Green);
Note the else statement above. If you are using an older buildversion than 21 you will need to hard-code your color to the styles.xml in your Android project like this
<?xml version="1.0" encoding="utf-8" ?>
<resources>
<style name="MainTheme.Base" parent="Theme.AppCompat.Light.DarkActionBar">
<item name="android:statusBarColor">#544054</item>
</style>
</resources>
For iOS its similar
add this to your Info.plist (more docs here)
<key>UIStatusBarStyle</key>
<string>UIStatusBarStyleLightContent</string>
<key>UIViewControllerBasedStatusBarAppearance</key>
<false/>
and add this code to your SetStatusBarColor ethod in the iOS version of the StatusBar class
UIView statusBar = UIApplication.SharedApplication.ValueForKey(
new NSString("statusBar")) as UIView;
if (statusBar != null && statusBar.RespondsToSelector(
new ObjCRuntime.Selector("setBackgroundColor:")))
{
// change to your desired color
statusBar.BackgroundColor = Color.FromHex("#7f6550").ToUIColor();
}
I wrote a more detailed blog post on how to set the color of the statusbar from Xamarin.Forms if somebody is interested. It does only talk about Android and iOS but should give you an idea what to do with other platforms.
Another option for Android: change the color in the file \Resources\values\styles.xml (Android project).
<item name="colorPrimaryDark">#00FF00</item>
Using this approach you can change it on every page.
Application.Current.MainPage.SetValue(NavigationPage.BarBackgroundColorProperty, Color.Black);
Maybe I'm not understanding the question, but I hope this helps.
After searching around quite a bit trying to find out how to change the iPhoneX status bar color (the bit behind the notch), I found out that it automatically sets itself based on the BackroundColorproperty of the root ContentPage.
So in Xaml it's as easy as this:
<ContentPage.BackgroundColor>
<OnPlatform x:TypeArguments="Color"
iOS="Navy"
Android="Yellow"
/>
</ContentPage.BackgroundColor>
I'm basically using the approach described in one of the answers here: https://stackoverflow.com/a/46199029/960691, but modifying it a little by giving you a code snippet that I've focused for your individual question (at least I think!)
On the latest versions of Xamarin you no longer need sketchy plugins and can instead do the following on Android:
var androidColor = color.ToAndroid();
Xamarin.Essentials.Platform.CurrentActivity.Window.SetStatusBarColor(androidColor);
So a complete dependency example in Android:
using System;
using Android.OS;
using WikiSpiv.Droid.Extras;
using WikiSpiv.Extras;
using Xamarin.Forms;
using Xamarin.Forms.Platform.Android;
[assembly: Dependency(typeof(Statusbar))]
namespace WikiSpiv.Droid.Extras
{
public class Statusbar : IStatusBarPlatformSpecific
{
public Statusbar()
{
}
public void SetStatusBarColor(Color color)
{
if (Build.VERSION.SdkInt >= BuildVersionCodes.Lollipop)
{
var androidColor = color.ToAndroid();
Xamarin.Essentials.Platform.CurrentActivity.Window.SetStatusBarColor(androidColor);
}
}
}
}
In Forms:
using System;
using Xamarin.Forms;
namespace WikiSpiv.Extras
{
public interface IStatusBarPlatformSpecific
{
public void SetStatusBarColor(Color color);
}
}
And it can be called like this:
var statusbar = DependencyService.Get<IStatusBarPlatformSpecific>();
statusbar.SetStatusBarColor(Color.Green);
Step 1. Add interface in shared class
public interface IStatusBarColor
{
void changestatuscolor(string color);
}
Step 2. on main activity inject dependency and implement the interface
[assembly: Dependency(typeof(ETCrewReport.Droid.MainActivity))]
public class MainActivity : FormsAppCompatActivity, IStatusBarColor
{
......
...
public static Context context;
protected override void OnCreate(Bundle bundle)
{
}
public void changestatuscolor(string color)
{
try
{
if (Build.VERSION.SdkInt >= BuildVersionCodes.Lollipop)
{
var c = MainActivity.context as FormsAppCompatActivity;
c?.RunOnUiThread(() => c.Window.SetStatusBarColor(Android.Graphics.Color.ParseColor(color)));
}
}
catch (Exception ex)
{
}
}
Step 3. get the dependency in the required xaml.cs file on OnAppearing method
protected async override void OnAppearing()
{
try
{
DependencyService.Get<IStatusBarColor>().changestatuscolor(Color.Black.ToHex());
}
catch (Exception ex)
{
throw;
}
}
in your android
MainActivity.cs
after the
LoadApplication(new App());
add this line
Window.SetStatusBarColor(Android.Graphics.Color.Argb(255, 62, 102,
226));
the color code is Argb format (Alpha,Red,Green,Blue)
You can change your intensity with the alpha percentage from 0-255
below mentioned may help you with opacity of your alpha color
for black with 50% alpha use
Window.SetStatusBarColor(Android.Graphics.Color.Argb(80, 0, 0, 0));
100% - FF
95% - F2
90% - E6
85% - D9
80% - CC
75% - BF
70% - B3
65% - A6
60% - 99
55% - 8C
50% - 80
45% - 73
40% - 66
35% - 59
30% - 4D
25% - 40
20% - 33
15% - 26
10% - 1A
5% - 0D
0% - 00
For android:
protected override void OnCreate(Bundle savedInstanceState)
{
AppCompatDelegate.DefaultNightMode = AppCompatDelegate.ModeNightNo;
TabLayoutResource = Resource.Layout.Tabbar;
ToolbarResource = Resource.Layout.Toolbar;
this.SetStatusBarColor(Color.FromHex("#8EC5FC").ToAndroid());
base.OnCreate(savedInstanceState);
Xamarin.Essentials.Platform.Init(this, savedInstanceState);
global::Xamarin.Forms.Forms.Init(this, savedInstanceState);
LoadApplication(new App());
}
This works for me.
In the App.xaml
<Color x:Key="navBarRed">#AA0000</Color>
<Color x:Key="navBarBlue">#F4721C</Color>
<Color x:Key="navBarColour">#F4721C</Color>
<Style TargetType="NavigationPage">
<Setter Property="BarBackgroundColor" Value="{DynamicResource navBarColour}"/>
</Style>
Then when you want to change the colour:
if (Condition == true)
App.Current.Resources["navBarColour"] = App.Current.Resources["navBarBlue"];
else
App.Current.Resources["navBarColour"] = App.Current.Resources["navBarRed"];
Related
I'am using XamarinForms and I wanna know if I can set the backgroundColor using the configuration of the app.xaml, I'm using styles and themes that can be change at runtime, it is possible?
I'm using styles and themes that can be change at runtime, it is possible?
If you want to change status bar background at runtime, I suggest you can use DependencyService to change status bar background in Android platform.
Add this code to your Xamarin.Forms project(shared code project)
public interface IStatusBarPlatformSpecific
{
void SetStatusBarColor(Xamarin.Forms.Color color);
}
Implement the interface on Android platform. don't forget to register the platform implementations.
[assembly: Dependency(typeof(ChangeStatusbar))]
namespace FormsSample.Droid
{
public class ChangeStatusbar : IStatusBarPlatformSpecific
{
public void SetStatusBarColor(Xamarin.Forms.Color color)
{
// The SetStatusBarcolor is new since API 21
if (Build.VERSION.SdkInt >= BuildVersionCodes.Lollipop)
{
var androidColor = color.AddLuminosity(-0.1).ToAndroid();
//Just use the plugin
Xamarin.Essentials.Platform.CurrentActivity.Window.SetStatusBarColor(androidColor);
}
else
{
// Here you will just have to set your
// color in styles.xml file as shown below.
}
}
}
}
Now, you can change status bar background by calling the Get method to resolve the IStatusBarPlatformSpecific interface
private void btn1_Clicked(object sender, EventArgs e)
{
var statusbar = DependencyService.Get<IStatusBarPlatformSpecific>();
statusbar.SetStatusBarColor(Color.Green);
}
The screenshot:
The status bar should go the same colour as the navigation bar. You can set that to anything you like. I use styles to set this in a ContentPage as follows.
protected override void OnAppearing()
{
(this.Parent as NavigationPage).Style = (Style)Application.Current.Resources["NavBarColour"];
base.OnAppearing();
}
];
For Android modify Resources/Values/Styles.xml file as
<style name="MainTheme" parent="MainTheme.Base">
<item name="android:statusBarColor">#ffffff</item>
<item name="android:navigationBarColor">#ffffff</item>
</style>
i am using Xamarin forms and i have a project that requires the font size to be 32 pixels. I kept searching on google however i could not find an answer on how to convert this pixels in Xamarin device-independent units. I would greatly appreciate some help.
Thank you.
Xamarin uses DIU (device-independent units) about everywhere.
Have a look at https://learn.microsoft.com/en-us/xamarin/xamarin-forms/creating-mobile-apps-xamarin-forms/summaries/chapter05
I had a similiar issue and found out via trial and error that Xamarin.Essentials.DeviceDisplay.MainDisplayInfo.Density returns the amount of pixels per DIU on the device (tested on iPod Touch, Nokia 8 and Firetablet).
So this should be correct:
myLabel.FontSize = 32 / Xamarin.Essentials.DeviceDisplay.MainDisplayInfo.Density;
But as Jason has stated, you might want to check your requirements, because the more pixels are on the device, smaller the font gets. Thats why people use DIU in the first place :-)
It is probably better to have a look at how big the font is on the customers homepage. Maybe measure it there in inches, centimeters or whatever fits you and then do the math to convert that to DIUs (see link above, 64 DIU = 1 centimeter).
You could use custom renderer to invoke native method to set 32 pixels.Based on Button control, you can create a custom Button in Xamaarin forms as follows:
public class MyButton : Button
{
}
Then Andoird solution create the custom rendere class as follows:
[assembly: ExportRenderer(typeof(Xamarin.Forms.MyButton), typeof(CustomButtonRenderer))]
namespace AppShellTest.Droid
{
[Obsolete]
public class CustomButtonRenderer: ButtonRenderer
{
protected override void OnElementChanged(ElementChangedEventArgs<Xamarin.Forms.Button> e)
{
base.OnElementChanged(e);
if (Control != null)
{
// do whatever you want to the UITextField here!
Control.SetTextSize(Android.Util.ComplexUnitType.Px, 32);
}
}
}
}
About other controls, also can create their custom renderers to do.
=================================Update===============================
The method that can convert dp to px or px to dp, you can check that whether it works for you.
public int dip2px(Context context, float dpValue)
{
float scale = context.Resources.DisplayMetrics.Density;
return (int)(dpValue * scale + 0.5f);
}
public int px2dip(Context context, float pxValue)
{
float scale = context.Resources.DisplayMetrics.Density;
return (int)(pxValue / scale + 0.5f);
}
Then renderer code will be:
public class CustomButtonRenderer: ButtonRenderer
{
protected override void OnElementChanged(ElementChangedEventArgs<Xamarin.Forms.Button> e)
{
base.OnElementChanged(e);
if (Control != null)
{
// do whatever you want to the UITextField here!
Control.SetTextSize(Android.Util.ComplexUnitType.Px, dip2px(32));
}
}
public int dip2px(float dpValue)
{
float scale = MainActivity.instance.Resources.DisplayMetrics.Density;
return (int)(dpValue * scale + 0.5f);
}
}
The MainActivity.instance declared in MainActivity that means the instance of MainActivity.
public class MainActivity : global::Xamarin.Forms.Platform.Android.FormsAppCompatActivity
{
public static MainActivity instance { set; get; }
protected override void OnCreate(Bundle savedInstanceState)
{
TabLayoutResource = Resource.Layout.Tabbar;
ToolbarResource = Resource.Layout.Toolbar;
instance = this;
base.OnCreate(savedInstanceState);
Xamarin.Essentials.Platform.Init(this, savedInstanceState);
global::Xamarin.Forms.Forms.Init(this, savedInstanceState);
LoadApplication(new App());
}
...
I have AlertDialog. Bu default the alertDialog is like this:
I want to change the color of OK button and add border color. Is there a solution for this customization .
This is my code:
await Application.Current.MainPage.DisplayAlert("Alert!", " This is DisplayAlert", "OK");
You could use [DependencyService] to call native AlerDialog and change it in specific platforms,here is a simple sample that change the color of the action button .
in Forms ,create the interface:
public interface IPopUp
{
void Popup(string title, string message,Color titleColor,Color messageColor,Color OKButtonColor ,EventHandler handler);
}
in iOS
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using App10.iOS;
using Foundation;
using UIKit;
using Xamarin.Forms;
using Xamarin.Forms.Platform.iOS;
using App10;
[assembly: Dependency(typeof(PopupImplemention))]
namespace App10.iOS
{
public class PopupImplemention : IPopUp
{
public void Popup(string title, string message, Color titleColor, Color messageColor, Color OKButtonColor, EventHandler handler)
{
UIAlertController alertController = UIAlertController.Create(title,message,UIAlertControllerStyle.Alert);
var firstAttributes = new UIStringAttributes
{
ForegroundColor =titleColor.ToUIColor(),
};
var secondAttributes = new UIStringAttributes
{
ForegroundColor =messageColor.ToUIColor(),
};
alertController.SetValueForKey(new NSAttributedString(title, firstAttributes), new NSString("attributedTitle"));
alertController.SetValueForKey(new NSAttributedString(message, secondAttributes), new NSString("attributedMessage"));
UIAlertAction cancelAction = UIAlertAction.Create("Cancel",UIAlertActionStyle.Cancel,null);
UIAlertAction okAction = UIAlertAction.Create("OK", UIAlertActionStyle.Default,(sender)=> { handler?.Invoke(sender, new EventArgs()) ; });
okAction.SetValueForKey(OKButtonColor.ToUIColor(), new NSString("_titleTextColor"));
alertController.AddAction(cancelAction);
alertController.AddAction(okAction);
var currentViewController = topViewControllerWithRootViewController(UIApplication.SharedApplication.Delegate.GetWindow().RootViewController);
currentViewController.PresentViewController(alertController,true,null);
}
UIViewController topViewControllerWithRootViewController(UIViewController rootViewController)
{
if (rootViewController is UITabBarController)
{
UITabBarController tabBarController = (UITabBarController)rootViewController;
return topViewControllerWithRootViewController(tabBarController.SelectedViewController);
}
else if (rootViewController is UINavigationController)
{
UINavigationController navigationController = (UINavigationController)rootViewController;
return topViewControllerWithRootViewController(navigationController.VisibleViewController);
}
else if (rootViewController.PresentedViewController != null)
{
UIViewController presentedViewController = rootViewController.PresentedViewController;
return topViewControllerWithRootViewController(presentedViewController);
}
else
{
return rootViewController;
}
}
}
}
in Android
in MainActivity
public static MainActivity Intance;
protected override void OnCreate(Bundle savedInstanceState)
{
TabLayoutResource = Resource.Layout.Tabbar;
ToolbarResource = Resource.Layout.Toolbar;
base.OnCreate(savedInstanceState);
Intance = this;
Xamarin.Essentials.Platform.Init(this, savedInstanceState);
global::Xamarin.Forms.Forms.Init(this, savedInstanceState);
LoadApplication(new App());
}
using Xamarin.Forms;
using xxx;
using xxx.Droid;
using Android;
using System;
using Xamarin.Forms.Platform.Android;
using Android.Support.V7.App;
using Android.Text;
[assembly: Dependency(typeof(PopupImplemention))]
namespace xxx.Droid
{
public class PopupImplemention : IPopUp
{
public void Popup(string title, string message, Color titleColor, Color messageColor, EventHandler handler)
{
// because html.string could not support format string , so you need to set the color directly in the string with a static value
Android.Support.V7.App.AlertDialog.Builder alert = new Android.Support.V7.App.AlertDialog.Builder(MainActivity.Intance);
alert.SetTitle(title);
alert.SetMessage(message);
alert.SetPositiveButton(Html.FromHtml("<font color='#0000ff'>OK</font>"), (senderAlert, args) =>
{
handler?.Invoke(senderAlert, args);
});
Android.Support.V7.App.AlertDialog dialog = alert.Create();
dialog.Show();
}
}
}
And call it in forms
DependencyService.Get<IPopUp>().Popup("Title","xxxxxxxxxxxx",Color.Red,Color.Blue,Color.Green,(sen,args)=> {
// handle the logic when clikc the OK button
});
You can use cross platform libraries like this one: https://github.com/aritchie/userdialogs
You will need to create a styles.xml and configure it for Android that way. There is currently no way to customize that native control through any of the Xamarin.Forms API's as far as I am aware.
Example:
<style name="AppCompatAlertDialogStyle" parent="Theme.AppCompat.Dialog.Alert">
<item name="colorAccent">#c7ac56</item>
<item name="android:textColor">#c7ac56</item>
<item name="android:background">#5c8487</item>
</style>
Here is a good tutorial on an example on how to do this: http://gmariotti.blogspot.com/2015/04/a-material-styled-alertdialog.html
If you are using Xamarin Android you probably could also hook into the AlertDialog.Builder and set the proprieties pro grammatically: https://developer.android.com/reference/android/app/AlertDialog.Builder
I need to increase the distance between the soft-keyboard and the editor in the UI. Currently, the keyboard overlaps the editor bottom part.
Screenshot adding below:
Is there any solution for this?
Try the below code it will be help you.
In Xamarin Android Project
public class MainActivity
{
protected override void OnCreate(Bundle savedInstanceState)
{
Window.SetSoftInputMode(Android.Views.SoftInput.AdjustUnspecified);
}
}
or in AndroidManifest.xml
<activity android:name=".myActivity"
android:label="#string/app_name"
android:screenOrientation="sensorPortrait"
android:windowSoftInputMode="adjustPan"/>
check the java code on given link- KeyboardSize
Xamarin forms: How to increase the distance between keyboard and editor
You could implement this feature by add paddingBottom property for your Edior.
Here is an example, add the paddingBottom property in your EditorRenderer:
public class CustomEditorRenderer : EditorRenderer
{
public CustomEditorRenderer(Context context) : base(context)
{
}
protected override void OnElementChanged(ElementChangedEventArgs<Xamarin.Forms.Editor> e)
{
base.OnElementChanged(e);
if (Control == null)
return;
//Control.Background = new ColorDrawable(Android.Graphics.Color.Transparent);
//Control.Background = null;
float scale = Context.Resources.DisplayMetrics.Density;
int dpAsPixels = (int)(50 * scale + 0.5f);
Control.SetPadding(0, 0, 0, dpAsPixels);
}
}
Effect: Original space, Custom space.
I'm using new forms feature Right-to-Left, it works well except MasterDetail hamburger menu icon. It stays on the left side and I need to move it to right whem localization is changed. Any ideas or could somebody help me with custom renderer?
well not impossible but some dirty coding is needed:
please check the solution here
as recap:
To force the layout RTL and LTR on IOS:
1- Create this class/service
using System;
using System.IO;
using Xamarin.Forms;
using yourproject.iOS;
using yourproject.database;
using ObjCRuntime;
using System.Runtime.InteropServices;
using UIKit;
using System.Diagnostics;
[assembly: Dependency(typeof(PathManager_IOS))]
namespace yourproject.iOS
{
public class PathManager_IOS : IPathManager
{
[DllImport(ObjCRuntime.Constants.ObjectiveCLibrary, EntryPoint = "objc_msgSend")]
internal extern static IntPtr IntPtr_objc_msgSend(IntPtr receiver, IntPtr selector, UISemanticContentAttribute arg1);
public PathManager_IOS()
{
}
public void SetLayoutRTL()
{
try
{
Selector selector = new Selector("setSemanticContentAttribute:");
IntPtr_objc_msgSend(UIView.Appearance.Handle, selector.Handle, UISemanticContentAttribute.ForceRightToLeft);
}
catch (Exception s)
{
Debug.WriteLine("failed to set layout...."+s.Message.ToString());
}
}
public void SetLayoutLTR()
{
try
{
Selector selector = new Selector("setSemanticContentAttribute:");
IntPtr_objc_msgSend(UIView.Appearance.Handle, selector.Handle, UISemanticContentAttribute.ForceLeftToRight);
}
catch (Exception s)
{
Debug.WriteLine("failed to set layout...." + s.Message.ToString());
}
}
}
}
ps: please change "yourproject" to your project name...
To Call this on startup
in AppDelegate.cs
PathManager_IOS pathManager = new PathManager_IOS();
if (lang == 3)
{
pathManager.SetLayoutRTL();/* RTL */
}
if (lang == 1||lang == 2)
{
pathManager.SetLayoutLTR();/* LTR */
}
LoadApplication(new App(m, lang));
TO call this from the PCL shared pages or project
/* arabic */
DependencyService.Get<IPathManager>().SetLayoutRTL();
/* English */
DependencyService.Get<IPathManager>().SetLayoutLTR();
Don't forget to set the flow direction on language change
if(lang==3)
{//arabic
this.FlowDirection = FlowDirection.RightToLeft;
this.Master.FlowDirection= FlowDirection.RightToLeft;
this.Detail.FlowDirection= FlowDirection.RightToLeft;
}
hope this helps! all this for that hamburger icon !!!
Cheers,
Rabih
To force Android navigation Bar to be RTL use masterDetailPage renderer on Android project something like this:
public class MyMasterDetailPageRenderer : MasterDetailPageRenderer
{
public MyMasterDetailPageRenderer(Context context) : base(context)
{
}
protected override void OnLayout(bool changed, int l, int t, int r, int b)
{
base.OnLayout(changed, l, t, r, b);
var toolbar = FindViewById<Android.Support.V7.Widget.Toolbar>(Resource.Id.toolbar);
toolbar.LayoutDirection = LayoutDirection.Rtl;
}
}
the first step is to set master direction flow
<MasterDetailPage xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
x:Class="APPNAME.MainPage"
FlowDirection="RightToLeft">
and for Android you need to add android:supportsRtl="true" to AndroidManifest.xml like
<application android:label="APPNAME.Android" android:theme="#style/MainTheme" android:supportsRtl="true"></application>
and then your master page is rtl as well as the action bar.