Amil Osmanli
Amil Osmanli

Reputation: 135

Changing status bar color on Android devices with AngularJS

Some mobile websites change the color of the status bar and search bar in Android devices. For example when I open the BBC mobile website on my Android 5.0 device, top bar changes to red color.

Anybody have any idea how this can be achieved using AngularJS?

Upvotes: 2

Views: 2296

Answers (1)

nickgraef
nickgraef

Reputation: 2417

The HTML solution for this is a simple meta tag (with your customized color) added to the head section of your html template:

<meta name="theme-color" content="#0041C8">

Note that this will currently only have an effect for users running Chrome on Android 5.0+ with the "Merge tabs and apps" setting on.


If you want the color to be dynamic, you can bind it to a value in an Angular controller. When the value changes, the displayed color will change as well. There are several different ways to accomplish this (and this is a non-exhaustive list).

Option 1. head-scoped controller

In this method, we create a controller that is bound to the template's head. Because head doesn't have any UI components, we can't change the color value directly on the scope from user actions. (We can accomplish this indirectly by listening for events from other controllers or injecting a shared service.) However, this method is still useful for setting a calculated color on load. For example, we could change the color based on the time of day.

First, create a controller for the head:

.controller('HeadCtrl', function ($scope) {
    $scope.theme.color = calculateColor();

    function calculateColor() {
        var hour = (new Date()).getHours();
        var lightness = Math.sin(hour / 24 * Math.PI) * 100;
        return 'hsl(200, 25%, ' + lightness + '%)';
    }
})

Then add the binding to your template:

<head ng-controller="HeadCtrl">
    <meta name="theme-color" content="{{ theme.color }}">
</head>

Option 2. head-scoped controller with service

As mentioned above, there are ways of binding user actions from other controllers to the color value on our HeadCtrl. This method uses a service to make the color configurable by other controllers.

First, create the service with the initial color value:

.service('theme', function () {
    this.color = '#0041C8';
})

Then create a controller for the head, inject the theme service, and add it to the scope:

.controller('HeadCtrl', function ($scope, theme) {
    $scope.theme = theme;
})

The template binding is the same as in Option 1:

<head ng-controller="HeadCtrl">
    <meta name="theme-color" content="{{ theme.color }}">
</head>

You can now inject the service into other controllers. Any changes to theme.color in these controllers will be reflected in the meta tag.

Option 3. html-scoped controller

This method uses the prototypical inheritance of nested controllers to make the theme color available for other controllers to change.

First, create the controller with the initial color value:

.controller('MainCtrl', function ($scope) {
    $scope.theme = {
        color: '#0041C8'
    };
})

Notice that theme is an object rather than a single themeColor string value. This is important for controller inheritance.

Then add the binding to your template:

<html ng-app="myApp" ng-controller="MainCtrl">
    <head>
        <meta name="theme-color" content="{{ theme.color }}">
    </head>

Your other controllers will now inherit theme on their $scope, so you can change $scope.theme.color in the controller or theme.color in the template. For example, this creates a button that changes the color to red when clicked:

<div ng-controller="SomeOtherCtrl">
    <!-- ... -->
    <button ng-click="theme.color = '#FF0000'">Red</button>
</div>

This answer ended up being more of a lesson in sharing data between controllers, but it illustrates that you can bind color data to the content attribute and the client will update the displayed color.

Source: HTML5 Rocks

Upvotes: 7

Related Questions