Работа с RadSideDrawer и RadListView в мобильном приложении NativeScript Angular 2

Работа с RadSideDrawer и RadListView в мобильном приложении NativeScript Angular 2

Сегодня мы рассмотрим пример включения бокового меню в приложение 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. Так мы отделяем часть меню от части главного окна приложения.

В 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 = FrameModule.topmost().currentPage.getViewById("radlistview");
Toast.makeText("Deleted").show();
this.emails.splice(this.selected, 1);
radListView.notifySwipeToExecuteFinished();
}

В методе onDelete мы получаем RadListView из интерфейса. Мы знаем позицию элемента, с которым работаем, поэтому можем её использовать для удаления элемента и возвратить свайп обратно. То же самое применимо к методу onArchive:

public onArchive() {
let radListView = FrameModule.topmost().currentPage.getViewById("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

Leave a Comment