Our website is made possible by displaying online advertisements to our visitors. Please consider supporting us by disabling your ad blocker.

Use The Android Palette Class With NativeScript

TwitterFacebookRedditLinkedInHacker News

I’m a big fan of Material Design, the ripple (ink) effect and the use of color are my favorites. According to the Material Design spec in regards to color:

Color in material design is inspired by bold hues juxtaposed with muted environments, deep shadows, and bright highlights. Material takes cues from contemporary architecture, road signs, pavement marking tape, and athletic courts. Color should be unexpected and vibrant.

The other day I wanted to change the action bar color to style with a user’s profile picture. Since there is no way to guess what color the picture is going to be, the Palette class and its methods to extract colors from the image were exactly what I needed.

The code to achieve this is pretty simple and doesn’t take much effort. So lets dive in.

NativeScript Palettes

Create a new NativeScript app using your command line, navigate into the newly created app, and then add the Android platform:

tns create PaletteApp
cd PaletteApp
tns platform add android

Now that we have our app we need to modify the build.gradle file to include the Palette library. This will give us access to the Palette classes needed.

compile "com.android.support:palette-v7:23.1.1"

Next open the main-page.xml and change it to the following:

<page xmlns="http://schemas.nativescript.org/tns.xsd" loaded="pageLoaded">
<page.actionBar>
    <ActionBar color="{{ vibrant.textColor }}" title="Palettize Me" backgroundColor="{{ vibrant.color }}" />
  </page.actionBar>
<scroll-view>
  <stack-layout>

   <grid-layout id="PicLayout" rows="*, auto, auto" columns="auto, *, auto" style="background-color: #e5e5e5; margin-bottom:20; height: 280">

        <image loaded="picLoaded" row="0" colSpan="3" rowSpan="2" src="~/images/deadpool.jpg" stretch="aspectFill" />

        <label row="1" colSpan="3" fontSize="50" text="Contrast Baby" textWrap="true" color="white" />

   </grid-layout>

    <label text="Vibrant" color="{{ vibrant.color }}"  />
    <label text="Dark Vibrant" color="{{ darkVibrant.color }}" />
    <label text="Light Vibrant" color="{{ lightVibrant.color }}" />

  </stack-layout>  
 </scroll-view>
</page>

The main element here is the <image> element, I’m using a local image in this example. So take an image you have, preferably something with some prominent colors on it to really see the end result. Once you have an image you’d like to use, copy it into the app/images folder. You can change the path but I like to have a specific folder containing images. Okay, now that you have an image and the UI markup complete. We need to look at the code to make the Android Palette class available and to use its methods.

Open your main-page.js file and change it to the following, do not get overwhelmed as we will break down exactly what’s happening.

var app = require("application");
var frame = require('ui/frame');
var Observable = require("data/observable");
var Color = require("color").Color;
var platformModule = require("platform");

var viewModel = new Observable.Observable({});


function pageLoaded(args) {
    var page = args.object;
    page.bindingContext = viewModel;
}
exports.pageLoaded = pageLoaded;

// **** The magic starts here ****
function picLoaded(args) {

    try {

        var img = args.object.android;
        var drawable = img.getDrawable();
        var bmp = drawable.getBitmap();

        // Create the Palette
        var Palette = new android.support.v7.graphics.Palette.from(bmp).generate();

        // *** Vibrant **** //
        var vibrantSwatch = Palette.getVibrantSwatch();
        var vibrantRgb = vibrantSwatch.getRgb();
        var vibrantBodyText = vibrantSwatch.getBodyTextColor();

        // *** Dark Vibrant *** //
        var darkVibrantSwatch = Palette.getDarkVibrantSwatch();
        var darkVibrantRgb = darkVibrantSwatch.getRgb();
        var darkVibrantBodyText = darkVibrantSwatch.getBodyTextColor();

        // *** Light Vibrant *** //
        var lightVibrantSwatch = Palette.getLightVibrantSwatch();
        var lightVibrantRgb = lightVibrantSwatch.getRgb();
        var lightVibrantBodyText = lightVibrantSwatch.getBodyTextColor();

        // Create our NativeScript colors and bindings for styling
        viewModel.set("vibrant", { color: new Color(vibrantRgb), textColor: vibrantBodyText });
        viewModel.set("darkVibrant", { color: new Color(darkVibrantRgb), textColor: darkVibrantBodyText });
        viewModel.set("lightVibrant", { color: new Color(lightVibrantRgb), textColor: lightVibrantBodyText });    

        // Change statusbar color on Lollipop
        if (platformModule.device.sdkVersion >= "21") {
            var window = app.android.foregroundActivity.getWindow();
            window.setStatusBarColor(new Color(darkVibrantRgb).android);
        }

    } catch (e) {
        console.log(e);
    }

}
exports.picLoaded = picLoaded;

View Your Work

At this point you are set to run the app and everything should work fine, assuming you have an image in the correct path, the Palette library added to your gradle file and the code changes.

Now lets break down what we are doing. First thing we are making sure to require the modules needed in our NativeScript app. I’m not going to explain the specifics of each module, if you’d like to read more about them, the NativeScript docs provide all the info you need and some very useful examples.

var app = require("application");
var frame = require('ui/frame');
var Observable = require("data/observable");
var Color = require("color").Color;
var platformModule = require("platform");

Once we have our modules the next block is our pageLoaded() function. In this function, we are setting our viewModel (Observable) to the page.bindingContext.

// Our model for databinding to the UI
var viewModel = new Observable.Observable({});

function pageLoaded(args) {
    var page = args.object;
    page.bindingContext = viewModel;
}
exports.pageLoaded = pageLoaded;

Next the native Android Palette code is in the picLoaded() function. This function is attached to our UI on the <image> element we are using on the loaded event that NativeScript provides. So once the image is loaded our function will execute.

The first 4 lines are very important. To generate an instance of the Palette we need a bitmap so we take the native Android approach to get our bitmap from the image and then create our Palette.

var img = args.object.android;
var drawable = img.getDrawable();
var bmp = drawable.getBitmap();

// Create the Palette
var Palette = new android.support.v7.graphics.Palette.from(bmp).generate();

With our Palette generated we just need to get the colors returned and use them where we want in our UI. This code is executing getVibrantSwatch() and then with the returned Swatch we call getRgb() and getBodyTextColor(). These methods will return colors to use in our UI that were extracted from the image. Once we have the two colors, we just set them to a view model property “vibrant” as an object. This way in our markup we can easily call {{ vibrant.color }}.

// *** Vibrant **** //
var vibrantSwatch = Palette.getVibrantSwatch();
var vibrantRgb = vibrantSwatch.getRgb();
var vibrantBodyText = vibrantSwatch.getBodyTextColor();
viewModel.set("vibrant", { color: new Color(vibrantRgb), textColor: vibrantBodyText });

Conclusion

That’s all there is to using the Palette in your NativeScript Android app. This guide should provide a good starting point to using the Android Palette in your app. If you have any questions or comments then let me know. One last note, thanks to Nic Raboy for allowing me to write a guest post on his blog. I have tremendous respect for Nic and if it isn’t evident, he has been influential in my venture into blogging about software.

Brad Martin

Brad Martin

I'm a husband, father and full stack software developer. You can find out more about me on my personal blog @ http://bradmartin.net