In Xamarin Forms is there any way I can change the size of the images used in the tab bars when using Xamarin Shell? - xamarin

I would like to be able to customize the bottom tab bar. From what I understand this isn’t yet possible but it might be a future feature. Until that time has anyone come across any custom renderers for iOS and Android that would allow me to change the size of the images that display in the bottom tab area?

You could use Custom Renderer to reset the size of icon in specific platforms .
in iOS projet
In the renderer I set the first icon as 60pt *60pt . You need to set the size on each item
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using xxx;
using xxx.iOS;
using CoreGraphics;
using Foundation;
using UIKit;
using Xamarin.Forms;
using Xamarin.Forms.Platform.iOS;
[assembly: ExportRenderer(typeof(AppShell), typeof(MyShellRenderer))]
namespace xxx.iOS
{
public class MyShellRenderer : ShellRenderer
{
protected override IShellSectionRenderer CreateShellSectionRenderer(ShellSection shellSection)
{
var renderer = base.CreateShellSectionRenderer(shellSection);
if (renderer != null)
{
}
return renderer;
}
protected override IShellTabBarAppearanceTracker CreateTabBarAppearanceTracker()
{
return new CustomTabbarAppearance();
}
}
public class CustomTabbarAppearance : IShellTabBarAppearanceTracker
{
public void Dispose()
{
}
public void ResetAppearance(UITabBarController controller)
{
}
public void SetAppearance(UITabBarController controller, ShellAppearance appearance)
{
UITabBar myTabBar = controller.TabBar;
if (myTabBar.Items != null)
{
UITabBarItem itemOne = myTabBar.Items[0];
itemOne.Image = ScalingImageToSize(UIImage.FromBundle("tab_feed.png"),new CGSize(60,60)); // set the size here if you want to customize it
itemOne.SelectedImage = ScalingImageToSize(UIImage.FromBundle("tab_feed.png"), new CGSize(60, 60));
UITabBarItem itemTwo = myTabBar.Items[1];
itemTwo.Image = UIImage.FromBundle("tab_about.png");
itemTwo.SelectedImage = UIImage.FromBundle("tab_about.png");
//The same logic if you have itemThree, itemFour....
}
}
public UIImage ScalingImageToSize(UIImage sourceImage, CGSize newSize)
{
UIGraphics.BeginImageContextWithOptions(newSize, false, UIScreen.MainScreen.Scale);
sourceImage.Draw(new CGRect(0, 0, newSize.Width, newSize.Height));
UIImage newImage = UIGraphics.GetImageFromCurrentImageContext();
UIGraphics.EndImageContext();
return newImage;
}
public void UpdateLayout(UITabBarController controller)
{
}
}
}
in Android
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Android.App;
using Android.Content;
using Android.Graphics;
using Android.Graphics.Drawables;
using Android.OS;
using Android.Runtime;
using Android.Support.Design.Widget;
using Android.Views;
using Android.Widget;
using xxx;
using xxx.Droid;
using Xamarin.Forms;
using Xamarin.Forms.Platform.Android;
[assembly: ExportRenderer(typeof(AppShell), typeof(MyShellRenderer))]
namespace xxx.Droid
{
public class MyShellRenderer : ShellRenderer
{
Context context;
public MyShellRenderer(Context context) : base(context)
{
this.context = context;
}
protected override IShellBottomNavViewAppearanceTracker CreateBottomNavViewAppearanceTracker(ShellItem shellItem)
{
return new CustomBottomNavAppearance(context);
}
}
public class CustomBottomNavAppearance : IShellBottomNavViewAppearanceTracker
{
Context context;
public CustomBottomNavAppearance(Context context)
{
this.context = context;
}
public void Dispose()
{
}
public void ResetAppearance(BottomNavigationView bottomView)
{
}
public void SetAppearance(BottomNavigationView bottomView, ShellAppearance appearance)
{
bottomView.ItemIconSize=250;
//The same logic if you have myItemTwo, myItemThree....
}
}
}

Related

Xamarin Shell.BackgroundColor is wrong

In my AppShell I am setting the background color of the shell, like this:
<Setter Property="Shell.BackgroundColor" Value="#0075BE" />
However, when the app runs in an iOS emulator, the title bar actually has a BackgroundColor of #2588C6 (I checked with a color picker).
In an Android emulator, the color is closer at #0073C1, but still incorrect.
How do I get the title bar to be the actual color that I have specified?
Just add this line in AppDelegate.cs
UINavigationBar.Appearance.Translucent = false;
You can have a try with Xamarin.Forms Shell Custom Renderers
IOS:
using UIKit;
using Xamarin.Forms;
using Xamarin.Forms.Platform.iOS;
[assembly: ExportRenderer(typeof(Xaminals.AppShell), typeof(Xaminals.iOS.MyShellRenderer))]
namespace Xaminals.iOS
{
public class MyShellRenderer : ShellRenderer
{
protected override IShellSectionRenderer CreateShellSectionRenderer(ShellSection shellSection)
{
var renderer = base.CreateShellSectionRenderer(shellSection);
if (renderer != null)
{
(renderer as ShellSectionRenderer).NavigationBar.BackgroundColor = UIColor.Red;
(renderer as ShellSectionRenderer).NavigationBar.SetBackgroundImage(new UIImage(), UIBarMetrics.Default);
}
return renderer;
}
}
}
Android:
using Android.Content;
using Xamarin.Forms;
using Xamarin.Forms.Platform.Android;
[assembly: ExportRenderer(typeof(Xaminals.AppShell), typeof(Xaminals.Droid.MyShellRenderer))]
namespace Xaminals.Droid
{
public class MyShellRenderer : ShellRenderer
{
public MyShellRenderer(Context context) : base(context)
{
}
protected override IShellToolbarAppearanceTracker CreateToolbarAppearanceTracker()
{
return new MyShellToolbarAppearanceTracker(this);
}
}
public class MyShellToolbarAppearanceTracker : ShellToolbarAppearanceTracker
{
public MyShellToolbarAppearanceTracker(IShellContext context) : base(context)
{
}
public override void SetAppearance(Toolbar toolbar, IShellToolbarTracker toolbarTracker, ShellAppearance appearance)
{
base.SetAppearance(toolbar, toolbarTracker, appearance);
toolbar.SetBackgroundColor(Android.Graphics.Color.ParseColor("#0075BE"));
}
}
}

Is there a better way to set TabbedPage bottom tab bar height than in ViewModel?

I want to change the height of the bottom TabBar in my Xamarin app. Now I am doing this via ViewModel properties:
public partial class MainPage : TabbedPage
{
public int TabBarHeight
{
get { return _tabBarHeight; }
set { _tabBarHeight = value; OnPropertyChanged(); }
}
int _tabBarHeight = 200;
And a custom renderer for iOS:
using System;
using UIKit;
using Xamarin.Forms;
using Xamarin.Forms.Platform.iOS;
using System.Diagnostics;
using Ja.Enums;
using System.ComponentModel;
using CoreGraphics;
[assembly: ExportRenderer(typeof(TabbedPage), typeof(Ja.iOS.TabbedPageRenderer))]
namespace Ja.iOS
{
public class TabbedPageRenderer : TabbedRenderer
{
private MainPage _page;
public TabbedPageRenderer()
{
this.ViewControllerSelected += OnTabbarControllerItemSelected;
}
public override void ViewWillLayoutSubviews()
{
base.ViewWillLayoutSubviews();
TabBar.Frame = new CGRect(TabBar.Frame.X, TabBar.Frame.Y + (TabBar.Frame.Height - _page.TabBarHeight), TabBar.Frame.Width, _page.TabBarHeight);
}
protected override void OnElementChanged(VisualElementChangedEventArgs e)
{
base.OnElementChanged(e);
if (e.OldElement != null)
{
e.OldElement.PropertyChanged -= Current_PropertyChanged;
return;
}
if (e.NewElement != null)
{
_page = (MainPage)e.NewElement;
e.NewElement.PropertyChanged += Current_PropertyChanged;
}
}
void Current_PropertyChanged(object sender, System.ComponentModel.PropertyChangedEventArgs e)
{
if (e.PropertyName == "FrameHeight")
ViewWillLayoutSubviews();
}
}
}
Is this an optimal way to be doing this? I seem to remember having a shared class. That class would contain the code that's in the first few lines of my main as bound elements.
Could anyone comment on this and perhaps suggest a better way of doing this.
Looks like something I would use a Custom Control for (which is what I think you mean with 'shared class').
First you create the class below in your PCL. A CustomTabbedPage, which inherits from TabbedPage but has one extra property: 'TabBarHeight'
public class CustomTabbedPage : TabbedPage {
public static readonly BindableProperty TabBarHeightProperty = BindableProperty.Create("TabBarHeight", typeof(int), typeof(TabbedPage), 0);
public int TabBarHeight {
get { return (int)GetValue(TabBarHeightProperty); }
set { SetValue(TabBarHeightProperty, value); }
}
}
Now edit your renderer to a renderer of the CustomTabbedPage. Then you can easily access the TabBarHeight property by using this.Element.TabBarHeight.
using System;
using UIKit;
using Xamarin.Forms;
using Xamarin.Forms.Platform.iOS;
using System.Diagnostics;
using Ja.Enums;
using System.ComponentModel;
using CoreGraphics;
[assembly: ExportRenderer(typeof(CustomTabbedPage), typeof(Ja.iOS.CustomTabbedPageRenderer))]
namespace Ja.iOS
{
public class CustomTabbedPageRenderer : TabbedRenderer
{
public TabbedPageRenderer()
{
this.ViewControllerSelected += OnTabbarControllerItemSelected;
}
public override void ViewWillLayoutSubviews()
{
base.ViewWillLayoutSubviews();
TabBar.Frame = new CGRect(TabBar.Frame.X, TabBar.Frame.Y + (TabBar.Frame.Height - this.Element.TabBarHeight), TabBar.Frame.Width, this.Element.TabBarHeight);
}
protected override void OnElementChanged(VisualElementChangedEventArgs e)
{
base.OnElementChanged(e);
if (e.OldElement != null) {
e.OldElement.PropertyChanged -= Element_PropertyChanged;
}
if (e.NewElement != null) {
e.NewElement.PropertyChanged += Element_PropertyChanged;
}
}
void Current_PropertyChanged(object sender, System.ComponentModel.PropertyChangedEventArgs e)
{
if (e.PropertyName == "FrameHeight")
ViewWillLayoutSubviews();
}
}
}
There might be some syntax errors in there but you get the point.
Shoot if you have any questions.

Xamarin white screen in local machine

enter image description here
Hello,
I have a problem with Xamarin, when i run program i see only white screen, just like on picture.
MainPage.xaml.cs have this code:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Xamarin.Forms;
namespace Hello
{
public class App : Application
{
public App()
{ // The root page of your application
MainPage = new ContentPage
{
Content = new StackLayout
{
VerticalOptions = LayoutOptions.Center,
Children = {
new Label {
HorizontalTextAlignment = TextAlignment.Center,
Text = "Welcome to Xamarin Forms!"
}
}
}
};
}
protected override void OnStart()
{
// Handle when your app starts
}
protected override void OnSleep()
{
// Handle when your app sleeps
}
protected override void OnResume()
{
// Handle when your app resumes
}
}
}
I take this code from "Creating Mobile Apps with Xamarin Forms", somebody know what is wrong with this program?
Write your code in Shared project's App.xaml.cs class which is partial class. The code above you are showing is not partial class. Probably, as your screenshot showing you have written App class code in Main.axml.cs file
using System;
using Xamarin.Forms;
using Xamarin.Forms.Xaml;
[assembly: XamlCompilation(XamlCompilationOptions.Compile)]
namespace App
{
public partial class App : Application
{
public App()
{
InitializeComponent();
//MainPage = new MainPage();
MainPage = new ContentPage
{
Content = new StackLayout
{
VerticalOptions = LayoutOptions.Center,
Children =
{
new Label
{
HorizontalTextAlignment=TextAlignment.Center,
Text="Welcome to xamarin forms"
}
}
}
};
}
}
}

Customizing the progress bar color in UWP using Xamarin Forms

I made a progress bar customization (custom renderer) to change the progress bar color in iOS and Droid as seen in the following
Custom progress bar class in the PCL:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Xamarin.Forms;
namespace App2
{
public class ColorProgressBar : ProgressBar
{
public static BindableProperty BarColorProperty
= BindableProperty.Create<ColorProgressBar, Color>(p =>
p.BarColor, default(Color));
public Color BarColor
{
get { return (Color)GetValue(BarColorProperty); }
set { SetValue(BarColorProperty, value); }
}
}
}
Custom renderer for iOS:
using App2;
using App2.iOS;
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Linq;
using System.Text;
using Xamarin.Forms;
//using MonoTouch.Foundation;
//using MonoTouch.UIKit;
using Xamarin.Forms.Platform.iOS;
[assembly: ExportRenderer(typeof(ColorProgressBar),
typeof(ColorProgressBarRenderer))]
namespace App2.iOS
{
public class ColorProgressBarRenderer : ProgressBarRenderer
{
public ColorProgressBarRenderer()
{ }
protected override void
OnElementChanged(ElementChangedEventArgs<ProgressBar> e)
{
base.OnElementChanged(e);
if (e.NewElement == null)
return;
if (Control != null)
{
UpdateBarColor();
}
}
protected override void OnElementPropertyChanged(object sender,
PropertyChangedEventArgs e)
{
base.OnElementPropertyChanged(sender, e);
if (e.PropertyName ==
ColorProgressBar.BarColorProperty.PropertyName)
{
UpdateBarColor();
}
}
private void UpdateBarColor()
{
var element = Element as ColorProgressBar;
Control.TintColor = element.BarColor.ToUIColor();
}
}
}
Custom renderer for Android:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Android.App;
using Android.Content;
using Android.OS;
using Android.Runtime;
using Android.Views;
using Android.Widget;
using Android.Renderscripts;
using static Java.Util.ResourceBundle;
using Xamarin.Forms.Platform.Android;
using Android.Graphics;
using System.ComponentModel;
using Xamarin.Forms;
using App2;
using App2.Droid;
[assembly: ExportRenderer(typeof(ColorProgressBar),
typeof(ColorProgressBarRenderer))]
namespace App2.Droid
{
public class ColorProgressBarRenderer : ProgressBarRenderer
{
public ColorProgressBarRenderer()
{ }
protected override void
OnElementChanged(ElementChangedEventArgs<Xamarin.Forms.ProgressBar>
e)
{
base.OnElementChanged(e);
if (e.NewElement == null)
return;
if (Control != null)
{
UpdateBarColor();
}
}
protected override void OnElementPropertyChanged(object sender,
PropertyChangedEventArgs e)
{
base.OnElementPropertyChanged(sender, e);
if (e.PropertyName ==
ColorProgressBar.BarColorProperty.PropertyName)
{
UpdateBarColor();
}
}
private void UpdateBarColor()
{
var element = Element as ColorProgressBar;
// http://stackoverflow.com/a/29199280
Control.IndeterminateDrawable.SetColorFilter(
element.BarColor.ToAndroid(), PorterDuff.Mode.SrcIn);
Control.ProgressDrawable.SetColorFilter(
element.BarColor.ToAndroid(), PorterDuff.Mode.SrcIn);
}
}
}
I'm setting the custom progress bar's color this way:
var progressBar = new ColorProgressBar();
progressBar.BarColor = Color.Red;
I don't understand how to make a custom renderer class for UWP that changes the color of the progress bar. Could someone please help me understand how to do this class?
You're going to want to update the Foreground property of the native Windows.UI.Xaml.Controls.ProgressBar control to change the color.
It should look something like this:
private void UpdateBarColor()
{
var element = Element as ColorProgressBar;
Control.Foreground = new Windows.UI.Xaml.Media.SolidColorBrush(
GetWindowsColor(element.BarColor));
}
Windows.UI.Color GetWindowsColor(Color color)
{
return Windows.UI.Color.FromArgb((byte)(255 * color.A), (byte)(255 * color.R), (byte)(255 * color.G), (byte)(255 * color.B));
}
This will take your BarColor, use it to make a SolidColorBrush of the right color, and then assign that to your native ProgressBar control.

passing string data from Android MainActivity to PCL TabbedPage xamarin.form

Hello everyone Good Day how do I pass string value or data from Android MainActivity to PCL TabbedPage?
MainActivity.cs
using System;
using Android.App;
using Android.Content;
using Android.Content.PM;
using Android.Runtime;
using Android.OS;
using Android.Telephony;
using Xamarin.Forms;
namespace NegDrClient.Droid
{
[Activity (Label = "Neg Client", Icon = "#drawable/logo", MainLauncher = true, ScreenOrientation = ScreenOrientation.Portrait)]
public class MainActivity : global::Xamarin.Forms.Platform.Android.FormsApplicationActivity
{
protected override void OnCreate (Bundle bundle)
{
base.OnCreate (bundle);
global::Xamarin.Forms.Forms.Init (this, bundle);
global::ZXing.Net.Mobile.Forms.Android.Platform.Init ();
LoadApplication (new App ());
}
public override void OnRequestPermissionsResult(int requestCode, string[] permissions, Permission[] grantResults)
{
global::ZXing.Net.Mobile.Forms.Android.PermissionsHandler.OnRequestPermissionsResult (requestCode, permissions, grantResults);
}
public string GetNumber()
{
TelephonyManager telephonyManager =
(TelephonyManager) Forms.Context.GetSystemService(Android.Content.Context.TelecomService);
var number = telephonyManager.Line1Number;
return number.ToString();
}
}
}
I need to call the GetNumber() method so I can assign it to my login entry, Thanks.
You can do this via a Dependency Service.
Add the following interface to your Xamarin.Forms project:
public interface IPhone
{
string GetNumber();
}
Add that interface to your existing MainActivity within your Xamarin.Android project:
public class MainActivity : global::Xamarin.Forms.Platform.Android.FormsApplicationActivity, IPhone
Register that Dependency class (above your namespace NegDrClient.Droid):
[assembly: Xamarin.Forms.Dependency(typeof(MainActivity))]
Now you can call it in your Xamarin.Forms project:
var GetNumberButton = new Button()
{
Command = new Command(() => {
Device.BeginInvokeOnMainThread(() =>
{
var number = DependencyService.Get<IPhone>().GetNumber();
System.Diagnostics.Debug.WriteLine(number);
});
})
};
Note: Your GetNumber method has an error in it, should be:
public string GetNumber()
{
var telephonyManager = (TelephonyManager)Forms.Context.GetSystemService(Context.TelephonyService);
return telephonyManager.Line1Number;
}

Resources