NativeScript 预览通过在世界上最流行的编程语言 JavaScript 中提供平台 API,实现了加速原生移动开发的概念。这让你如虎添翼。能够绕过本地开发限制,直接尝试原生 API 并获得即时反馈,这彻底改变了游戏规则!
为了说明这种新的工作流程,我们将提供一个“Hello World”类型的示例,只需几行代码即可切换手机的手电筒开关。
要快速了解 NativeScript 预览的工作原理,你可以在我们的主页上阅读相关内容:此链接。
简而言之,你需要下载设备上的 NativeScript 预览应用,然后扫描 StackBlitz 项目中的二维码,将应用程序推送到你的手机。然后,当你编辑应用程序时,这些更改将实时推送到你的手机。非常酷!
我们想要演示的示例在下面的链接中,让我们开始吧!
在你浏览应用程序时,有一些值得注意的细节需要说明。我们想要指出 NativeScript 特定的部分,以便你了解编写移动应用程序需要多少(或少)代码。
为了赋予我们的 Angular 应用程序原生功能,我们首先需要将 NativeScriptModule
连接到我们的主模块。
我们通过从 '@nativescript/angular'
导入 NativeScriptModule
,然后将其添加到 NgModule
配置对象中的导入中来实现这一点。
import { NgModule, NO_ERRORS_SCHEMA } from '@angular/core'
import { NativeScriptModule } from '@nativescript/angular'
import { AppRoutingModule } from './app-routing.module'
import { AppComponent } from './app.component'
import { TorchComponent } from './torch.component'
@NgModule({
bootstrap: [AppComponent],
imports: [NativeScriptModule, AppRoutingModule],
declarations: [AppComponent, TorchComponent],
providers: [],
schemas: [NO_ERRORS_SCHEMA],
})
export class AppModule {}
我们大胆地假设每个非平凡的应用程序都将拥有多个路由,因此我们也将更新我们的路由模块。这将遵循声明路由的标准约定,唯一的区别是我们正在导入并在 NgModule
配置对象中初始化 NativeScriptRouterModule
。
import { NgModule } from '@angular/core'
import { Routes } from '@angular/router'
import { NativeScriptRouterModule } from '@nativescript/angular'
import { TorchComponent } from './torch.component'
const routes: Routes = [
{ path: '', redirectTo: '/torch', pathMatch: 'full' },
{ path: 'torch', component: TorchComponent },
]
@NgModule({
imports: [NativeScriptRouterModule.forRoot(routes)],
exports: [NativeScriptRouterModule],
})
export class AppRoutingModule {}
TorchComponent
完全是 Angular 的构造,当你考虑到你获得的回报时,这真是令人难以置信。在下面的代码片段中,我们有一个基本的按钮,它响应 tap
事件并调用 toggle
。
<GridLayout>
<Button
text="Toggle Torch"
class="btn-primary"
width="300"
(tap)="toggle()"
></Button>
</GridLayout>
在组件类中,我们调用 toggleDeviceTorch
并传入本地 enabled state
。那么手电筒是如何激活的呢?这就是事情变得更有趣的地方。
import { Component } from '@angular/core';
import { toggleDeviceTorch } from './torch';
@Component({
selector: 'ns-torch',
templateUrl: './torch.component.html',
})
export class TorchComponent {
enabled = false;
toggle() {
this.enabled = !this.enabled;
toggleDeviceTorch(this.enabled);
}
}
请注意,我们正在从 ./torch
导入 toggleDeviceTorch
,这将是我们旅程中的下一站。
在 ./torch
目录中,我们有三个文件。首先,我们有一个 index.d.ts
,它基本上是一个类型定义文件。然后,我们有 index.android.ts
和 index.ios.ts
,这对于 NativeScript 的新手开发者来说可能是一个“啊哈”时刻。不可避免的问题出现了,iOS 和 Android 之间的逻辑在哪里切换?好问题,答案是 NativeScript 在幕后为你处理了这一切。它将生成特定于平台的包并自动修剪针对其他平台的代码。
export declare function toggleDeviceTorch(enable: boolean);
我们不会深入探讨特定于平台的 API 细节,但让我们快速浏览一下 toggleDeviceTorch
的 iOS 和 Android 版本。
请注意,每个平台的实现都遵循 TypeScript 定义,这使得能够在平台之间无缝切换。也就是说,我们正在实例化一个 AVCaptureDevice
实例并将该引用存储为 device
。从这里,我们可以检查设备是否具有手电筒,以防万一我们在模拟器上运行。如果是,我们将解锁设备以进行配置,并根据 enable
参数,打开或关闭手电筒。只需几行代码就能做到这一点,真是不错!
export function toggleDeviceTorch(enable: boolean) {
const device = AVCaptureDevice.defaultDeviceWithMediaType(AVMediaTypeVideo);
if (device?.hasTorch) {
device.lockForConfiguration();
if (enable) {
device.setTorchModeOnWithLevelError(1.0);
} else {
device.torchMode = AVCaptureTorchMode.Off;
}
device.unlockForConfiguration();
}
}
我们鼓励每个人查看平台文档并将 NativeScript 与原生 API 进行比较。你可以在此处查看 iOS 文档:这里。
Android 版本更加简洁,但遵循类似的原理。我们获取对 Android 应用程序上下文 的引用,然后使用该上下文获取对相机服务的引用。从那里,我们获取对相机本身的引用,然后根据 enable
属性调用 setTorchMode
打开或关闭。
import { Utils } from '@nativescript/core';
export function toggleDeviceTorch(enable: boolean) {
const appContext = Utils.android.getApplicationContext();
const cameraManager = appContext.getSystemService(
android.content.Context.CAMERA_SERVICE
);
const camera = cameraManager.getCameraIdList()[0];
cameraManager.setTorchMode(camera, enable);
}
你可以在此处查看 Android 文档:这里。
当开发者体验到从 StackBlitz 到设备的实时更新并意识到原生平台 API 触手可及的力量时,这是一个美好的时刻。目标是使丰富的平台开发感觉与你已经熟悉的任何 JavaScript 应用程序开发一样自然。
希望你喜欢这个手电筒演示。