web-dev-qa-db-fra.com

Empêcher la fermeture par le bouton de retour dans les formulaires xamarin sur android

Je souhaite empêcher la fermeture de l'application en appuyant sur le bouton de retour matériel dans les formulaires xamarin sur Android.

Je veux que vous puissiez naviguer avec le bouton de retour matériel dans l'application (ce qui fonctionne), mais ne voulez pas quitter, lorsque la première page de la pile de navigation est atteinte.

J'ai essayé d'utiliser l'événement OnSleep dans les formulaires xamarin, mais ici je ne peux pas annuler la sortie.

J'ai également essayé d'attraper le bouton de retour dans Android:

    public override void OnBackPressed()
    {
        //base.OnBackPressed();
    }

Mais lorsque j'utilise des formulaires xamarin, je ne sais pas quelle page est actuellement affichée. Je ne sais donc pas si la navigation en arrière est autorisée ou non

17
Chris

Cela fonctionne avec l'évaluation de NavigationStack (lorsque vous utilisez NavigationPage).

Dans mon activité, je remplace le OnBackPressed

public override void OnBackPressed()
{
    if(App.Instance.DoBack)
    {
        base.OnBackPressed();
    }
}

Dans mon application de formulaires xamarin (App.Instance (c'est un singleton)), j'évaluerai le NavigationStack de la page actuelle comme ceci.

public bool DoBack
{
    get
    {
        NavigationPage mainPage = MainPage as NavigationPage;
        if (mainPage != null)
        {
            return mainPage.Navigation.NavigationStack.Count > 1;
        }
        return true;                
    }
}

Lorsqu'il ne reste qu'une page dans le NavigationStack, je n'appellerai pas base.OnBackPressed, afin de ne pas fermer l'application.

![tester]

18
Chris

Et voici à quoi pourrait ressembler le code pour un scénario de page MasterDetail Xamarin Forms ...

    public bool DoBack
    {
        get
        {
            MasterDetailPage mainPage = App.Current.MainPage as MasterDetailPage;

            if (mainPage != null)
            {    
                bool canDoBack = mainPage.Detail.Navigation.NavigationStack.Count > 1 || mainPage.IsPresented;

                // we are on a top level page and the Master menu is NOT showing
                if (!canDoBack)
                {
                    // don't exit the app just show the Master menu page
                    mainPage.IsPresented = true;
                    return false; 
                }
                else
                {
                    return true;
                }                    
            }
            return true;
        }
    }
11
Iain STIRZAKER

Donnez simplement un appel vide dans la page où voulez-vous empêcher, comme

protected override bool OnBackButtonPressed()
{
return true;
}

Cela empêchera le bouton de retour dans XF-Droid.

9
Senthamizh

Élargir la réponse de Chris car il n'y a pas de App.Instance Maintenant et on ne peut pas accéder à l'application de manière statique dans le code de la plate-forme.

1. App.xaml.cs

public bool DoBack 
{
    get 
    {
        return MainPage.Navigation.NavigationStack.Count > 1;
    }
}

2. MainActivity.cs Sous Android

  • déclarer la variable de classe App

    App app;

  • dans OnCrate(Bundle bundle) changer LoadApplication(new App()); en

    app = new App();
    LoadApplication(app);

  • et remplacer la méthode OnBackPressed()

    public override void OnBackPressed()
    {
        if (app.DoBack)
        {
            base.OnBackPressed();
        }
    
    } 
    
2
Prateek

Voici une solution qui fonctionne sur Android.
Introduisez un compteur dans la classe d'application et incrémentez-le avec chaque OnStart et décrémentez-le avec chaque OnStop de cette façon lorsque le compteur est 1 you ' Je sais que vous en êtes à votre dernière activité.

Inutile de dire que vous utilisez une implémentation d'activité de base afin de ne pas avoir à copier le code de plaque de la chaudière.

0
Alex.F

Vous pouvez utiliser ce nuget nuget chd.hwBackButtonManager

projet github

0
Noe Miranda Franco

La solution proposée peut très bien fonctionner, mais je n'aime pas "l'exposition aux propriétés statiques" pour résoudre les problèmes. De plus, je n'aime pas l'utilisation de solutions "propriétés en tant que méthodes", surtout quand beaucoup de logique est impliquée.

Le problème principal ici comment nous pouvons gérer la méthode OnBackButton () de notre classe Xamarin.Forms.Application.

Que diriez-vous de faire la même chose d'une manière plus élégante?

Vous devez d'abord étendre la classe Xamarin.Forms.Application comme ceci:

namespace YourNameSpace
{
    public class Application : Xamarin.Forms.Application
    {
        #region Public Methods

        public bool HandleBackButton()
        {
            return OnBackPressed();
        }

        #endregion

        #region Application Methods

        protected virtual bool OnBackPressed()
        {
            return false;
        }

        #endregion
    }
}

L'implémentation de votre application utilise désormais cette classe comme classe de base. N'oubliez pas de modifier votre xaml et vos xaml.cs en conséquence:

<common:Application xmlns="http://xamarin.com/schemas/2014/forms"
             xmlns:x="http://schemas.Microsoft.com/winfx/2009/xaml"
             xmlns:common="clr-namespace:YourNameSpace"
             x:Class="YourNameSpace.App">
</common:Application>

Dans votre implémentation App.cs, vous pouvez désormais remplacer la méthode OnBackButton ().

public partial class App : YourNameSpace.Application
{
    #region Constructors

    public App()
    {
        InitializeComponent();
    }

    #endregion

    #region App Methods

    protected override bool OnBackPressed()
    {
        // Handle when the back button is pressed
        return false;
    }

    #endregion
}

Ensuite, vous devez modifier un peu l'implémentation de votre classe d'activité.

public class MainActivity : global::Xamarin.Forms.Platform.Android.FormsAppCompatActivity
{
    #region Constants and Fields

    private App _app;

    #endregion

    #region Activity Methods

    protected override void OnCreate(Bundle bundle)
    {
        TabLayoutResource = Resource.Layout.Tabbar;
        ToolbarResource = Resource.Layout.Toolbar;

        base.OnCreate(bundle);

        global::Xamarin.Forms.Forms.Init(this, bundle);

        _app = new App();
        LoadApplication(_app);
    }

    public override void OnBackPressed()
    {
        if(!_app.HandleBackButton())
            base.OnBackPressed();
    }

    #endregion
}
0
Francesco