4

This question seems to be asked quite often, but looking through the various answers (non Xamarin) non of them work with Xamarin...

In my activity I have tried various forms of doing:

public override void OnWindowFocusChanged( bool hasFocus ) {
  base.OnWindowFocusChanged( hasFocus );

  if ( hasFocus ) {
    var uiOptions =
      SystemUiFlags.HideNavigation |
      SystemUiFlags.LayoutHideNavigation |
      SystemUiFlags.LayoutFullscreen |
      SystemUiFlags.Fullscreen |
      SystemUiFlags.LayoutStable |
      SystemUiFlags.ImmersiveSticky;

    Window.DecorView.SystemUiVisibility = (StatusBarVisibility) uiOptions;
  }
}

I have also tried this in the activity OnCreate(). Nothing seems to work.

I have read: https://developer.android.com/training/system-ui/immersive.html https://cmsdk.com/android/hide-navigation-bar-android-xamarin.html http://codegur.com/28394281/in-xamarin-android-how-can-i-hide-the-navigation-bar

Activity.cs:

using Android.App;
using Android.Graphics;
using Android.OS;
using Android.Support.V4.Content;
using Android.Views;
using Android.Widget;
using Calligraphy;
using Dictionary.Fragments;
using Dictionary.Logic.Translation;
using Newtonsoft.Json;

namespace Dictionary.Activities {

  [Activity( MainLauncher = true )]
  public class MainActivity: Activity {

    protected override void OnCreate( Bundle bundle ) {
      base.OnCreate( bundle );
      SetContentView( Resource.Layout.Main );
      SetToolbar();
      SetStatusBarColor();
      ShowSearchFragment();
    }

    public override void OnWindowFocusChanged( bool hasFocus ) {
      base.OnWindowFocusChanged( hasFocus );

      if ( hasFocus ) {
        var uiOptions =
          SystemUiFlags.HideNavigation |
          SystemUiFlags.LayoutHideNavigation |
          SystemUiFlags.LayoutFullscreen |
          SystemUiFlags.Fullscreen |
          SystemUiFlags.LayoutStable |
          SystemUiFlags.ImmersiveSticky;

        Window.DecorView.SystemUiVisibility = (StatusBarVisibility) uiOptions;
      }
    }

    public override bool OnCreateOptionsMenu( IMenu menu ) {
      MenuInflater.Inflate( Resource.Menu.Toolbar, menu );
      return base.OnCreateOptionsMenu( menu );
    }

    protected override void AttachBaseContext( Android.Content.Context @base ) {
      base.AttachBaseContext( CalligraphyContextWrapper.Wrap( @base ) );
    }

    private void SetStatusBarColor() {
      Window.AddFlags( WindowManagerFlags.DrawsSystemBarBackgrounds );
      Window.SetStatusBarColor( new Color( ContextCompat.GetColor( this, Resource.Color.PrimaryColorDark ) ) );
    }

    private void SetToolbar() {
      var toolbar = FindViewById<Toolbar>( Resource.Id.toolbar );
      SetActionBar( toolbar );
      ActionBar.Title = GetString( Resource.String.AppName );
    }

    private void ShowSearchFragment() {
      var searchFragment = new SearchFragment();
      searchFragment.TranslationSelected += OnTranslationSelected;
      var fragTrans = FragmentManager.BeginTransaction();
      fragTrans.Add( Resource.Id.fragHolder, searchFragment );
      fragTrans.Commit();
    }
  }
}

Issue found:

This edit box in my Search Fragment is causing the keyboard to show, breaking the fullscreen mode, even when the keyboard is gone, full screen does not return.

<EditText android:id="@+id/txtSearch"
                    android:layout_width="match_parent"
                    android:layout_height="48dp"
                    android:background="#FFF"
                    android:gravity="center"
                    android:hint="@string/SearchHint"
                    android:imeOptions="flagNoExtractUi|actionDone"
                    android:inputType="textNoSuggestions"
                    android:singleLine="true"
                    android:textColorHint="#ABABAB"
                    android:textSize="18sp"
                    fontPath="Fonts/amiri-regular.ttf"
                    android:textCursorDrawable="@drawable/cursor"/>
sprocket12
  • 5,368
  • 18
  • 64
  • 133
  • Very strange that I can't reproduce your issue, your code works fine by my side. Can you please provide your xamarin version? On what device have you tested your code? I ran it on Android emulator and it works perfect. – Grace Feng Mar 20 '17 at 03:27
  • @GraceFeng-MSFT I am testing on a LG G3 running Marshmallow, and also on the emulator running Marshmallow, both product the same result, I would be interested in seeing your layouts, styles and activity as I feel its something subtle I am doing is messing it up. Perhaps I should not be showing the keyboard, or applying a custom theme... – sprocket12 Mar 20 '17 at 06:51
  • I also tested on Android 6.0 emulator, here is my [screenshot](https://i.stack.imgur.com/Yc1Zf.png), have you tried your code with a blank android app? – Grace Feng Mar 20 '17 at 06:59
  • @GraceFeng-MSFT You were right, I found the cause to be a EditText in my SearchFragment, which takes the focus and brings up the keyboard, which makes this not work, even after the keyboard is gone. – sprocket12 Mar 20 '17 at 07:03
  • I was looking for hide the navigation bar in nexus 5X. Your question gave me a answer :). first piece of code but i called inside the onresume. – Suchith May 29 '19 at 06:32

3 Answers3

2

I propose a little improvement to @Grace Feng answer. If we add a constructor to the class of the listener

public class OnGlobalLayoutListener : Java.Lang.Object, IOnGlobalLayoutListener
{

    private int mScreenheight;

    private View mDecorView;

    public OnGlobalLayoutListener(int mioScreenheight, View mioDecorView)
    {
        mScreenheight = mioScreenheight;
        mDecorView = mioDecorView;
    }

    public void OnGlobalLayout()
    {
        Rect r = new Rect();

        var keypadHeight = mScreenheight - r.Bottom;
        if (keypadHeight <= mScreenheight * 0.15)
        {
            var uiOptions =
                SystemUiFlags.HideNavigation |
                SystemUiFlags.LayoutFullscreen |
                SystemUiFlags.Fullscreen |
                SystemUiFlags.ImmersiveSticky;

            mDecorView.SystemUiVisibility = (StatusBarVisibility)uiOptions;
        }

    }
}

we can use it in any activity:

        RelativeLayout vista = FindViewById<RelativeLayout>(Resource.Id.main);

        int altezza_schermo = vista.Height;

        View decorView = Window.DecorView;

        vista.ViewTreeObserver.AddOnGlobalLayoutListener(new OnGlobalLayoutListener(altezza_schermo, decorView));
Francesco
  • 2,042
  • 2
  • 19
  • 29
1

I found the cause to be a EditText in my SearchFragment, which takes the focus and brings up the keyboard, which makes this not work, even after the keyboard is gone.

I think a workaround for this issue is to detect whether the keyboard is open or not, and if the keyboard is closed, set the view to full screen again.

You can create a listener to detect if the keyboard is closed. For example:

protected override void OnCreate(Bundle bundle)
{
    base.OnCreate(bundle);

    // Set our view from the "main" layout resource
    SetContentView(Resource.Layout.Main);

    decorview = Window.DecorView;
    LinearLayout root = FindViewById<LinearLayout>(Resource.Id.rootView);
    screenheight = root.Height;
    root.ViewTreeObserver.AddOnGlobalLayoutListener(new mOnGlobalLayoutListener());
}

public static int screenheight;
public static View decorview;

And the mOnGlobalLayoutListener can be something like this:

public class mOnGlobalLayoutListener : Java.Lang.Object, IOnGlobalLayoutListener
{
    public void OnGlobalLayout()
    {
        Rect r = new Rect();
        var keypadHeight = MainActivity.screenheight - r.Bottom;
        if (keypadHeight <= MainActivity.screenheight * 0.15)
        {
            var uiOptions =
                SystemUiFlags.HideNavigation |
                SystemUiFlags.LayoutHideNavigation |
                SystemUiFlags.LayoutFullscreen |
                SystemUiFlags.Fullscreen |
                SystemUiFlags.LayoutStable |
                SystemUiFlags.ImmersiveSticky;

            MainActivity.decorview.SystemUiVisibility = (StatusBarVisibility)uiOptions;
        }
    }
}

Tested and it works fine when the keyboard is closed.

Grace Feng
  • 16,564
  • 2
  • 22
  • 45
0

The whole thing in Oncreate can be replaced with:

decorview = Window.DecorView;
decorview.ViewTreeObserver.AddOnGlobalLayoutListener(new mOnGlobalLayoutListener());

Most of the stuff in unknown with this release of Xamarin forms