Сегодня мы рассмотрим пример включения бокового меню в приложение NativeScript под Android и iOS, построенное на Angular 2. Ну и чтобы два раза не вставать было интереснее, добавим в него мощный компонент построения списков RadListView.
Компоненты RadSideDrawer и RadListView доступны только в пакете NativeScript UI, который включает как бесплатную, так и платную версии. Всё, что мы рассмотрим в этом материале, доступно в бесплатной версии.
Для дальнейшей работы убедитесь в том, что у вас установлен NativeScript не ниже версии 2.5 и Android SDK и / или Xcode.
И если кто не в курсе, приложения под iOS можно разрабатывать только имея Mac.
Создадим чистый проект. Откройте командную строку и введите поочерёдно следующие команды:
tns create AwesomeProject --ng
cd AwesomeProject
tns platform add ios
tns platform add android
Более подробно об установке и настройке NativeScript читайте в официальной документации.
В нашем приложении будут использованы всплывающие сообщения. Установим плагин для этого:
tns plugin add nativescript-toast
Вот как будет выглядеть наше приложение в конце:
Приложение не будет особо блистать функционалом: в центре будет список элементов, а боковое меню будет выдвигаться по свайпу. В нём будут несколько элементов, по нажатию на которые появится всплывающее сообщение. А в главном списке элементов будут реализованы функции горизонтального свайпа и «потянуть для обновления».
Теперь установим компоненты RadSideDrawer и RadListView. Выполните команду в терминале:
tns plugin add nativescript-telerik-ui
Более подробно об этом компоненте здесь.
После установки необходимо включить компоненты в приложение. Откроем файл app/app.module.ts и добавим в него такие строки:
import { NgModule, NO_ERRORS_SCHEMA } from "@angular/core";
import { NativeScriptModule } from "nativescript-angular/nativescript.module";
import { SIDEDRAWER_DIRECTIVES } from "nativescript-telerik-ui/sidedrawer/angular";
import { LISTVIEW_DIRECTIVES } from 'nativescript-telerik-ui/listview/angular';
import { AppComponent } from "./app.component";
@NgModule({
declarations: [
AppComponent,
LISTVIEW_DIRECTIVES,
SIDEDRAWER_DIRECTIVES
],
bootstrap: [AppComponent],
imports: [NativeScriptModule],
schemas: [NO_ERRORS_SCHEMA]
})
export class AppModule { }
Обратите внимание, мы импортировали две директивы NativeScript UI и добавили их в массив declarations блока @NgModule. Такие же действия потребуются в случае установки других компонентов пакета NativeScript UI.
Разработка бокового меню
Откроем файл app/app.component.ts и добавим в него такой код:
import { Component, ViewChild, OnInit } from "@angular/core";
import { ListViewEventData, RadListView } from "nativescript-telerik-ui/listview";
import { RadSideDrawerComponent, SideDrawerType } from "nativescript-telerik-ui/sidedrawer/angular";
import { View } from 'ui/core/view';
import * as Utils from "utils/utils";
import * as FrameModule from "ui/frame";
import * as Toast from 'nativescript-toast';
@Component({
selector: "my-app",
templateUrl: "app.component.html",
})
export class AppComponent implements OnInit {
public emails: Array
public selected: number;
private drawer: SideDrawerType;
@ViewChild(RadSideDrawerComponent)
public drawerComponent: RadSideDrawerComponent;
public constructor() {
this.emails = [
"Welcome to The Polyglot Developer Newsletter!",
"Raspberry Pi Zero's Available!",
];
}
public ngOnInit() {
this.drawer = this.drawerComponent.sideDrawer;
}
public onPullToRefreshInitiated(args: any) { }
public onSwipeCellStarted(args: ListViewEventData) { }
public onDelete() { }
public onArchive() { }
public onMenuTapped(value: any) {
Toast.makeText(value + " menu item selected").show();
this.drawer.closeDrawer();
}
}
Здесь мы сделали следующее: в классе AppComponent ввели несколько общих и частных переменных. В переменной emails будет храниться список строк, которые мы выведем в RadListView. Переменная selected сообщит нам, какой элемент выбран в RadListView, чтобы мы могли запустить соответствующий метод. Переменная drawer будет ссылаться на компонент RadSideDrawer и мы сможем выполнять такие действия как открытие/закрытие меню.
По причине простоты реализации, мы инициируем строки, представляющие электронные адреса, в методе constructor. После вызова constructor будет вызван ngOnInit, где мы зададим @ViewChild равный переменной drawer.
Мы ещё не касались интерфейса, но при клике на элемент в боковом меню нам нужно будет выполнить метод. Метод onMenuTapped возьмёт любое значение и выведет во всплывающем сообщении. После показа сообщения, боковое меню закроется.
А теперь давайте построим интерфейс!
Откроем файл app/app.component.html и включим в него следующую разметку:
Не касаясь пока тегов class, у нас здесь есть
В tkDrawerContent (это наше боковое меню) у нас есть список компонентов
Довольно просто, не так ли?
Перейдём к главному представлению в секции tkMainContent.
Добавление многофункционального списка
Для начала вернёмся в логику на TypeScript, в которой мы оставили недописанными пару методов.
Откроем файл app/app.component.ts и добавим код:
public onPullToRefreshInitiated(args: any) {
var radListView = args.object;
setTimeout(() => {
this.emails.push("NativeScript for the Angular Developer");
radListView.notifyPullToRefreshFinished();
}, 500);
}
Здесь в методе onPullToRefreshInitiated мы получаем ссылку на наш RadListView и настраиваем таймаут в полсекунды. Наши данные статичны и в таймауте нет необходимости, но они легко могут приходить и из базы данных, поэтому при срабатывании таймера мы увидим что мы хотели реализовать.
Реализовать свайпы в RadListView можно несколькими способами. Предположим, что мы хотим добавить кнопки действий. То есть, сдвинув элемент, мы увидим кнопки, на которые можно нажать.
public onSwipeCellStarted(args: ListViewEventData) {
var swipeLimits = args.data.swipeLimits;
swipeLimits.threshold = 60 * Utils.layout.getDisplayDensity();
swipeLimits.left = 120 * Utils.layout.getDisplayDensity();
swipeLimits.right = 120 * Utils.layout.getDisplayDensity();
this.selected = args.itemIndex;
}
Здесь мы задали расстояние, на которое можно сдвинуть элемент в любую сторону, относительно размера экрана.
И у нас элемент списка не имеет жёсткой привязки к кнопкам в свайпе, поэтому необходимо получить информацию о том, какой элемент был сдвинут. Это понадобится для реализации клика на кнопки свайпа.
public onDelete() {
let radListView =
Toast.makeText("Deleted").show();
this.emails.splice(this.selected, 1);
radListView.notifySwipeToExecuteFinished();
}
В методе onDelete мы получаем RadListView из интерфейса. Мы знаем позицию элемента, с которым работаем, поэтому можем её использовать для удаления элемента и возвратить свайп обратно. То же самое применимо к методу onArchive:
public onArchive() {
let radListView =
Toast.makeText("Archived").show();
this.emails.splice(this.selected, 1);
radListView.notifySwipeToExecuteFinished();
}
Перейдём снова к интерфейсу. Откроем app/app.component.html и посмотрим на полный пример:
Внутри RadListView у нас есть атрибут id и методы onDelete и onArchive могут получить ссылку на нужный компонент. Список строится из нашего массива в переменной emails и здесь же перечислены привязки к методам логики в коде TypeScript.
Строки в пременной списка представлены компонентом
tkListItemSwipeTemplate показывает, что это представление будет показано при свайпе. Это трёхколоночный макет сетки с кнопками по углам.
А теперь вернёмся к тегам class, упомянутым нами ранее, и рассмотрим стилизацию приложения.
Улучшения интерфейса с помощью CSS
Для простоты мы будем использовать только глобальные стили. Откройте файл app/app.css и добавьте следующее:
.sideStackLayout {
background-color: #555555;
color: #FFFFFF;
}
.sideTitleStackLayout {
padding: 16;
font-weight: bold;
background-color: #333333;
}
.sideLabel {
padding: 16;
}
.listItemStackLayout {
padding: 16;
background-color: #FFFFFF;
}
.archiveViewStackLayout {
padding: 16;
background-color: #387EF5;
color: #FFFFFF;
}
.deleteViewStackLayout {
padding: 16;
background-color: #EF473A;
color: #FFFFFF;
}
@import 'nativescript-theme-core/css/core.light.css';
Здесь нет ничего, кроме цвета фона и отступов, но наш интерфейс заметно преобразился.
Выполните команду tns run [platform] и будет собрано и запущено приложение для выбранной платформы.
По материалам «Use A Side Drawer And Feature Rich List View In A NativeScript Angular App» by Nic Raboy
Разработчик: java, kotlin, c#, javascript, dart, 1C, python, php.
Пишите: @ighar. Buy me a coffee, please :).