Переключить полноэкранный режим со стабильной версткой, используя Xamarin.Forms / Xamarin.Droid - PullRequest
0 голосов
/ 13 июня 2019

Я создаю приложение, которое должно иметь возможность переключаться между двумя режимами просмотра:

  • Полноэкранный режим: представление должно отображаться на весь экран без заголовка / панели навигации / панели действий.
  • Полу-полноэкранный режим: вид должен по-прежнему заполнять весь экран, но заголовки / навигация / панели действий теперь должны отображаться перед видом без изменения размера представления.

Чтобы проверить поведение переключения между этими двумя режимами, я создал простой тестовый проект, который переключается между этими двумя режимами каждые две секунды.

Полноэкранный режим работает, как задумано, но есть две проблемы сполу-полноэкранный режим, как показано на изображениях ниже:

  1. Содержимое вида (метка с пятью строками текста) сдвигается вниз.Я хочу, чтобы он оставался в верхней части экрана, частично скрываясь за системными панелями.
  2. Панель действий отображается за строкой состояния.Я хочу, чтобы он отображался под строкой состояния.

Что мне нужно изменить, чтобы получить желаемое поведение?(Я предполагаю, что изменения должны быть сделаны в функции ToggleFullscreen в Page1.xaml.cs или MainActivity.cs)

enter image description here

Мой код выглядит так:

App.xaml.cs

using System;
using Xamarin.Forms;
using Xamarin.Forms.Xaml;

namespace ActionBarTest
{
    public partial class App : Application
    {
        public App()
        {
            InitializeComponent();

            var np = new NavigationPage(new Page1());
            np.Title = "ActionBarTest";
            MainPage = np;
        }
    }
}

Page1.xaml

<?xml version="1.0" encoding="utf-8" ?>
<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
             xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
             xmlns:d="http://xamarin.com/schemas/2014/forms/design"
             xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
             mc:Ignorable="d"
             x:Class="ActionBarTest.Page1">
    <ContentPage.Content>
        <StackLayout>
            <Label Text="Welcome to Xamarin.Forms!"
                   VerticalOptions="Start" 
                   HorizontalOptions="CenterAndExpand" />
            <Label Text="Line one"
                   VerticalOptions="Start" 
                   HorizontalOptions="CenterAndExpand" />
            <Label Text="Line two"
                   VerticalOptions="Start" 
                   HorizontalOptions="CenterAndExpand" />
            <Label Text="Line three"
                   VerticalOptions="Start" 
                   HorizontalOptions="CenterAndExpand" />
            <Label Text="Line four"
                   VerticalOptions="Start" 
                   HorizontalOptions="CenterAndExpand" />
        </StackLayout>
    </ContentPage.Content>
</ContentPage>

Page1.xaml.cs

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;

using Xamarin.Forms;
using Xamarin.Forms.Xaml;

namespace ActionBarTest
{
    [XamlCompilation(XamlCompilationOptions.Compile)]
    public partial class Page1 : ContentPage
    {
        public Page1()
        {
            InitializeComponent();

            Task.Factory.StartNew(() => {
                while (true)
                {
                    Thread.Sleep(2000);
                    ToggleFullscreen(true);
                    Thread.Sleep(2000);
                    ToggleFullscreen(false);
                }
            });
        }
    }

    private void ToggleFullscreen(bool isFullscreen){
        Xamarin.Forms.Device.BeginInvokeOnMainThread(() => { NavigationPage.SetHasNavigationBar(this, !isFullscreen); });
    }
}

MainActivity.cs

using System;
using System.Threading;
using Android.App;
using Android.Content.PM;
using Android.Runtime;
using Android.Views;
using Android.Widget;
using Android.OS;

namespace ActionBarTest.Droid
{
    [Activity(Label = "ActionBarTest", Icon = "@mipmap/icon", Theme = "@style/MainTheme", MainLauncher = true, ConfigurationChanges = ConfigChanges.ScreenSize | ConfigChanges.Orientation)]
    public class MainActivity : global::Xamarin.Forms.Platform.Android.FormsAppCompatActivity
    {
        protected override void OnCreate(Bundle savedInstanceState)
        {
            TabLayoutResource = Resource.Layout.Tabbar;
            ToolbarResource = Resource.Layout.Toolbar;

            base.OnCreate(savedInstanceState);

            Xamarin.Essentials.Platform.Init(this, savedInstanceState);
            global::Xamarin.Forms.Forms.Init(this, savedInstanceState);
            LoadApplication(new App());

            System.Threading.Tasks.Task.Factory.StartNew(() => {
                while (true)
                {
                    Thread.Sleep(2000);
                    ToggleFullscreen(true);
                    Thread.Sleep(2000);
                    ToggleFullscreen(false);
                }
            });
        }

        private void ToggleFullscreen(bool isFullscreen)
        {
            RunOnUiThread(() =>
            {
                if (isFullscreen)
                {
                    Window.DecorView.SystemUiVisibility = (StatusBarVisibility)(
                        SystemUiFlags.Fullscreen
                        | SystemUiFlags.HideNavigation
                        | SystemUiFlags.Immersive
                        | SystemUiFlags.ImmersiveSticky
                        | SystemUiFlags.LowProfile
                        | SystemUiFlags.LayoutStable
                        | SystemUiFlags.LayoutHideNavigation
                        | SystemUiFlags.LayoutFullscreen
                    );
                }
                else
                {
                    Window.DecorView.SystemUiVisibility = (StatusBarVisibility)(
                        SystemUiFlags.LayoutStable
                        | SystemUiFlags.LayoutHideNavigation
                        | SystemUiFlags.LayoutFullscreen
                    );
                }
            });
        }

        public override void OnRequestPermissionsResult(int requestCode, string[] permissions, [GeneratedEnum] Android.Content.PM.Permission[] grantResults)
        {
            Xamarin.Essentials.Platform.OnRequestPermissionsResult(requestCode, permissions, grantResults);

            base.OnRequestPermissionsResult(requestCode, permissions, grantResults);
        }
    }
}

1 Ответ

0 голосов
/ 14 июня 2019

Вы можете добавить Y offset из stackLayout, когда isFullScreen = false. Например, присвойте имя stackLayout в Xaml и в коде:

private void ToggleFullscreen(bool isFullscreen)
{
    Xamarin.Forms.Device.BeginInvokeOnMainThread(() => {

        if (isFullscreen)
        {
            myStackLayout.TranslationY = 0;
        }
        else
        {
            myStackLayout.TranslationY = -64;
        }

        NavigationPage.SetHasNavigationBar(this, !isFullscreen);

    });
}

И в вашей MainActivity удалите SystemUiFlags.LayoutHideNavigation ,SystemUiFlags.LayoutFullscreen, когда isFullScreen = false:

private void ToggleFullscreen(bool isFullscreen)
{
    RunOnUiThread(() =>
    {
        if (isFullscreen)
        {
            Window.DecorView.SystemUiVisibility = (StatusBarVisibility)(
                SystemUiFlags.Fullscreen
                | SystemUiFlags.HideNavigation
                | SystemUiFlags.Immersive
                | SystemUiFlags.ImmersiveSticky
                | SystemUiFlags.LowProfile
                | SystemUiFlags.LayoutStable
                | SystemUiFlags.LayoutHideNavigation
                | SystemUiFlags.LayoutFullscreen
            );
        }
        else
        {
            Window.DecorView.SystemUiVisibility = (StatusBarVisibility)(
                SystemUiFlags.LayoutStable
            );
        }
    });
}

Я загрузил образец, и вы можете проверить: toggle-model-xamarin.forms

на моем телефоне смещение должно быть -74 - есть ли надежный способ определить его с телефона на телефон?

Вы можете получить смещение, получив высоту status bar и action bar: используйте службу зависимостей , чтобы сначала получить высоту, а затем установите смещение, вы можете посмотреть на эту тему о Android-статус-бар-высота-в-Xamarin-андроида .

Дизайн все еще мигает, пока он перемещается - нет ли способа избежать репозиции вообще?

Понятия не имею о вспышках, кажется, показывает вид по очереди.

Я не упоминал, что у представления есть элементы, которые должны остаться в нижней части экрана, и при использовании TranslateY это двигался также вверх

В этой ситуации вы можете установить смещение только для вида, который вы хотите изменить, а не для всего вида.

...