Build a custom NativeScript view component for Android

Building a custom NativeScript XML view component for Android is uniquely different than it’s iOS counterpart because of the Android Context which must be considered. Let’s look at how to properly build a custom view component based on an underlying native view widget. We will also look at what happens when our include.gradle file is not setup properly including handling problems with minimum sdk targets with plugins. Specifically, we will implement this Android widget representing the Google I/O 2016 clock. Learn how to create a custom AndroidManifest.xml inside your plugin to merge with your app's manifest to override certain characteristics. Read detailed documentation about the Android app manifest file.

You must be a Member to view code

00:00 Let's set up this Google Clock, which is an imitation from Google I/O 2016. This library uses Maven, so let's make sure we grab this section. We have our NativeScript clock, internal plug-in folder, and inside platforms, and Android, and we have our Include Gradle file, and make sure we remove these three dots.

00:19 Let's grab our dependencies here and add this line for our library. Let's create a clock.android typescript file and let's export a class called clock. We want to make sure that we extend the view class from UI core view, and now we're ready to set things up.

00:36 One of the first things we want to do is actually grab a reference to this Google Clock class.

00:41 We can use this package path to the class and just reference that here. A satisfied TSC will just declare var inaudible . We want to add a reference to this Android class.

00:53 Our two important getters here. One will be to Android itself. This will just return our Android instance and the other getter to the special native view property used under the hood, which return our Android instance.

01:07 Lastly, instead of overriding the unloaded method from the view class, we're going to use the create UI method, which is called on Android only. This is because it waits for the context to become available for Android to create the view. All we want to do here is just construct an instance of Google Clock in passing in this.context, which comes from the view super class.

01:32 At this point, we're ready to try this out. Let's go to our app component. Before we can use this in the view, with NativeScript for Angular, there's a couple things we need to do to register that element. First, let's actually import from the NativeScript clock, the clock class.

01:47 We want to import register element from the NativeScript Angular plug-in. This gives us the ability to register the element by name. In this case, we will just call it clock and this takes a resolver function, which we'll just hand back the class. In this case, it's our view class called clock. Now, I can just use it like any other component.

02:07 Before we can run this, let's just check our plug-in script to build. Previously, we had built this for iOS. Let's just make sure that this build's for iOS and Android. Let's also double check our internal plug-ins package JSON and make sure that we have specified that Android is supported, and at least NativeScript 2.5 is used. Now we're ready to run this.

02:30 When you run this, you might get a hard crash. I'd like to show you what happens when you forget a particular section in your include.gradle file. We can see up here, it says, "What went wrong?"

02:41 It says, "A problem occurred evaluating the root of the project," and it complains about our Gradle file but it doesn't really give you any direct indication as to what happened.

02:51 This error, I can tell you, is indicative of our Gradle missing the product flavors section. If we go back to our include.gradle file, we need to make sure that we have an Android key, which specifies products flavors and then defines the value of the name of our plug-in here, NativeScript clock. That will specify this dimension key, which will equal, also, the name of the plug-in.

03:16 Since we made a change to our include.gradle, let's make sure we build everything clean. Let's ensure that we do remove the platforms folder and now, let's try to running that again. This time when we run, we get another error.

03:28 This mentions that the manifest merger failed and it mentions the minimum SDK version 17 cannot be smaller than version 21 declared in the library. It provides a suggestion. We can remedy this by actually grabbing this line right here and adding a custom Android manifest, that XML file here in our plug-ins, platform, Android folder.

03:51 We want to define one specific node to merge into our overall apps manifest file. To do so, we just need to define an XML namespace that represents tools, which points at this Android schema and then, we'll use the uses SDK node and this is where we can drop that line. We can see this uses the tools namespace defined here to override the library.

04:14 This ensures that the SDK that's targeted from our app that we're running overrides the SDK which may be defined coming from this library. Since we made changes to the actual internal plug-in setup, let's make sure we remove platforms and run this fresh. Now, we have this sweet Google I/O Clock.