Reputation: 3073
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)
My code looks like this:
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);
}
}
}
Upvotes: 0
Views: 1278
Reputation: 15816
You can add a Y offset
of stackLayout
when isFullScreen = false
. For example, give a name to stackLayout
in Xaml
and in the code 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
:
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
on my phone, the offset had to be -74 -- is there a way of reliably determining it from phone to phone?
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.
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
Under this situation, you can only set the offset to the view you want to change instead of the whole view.
Upvotes: 0