[英]Toggleable fullscreen with stable layout using Xamarin.Forms/Xamarin.Droid
I'm making an app that must be able to toggle between two view modes: 我正在创建一个必须能够在两种视图模式之间切换的应用程序:
To test the behaviour of toggling between these two modes, I have created a simple test project that switches between these two modes every two seconds. 为了测试在这两种模式之间切换的行为,我创建了一个简单的测试项目,每两秒钟在这两种模式之间切换。
The fullscreen mode is working as intended, but there are two issues with the semi-fullscreen mode, as shown in the images below: 全屏模式按预期工作,但半全屏模式存在两个问题,如下图所示:
What do I need to change in order to get the behaviour I want? 为了获得我想要的行为,我需要改变什么? (I assume the changes must be made in the ToggleFullscreen function in Page1.xaml.cs or MainActivity.cs)
(我假设必须在Page1.xaml.cs或MainActivity.cs中的ToggleFullscreen函数中进行更改)
My code looks like this: 我的代码看起来像这样:
App.xaml.cs 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 的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 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 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);
}
}
}
You can add a Y offset
of stackLayout
when isFullScreen = false
. 当
isFullScreen = false
时,您可以添加stackLayout
的Y offset
。 For example, give a name to stackLayout
in Xaml
and in the code behiend: 例如,提供一个名称
stackLayout
在Xaml
,并在代码behiend:
private void ToggleFullscreen(bool isFullscreen)
{
Xamarin.Forms.Device.BeginInvokeOnMainThread(() => {
if (isFullscreen)
{
myStackLayout.TranslationY = 0;
}
else
{
myStackLayout.TranslationY = -64;
}
NavigationPage.SetHasNavigationBar(this, !isFullscreen);
});
}
And in your MainActivity, remove the SystemUiFlags.LayoutHideNavigation ,SystemUiFlags.LayoutFullscreen
when isFullScreen = false
: 在MainActivity中,当
isFullScreen = false
时,删除SystemUiFlags.LayoutHideNavigation ,SystemUiFlags.LayoutFullscreen
:
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
);
}
});
}
I have uploaded a sample and you can check: toggle-model-xamarin.forms 我上传了一个样本,您可以查看: toggle-model-xamarin.forms
on my phone, the offset had to be -74 -- is there a way of reliably determining it from phone to phone?
在我的手机上,偏移量必须是-74 - 有没有办法从手机到手机可靠地确定它?
You can get the offset by getting the height of status bar
and action bar
: use a dependency service to get the height first and then set the offset, you can look at this thread about android-status-bar-height-in-xamarin-android . 您可以通过获取
status bar
和action bar
的高度来获得偏移:使用依赖服务首先获取高度然后设置偏移量,您可以查看关于android-status-bar-height-in-xamarin-的此主题安卓 。
The design still flashes while it is repositioned -- is there no way of avoiding a reposition at all?
设计在重新定位时仍然闪烁 - 是否根本无法避免重新定位?
No idea about the flashes, it seems show the view one by one. 不知道闪光,似乎逐一显示视图。
I didn't mention that the view has elements that are supposed to stay at the bottom edge of the screen, and when using TranslateY, these are moved upwards as well
我没有提到视图中的元素应该保留在屏幕的下边缘,当使用TranslateY时,这些元素也会向上移动
Under this situation, you can only set the offset to the view you want to change instead of the whole view. 在这种情况下,您只能将偏移设置为要更改的视图而不是整个视图。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.