Reputation: 2550
I am working on Xamarin forms where I need to show master detail navigation after successful login screen. I want to change default hamburger icon but not able to change it.
Please see below code I am using.
Since my app have login screen so I don't want to show any navigation on Login screen. I am just setting main page in app.xaml.cs
public App()
{
InitializeComponent();
MainPage = new Login();
}
Now after login clicked I tried following approach to change icon but didn't work
var dashboard = new Dashboard(){Icon = "Menuicon.png" };
Application.Current.MainPage = dashboard;
Dashbaord
is masterdetail page and on its ctor, I am setting detail page like below
Detail = new NavigationPage((Page)Activator.CreateInstance(typeof(DashbaordDetail))) { Icon = "Menuicon.png" };
Its not reflecting new icon
Upvotes: 6
Views: 8966
Reputation: 2246
The accepted answer does not work, as it shows the hamburger icon also when there should be a back icon. Ronak Shetiyas answer above does work.
Code adapted for AndroidX AppCompat
public class NavigationPageRenderer : Xamarin.Forms.Platform.Android.AppCompat.MasterDetailPageRenderer
{
protected AndroidX.AppCompat.Widget.Toolbar TitleToolBar;
protected override void OnLayout(bool changed, int l, int t, int r, int b)
{
base.OnLayout(changed, l, t, r, b);
TitleToolBar = FindViewById<AndroidX.AppCompat.Widget.Toolbar>(Resource.Id.toolbar);
// change the default hamburger / back icon
if (TitleToolBar != null)
{
for (var i = 0; i < TitleToolBar.ChildCount; i++)
{
var imageButton = TitleToolBar.GetChildAt(i) as AndroidX.AppCompat.Widget.AppCompatImageButton;
var drawerArrow = imageButton?.Drawable as DrawerArrowDrawable;
if (drawerArrow == null)
continue;
var displayBack = false;
if (Xamarin.Forms.Application.Current.MainPage is MasterDetailPage masterDetailPage)
{
var detailPage = masterDetailPage.Detail;
var navPageLevel = detailPage.Navigation.NavigationStack.Count;
if (navPageLevel > 1)
displayBack = true;
imageButton.SetImageResource(displayBack
? Resource.Drawable.ic_arrow_back
: Resource.Drawable.ic_menu);
}
}
}
}
}
Upvotes: 0
Reputation: 980
i applied this tweak and it helped me. now i can see back button also after navigation
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);
if (toolbar != null)
{
for (var i = 0; i < toolbar.ChildCount; i++)
{
var imageButton = toolbar.GetChildAt(i) as ImageButton;
var drawerArrow = imageButton?.Drawable as DrawerArrowDrawable;
if (drawerArrow == null)
continue;
bool displayBack = false;
var app = Xamarin.Forms.Application.Current;
var detailPage = (app.MainPage as MasterDetailPage).Detail;
var navPageLevel = detailPage.Navigation.NavigationStack.Count;
if (navPageLevel > 1)
displayBack = true;
if (!displayBack)
ChangeIcon(imageButton, Resource.Drawable.iconMenu2);
if (displayBack)
ChangeIcon(imageButton, Resource.Drawable.back1);
}
}
}
private void ChangeIcon(ImageButton imageButton, int id)
{
if (Android.OS.Build.VERSION.SdkInt >= Android.OS.BuildVersionCodes.Lollipop)
imageButton.SetImageDrawable(Context.GetDrawable(id));
imageButton.SetImageResource(id);
}
Upvotes: 6
Reputation: 2899
You should use a custom renderer.
In your Android project, like this:
[assembly: ExportRenderer(typeof(CustomIcon.Views.MainPage), typeof(IconNavigationPageRenderer))]
namespace CustomIcon.Droid
{
public class IconNavigationPageRenderer : MasterDetailPageRenderer
{
private static Android.Support.V7.Widget.Toolbar GetToolbar() => (CrossCurrentActivity.Current?.Activity as MainActivity)?.FindViewById<Android.Support.V7.Widget.Toolbar>(Resource.Id.toolbar);
protected override void OnLayout(bool changed, int l, int t, int r, int b)
{
base.OnLayout(changed, l, t, r, b);
var toolbar = GetToolbar();
if (toolbar != null)
{
for (var i = 0; i < toolbar.ChildCount; i++)
{
var imageButton = toolbar.GetChildAt(i) as ImageButton;
var drawerArrow = imageButton?.Drawable as DrawerArrowDrawable;
if (drawerArrow == null)
continue;
imageButton.SetImageDrawable(Forms.Context.GetDrawable(Resource.Drawable.newIcon));
}
}
}
}
}
In your iOS project only use the same icon from you xaml file in your PCL project, like this:
<?xml version="1.0" encoding="utf-8" ?>
<MasterDetailPage xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
xmlns:local="clr-namespace:CustomIcon.Views;assembly=CustomIcon"
Title="MainPage"
Icon="newIcon.png"
x:Class="CustomIcon.Views.MainPage">
<MasterDetailPage.Master>
<local:MasterPage x:Name="masterPage" />
</MasterDetailPage.Master>
<MasterDetailPage.Detail>
<NavigationPage>
<x:Arguments>
<local:Page1 />
</x:Arguments>
</NavigationPage>
</MasterDetailPage.Detail>
For more information see my repo on github: https://github.com/wilsonvargas/CustomIconNavigationPage
Upvotes: 7