1. Базовые знания
1.1 Почему стоит выбрать NativeScript
1.1.1 Что такое NativeScript
NativeScript может использовать javascript для написания приложений для Android и iOS. Как показано на рисунке ниже, код NativeScript очень похож на код веб-разработки. Оба используют CSS для написания стилей и javascript для написания бизнес-логики. Разница в том, что NativeScript использует XML для описания структуры страницы (NativeScript оборачивает собственную библиотеку пользовательского интерфейса).
1.1.2 Сравнение режима мобильной разработки
Как показано на рисунке ниже, мобильные приложения можно разделить на четыре категории: нативные, гибридные, кросс-компилированные и JIT-компилированные.
1.1.3 Преимущества NativeScript
Меньше прокладочного кода (обрабатывает разницу между Android и iOS), однократная запись (используется один код для Android и iOS), развертывание в любом месте и т. д.
1.1.4 Какие приложения могут построить Nationscript
Поскольку приложения NativeScript запускаются непосредственно на устройстве и интерпретируются виртуальной машиной JavaScript, работающей внутри приложения, это означает, что приложения NativeScript не ограничены доступом к собственным API-интерфейсам или оборудованию устройства, поэтому любое приложение может быть написано как приложение NativeScript. Теоретически это так, но приложения NativeScript запускаются на виртуальной машине JavaScript, поэтому между приложением и «голым железом» существует дополнительный (хотя и небольшой) уровень абстракции. Извлекать из устройства все возможности производительности, поэтому оно не подходит для создания игр с интенсивным использованием графики.
1.1.5 Как работает NativeScript
-
NativeScript Runtime: NativeScript Runtime — это код интерфейса, который соединяет код JavaScript с собственными API-интерфейсами Android и iOS. Точно так же, как производители браузеров учат свои виртуальные машины JavaScript, как использовать объекты DOM и Windows, среда выполнения NativeScript обучает виртуальные машины JavaScript, как использовать базовый API собственного устройства. -
NativeScript Core Modules: Модули NativeScriptCore представляют собой набор библиотек, которые используются для создания приложений и указывают среде выполнения NativeScript, что делать на устройстве. Основной модуль состоит из различных библиотек, таких как компоненты пользовательского интерфейса (кнопки, списки, метки), навигация и приложения. -
JavaScript virtual machine: понимать и выполнять код JavaScript, но не знать, как взаимодействовать с устройством, поэтому команда разработчиков NativeScript написала код интерфейса (называемый NativeScript Runtime и NativeScript Core Modules), чтобы научить виртуальные машины JavaScript работать с API мобильных устройств, таких как Android. и iOS. -
NativeScript CLI: интерфейс командной строки NativeScript абстрагируется от сложности собственных инструментов и SDK, предоставляя нам набор независимых от платформы команд для создания и развертывания приложений.
1.2 Первое приложение NativeScript
- Ссылаться наДокументацияПолная настройка среды сборки
- существуетстраницаСкачайте Android Studio и следуйтеруководствоНастройте эмулятор Android
- Откройте инструмент командной строки и запустите
tns create HelloWorld --template tns-template-hello-world - войти в целевую папку
cd [filename] - Команда выполнения
tns run android --emulator, вы можете запустить код на эмуляторе Android
2. Создайте приложение
2.1 Анатомия приложения NativeScript
2.1.1 Изучение структуры приложения NATIVEScript
|- app //开发目录
|- App_Resources //放置Android和iOS平台特殊的配置,例如App的图标等。
|- Android
|- iOS
|- app.css //全局的CSS样式,app运行时载入
|- app.js //启动文件,里面说明了从哪个页面启动应用
|- bundle-config.js //用于配置webpack(如果已安装了)
|- main-page.js //写业务逻辑
|- main-page.xml //写页面代码
|- main-view-model.js //相当于MVVM框架的vm层
|- package.json //描述应用程序的特征和依赖项
|- references.d.ts //为编辑器提供TypeScript的智能提示
|- node_modules //依赖的库文件
|- platforms //由NativeScript自动生成和维护
|- package.json //描述应用程序的特征和依赖项
// package.json
{
"description": "NativeScript Application", //提供应用程序、功能和用途的简要说明
"license": "SEE LICENSE IN <your-license-filename>", //将协作开发人员指向您的许可文件,以描述其他人必须对您的应用程序代码作出贡献、修改、更改和重新分发哪些权限(可选)
"readme": "NativeScript Application", //指向应用程序的README文件
"repository": "<fill-your-repository-here>", //应用程序公共或私有代码存储库的位置(可选)
"nativescript": { //一个特定于nativescript的部分,带有应用程序的标识符,Android和iOS平台使用它惟一地标识应用程序
"id": "org.nativescript.myapp"
},
"dependencies": { //npm使用的外部库和应用程序所依赖的库版本的列表
"nativescript-theme-core": "~1.0.2",
"tns-core-modules": "3.1.0"
}
}
2.2 страницы и навигация
2.2.1 Создание многостраничного приложения
- Создайте проект HelloWorld, как и раньше.
- Войдите в папку приложения, удалите main-page.js, main-page.xml, main-view-model.js в папке, создайте папку представления в папке приложения, чтобы поместить страницы, и создайте отдельную папку для каждой страницы. , Папка должна называться так же, как и страница, а каталог файлов должен быть следующим:
|- app
|- views
|- home
|- home.css
|- home.xml
|- home.js
|- about
|- about.css
|- about.xml
|- about.js
- Измените файл запуска проекта app.js и измените стартовую страницу приложения на домашнюю страницу.
require("./bundle-config");
var application = require("application");
application.start({ moduleName: "views/home/home" }); //将moduleName的键值修改成home页面的路径
- Напишите следующий код в файле home.xml
<Page> //页面中所有其他元素的容器,类似于网页开发里面的body标签
<StackLayout> //布局元素,类似于网页开发里面的div标签
<Label text="Welcome to the Tekmo App!" /> //在屏幕上显示文本
</StackLayout>
</Page>
- Напишите следующий код в файле About.xml.
<Page>
<StackLayout>
<Label textWrap="true" text="Small company that wants to bring you the best in retro gaming!" /> //textWrap为true时会自动换行
<Label text="Come visit us in Louisville, KY" />
</StackLayout>
</Page>
2.2.2 Навигация между несколькими страницами
- Напишите следующий код в файле home.xml
<Page>
<StackLayout>
<Label text="Welcome to the Tekmo App!" />
<Button text="About" tap="onTap" /> //tap属性告诉NativeScript在单击按钮时调用onTap这个JavaScript函数
</StackLayout>
</Page>
- Напишите следующий код в файле home.js
var frameModule = require("ui/frame"); //获取NativeScript框架中导航模块的引用
function onTap() {
frameModule.topmost().navigate("views/about/about "); //使用frame模块导航到about页面
}
exports.onTap = onTap; //必须导出该函数,以便NativeScript运行时可以从UI访问它
2.2.3 Применение анимации перехода между навигациями по страницам
В следующей таблице показаны анимации перехода, поддерживаемые каждой платформой.
var frames = require("ui/frame");
function onTap() {
var navigationEntry = {
moduleName: "views/about/about",
transition: {
name: "slideBottom" //将想要应用的过渡动画写在这里
}
};
frames.topmost().navigate(navigationEntry);
}
exports.onTap = onTap;
2.3 Понимание макета страницы
Ссылаться наДокументацияучиться
2.4 Стиль написания приложения
Ссылаться наДокументацияучиться
3. Улучшить приложение
3.1 Привязка данных
3.1.1 Двусторонняя привязка обычных данных
- Напишите следующий код в файле home.xml
<Page loaded="onLoaded">
<StackLayout>
<Label text="{{ Name }}" /> //在{{}}内写入需要绑定的变量
</StackLayout>
</Page>
- Напишите следующий код в файле home.js
var observableModule = require("data/observable");
var viewModule = require ("ui/core/view");
exports.onLoaded = function(args){
var page = args.object;
var pet = new observableModule.Observable(); //pet对象是一个可观察的对象,它将绑定到页面上的所有元素
page.bindingContext = pet; //将pet设置为页面的绑定上下文,将其设置为用于绑定的页面级可观察对象
pet.set("Name", "Riven");
//也可以写成下面的形式
//var pet = new observable.fromObject({
// Name: "Riven"
//});
//page.bindingContext = pet;
}
3.1.2 Двусторонняя привязка данных списка
- Напишите следующий код в файле home.xml
<Page loaded="onLoaded">
<StackLayout>
<ListView items="{{ pages }}" itemTap="onItemTap"> //pages是一个可观察数组
<ListView.itemTemplate> //pages中的每一项会被渲染一次
<StackLayout>
<Label text="{{ title, title + ' Scrapbook Page' }}" /> //pages每一项上的title
</StackLayout>
</ListView.itemTemplate>
</ListView>
</StackLayout>
</Page>
- Напишите следующий код в файле home.js
var observable = require("data/observable");
var observableArray = require("data/observable-array");
exports.onLoaded = function(args) {
var page = args.object;
var filledPage = new observable.Observable({
title: "Riven's Page"
});
var home = new observable.Observable({
pages: new observableArray.ObservableArray(filledPage) //生成可观察对象数组
});
page.bindingContext = home;
};
Привязка данных содержимого может быть упакована в один файл PageName-View-Model.js облегчает несколько страниц обмениваться моделью представления.
3.2 Взаимодействие NativeScript с оборудованием устройства
3.2.1 Модуль файловой системы
var fileSystemModule = require("file-system"); //要使用文件系统模块,需要导入它
exports.onLoaded = function(){
var fileName = "myFile.json";
var file = fileSystemModule.knownFolders.documents().getFile(fileName); //使用documents文件夹存储应用程序需要的离线文件
var data = {name: "Brosteins", type: "filesystemexample"};
var jsonDataToWrite = JSON.stringify(data);
file.writeText(jsonDataToWrite); //将数据写入文件系统
console.log("Wrote to the file: " + jsonDataToWrite);
var jsonDataRead = file.readTextSync(); //使用对文件的引用来读取数据。数据可以同步读取,也可以异步读取
console.log("Read from the file: " + jsonDataRead);
file.remove(); //删除该文件
};
3.2.2 Камера
Установите плагин для камеры:npm install nativescript-camera --save
var camera = require("nativescript-camera");
var image = require("image-source");
exports.onAddImageTap = function (args) {
var page = args.object;
var scrapbookPage = page.bindingContext;
camera.requestPermissions(); //要使用照相机需要获得许可
camera
.takePicture() //返回一个promise
.then(function (picture) { //当promise解析后,调用then()函数,传递图片
image.fromAsset(picture).then(function (imageSource) {
scrapbookPage.set("image", imageSource); //创建要绑定到视图的图像源对象
});
});
}
Если вы сохраняете изображение, вам нужно использовать image.toBase64String("png") для преобразования двоичных данных изображения в строку base64, а затем сохранить его.
3.2.3 GPS-позиционирование
Установите целевой плагин:tns plugin add nativescript-geolocation
var camera = require("nativescript-camera");
var image = require("image-source");
var geolocation = require("nativescript-geolocation");
exports.onAddImageTap = function (args) {
var page = args.object;
var scrapbookPage = page.bindingContext;
if (!geolocation.isEnabled()) { //在使用位置服务之前,应该检查是否启用了它,并请求启用它
geolocation.enableLocationRequest();
}
camera
.takePicture({ width: 100, height: 100, keepAspectRatio: true })
.then(function (picture) {
image.fromAsset(picture).then(function (imageSource) {
scrapbookPage.set("image", imageSource);
});
geolocation.getCurrentLocation().then(function (location) { //获取位置数据会自动提示用户请求权限
scrapbookPage.set("lat", location.latitude); //返回的位置的纬度值
scrapbookPage.set("long", location.longitude); //返回的位置的经度值
});
});
};
3.3 Создайте профессиональный пользовательский интерфейс с темами
Ссылаться наДокументацияучиться
3.4 Улучшение взаимодействия с пользователем
3.4.1 Создайте более профессиональный пользовательский интерфейс с модальным
- XML-файл главной страницы выглядит следующим образом.
<Page backgroundColor="green" loaded="onLoaded">
<StackLayout backgroundColor="lightGreen">
<Button text="BirthDate" tap="onBirthDateTap"/>
</StackLayout>
</Page>
- Файл js главной страницы выглядит следующим образом
var page;
exports.onLoaded = function(args) {
page = args.object;
var scrapbookPage = page.navigationContext.model;
page.bindingContext = scrapbookPage;
};
exports.onBirthDateTap = function(args) {
var modalPageModule = "views/selectDate-page";
var context = { birthDate: page.bindingContext.birthDate };
var fullscreen = true;
page.showModal(
modalPageModule,
context,
function closeCallback(birthDate) { //关闭modal时的回调函数,可以将modal页面的数据传递回来
page.bindingContext.set("birthDate", birthDate);
},
fullscreen
);
};
- xml модальной страницы
<Page shownModally="onShownModally" loaded="onLoaded">
<StackLayout>
<DatePicker date="{{ date }}" />
<Button class="btn btn-primary btn-rounded-sm btn-active" text="Done" tap="onDoneTap" />
</StackLayout>
</Page>
- js модальной страницы
var observableModule = require("data/observable");
var model;
var closeCallback;
exports.onLoaded = function(args) {
var page = args.object;
model = new observableModule.fromObject({
date: new Date(Date.now())
});
page.bindingContext = model;
};
exports.onShownModally = function(args) {
closeCallback = args.closeCallback;
};
exports.onDoneTap = function(args) { closeCallback(model.date); };
3.4.2 Адаптация к планшетному ПК
может создатьpage-name.land.minWH600.xml,page-name.land.minWH600.js,page-name.land.minWH600.cssФайл записывается отдельно на страницу на стороне планшета.
3.5 Конфигурация перед развертыванием
3.5.1 Изменить значок приложения
1. Android
Иконки Android-приложений размещаются в каждой папке drawable-* в директории App_Resources, то есть устройства с разным разрешением используют соответствующие иконки
App_Resources/ AndroidManifest.xmlВ файле есть различные настройки приложения.
<application
android:name="com.tns.NativeScriptApplication"
android:allowBackup="true"
android:icon="@drawable/icon" //在这里修改app的图标
android:label="@string/app_name" //在string.xml里配置app_name
android:theme="@style/AppTheme" >
<activity
android:name="com.tns.NativeScriptActivity"
android:label="@string/title_activity_kimera" //在string.xml里配置使用时app的名字
android:configChanges="keyboardHidden|orientation|screenSize">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<activity android:name="com.tns.ErrorReportActivity"/>
</application>
2. iOS
существуетApp_Resources\iOS\Assets.xcassets\AppIcon.appiconsetПоместите под файл и используйте его в этомВеб-сайтСгенерированные иконки для iOS, которые нужно адаптировать под различные устройства
3.5.2 Изменить имя приложения
1. Android
существуетApp_Resources/Android/values/strings.xmlИзмените название приложения внутри
<resources>
<string name="app_name">Pet Scrapbook</string> //在这里改应用程序的名称
<string name="title_activity_kimera">Pet Scrapbook</string> //使用时app的名字
</resources>
2. iOS
существуетApp_Resources/iOS/Info.plistИзмените название приложения внутри
<key>CFBundleDisplayName</key>
<string>${PRODUCT_NAME}</string> //在这里修改名字,可以把名字直接写在<string>标签里
3.5.3 Изменить номер версии приложения
1. Android
существуетApp_Resources/ AndroidManifest.xmlконфигурация
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="__PACKAGE__"
android:versionCode="1" //用户看不到的内部版本号
android:versionName="1.0"> //用户在谷歌商店可以看到的版本号
2. iOS
существуетApp_Resources/iOS/Info.plistИзмените номер версии приложения внутри
<key>CFBundleVersion</key>
<string>1.0.0</string> //版本号
<key>CFBundleShortVersionString</key>
<string>1.0.0</string> //构建号
3.5.4 Измените приложение, чтобы оно адаптировалось к машине
1. Android
существуетApp_Resources/ AndroidManifest.xmlконфигурация
<supports-screens
android:smallScreens="true" //支持约2-3英寸的屏幕
android:normalScreens="true" //支持约2-5英寸的屏幕
android:largeScreens="true" //支持约4-7英寸的屏幕
android:xlargeScreens="true"/> //支持约7+英寸的屏幕
Размер экрана Android и соответствующее разрешение экрана DPI показаны в таблице ниже.
2. iOS
существуетApp_Resources/iOS/Info.plistСовместимость с различными устройствами
<key>UISupportedInterfaceOrientations</key> //适配iPhones
<array>
<string>UIInterfaceOrientationPortrait</string>
<string>UIInterfaceOrientationLandscapeLeft</string>
<string>UIInterfaceOrientationLandscapeRight</string>
</array>
<key>UISupportedInterfaceOrientations~ipad</key> //适配iPads
<array>
<string>UIInterfaceOrientationPortrait</string>
<string>UIInterfaceOrientationPortraitUpsideDown</string>
<string>UIInterfaceOrientationLandscapeLeft</string>
<string>UIInterfaceOrientationLandscapeRight</string>
</array>
3.5.5 Изменить стартовую страницу приложения
1. Android
drawable-nodpiв каталогеsplash_screen.xmlНастроил стартовую страницу приложения
<layer-list xmlns:android="http://schemas.android.com/apk/res/android" android:gravity="fill">
<item>
<bitmap android:gravity="fill" android:src="@drawable/background" /> //启动屏幕的背景图
</item>
<item>
<bitmap android:gravity="center" android:src="@drawable/logo" /> //启动屏幕中心的logo图片
</item>
</layer-list>
Фоновое изображение начального экрана и изображение логотипа в центре настраиваются так же, как и значок приложения.
2. iOS
- существует
App_Resources\iOS\Assets.xcassets\LaunchScreen.AspectFill.imagesetСтавим фоновое изображение заставки - существует
App_Resources\iOS\Assets.xcassets\LaunchScreen.Center.imagesetПоместите изображение логотипа в центр начального экрана. можно найти в этомВеб-сайтСоздавайте изображения, подходящие для различных устройств
4. Вывод
- Ссылка на эту статью: Официальный сайт книг"Книга нативного скрипта"
- Дополнительные учебные ресурсы: