FullScreen and Navigation Bar Color in a NativeScript Android app

The Story…

I’ve seen a few comments on various channels about how to change the status bar, navigation bar, and full screen layouts on Android in a NativeScript app. In this post I want to cover a few scenarios and how to achieve the specific layout you want in your app. So lets get started.

I’m going to assume you are familiar with NativeScript, if you aren’t then check out the getting started guide for a quick intro. Let us start with a fresh app using the CLI, path into the new app, and add the android platform.

tns create screenApp
cd screenApp
tns platform add android

Now that we have our new app, open your IDE and let’s modify the main-page.js file.

Full Screen with Transparent Status Bar

You can copy the next snippet and run it to see the result. The important parts are requiring the application and platform modules to easily add some checks for android and sdk versions as needed. Then in the pageLoaded function we will make the code changes to achieve the end result. In short we are setting the status bar to transparent then adding some flags to the Android Window. The last important piece is adding some padding to the first view in your layout. I’m getting the status bar height and using that as the top padding here.

var app = require("application");
var platform = require("platform");
var color = require("color");

// Event handler for Page "loaded" event attached in main-page.xml
function pageLoaded(args) {
    // Get the event sender
    var page = args.object;
    page.bindingContext = data;

    var View = android.view.View;

    if (app.android && platform.device.sdkVersion >= '21') {
        var window = app.android.startActivity.getWindow();
        // set the status bar to Color.Transparent

        var decorView = window.getDecorView();
            // | View.SYSTEM_UI_FLAG_HIDE_NAVIGATION // hide nav bar
            // | View.SYSTEM_UI_FLAG_FULLSCREEN // hide status bar

    var statusHeight = getStatusBarHeight();
    // // Need to add some padding to whatever your first View(widget)
    // var actionbar = page.actionBar._toolbar;
    // // Set the padding to match the Status Bar height
    // actionbar.setPadding(0, statusHeight, 0, 0);

     var lab = page.getViewById('myLabel').android;
     lab.setPadding(0, statusHeight, 0, 0);

exports.pageLoaded = pageLoaded;

// A method to find height of the status bar
function getStatusBarHeight() {
    var result = 0;
    var resourceId = app.android.currentContext.getResources().getIdentifier('status_bar_height', 'dimen', 'android');
    if (resourceId) {
        result = app.android.currentContext.getResources().getDimensionPixelSize(resourceId);
    return result;

Resulting Layout


FullScreen “Immersive” Mode

To read about using the “Immersive” mode in Android read the docs here. The Fullscreen immersive mode will give you the full device screen for your layout and allow the user to swipe near the edges of the screen to bring the navigation bar and status bar back into view momentarily. There are some specifics to achieving this correctly, but the following code change will give you what you need. Just uncomment two lines from the .setSystemUiVisibility() method from above.

var decorView = window.getDecorView();
            | View.SYSTEM_UI_FLAG_HIDE_NAVIGATION // hide nav bar
            | View.SYSTEM_UI_FLAG_FULLSCREEN // hide status bar


Resulting Layout


At this point you could try various options with the different flags in the code to hide the navigation bar or just the status bar. So let’s move on to one final piece with the navigation bar and it’s a nice effect. COLOR.

Color the Navigation Bar

At the beginning of our pageLoaded function we have a call to the Android method .setStatusBarColor() to change the statusbar color. Well Android also has a nice method for the navigation bar –.setNavigationBarColor(), add the following line after your var window. *REMINDER* Do not forget to comment out the two flags we uncommented a moment ago (SYSTEM_UI_FLAG_FULLSCREEN and SYSTEM_UI_FLAG_HIDE_NAVIGATION). If you leave them enabled, you won’t have a status bar or navigation bar.

 window.setNavigationBarColor(new color.Color('#3489db').android);


Resulting Layout



In this tutorial we covered the basic code for manipulating the Android Window using various flags and methods to style the status bar and navigation bar. I plan on making a plugin for the navigation bar styling with an XML attribute to avoid users having to deal with the native code. If you haven’t check out Burke Holland’s plugin called nativescript-statusbar which allows you to set the color of the iOS and Android statusbar with a simple XML tag. The plugin is listed on NPM here: https://www.npmjs.com/package/nativescript-statusbar I hope you’ve enjoyed reading and if you have any questions feel free to leave in the comments. Follow me on Twitter @BradWayneMartin for more NativeScript tutorials and information.

30 thoughts on “FullScreen and Navigation Bar Color in a NativeScript Android app

  1. Thanks for putting this together Brad!

    I’ll drop in one other tip that helped me out. In my case I wanted this code to not be tied to any individual view, as my app can potentially start on two different pages (depending on whether the user has an existing login token), so I ended up putting this bit of code in my app.js before I call start().

    var application = require("application");
    application.android.onActivityStarted = function() {
        // The code described in this article


      1. I got an error doing this because i had the same problem. Probably I’m not doing it right. Can you please put me thru


    1. Without debugging I would guess there​ is an issue existing the native Android View class then. That’s odd. Have you searched the nativescript repo to see if it’s been reported?


    1. Hi, the immersive mode flag is a global change on Android for the current app when it’s added. So all you would do to only use one on page is to apply it and then remove it when you’re navigating away from that page. Nativescript has several page life cycle events that you can use. The navigatingFrom is probably a good start for your question. Hope that helps.


  2. Hi, i applied the immersive mode to one page. But when i tap on the screen, the status bar appears and then it doesn’t disappear. How can i fix it?


  3. On line 11 in your first block of code:

    var View = android.view.View;

    where are you importing that android reference from? I’ve tried importing it from platform and it doesnt have any fields called ‘view’.


    1. Pete, `android.view.View` is part of the android native API. So it’s not being imported, you just have direct access to it with NativeScript with its foundation on providing direct access to native APIs. I’m sure you figured this out by now, sorry for the late reply.


  4. my emulator says: “data is not defined, undefined” – did everything exactly as you wrote. anything i may have missed in the main-page.xml?


      1. Thanks for your fast reply. Emulator leaving me with “Cannot read property of ‘android’ of undefined, undefined”. Completely replaced the contents of the file main-page.js with your code.


      2. K. There are a few ways to approach this. You can install the tns platform declarations package to your app which will give you access to the typings and packages of Android/iOS. You also usually want to safeguard any calls to the native apis with a check of the platform. You can check the forums or some of my plugins have plenty of sample code for this. Ive been telling myself to get back into blogging but haven’t had time 🙂 thanks for reading. Also you can find some really helpful people if you’re getting started on the NS slack community.


  5. Hey Brad, thanks the tutorial! I’m running a Nativescript Angular app and calling your functions using page.on(loaded). I’ve been able to get the status bar to be transparent thanks to you, but I can’t get the code to calculate the height of the status bar to work; when I try determining the resourceId, app.android.currentContext is null. Do you have any idea as to why this is happening?


  6. Hi Brad,

    Thank you for this article !
    I tried several things but when i want to apply what you explain, i cannot access to “View.SYSTEM_UI_FLAG_IMMERSIVE_STICKY”, i think that the problem is with the “tns-platform-declarations\android17.d.ts” which does not contains this flag.

    I understand that the tns-platform-declarations that i have (fresh install) corresponds to API versions 17 and that this flag is new in the API version 19

    So, if you think my feeling is good, how to update this “tns-platform-declarations” ?

    Thank you in advance


  7. –> get window of undefined error. with your code……. its not working for me

    [Redmi]: An uncaught Exception occurred on “main” thread.
    Calling js method onCreateView failed

    TypeError: Cannot read property ‘getWindow’ of undefined
    File: “file:///data/data/org.nativescript.preview/files/app/views/home/products/products.js, line: 14, column: 47

    Frame: function:’exports.loaded’, file:’file:///data/data/org.nativescript.preview/files/app/views/home/products/products.js’, line: 14, column: 48
    Frame: function:’Observable.notify’, file:’file:///data/data/org.nativescript.preview/files/app/tns_modules/tns-core-modules/data/observable/observable.js’, line: 110, column: 23
    Frame: function:’Observable._emit’, file:’file:///data/data/org.nativescript.preview/files/app/tns_modules/tns-core-modules/data/observable/observable.js’, line: 127, column: 18
    Frame: function:’ViewBase.onLoaded’, file:’file:///data/data/org.nativescript.preview/files/app/tns_modules/tns-core-modules/ui/core/view-base/view-base.js’, line: 236, column: 14
    Frame: function:’View.onLoaded’, file:’file:///data/data/org.nativescript.preview/files/app/tns_modules/tns-core-modules/ui/core/view/view.js’, line: 208, column: 35
    Frame: function:’Page.onLoaded’, file:’file:///data/data/org.nativescript.preview/files/app/tns_modules/tns-core-modules/ui/page/page.js’, line: 43, column: 35
    Frame: function:”, file:’file:///data/data/org.nativescript.preview/files/app/tns_modules/tns-core-modules/ui/core/view-base/view-base.js’, line: 311, column: 90
    Frame: function:’ViewBase.callFunctionWithSuper’, file:’file:///data/data/org.nativescript.preview/files/app/tns_modules/tns-core-modules/ui/core/view-base/view-base.js’, line: 304, column: 9
    Frame: function:’ViewBase.callLoaded’, file:’file:///data/data/org.nativescript.preview/files/app/tns_modules/tns-core-modules/ui/core/view-base/view-base.js’, line: 311, column: 14
    Frame: function:’ViewBase.loadView’, file:’file:///data/data/org.nativescript.preview/files/app/tns_modules/tns-core-modules/ui/core/view-base/view-base.js’, line: 439, column: 18
    Frame: function:’ViewBase._addViewCore’, file:’file:///data/data/org.nativescript.preview/files/app/tns_modules/tns-core-modules/ui/core/view-base/view-base.js’, line: 434, column: 18
    Frame: function:’ViewBase._addView’, file:’file:///data/data/org.nativescript.preview/files/app/tns_modules/tns-core-modules/ui/core/view-base/view-base.js’, line: 420, column: 14
    Frame: function:’FragmentCallbacksImplementation.onCreateView’, file:’file:///data/data/org.nativescript.preview/files/app/tns_modules/tns-core-modules/ui/frame/frame.js’, line: 588, column: 24
    Frame: function:’FragmentClass.onCreateView’, file:’file:///data/data/org.nativescript.preview/files/app/tns_modules/tns-core-modules/ui/frame/fragment.js’, line: 27, column: 38

    at com.tns.Runtime.callJSMethodNative(Native Method)
    at com.tns.Runtime.dispatchCallJSMethodNative(Runtime.java:1101)
    at com.tns.Runtime.callJSMethodImpl(Runtime.java:983)
    at com.tns.Runtime.callJSMethod(Runtime.java:970)
    at com.tns.Runtime.callJSMethod(Runtime.java:954)
    at com.tns.Runtime.callJSMethod(Runtime.java:946)
    at com.tns.FragmentClass.onCreateView(FragmentClass.java:45)
    at android.app.Fragment.performCreateView(Fragment.java:2220)
    at android.app.FragmentManagerImpl.moveToState(FragmentManager.java:973)
    at android.app.FragmentManagerImpl.moveToState(FragmentManager.java:1148)
    at android.app.BackStackRecord.run(BackStackRecord.java:799)
    at android.app.FragmentManagerImpl.execPendingActions(FragmentManager.java:1537)
    at android.app.FragmentManagerImpl$1.run(FragmentManager.java:482)
    at android.os.Handler.handleCallback(Handler.java:742)
    at android.os.Handler.dispatchMessage(Handler.java:95)
    at android.os.Looper.loop(Looper.java:157)
    at android.app.ActivityThread.main(ActivityThread.java:5571)
    at java.lang.reflect.Method.invoke(Native Method)
    at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:745)
    at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:635)


  8. –> this was my js and xml

    var ProductViewModel = require(“../../../view-models/main-view-model/product-view-model”);
    var ProductViewModel = new ProductViewModel();
    var app = require(“application”);
    var platform = require(“platform”);
    var color = require(“color”);

    exports.loaded = function (args) {
    page = args.object;
    page.bindingContext = ProductViewModel;

    var View = android.view.View;
    if (app.android && platform.device.sdkVersion >= ’21’) {
    var window = app.android.startActivity.getWindow();
    // set the status bar to Color.Transparent

    var decorView = window.getDecorView();
    // | View.SYSTEM_UI_FLAG_HIDE_NAVIGATION // hide nav bar
    // | View.SYSTEM_UI_FLAG_FULLSCREEN // hide status bar


    exports.onNavBtnTap = function () {



  9. Hi Martin, i have set fullscreen mode in the first screen , and statusbarstyle mode light in the next screen. if i go back to the first screen statusbarstyle is still apllied even after i set fullscreen mode . can you please provide a solution to set fullscreen mode for only few screens


    1. You’ll need to handle this on a case by case basis. When setting these flags you’re doing so globally on the Android window screen, this isn’t something each page has but rather the entire application activity on Android. So you’d just reset the flags during navigation or on the loaded event of the page you’re going to. There is also a swiss-army-knife plugin for nativescript with many utility functions that will help simplify your code or at least help you implement the resetting and setting.


  10. Can you please add the same piece of code in Typescript or Angular?. The PageLoad event is not firing in my case.


  11. I have searched/tried for a while to find a way to change the text color of the status bar on android too.
    Just wanted to note that you can set the Android status bar text color since android lollipop?
    with View.SYSTEM_UI_FLAG_LIGHT_STATUS_BAR to grey (for light backgrounds).

    window.setStatusBarColor(new color.Color(“#ffffff”).android);


    shows greyish text on white background for the status bar on Android.


Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Google photo

You are commenting using your Google account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s