i want to change navigation bar title icon on my xamarin.forms ios application.You can find requested point at the attached image.app_screenshot
You can achieve this by using Custom Renderers on Xamarin.Forms. Since each UIViewController has its own NavigationItem, you should do this in your particular page which you want to modify its LeftBarButtonItem. Here is my Renderer for you referring to:
[assembly: ExportRenderer(typeof(CustomPage), typeof(CustomPageRenderer))]
namespace UIBarButtomItemsForms.iOS
{
public class CustomPageRenderer : PageRenderer
{
protected override void OnElementChanged(VisualElementChangedEventArgs e)
{
base.OnElementChanged(e);
}
public override void ViewWillAppear(bool animated)
{
base.ViewWillAppear(animated);
var navigationItem = NavigationController.TopViewController.NavigationItem;
UIBarButtonItem leftItem = new UIBarButtonItem(UIImage.FromBundle("Image.png"), UIBarButtonItemStyle.Plain, (sender, args) =>
{
});
navigationItem.SetLeftBarButtonItem(leftItem, false);
}
}
}
Then on Forms you can use this CustomPage, please notice that you should make your MainPage wrapped in a NavigationPage: MainPage = new NavigationPage(new MainPage());
Take a look at Change the Back Button: https://developer.xamarin.com/recipes/ios/content_controls/navigation_controller/change_the_back_button/
Related
I am working on xamarin forms. I wanted to change the Toolbar back icon how to do it. I searched lot about it. I didn't get proper solution. Any help would be appreciated.
Thanks
praveen
Try this
LoadApplication(new App());
var upArrow = Resources.GetDrawable(Resource.Drawable.abc_ic_ab_back_mtrl_am_alpha);
upArrow.SetColorFilter(Resources.GetColor(Resource.Color.white), PorterDuff.Mode.SrcIn);
ActionBar.SetHomeAsUpIndicator(upArrow);
References
https://forums.xamarin.com/discussion/57791/cant-change-android-back-button-in-xamarin-forms
https://forums.xamarin.com/discussion/103317/change-navigation-bar-back-button-color-in-xamarin-android
How to change the toolbar back icon in xamarin forms android
You could refer to my answer: How to change navigation page back button in xamarin forms.
I write it here again:
We need to custom a NavigationPageRenderer, override the OnPushAsync method to set the Toolbar's navigation icon.
using AToolbar = Android.Support.V7.Widget.Toolbar;
[assembly: ExportRenderer(typeof(CustomNavigationPage), typeof(NavigationPageRendererDroid))] // APPCOMP
...
public class NavigationPageRendererDroid : Xamarin.Forms.Platform.Android.AppCompat.NavigationPageRenderer // APPCOMP
{
public AToolbar toolbar;
public Activity context;
protected override Task<bool> OnPushAsync(Page view, bool animated)
{
var retVal = base.OnPushAsync(view, animated);
context = (Activity)Xamarin.Forms.Forms.Context;
toolbar = context.FindViewById<Android.Support.V7.Widget.Toolbar>(Droid.Resource.Id.toolbar);
if (toolbar != null)
{
if (toolbar.NavigationIcon != null)
{
toolbar.NavigationIcon = Android.Support.V4.Content.ContextCompat.GetDrawable(context, Resource.Drawable.Back);
//toolbar.SetNavigationIcon(Resource.Drawable.Back);
}
}
return retVal;
}
}
The CustomNavigationPage are defined in PCL :
public class CustomNavigationPage : NavigationPage
{
public CustomNavigationPage(Page startupPage) : base(startupPage)
{
}
}
Usage :
public App()
{
InitializeComponent();
MainPage = new CustomNavigationPage(new MainPage());
}
...
// In MainPage
private async void Button_Clicked(object sender, EventArgs e)
{
await Navigation.PushAsync(new TestPage());
}
[Effect].
how would I use Dependency Injection to use the Flyoutnavigation for my iOS project.
I have decided to stick with the default MasterDetailPage for Android as it doesn't look as bad as iOS.
This is what I have done so far:
In PCL
IMainPage.cs:
public interface IMainPage
{
Page GetMainPage();
}
App.cs:
public partial class App : Application
{
public App()
{
MainPage = DependencyService.Get<IMainPage>().GetMainPage();
}
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
}
}
In Android
MainPage_Android.cs:
[assembly: Xamarin.Forms.Dependency(typeof(MainPage_Android))]
namespace ProjectName.Droid
{
public class MainPage_Android : MasterDetailPage, IMainPage
{
private NavigationPage detail;
private MasterPage master;
public Page GetMainPage()
{
MasterDetailPage mdp = new MasterDetailPage();
//Master
master = new MasterPage();
MasterBehavior = MasterBehavior.Popover;
mdp.Master = master;
//Detail
detail = new NavigationPage(new Home())
{
BarBackgroundColor = Color.FromHex("#01A0E1"),
BarTextColor = Color.White
};
mdp.Detail = detail;
return mdp;
}
}
}
In iOS
I am stuck here.. How do I return a page using the Flyoutnavigation?
If you want to use default style on Android and custom style on iOS, you can try to make a custom renderer for MasterDetailPage on iOS. Then embed your Flyoutnavigation.
This is my iPad renderer:
[assembly: ExportRenderer(typeof(MainPage), typeof(MainPageRenderer))]
namespace FlyoutNavigationDemo.iOS
{
public class MainPageRenderer : TabletMasterDetailRenderer
{
//put your Flyoutnavigation's code here
}
}
Since Flyoutnavigation has too much code. I make a small sample for you, you can refer to here for more details.
I try set Icon for my Pages in Xaml:
Icon="icon.png
But it's not working, so I found other solution: How to add an icon in navigation bar for navigation page in xamarin forms for android?
It's custom render and working:
[assembly: ExportRenderer(typeof(NavigationPage), typeof(CustomMapRenderer))]
namespace XamarinFormsMaps.Droid
{
public class CustomMapRenderer : NavigationPageRenderer
{
protected override void OnElementChanged(ElementChangedEventArgs<NavigationPage> e)
{
base.OnElementChanged(e);
var bar = (Android.Support.V7.Widget.Toolbar)typeof(NavigationPageRenderer)
.GetField("_toolbar", BindingFlags.NonPublic | BindingFlags.Instance)
.GetValue(this);
bar.SetLogo(Resource.Drawable.icon); //how to load other icon, when Page is changing?
}
}
}
But I want set other Icon for other Pages... It's code set the same Icon for all pages. How to resolve it?
You can be notified when the current page of Navigation is changed by using below code.
It's a method in NavigationPageRenderer.
protected override void OnElementPropertyChanged(object sender, System.ComponentModel.PropertyChangedEventArgs e)
{
if (e.PropertyName == "CurrentPage")
{
var page = Element.CurrentPage as ContentPage;
if (page != null)
{
//do what you want.
}
}
}
I want to open Xamarin forms page from Xamarin Android project. On android project I created toolabar item image, where I am calling event to open page from Xamarin forms project.
Here is my MainActivity.cs toolabar image item implementation:
public class MainActivity : global::Xamarin.Forms.Platform.Android.FormsApplicationActivity
{
private IMenu CurrentMenu { get; set; }
private ImageView imgSmallC { get; set; }
public override bool OnCreateOptionsMenu(IMenu menu)
{
ActionBar.DisplayOptions = ActionBarDisplayOptions.HomeAsUp | ActionBarDisplayOptions.ShowCustom | ActionBarDisplayOptions.ShowTitle | ActionBarDisplayOptions.ShowHome;
LayoutInflater inflater = (LayoutInflater)ActionBar.ThemedContext.GetSystemService(LayoutInflaterService);
View customActionBarView = inflater.Inflate(Resource.Layout.actionbar_custom_view_done, null);
imgSmallC = (ImageView)customActionBarView.FindViewById<ImageView>(Resource.Id.ImgSmallC);
imgSmallC.Click += (object sender, EventArgs args) =>
{
StartActivity(typeof(MyPopupPage));
};
return base.OnCreateOptionsMenu(menu);
}
}
In StartActivity I am calling MyPopupPage.xaml page from Xamarin forms project, but unfortunately when I am debugging project and I click on toolbar image I get such a error:
System.ArgumentException: type Parameter name: Type is not derived
from a java type.
You can not use a Xamarin.Form based Page as an Android Activity, they are two completely different things.
You can access the Xamarin.Forms Application singleton from the Xamarin.Android project and use that to PushModelAsync or PushAsync
Example (using full Namespace):
await Xamarin.Forms.Application.Current.MainPage.Navigation.PushModalAsync(new PushPageFromNative.MyPage());
A Dependency Service-based Example:
Interface:
using System;
namespace PushPageFromNative
{
public interface IShowForm
{
void PushPage();
}
}
Xamarin.Form-based code:
var pushFormBtn = new Button
{
Text = "Push Form",
VerticalOptions = LayoutOptions.CenterAndExpand,
HorizontalOptions = LayoutOptions.CenterAndExpand,
};
pushFormBtn.Clicked += (sender, e) =>
{
DependencyService.Get<IShowForm>().PushPage();
};
Xamarin.Android Dependancy Implementation:
async public void PushPage()
{
// Do some Android specific things... and then push a new Forms' Page
await Xamarin.Forms.Application.Current.MainPage.Navigation.PushModalAsync(new PushPageFromNative.MyPage());
}
I am new with Xamarin, but I am training by creating parking application. Now I got issue by trying to access to another layout.
This is my MainActivity.cs
[Activity(Label = "CustomActionBarParking", MainLauncher = true, Icon = "#drawable/icon", Theme ="#style/CustomActionBarTheme")]
public class MainActivity : Activity
{
private LinearLayout mBarZone;
protected override void OnCreate(Bundle bundle)
{
base.OnCreate(bundle);
ActionBar.SetDisplayShowCustomEnabled(true);
SetContentView(Resource.Layout.action_bar);
mBarZone = FindViewById<LinearLayout>(Resource.Id.linearLayout2);
mBarZone.Click += (object sender, EventArgs args) =>
{
SetContentView(Resource.Layout.zones_list);
};
}}}
Here I am accessing from my menu, by clicking on "Zones" action bar. And open "zones list" layout.
From here I want to access to another Layout: vehicle_not_parked by clicking on blue zone action bar button. But I don't know where I have to initialize it, because when I initialized that in MainAcitivy class on OnCreate method, then I got error, that my object is nullable. Then I create ZonesActivity.cs which looks like this:
[Activity(Label = "CustomActionBarParking")]
public class ZonesActivity : Activity
{
private LinearLayout mBlueZone;
protected override void OnCreate(Bundle savedInstanceState)
{
base.OnCreate(savedInstanceState);
SetContentView(Resource.Layout.zones_list);
mBlueZone = FindViewById<LinearLayout>(Resource.Id.linearLayout2);
mBlueZone.Click += (object sender, EventArgs args) =>
{
SetContentView(Resource.Layout.vehicle_not_parked);
};
}}}
But when I tryed to call this class in Main Activity class I have to deal with Bundle savedInstanceState property. I am not really know how I can from one view -> 2nd view and then -> 3rd view.
If I understand you correctly, your swapping out the layouts in the button click event? I think it would be best to start a new activity
mBarZone.Click += delegate {
StartActivity(typeof(ZonesActivity));
};
Docs on starting a new activity