I have recently updated xamarin forms to 1.5.1-pre1 so that I can use the beautiful AppCompat themes. It works and looks very nice.
I do have one problem, in my old FormsApplicationActivity I used to override the OnOptionsItemSelected method to intercept when the user was clicking on the back arrow icon and do some viewmodel cleanup. Apparently this method is not being called after using the FormsAppCompatActivity.
How can I intercept the "soft" back button press (toolbar icon not hard back button) ?
I also tried to override the Xamarin.Forms.Platform.Android.AppCompat.NavigationPageRenderer but i can't seem to override it :(
Does anyone have a clue how I can intercept this?
You can add the following to your custom renderer. You can either user current activity plugin or cast your context to activity.
var toolbar = CrossCurrentActivity.Current?.Activity?.FindViewById<Toolbar>(Resource.Id.toolbar);
toolbar.NavigationClick += ToolbarNavigationClick;
Have a look at the last two lines of the OnCreate() After adding them OnOptionsItemSelected was called as expected).
https://raw.githubusercontent.com/UdaraAlwis/Xamarin-Playground/master/XFNavBarBackBtnClickOverride/XFNavBarBackBtnClickOverride/XFNavBarBackBtnClickOverride.Droid/MainActivity.cs
Toolbar toolbar = this.FindViewById<Toolbar>(Resource.Id.toolbar);
SetSupportActionBar(toolbar);
In Xamarin.Forms there's a better way to intercept the NavigationBar back button pressed and the hardware back button pressed, which is creating your own NavigationRenderer and overriding the method OnPopViewAsync:
[assembly: ExportRenderer(typeof(NavigationPage), typeof(CustomNavigationRenderer))]
namespace YourApp.Droid
{
public class CustomNavigationRenderer : NavigationPageRenderer
{
public CustomNavigationRenderer(Context context) : base(context)
{
}
protected override async Task<bool> OnPopViewAsync(Page page, bool animated)
{
// Write your code here
}
}
}
Hope this helps
Related
We have designed a custom popup with Content View, which will be invoked in a content page. When clicked on hardware back custom popup is getting closed, because Content View as no property to hand hardware back button Pressed. OnBackButtonPressed() is used only for Content Page. Can I get any solution to handle hardware back for content view to stop popup from closing.
To manage hardware back button you must override OnBackPressed() method in MainActivity class, in android project. In your popup you may have some property to check if can be closed and then check it from MainActivity class.
public override void OnBackPressed()
{
if (CheckIfCanBePressedMethod())
{
// back pressed will be ignored
// code here
}
else
{
// default behavior
base.OnBackPressed();
}
}
Set the flag on Contentpage when you open popup make the bool as true.
bool isShowPopup = false;
public override void OnBackPressed()
{
if (!isShowPopup)
{
base.OnBackPressed();
}
}
Is there any way to detect the press of the back button of the Navigation Page in Xamarin forms?
You can override your navigation page "OnBackButtonPressed" method:
protected override bool OnBackButtonPressed()
{
Device.BeginInvokeOnMainThread(async () =>
{
if (await DisplayAlert("Exit?", "Are you sure you want to exit from this page?", "Yes", "No"))
{
base.OnBackButtonPressed();
await App.Navigation.PopAsync();
}
});
return true;
}
If you are using the shell, you can override the Shell's OnNavigating event:
void OnNavigating(object sender, ShellNavigatingEventArgs e)
{
// Cancel back navigation if data is unsaved
if (e.Source == ShellNavigationSource.Pop && !dataSaved)
{
e.Cancel();
}
}
Update:
OnBackButtonPressed event will get fired ONLY on Android when user press the Hardware back button.
Seems like you are more interested to implement when any page get disappeared you want to do something!
In that case:
You have the page's two methods -
protected override void OnAppearing()
{
base.OnAppearing();
Console.WriteLine("Hey, Im coming to your screen");
}
protected override void OnDisappearing()
{
base.OnDisappearing();
Console.WriteLine("Hey, Im going from your screen");
}
You can override those 2 methods on any page to track when they appear and disappear.
Recent updates to Xamarin forms mean you can now do this in an application made with Shell Navigation for navigation back arrow on both platforms.
Use the Shell.SetBackButtonBehavior method, for example running this code in the constructor of your page object will allow the back navigation to take place only when the bound viewmodel is not busy:
Shell.SetBackButtonBehavior(this, new BackButtonBehavior
{
Command = new Command(async() =>
{
if (ViewModel.IsNotBusy)
{
await Shell.Current.Navigation.PopAsync();
}
})
});
In the body of the Command you can do whatever you need to do when you are intercepting the click of the back button.
Note that this will affect only the navigation back button, not the Android hardware back button - that will need handling separately as per the answers above. You could write a shared method called from both the back button pressed override and the command on shell back button behaviour places to share the logic.
You must override native navigationbar button behavior with custom renderer. OnBackButtonPressed triggers only physical device button. You can read good article how to achive this here
In my Xamarin app, I create a button (Xamarin.Forms.Button) programmatically. I need this button to show a different background image under normal vs hovered state. I have created a style resource similar to what is described at How to indicate currently selected control in Xamarin?. However, I cannot figure out how to apply this style to the button.
The Button class exposes a property called Image that is of FileImageSource type. The closest API I found to load my style resource is ImageSource.FromResource static method. However, this method seems to return StreamImageSource instance which is not what we need.
Class Button does not seem to provide any Style property.
Can you please suggest how I can programmatically associate a style to the button? Regards.
To achieve this request you need custom renderers.
To be able to apply your style f.e.: "myButtonStyle.xml" you have to create a custom renderer for your target platform:
Android:
[assembly: ExportRenderer (typeof (YourExtendedButtonClass), typeof (MyCustomButtonRenderer))]
namespace YourApp.Droid
{
public class MyCustomButtonRenderer : ButtonRenderer
{
protected override void OnElementChanged(ElementChangedEventArgs<Button> e)
{
base.OnElementChanged(e);
var myButton = this.Control as Android.Widget.Button;
myButton?.SetBackgroundResource(Resource.Drawable.myButtonStyle);
}
}
}
I'm working on Xamarin.iOS.When i move from one view controller to another a navigation bar is added to the view on which i just moved and a back button appears. On clicking the back button it returns me to the parent view. But i want some different functionality rather than returning to the parent view.
Can anyone help me out!
This can be accomplished by creating a custom button, and then setting that button as the back button for the view controller, such as:
public override void ViewDidLoad()
{
base.ViewDidLoad();
// Perform any additional setup after loading the view, typically from a nib.
UIBarButtonItem backButton = new UIBarButtonItem("title", UIBarButtonItemStyle.Bordered, handleBack);
this.NavigationItem.LeftBarButtonItem = backButton;
}
public void handleBack(object sender, EventArgs e)
{
Console.WriteLine("back!");
}
I hope this helps!
i made custom view which extend textView with this constractors :
// Default constructor override
public AutoResizeTextView(Context context) {
this(context, null);
}
// Default constructor when inflating from XML file
public AutoResizeTextView(Context context, AttributeSet attrs) {
this(context, attrs, 0);
}
how to i add it to my palette in android studio ?
i saw button that allows to to chose custom view but after i click on it nothing happen :
after i click on the class that i want the window is closed and nothing happen ...
I found this official guide to add custom views in the palette.