When working with view markup in NativeScript, you interact with a set of pre-registered elements, such as GridLayout
, Button
, and Label
. These are commonly referred to as "view components."
You can also create custom native elements or extend existing ones to add specialized functionality to your application.
This guide demonstrates how to:
import { View } from '@nativescript/core'
export class Checkbox extends View {
// implementation details
}
Registering New Elements
You could use Checkbox
within XML markup by providing any namespace prefix and the path to it.
<Page xmlns="http://schemas.nativescript.org/tns.xsd"
xmlns:custom="./checkbox">
<StackLayout>
<custom:Checkbox width="200" height="200" />
</StackLayout>
</Page>
The registration can occur anywhere the view is needed or commonly in app.component.ts
, the root bootstrap component, making it available for use anywhere in your application.
import { registerElement } from '@nativescript/angular'
import { Checkbox } from './checkbox'
registerElement('Checkbox', () => Checkbox)
You can now use it like anything else:
html<StackLayout>
<Checkbox width="200" height="200" />
</StackLayout>
The registration can be done in the bootsrap file, commonly app.ts
. With Svelte, we use camelCase on elements where applicable.
import { registerNativeViewElement } from '@nativescript-community/svelte-native/dom'
import { Checkbox } from './checkbox'
registerNativeViewElement('checkbox', () => Checkbox)
You can now use it like anything else:
html<stackLayout>
<checkbox width="200" height="200" />
</stackLayout>
The registration can be done in the bootsrap file, commonly app.ts
. With React, we use camelCase on elements where applicable.
import { registerElement } from 'react-nativescript'
import { Checkbox } from './checkbox'
registerElement('checkbox', () => Checkbox)
You can now use it like anything else:
html<stackLayout>
<checkbox width="200" height="200" />
</stackLayout>
The registration can be done in the bootsrap file, commonly app.tsx
.
import { registerElement } from 'dominative'
import { Checkbox } from './checkbox'
registerElement('checkbox', Checkbox)
You can now use it like anything else:
html<stacklayout>
<checkbox width="200" height="200" />
</stacklayout>
The registration can be done in the bootsrap file, commonly app.ts
.
import { registerElement } from 'nativescript-vue'
import { Checkbox } from './checkbox'
registerElement('Checkbox', () => Checkbox)
You can now use it like anything else:
html<StackLayout>
<Checkbox width="200" height="200" />
</StackLayout>
Creating Custom View Components
The process for creating new NativeScript view components is consistent across Angular, React, Solid, Svelte, TypeScript, and Vue.
Anatomy of a Custom View Every custom NativeScript view must have:
createNativeView
: Construct and return a platform-native view. Note: It's only required if you want to override what's being returned from the extended class.initNativeView
: Perform initialization after creation.disposeNativeView
: Cleanup resources when removed.Example:
tsimport { View } from '@nativescript/core'
export class CustomView extends View {
createNativeView() {
// return UIView or android.view.View instance
}
initNativeView() {
// initialization code
}
disposeNativeView() {
// cleanup code
}
}
Extending Existing Views
You can extend any existing NativeScript view, for example:
tsimport { ContentView, Label, Button } from '@nativescript/core'
export class CustomView1 extends ContentView {}
export class CustomView2 extends Label {}
export class CustomView3 extends Button {}
createNativeView
Examples
This method must return an instance of the native view:
ts// iOS
createNativeView() {
return new WKWebView({ frame: CGRectZero, configuration });
}
// Android
createNativeView() {
return new android.webkit.WebView(this._context);
}
Initialization and Cleanup
initNativeView
: Perform setup after the view has been created.disposeNativeView
: Free resources as needed.Explore more examples within NativeScript core and plugins:
For additional details on advanced topics like using Cocoapods or Gradle, refer to this blog series.
Project Structure for Custom Views Create a dedicated folder for your component, such as:
bash./checkbox
common.ts
index.android.ts
index.ios.ts
index.d.ts
This structure encapsulates platform-specific implementations and shared logic, simplifying imports and registration:
tsimport { Checkbox } from './checkbox'
Real-World Example: Custom Checkbox
Let's create a <Checkbox>
component that behaves consistently on iOS and Android like this:
See the full working example on StackBlitz:
In NativeScript, creating custom UI components can be straightforward and powerful. In this guide, you'll learn how to build a simple, reusable Checkbox component using only built-in modules from @nativescript/core
. We'll leverage a combination of GridLayout
, Label
, and Material Design icons.
GridLayout
The base structure of our Checkbox will utilize GridLayout
, which serves as a container for the checkbox icon:
import { GridLayout } from '@nativescript/core'
export class CheckboxCommon extends GridLayout {}
2. Initialize Checkbox with a Font Icon
Next, we'll add a Label to serve as our checkbox icon, using Material Design icons for the visual representation.
typescriptimport { GridLayout, Label, Color } from '@nativescript/core'
export class CheckboxCommon extends GridLayout {
checked = false
defaultColor = new Color('#dddddd')
selectionColor = new Color('#4CAF50')
private _iconLabel: Label
private _circleIcon = String.fromCharCode(0xf764)
private _checkmarkIcon = String.fromCharCode(0xf5e0)
constructor() {
super()
this.horizontalAlignment = 'center'
this.verticalAlignment = 'middle'
this._iconLabel = new Label()
this._iconLabel.text = this._circleIcon
this._iconLabel.className = 'mat'
this._iconLabel.color = this.defaultColor
this._iconLabel.horizontalAlignment = 'center'
this._iconLabel.verticalAlignment = 'middle'
this.addChild(this._iconLabel)
}
}
Include Material Design Icons in your project by adding this CSS class in your app.css
:
.mat {
font-family: 'Material Design Icons', 'MaterialDesignIcons';
font-weight: 400;
}
Ensure you've added the MaterialDesignIcons font file to your app's fonts
directory.
To enhance user interaction, add a simple scaling animation when toggling the checkbox state:
typescriptimport { CoreTypes } from '@nativescript/core'
export class CheckboxCommon extends GridLayout {
// existing properties and constructor...
private _animateCheckmark() {
if (!this.checked) {
this._iconLabel.color = this.defaultColor
}
this._iconLabel
.animate({
scale: { x: 0.5, y: 0.5 },
duration: 200,
curve: CoreTypes.AnimationCurve.easeInOut,
})
.then(() => {
this._iconLabel.text = this.checked
? this._checkmarkIcon
: this._circleIcon
if (this.checked) {
this._iconLabel.color = this.selectionColor
}
this._iconLabel.animate({
scale: { x: 1, y: 1 },
duration: 200,
curve: CoreTypes.AnimationCurve.easeInOut,
})
})
}
}
4. Defining Customizable Properties
NativeScript's Property
system allows you to easily expose customizable attributes:
const sizeProperty = new Property<CheckboxCommon, number>({
name: 'size',
defaultValue: 24,
affectsLayout: __APPLE__,
})
const checkedProperty = new Property<CheckboxCommon, boolean>({
name: 'checked',
defaultValue: false,
valueConverter: booleanConverter,
})
const defaultColorProperty = new Property<CheckboxCommon, Color>({
name: 'defaultColor',
equalityComparer: Color.equals,
valueConverter: (v) => new Color(v),
})
const selectionColorProperty = new Property<CheckboxCommon, Color>({
name: 'selectionColor',
equalityComparer: Color.equals,
valueConverter: (v) => new Color(v),
})
These properties automatically handle conversions, such as strings to colors or booleans.
5. Connecting Properties to Native Views Link these properties to your checkbox component:
typescriptexport class CheckboxCommon extends GridLayout {
// existing implementation...
[sizeProperty.setNative](value: number) {
this._iconLabel.fontSize = value
}
[checkedProperty.setNative](value: boolean) {
this.checked = value
if (this.isLoaded) {
this._animateCheckmark()
}
}
[defaultColorProperty.setNative](value: Color) {
this.defaultColor = value
if (this._iconLabel) {
this._iconLabel.color = this.defaultColor
}
}
[selectionColorProperty.setNative](value: Color) {
this.selectionColor = value
}
}
// Register properties
sizeProperty.register(CheckboxCommon)
checkedProperty.register(CheckboxCommon)
defaultColorProperty.register(CheckboxCommon)
selectionColorProperty.register(CheckboxCommon)
Complete Example and Testing
Explore and interact with the complete example directly in the flavor you love:
Creating custom components in NativeScript allows you to:
Whether creating fully native views or hybrid custom components, NativeScript provides flexibility and efficiency to meet your application's needs.
Customize Existing Elements? Rather than create new elements from scratch, you may want to just adjust existing view elements. Learn about how to extend any element for custom behavior here.
RetroSearch is an open source project built by @garambo | Open a GitHub Issue
Search and Browse the WWW like it's 1997 | Search results from DuckDuckGo
HTML:
3.2
| Encoding:
UTF-8
| Version:
0.7.4