Запретить закрытие по обратной кнопке в форме xamarin на андроиде

Я хочу предотвратить закрытие приложения, нажав кнопку возврата оборудования в форматах xamarin на Android.

Я хочу, чтобы вы могли перемещаться с помощью кнопки "Назад" в приложении (что работает), но не хотите выйти, когда достигнута первая страница в стеке навигации.

Я попытался использовать событие OnSleep в форматах xamarin, но здесь я не могу отменить выход.

Я также попытался поймать кнопку back в android:

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

Но при использовании форм xamarin я не знаю, какая страница в настоящее время отображается. Поэтому я не знаю, разрешена ли навигация или нет.

Ответ 1

Он работает с оценкой NavigationStack (при использовании NavigationPage).

В моей деятельности я переопределяю OnBackPressed

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

В моем приложении xamarin forms (App.Instance(это singleton)), я буду оценивать NavigationStack текущей страницы, как это.

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

Когда в навигационном стеке осталось только одна страница, я не буду называть base.OnBackPressed, чтобы я не закрыл приложение.

! [Тест]

Ответ 2

И вот, какой код мог бы выглядеть для сценария страницы Xamarin Forms MasterDetail...

    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;
        }
    }

Ответ 3

Просто введите пустой вызов на странице, где вы хотите предотвратить, например

protected override bool OnBackButtonPressed()
{
return true;
}

Это предотвратит обратную кнопку в XF-Droid.

Ответ 4

Расширяем ответ криса, поскольку сейчас нет App.Instance, и невозможно получить доступ к приложению статическим способом в коде платформы.

1. App.xaml.cs

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

2. MainActivity.cs в рамках проекта Android

  • объявить переменную класса App

    App app;

  • в OnCrate(Bundle bundle) измените LoadApplication(new App()); на

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

  • и метод переопределения OnBackPressed()

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

Ответ 5

Вот решение, которое работает на Android.
Внесите счетчик в класс приложения и увеличьте его с каждым OnStart и уменьшите его с каждым OnStop таким образом, когда счетчик 1, вы узнаете, что находитесь в своем последнем действии.

Излишне говорить, что используйте реализацию базовой активности, так что вам не нужно копировать код котельной плиты.

Ответ 6

Предлагаемое решение может работать хорошо, но мне не нравится "статическое воздействие на свойства" для решения проблем. Более того, мне не нравится использование решений "свойства как методы", особенно когда задействована большая логика.

Основная проблема здесь в том, как мы можем обрабатывать метод OnBackButton() из нашего класса Xamarin.Forms.Application.

Как насчет того, чтобы сделать то же самое более элегантным способом?

Сначала вам нужно расширить класс Xamarin.Forms.Application следующим образом:

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
    }
}

Теперь ваша реализация приложения будет использовать этот класс в качестве базового класса. Не забудьте изменить свой xaml и ваш xaml.cs соответственно:

<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>

В вашей реализации App.cs вы теперь можете переопределить метод 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
}

Затем вам нужно немного изменить свою реализацию класса активности.

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
}