Reputation: 12014
What I want to achieve is that the app starts with a login page
and after login the Main page
should be show. From there other pages can be opened and normal navigation is allowed.
However, I do not want the users to navigate back to the login page. After the login the main page
must be the root of the navigation.
I found lots of information on google on how to do it, but they all don't seem to work for me. Mainly I've been told to make my main page
the root by setting MainPage
directly to my PageMain
that is also in my code now, but it does not works.
Other method should be to remove the login page
from the navigation stack, but I can't get that to work. The samples I find compile but on runtime they crash my application saying either I cannot remove the current page or the page I am removing is not found.
Here is my code:
My app starts with PageLogin
, for now it just has a button and when you click on it then it opens my PageMain
private void ButtonLogin_Clicked(object sender, EventArgs e)
{
// almost does what I want
Application.Current.MainPage = new PageMain();
// almost does what I want
// make PageMain the new main page, so you cannot go back to the login screen
//Application.Current.MainPage = new NavigationPage(new PageMain());
// error you cannot remove the page you are on
//var _navigation = Application.Current.MainPage.Navigation;
//var _lastPage = _navigation.NavigationStack.LastOrDefault();
////Remove last page
//_navigation.RemovePage(_lastPage);
////Go back
//_navigation.PopAsync();
// error page does not exists
//Application.Current.MainPage.Navigation.RemovePage(this);
//Navigation.PopAsync(); not supported on android
//Navigation.RemovePage(this); not supported on android
}
The MainPage is set in App.xaml.cs like this
public partial class App : Application
{
public App()
{
InitializeComponent();
//MainPage = new NavigationPage(new Pages.PageLogin());
MainPage = new Pages.PageLogin();
}
The code above opens my page PageMain
so far so good.
Now when I click on the back button
of the device, my app minimizes (or whatever it does on android to hide itself)
This is good because I don't want the user to go back to the login form
But, when I now click on recent apps
button on the device, and click on my app to get it back in foreground, it moves back to the login form.
See this vid
How can I avoid that ?
EDIT
I tried setting IsTabStop
to false, but also no result
public PageLogin()
{
InitializeComponent();
this.IsTabStop = false;
ButtonLogin.Clicked += ButtonLogin_Clicked;
}
Upvotes: 4
Views: 1211
Reputation: 12014
I worked out a method base on CFun's answer that seems to work fine during my tests.
I will show my implementation of this answer here, so it can be used by other people with the same problem.
And by doing so I also give a change to everybody to comment on this implementation of that answer.
The idea is to keep a reference to the prior page, everytime another page is opened. Then in the MainActivity.cs
in the OnBackPressed
method I can check if I am on the Root Page
(which is my PageMain) or not.
When on the root page I can do MoveTaskToBack
and otherwise I can set the current page to priorPage
.
Here is the code:
What I did, first in my App.xaml.cs
I put this static variable priorPage
public partial class App : Application
{
public static Page priorPage;
public App()
{
InitializeComponent();
MainPage = new Pages.PageLogin();
}
Then when my app starts (first page is the login page) and the user clicks on login, this code will be executed. The variable priorPage
will be set to the page that currently is active, before opening a new page
private void ButtonLogin_Clicked(object sender, EventArgs e)
{
App.priorPage = this;
Application.Current.MainPage = new PageMain();
}
The same principle will be used for every page that is opened
private void ButtonSettings_Clicked(object sender, EventArgs e)
{
App.priorPage = this;
Application.Current.MainPage = new PageSettings();
}
And finally, in the MainActivity.cs
I can now do this
public override void OnBackPressed()
{
if (App.Current.MainPage is PageMain)
{
MoveTaskToBack(true); // you are on the root, hide the app
}
else if (App.priorPage != null)
{
App.Current.MainPage = App.priorPage; // navigate back to you prior page
}
else
{
base.OnBackPressed();
}
}
Upvotes: 0
Reputation: 9671
This is a pure Android behavior and has nothing to do with Xamarin.Forms, when pressing the back button while your navigation stack of the app is empty, depending on which Android version is running, it will behave like follow:
The system moves the activity and its task to the background instead of finishing the activity. This behavior matches the default system behavior when navigating out of an app using the Home button or gesture.
In most cases, this behavior means that users can more quickly resume your app from a warm state, instead of having to completely restart the app from a cold state...
Source: Back press behavior for root launcher activities.
In your case when you press the back button on the main screen, Android finishes the activity, if you want to confirm that, set a breakpoint on your AppShell.cs
constructor or MainActivity.cs/OnCreate()
you will notice that:
MainActivity.OnResume()
.OnBackPressed()
in your MainActivity
with an empty code:public override void OnBackPressed()
{
}
public override void OnBackPressed() => MoveTaskToBack(true);
More on OnBackPressed()
Upvotes: 1