How to set page icon in Xamarin Forms? - android

I'm trying to set page icon. There is App class of PCL below.
public App()
{
CustomMainPage mainPage = new CustomMainPage();
NavigationPage rootPage = new NavigationPage(mainPage);
this.MainPage = rootPage;
}
What I tried to do?
NavigationPage.SetTitleIcon(mainPage, "icon.png");
The second approach.
NavigationPage.SetTitleIcon(this, "icon.png");
The third approach.
NavigationPage.SetTitleIcon(rootPage, "icon.png");
File icon.png is situated into Resources/drawable.
And finally I decided to implement my custom renderer for the NavigationPage in Xamarin Forms. NavigationPage is setted to MainPage property into App class of PCL.
I created DroidNavigationRenderer class into Android project.
[assembly: ExportRenderer(typeof(NavigationPage), typeof(DroidNavigationPageRenderer))]
namespace App1.Droid.DroidRenderers
{
public class DroidNavigationPageRenderer : NavigationPageRenderer
{
protected override void OnElementChanged(ElementChangedEventArgs<NavigationPage> e)
{
base.OnElementChanged(e);
var actionBar = ((Activity)Context).ActionBar;
actionBar.SetIcon(Resource.Drawable.icon);
}
}
}
But actionBar is always returns as null.
What I do wrong and how to fix it?

In your ContentPage, you have the Icon property.
You can set it this way
Icon = Device.OnPlatform("Menu", "ic_fa_bars.png", "Assets/Icons/reload.png");

What is your CustomMainPage class? If I have TabbedPage and set one of its child I do it this way:
var navigationPage = new NavigationPage(mainPage);
if (Device.RuntimePlatform == Device.iOS)
{
navigationPage.Icon = "services.png";
}
hope it helps

Related

How do I get a reference to ActionBarDrawerToggle?

I have a Xamarin Forms application that I am porting from a FormsActivity to an AppCompatActivity. For functional requirements, the hamburger icon should always show, which I have done by using
NavigationPage.SetHasBackButton(nextPage, false);
But this does not work with AppCompat and the issue report has sat unaddressed for over a year, so I'm trying to get around the issue with a custom renderer. I can successfully create the icon and display it, but tapping on it does not display the correct behavior. I'm thinking what I need to do is set the DrawerIndicatorEnabled to true and call SyncState, but I need a reference to the ActionBarDrawerToggle to do that and I haven't figured out how to get it.
Edit: This is the bug report with screen shots:
https://github.com/xamarin/Xamarin.Forms/issues/2577
Here is the custom NavigationPageRenderer:
[assembly: ExportRenderer(typeof(CustomNavigationPage), typeof(CustomNavigationPageRenderer))]
namespace HeaderTest.Droid
{
public class CustomNavigationPageRenderer : NavigationPageRenderer // APPCOMP
{
public CustomNavigationPageRenderer(Context context) : base(context)
{
}
protected override Task<bool> OnPushAsync(Page view, bool animated)
{
var retVal = base.OnPushAsync(view, false);
var context = (Activity)Context;
var toolbar = context.FindViewById<AToolbar>(Resource.Id.toolbar);
if (toolbar != null)
{
var icon = new DrawerArrowDrawable(context)
{
SpinEnabled = false,
};
toolbar.NavigationIcon = icon;
}
return retVal;
}
}
}

page has two tool bars

I am starting the NavigationPage in the App.cs class:
MainPage = new NavigationPage(new PageA());
In PageA(), I am are calling "PushAsync":
public partial class MainPage : ContentPage
{
public MainPage()
{
InitializeComponent();
}
private void btnCourseList_Clicked(object sender, EventArgs e)
{
Navigation.PushAsync(new PageB());
}
}
If I click back button on PageB(), it goes to PageA() in which it has two tool bars.
Any idea how to fix this?
The reason for it is very simple you are providing two navigation pages in the page lifecycle which is in turn showing two Navbar's
Solution :
In your App.xaml.cs add a static NavigationPage property something like this:
public static NavigationPage NavigationPage { get; set; }
Assign this a Page in your app.xaml constructor something like this :
App.NavigationPage = new NavigationPage(new yourPage) ;
Then Assign this NavigationPage as your MainPage like this:
MainPage=App.NavigationPage;
Now Whenever you plan on going to the next page call the next page like this:
App.NavigationPage.PushAsync(new YourNewPage());
Goodluck!
In case of queries revert.

Remove shadow from Android Button built in Xamarin forms

I am trying to get rid of the shadow that is being displayed at the bottom of a button in android built using xamarin forms. I have tried all that I could. But I have not achieved it.
I have attached an image for reference.
I request your'l to help me and put me out of my misery.
Thanks in advance
1) Create custom control and derive it from Button.
public class ButtonWithoutShadow : Button
{
}
2) Create custom renderer
[assembly: ExportRenderer(typeof(ButtonWithoutShadow), typeof(ButtonWithoutShadowRenderer))]
public class ButtonWithoutShadowRenderer : ButtonRenderer
{
protected override void OnElementChanged(ElementChangedEventArgs<Button> e)
{
base.OnElementChanged(e);
if (Control != null)
{
Control.Elevation = 0;
}
}
}
3) In xaml page use this button:
<controls:ButtonWithoutShadow TextColor="White" HorizontalOptions="Center" WidthRequest="185" HeightRequest="52" BackgroundColor="#ffcd00" Font="Roboto-Regular" FontSize="23" Text="Поиск" BorderRadius="0" BorderWidth="0" />
[assembly: ExportRenderer(typeof(Button),typeof(FlatButtonRenderer))]
namespace Project.Droid
{
public class FlatButtonRenderer : ButtonRenderer
{
protected override void OnDraw(Android.Graphics.Canvas canvas)
{
base.OnDraw(canvas);
}
}
}
<Button BackgroundColor="Transparent" Text="ClickMe"/>
Source : https://stackoverflow.com/a/39966574/7794690
For me, only thing that removed the shadow was doing this in a custom button render:
Control.StateListAnimator = null;
It may be dependent on API level, though, so might also require:
Control.Elevation = 0;

Can't add ToolbarItem to ContentPage

I declare my main page:
public App () {
MainPage = new NavigationPage(new MainPage());
}
Then on main page open ContantPage after tapping a button:
class MainPage : ContentPage {
public MainPage() {
button.Clicked += to_my_contentpage;
//...
}
private async void to_my_contentpage(object sender, EventArgs e) {
await Navigation.PushModalAsync(new my_contentpage());
//using PushAsync doesn't help
}
}
And try to show button on this page as ToolbarItem:
public class my_contentpage : ContentPage {
public my_contentpage () {
ToolbarItem AddButton = new ToolbarItem("AddButton", "AddIcon.png", () => {
Console.WriteLine("Clicked");
});
this.ToolbarItems.Add(new ToolbarItem());
//...
this.Content = new StackLayout { Children = { header, listView } };
}
}
I feel like doing everithing according to this answer but my ToolbarItem is not included to my page:
How do i add toolbar for android in xamarin,forms as ToolbarItem is not working for .droid?
What am I doing wrong?
PushModalAsync is not going to work in this case, since you need to have a Navigation Bar in order to add ToolBarItems to it.
Since a Modal page explicitly does not show/contain a NavigationBar you are not going to be able to do it this way.
Solutions:
Create a Custom NavigationBar and add any Views you need to it.
Do not use a Modal Page.
Hope this helps.

Add Mapbox to Android View in Xamarin Forms Custom Renderer

I cannot figure out how to get a Mapbox map going in a custom view renderer on Android using Xamarin.Forms. It's driving me bonkers.
In my PCL, I have a map view.
public class MapView: View
{
public MapView() { }
}
For iOS, the "getting started" help was close enough to get it working on iOS, like so:
[assembly: ExportRenderer (typeof(Shared.Mobile.MapView), typeof(MapViewRenderer))]
namespace Clients.iOS
{
public class MapViewRenderer : ViewRenderer<Shared.Mobile.MapView, UIView>
{
protected override void OnElementChanged(ElementChangedEventArgs<Shared.Mobile.MapView> e)
{
base.OnElementChanged(e);
if (e.NewElement == null)
{
return;
}
var uiView = new UIView(new CoreGraphics.CGRect(0, 0, 500, 700));
SetNativeControl(uiView);
var mapView = new MapView(Control.Bounds);
mapView.SetCenterCoordinate(new CoreLocation.CLLocationCoordinate2D(40.81, -96.68), false);
mapView.SetZoomLevel(11, false);
mapView.AddAnnotation(new PointAnnotation
{
Coordinate = new CoreLocation.CLLocationCoordinate2D(40.81, -96.68),
Title = "Lincoln, NE",
Subtitle = "What-what"
});
uiView.AddSubview(mapView);
}
}
}
On the Android side, not so much. (https://components.xamarin.com/gettingstarted/mapboxsdk). They're putting in XML and an Activity of sorts, but my knowledge in mobile doesn't extend far from Xamarin.Forms at the moment, so I can't seem to bridge the gap between the two. My Android renderer looks like this:
public class MapViewRenderer : ViewRenderer<Shared.Mobile.MapView, Android.Views.View>
{
protected override void OnElementChanged(ElementChangedEventArgs<Shared.Mobile.MapView> e)
{
base.OnElementChanged(e);
var view = new Android.Views.View(Context);
SetNativeControl(view); // NullReferenceException will be thrown if the native control is not set
if (Control == null)
{
return;
}
var mapView = new MapView(Forms.Context, "thisismyaccesscode");
mapView.CenterCoordinate = new LatLng(41.885, -87.679);
mapView.ZoomLevel = 11;
mapView.SetMinimumHeight(250);
mapView.SetMinimumWidth(250);
mapView.AddMarker(new MarkerOptions().SetPosition(new LatLng(40.81, -96.68)).SetTitle("Lincoln, NE"));
view.AddSubview(mapView) // I wish this method existed
}
}
My final call to AddSubview(mapView) is not in fact a method of the View class as it is the UIView class on iOS. Here's where I'm stuck. I cannot figure out how to display the MapView. Please help.
As you have already mentioned you can't call AddSubview as it is an iOS method.
On Android its the equivalent of AddView.
However - You are attempting to do this type of operation on a Android View object and not on a ViewGroup object, so its not possible.
First instead of doing:-
var view = new Android.Views.View(Context);
try instantiating the MapView directly such like:-
var view = new MapView(Context, "thisismyaccesscode");
Your SetNativeControl call on the view is fine.
I haven't tried the Mapbox component, so I'm unclear on the exact parameter types it is expecting in the code above.
Should that not work, however, then do something like the following:-
var view = new Android.Widget.FrameLayout(Context);
var mapView = new MapView(Forms.Context, "thisismyaccesscode");
mapView.CenterCoordinate = new LatLng(41.885, -87.679);
mapView.ZoomLevel = 11;
mapView.SetMinimumHeight(250);
mapView.SetMinimumWidth(250);
mapView.AddMarker(new MarkerOptions().SetPosition(new LatLng(40.81, -96.68)).SetTitle("Lincoln, NE"));
view.AddView(mapView);
SetNativeControl(view);
You will have to change your first line to the following also:-
public class MapViewRenderer : ViewRenderer<Shared.Mobile.MapView, Android.Widget.FrameLayout>

Categories

Resources