În ultimul articol, v-am prezentat la NativeScript. Acolo ați învățat elementele de bază ale NativeScript și cum diferă de celelalte cadre de dezvoltare mobile. De data aceasta veți obține mâinile murdare prin crearea primei aplicații NativeScript. Vă voi trece prin întregul proces de construire a unei aplicații cu NativeScript, de la configurarea mediului dvs. de dezvoltare la rularea aplicației de pe dispozitiv. Iată o schiță a ceea ce voi discuta:
Vom rula în mod specific aplicația de pe platforma Android. Dar puteți continua de-a lungul timpului dacă doriți să vă deplasați la iOS deoarece codul va fi aproape același. Singurele diferențe sunt în procesul de configurare a NativeScript și a comenzilor pe care le executați la rularea aplicației.
Codul sursă completat pentru această aplicație este disponibil din reparația GitHub tutorial.
Pentru a configura NativeScript, trebuie mai întâi să instalați Node.js. Odată ce Node.js este instalat, puteți instala instrumentul de linie de comandă NativeScript executând npm install -g nativescript
pe terminalul tău.
Ultimul pas este să instalați instrumentul de dezvoltare pentru fiecare platformă pe care doriți să o implementați. Pentru Android, acesta este setul SDK Android. Pentru iOS, este XCode. Puteți urma ghidul de instalare de pe site-ul web NativeScript pentru instrucțiuni mai detaliate despre modul de configurare a software-ului necesar pentru mediul dvs. de dezvoltare.
După ce vă configurați mediul, executați tns doctor
pentru a vă asigura că mediul dvs. este pregătit pentru dezvoltarea NativeScript. Dacă sunteți pe Linux sau Windows, veți vedea ceva de genul acesta dacă mediul dvs. este gata:
NOTĂ: Puteți dezvolta pentru iOS numai pe sistemele Mac OS X. Pentru a putea lucra cu dispozitive i proiecte iOS, aveți nevoie de Mac OS X Mavericks sau mai târziu. Componentele dvs. sunt actualizate. Nu s-au detectat probleme.
Există o notă acolo pe care o puteți dezvolta numai pentru iOS numai pe sistemele Mac OS X. Aceasta înseamnă că, dacă sunteți pe un PC, veți putea să implementați numai pe dispozitive Android. Cu toate acestea, dacă sunteți pe Mac, veți putea implementa atât platforme iOS, cât și platforme Android.
Dacă întâmpinați probleme în timpul configurării, puteți primi o invitație de a vă alătura comunității NativeScript Slack și după ce v-ați alăturat, accesați canalul de pornire și întrebați-vă întrebările acolo.
Aplicația pe care o vom construi este o aplicație care acceptă note. Acesta va permite utilizatorului să creeze note, fiecare cu un atașament de imagine opțional ce va fi capturat cu camera aparatului. Notele sunt persistente utilizând setările aplicației NativeScript și pot fi șterse individual.
Iată ce va arăta aplicația:
Începeți prin a executa următoarea comandă pentru a crea un nou proiect NativeScript:
tns create noter --appid "com.yourname.noter"
noter
este numele proiectului și com.yourname.noter
este ID-ul unic al aplicației. Acesta va fi folosit ulterior pentru a identifica aplicația dvs. după ce o trimiteți la Play sau App Store. În mod implicit, funcția tns crea
comanda va crea următoarele dosare și fișiere pentru dvs.:
De obicei, trebuie să atingeți doar fișierele din interiorul lui aplicaţia director. Dar există, de asemenea, cazuri în care este posibil să aveți nevoie să editați fișiere în interiorul platforme /Android director. Un astfel de caz este atunci când un plugin pe care încercați să îl utilizați nu leagă automat dependențele și activele de care are nevoie.
Apoi, navigați la aplicaţia director și șterge toate fișierele, cu excepția App_Resources pliant. Apoi creați următoarele fișiere:
Acestea sunt fișierele care vor fi utilizate de timpul de execuție NativeScript. La fel ca la crearea paginilor web, .css fișierele sunt folosite pentru styling și .js fișiere pentru funcționalitate. Dar pentru marcarea aplicației folosim XML în loc de HTML. De obicei, creați un folder separat pentru fiecare ecran al aplicației (de exemplu, conectați-vă, înscrieți-vă sau tabloul de bord) și aveți fișiere XML, CSS și JavaScript în fiecare folder. Dar, deoarece această aplicație are doar un singur ecran, am creat toate fișierele din directorul rădăcină.
Dacă aveți nevoie de mai multe informații despre structura directorului NativeScript, consultați Capitolul 2 al Ghidului de inițiere a instrucțiunilor NativeScript.
Deschide app.js fișier și adăugați următorul cod:
aplicația var = solicită ("aplicație"); application.start (modulName: "note-page");
Acesta este punctul de intrare pentru o aplicație NativeScript. Utilizează modulul aplicației și modulul său start
pentru a specifica modulul utilizat pentru pagina inițială a aplicației. În acest caz, am specificat note de pagini
, ceea ce înseamnă că modulul este note-page.js, marcajul este note-page.xml, și stilul pentru pagină este note-page.css. Aceasta este o convenție folosită în NativeScript, că toate fișierele pentru o anumită pagină trebuie să aibă același nume.
Deschide note-page.xml fișier și adăugați următorul cod:
Când creați pagini de aplicații în NativeScript, ar trebui să începeți întotdeauna cu
etichetă. Acesta este modul în care NativeScript știe că încercați să creați o pagină nouă. xmlns
atributul specifică adresa URL a schemei folosite pentru fișierul XML.
Dacă vizitați adresa URL a schemei specificată, puteți vedea definiția tuturor etichetelor XML pe care le puteți utiliza în limbajul NativeScript. încărcat
atributul specifică funcția care trebuie executată după încărcarea paginii. Vom analiza această definiție a funcției mai târziu în note-page.js fişier.
...
În mod implicit, antetul aplicației conține numai titlul aplicației. Dacă doriți să adăugați alte componente ale UI, va trebui să o redefiniți utilizând
. Apoi, în interiorul dvs. definiți lucrurile pe care doriți să le vedeți în antet. Titlul este specificat prin utilizarea
și stabilirea lui titlu
atribuiți titlului paginii pe care doriți.
Mai jos am folosit sintaxa mustață pentru a afișa valoarea APP_TITLE
definită în note-page.js fişier. Acesta este modul în care valorile de ieșire sunt legate de pagină.
...
Pentru a defini butoanele, utilizați mai întâi
ca părinte, și fiecare
vor fi butoanele pe care doriți să le definiți. Atingeți
atributul specifică o funcție care trebuie executată atunci când este apăsat butonul, în timp ce os.position
și android.position
sunt pozițiile butonului din iOS și Android.
Pentru a specifica textul butonului, puteți utiliza
„s text
atribut. Cu toate acestea, NativeScript nu permite în prezent modificarea culorii textului butonului prin CSS. De aceea am folosit-o
pentru a defini conținutul butonului și pentru a seta culoarea acestuia.
Următorul este conținutul real al paginii. Puteți aranja diferitele elemente utilizând unul sau mai multe containere de aspect. Mai jos am folosit două dintre aspectele disponibile: StackLayout
și GridLayout
.
StackLayout
vă permite să stivuiți toate elementele din interiorul acestuia. În mod prestabilit, orientarea acestui aspect este verticală, astfel încât fiecare componentă UI este stivuită sub ultima. Gândiți-vă la cărămizi lego cu un flux descendent.
Pe de altă parte, GridLayout
vă permite să aranjați elemente într-o structură de tabel. Dacă ați folosit vreodată Bootstrap sau alte cadre de rețea CSS atunci acest lucru ar trebui să vă pară natural. GridLayout
vă permite să definiți rânduri și coloane între care poate fi plasat fiecare componentă UI. Vom analiza modul în care este implementat mai târziu. Pentru moment, să trecem la cod.
Mai întâi, să definim forma pentru crearea unei noi note. La fel ca în HTML, puteți defini atribute, cum ar fi id
și cssClass
(echivalent cu HTML clasă
atribut). id
atributul este atașat unui element dacă doriți să îl manipulați din cod. În cazul nostru, vrem să animăm formularul mai târziu. cssClass
este folosit pentru a specifica clasa CSS pe care o veți utiliza pentru a modela elementul.
În interiorul formularului este un câmp de text pentru introducerea titlului notei, un buton pentru atașarea unei imagini, imaginea selectată și un buton pentru salvarea notei. Elementul de imagine este vizibil numai dacă attachment_img
are o valoare truthy. Acesta va fi cazul dacă o imagine a fost atașată anterior.
Următoarea este lista care arată notele care au fost deja adăugate de utilizator. Listele sunt create folosind ListView
componentă. Acest lucru acceptă articole
ca atribut obligatoriu. Valoarea poate fi fie o matrice simplă, fie o matrice observabilă.
Dacă nu trebuie să efectuați nici o formă de actualizare (de ex., Ștergerea sau actualizarea unui câmp) pentru fiecare element din matrice, va face o matrice JavaScript simplă. Altfel, utilizați o matrice observabilă care vă permite să efectuați actualizări ale matricei și să le reflectați automat în interfața de utilizare. Vom arunca o privire asupra modului în care o matrice observabilă este definită mai târziu.
De asemenea, rețineți că a ListView
poate avea un itemTap
, care vă permite să specificați funcția care trebuie executată atunci când un element din ListView
este lovit. Dar, în acest caz, nu l-am adăugat cu adevărat, deoarece nu trebuie să efectuăm nicio acțiune atunci când un element este folosit.
...
Elementele din ListView
pot fi definite folosind
. Aici folosim a
pentru a crea două rânduri și două coloane. coloane
atributul este folosit pentru a specifica câte coloane doriți în fiecare rând.
În acest caz, *, *
înseamnă că există două coloane, fiecare ocupând o cantitate egală din spațiul disponibil în rândul curent. Deci, dacă întregul rând are o lățime totală de 300 de pixeli, fiecare coloană va avea o lățime de 150 de pixeli. Deci, fiecare în parte *
reprezintă o coloană și utilizați o virgulă pentru a separa fiecare dintre ele.
rânduri
atributul funcționează similar, dar controlează spațiul utilizat de un singur rând. auto
înseamnă că va consuma doar spațiul necesar copiilor din fiecare rând.
După definirea coloane
și rânduri
în GridLayout
, tot trebuie să precizați care dintre copiii săi aparține rândului și coloanei. Primul rând conține titlul articolului (prima coloană) și butonul de ștergere (coloana a 2-a). Al doilea rând conține imaginea atașată la articol (prima coloană). Rândul și coloanele sunt specificate utilizând rând
și col
atribut pentru fiecare element.
De asemenea, observați utilizarea aliniere orizontala
și aliniere verticală
. Vă puteți gândi la acest lucru ca echivalentul codului NativeScript al HTML aliniere text
atribut. Dar în loc de text, aliniem componentele UI. aliniere orizontala
poate avea o valoare de dreapta
, stânga
, centru
, sau întinde
, in timp ce aliniere verticală
poate avea o valoare de top
, fund
, centru
, sau întinde
. Cele mai multe dintre acestea sunt explicative, cu excepția întinde
, care se întinde pentru a prelua spațiul disponibil orizontal sau vertical.
În acest caz, aliniere orizontala
și aliniere verticală
sunt folosite pentru a centra imaginea atât orizontal cât și vertical în interiorul coloanei. Și aliniere orizontala
este utilizat pe butonul de ștergere pentru al alinia la cea mai mare parte a celei de-a doua coloane.
Nu am specificat niciunul itemTap
atribut pentru ListView
. În schimb, vrem să atașăm o acțiune de ștergere care va fi executată ori de câte ori este apăsat un buton de ștergere dintr-un element de listă. Fiecare element are un index
atribut, pe care îl transmitem ca atribut personalizat pentru butonul de ștergere. Aceasta este cheia unică folosită pentru identificarea fiecărui element, astfel încât să putem să ne referim cu ușurință atunci când este necesar.
De asemenea, observați încărcat
atribut. Doar noi
are o încărcat
atribut, butoanele pot avea și una. Veți vedea mai târziu cum este folosit acest lucru.
Acum suntem gata să examinăm JavaScript care face totul să funcționeze. În această secțiune vom codifica note-page.js fişier.
Mai întâi importăm date / observabile
și date / observabile-matrice
module. Acestea sunt module încorporate în NativeScript care ne permit să creăm obiecte și tablouri observabile. Observatoarele ne permit să actualizăm automat interfața utilizator ori de câte ori aceste obiecte și reele se actualizează.
În aplicația noastră, pageArray
este utilizat pentru stocarea gamei de note, și pageData
este folosit pentru a le lega pe pagină. pageData
servește și ca container general pentru toate datele pe care dorim să le afișăm în interfața utilizator.
var Obsbleble = necesită ("date / observabile"); var ObservableArray = necesită ("date / observable-array"); var pageArray = new ObservableArray.ObservableArray (); var pageData = new Observable.Observabil (note: pageArray);
Apoi, importă toate celelalte module pe care le vom folosi în această pagină:
aparat foto
: pentru lucrul cu camera aparatului.vedere
: pentru trimiterea la anumite elemente din pagină. Gândește-te la el ca la echivalentul lui document.getElementById
în NativeScript.Ul / enums
: un dicționar global de valori constante pentru orice legătură cu UI.Ul / animație
: pentru animarea elementelor.aplicație-settings
: pentru date locale persistente.Sistemul de fișiere
: pentru a lucra cu sistemul de fișiere.var cameraModule = necesită ("camera"); var view = necesită ("ui / core / view"); var uiEnums = cer ("ui / enums"); var animație = necesită ("ui / animație"); var appSettings = necesită ("aplicație-setări"); var fs = necesită ("sistem de fișiere");
Apoi, inițializați valorile pentru variabilele care vor fi utilizate în întregul fișier. pagină
este utilizat pentru stocarea unei trimiteri la pagina curentă, notesArr
este copia simplă a tabelelor actuale din pagină și CURRENT_INDEX
este valoarea inițială a indexului care este folosit ca ID unic pentru fiecare notă.
pagina var; var noteArr = []; var current_index = -1;
pageLoaded ()
FuncţieFuncțiile devin disponibile în contextul paginii prin utilizarea exporturi
. Anterior în note-page.xml fișier, ați văzut că pageLoaded ()
funcția este executată atunci când pagina este încărcată.
exports.pageLoaded = funcția (args) ...
În interiorul pageLoaded ()
funcția, vom începe prin a obține referința la pagină. Apoi afișăm formularul pentru crearea unei note noi și obțineți valorile memorate în prezent ale noului titlu de notă și notele din setările aplicației.
pagina = args.object; paginaData.set ("showForm", adevărat); var nou_note_title = appSettings.getString ("new_note_title"); var notes = appSettings.getString ("note");
Apoi, încă în cadrul pageLoaded ()
, verificați dacă există note care sunt stocate local. Dacă nu, vom crea o serie de note. Această matrice va servi ca conținut implicit pentru utilizatorii noi ai aplicației. Cu toate acestea, dacă există deja unele note stocate local, le vom converti într-o matrice și apoi vom împinge acele date în tabloul observabil.
Rețineți că înainte de a împinge elementele în matricea observabilă, verificăm mai întâi dacă este goală. Trebuie să facem acest lucru deoarece utilizarea modulului camerei foto execută încărcat
eveniment din pagină încă o dată după selectarea unei imagini. Acest lucru înseamnă că, dacă nu suntem atenți, vom termina împingând duplicate în matrice de fiecare dată când utilizatorul folosește camera.
dacă (notele) note = [index: 0, titlu: 100 împingături, index: 1, titlul: 100 sit ups index: 3, titlu: "10 km de funcționare"]; altceva notes = JSON.parse (note); notesArr = note; dacă (! pageArray.length) pentru (var x = 0; x < notes.length; x++) current_index += 1; pageArray.push(notes[x]);
Acum, când avem setările pentru note, putem actualiza titlul paginii prin setarea acesteia ITEM_TITLE
atribuiți valorii pe care am obținut-o mai devreme din setările aplicației. Apoi legați pageData
la pagina, astfel încât interfața utilizator se actualizează automat ori de câte ori se efectuează o modificare a elementelor pe care le-am setat.
paginaData.set ("item_title", new_note_title); args.objectbindingContext = dateData;
Animați formularul pentru crearea noilor note. Noi facem asta folosind getViewById
funcția în vedere
și trecând în context (pagina curentă) ca primul argument și id
atributul atribuit elementului pe care doriți să îl manipulați.
Apoi, apelați anima
funcţie. Aceasta acceptă un obiect care conține setările de animație. Aici dorim ca formularul să alunece 160 pixeli față de poziția inițială pe o perioadă de 800 de milisecunde.
view.getViewById (pagina, 'form'). animate (: translate: x: 0, y: 160, durata: 800,);
newNote ()
Funcţie newNote ()
funcția este executată atunci când utilizatorul se apasă pe Articol nou articol de acțiune de pe antet. Aceasta ascunde și afișează elementul nou ListView
și alunecă forma în sus sau în jos, în funcție de valoarea curentă de showForm
.
Dacă showForm
este Adevărat
, ceea ce înseamnă că se arată în prezent, schimbăm opacitatea ListView
la 1
în cursul a 400 de milisecunde, apoi glisați formularul pentru al ascunde. În caz contrar, ascundem ListView
și glisați formularul în jos.
exports.newNote = funcția () var showForm = pageData.get ('showForm'); var top_position = (showForm)? -160: 160; var list_visibility = (showForm)? 1: 0; view.getViewById (pagina, 'lista'). animați (opacity: list_visibility, duration: 400); view.getViewById (pagina, 'form'). animați (: translate: x: 0, y: top_position, durata: 800,); paginaData.set ("showForm", "showForm");
btnLoaded ()
FuncţieÎn note-page.xml dosar, avem o încărcat
atribut în butonul pentru ștergerea unei note. Aceasta este funcția care se execută atunci când se întâmplă acest eveniment.
În mod implicit, funcția atribuită funcției itemTap
atribut în ListView
nu se execută atunci când un buton este definit în interiorul lui a ListView
articol. Acest lucru se datorează faptului că NativeScript presupune că acțiunile care trebuie efectuate pentru fiecare element de listă pot fi declanșate numai de acele butoane.
Codul de mai jos este o soluție pentru acest comportament implicit. Acest lucru elimină în mod esențial focalizarea pe butonul de ștergere, astfel încât să puteți executa în continuare o funcție atunci când un utilizator se deconectează pe a ListView
articol. În acest caz, nu avem nevoie de acest cod, deoarece nu am atribuit nici o funcționalitate pentru robinetele de articole, dar este un instrument bun pentru a avea atunci când lucrați cu liste.
exports.btnLoaded = funcția (args) var btn = args.object; btn.android.setFocusable (false);
camera deschisa()
FuncţieÎnainte este camera deschisa()
funcția, care se execută atunci când utilizatorul face clic pe Atașați imaginea buton. Starea curentă nu este menținută atunci când se utilizează modulul camerei, așa că mai întâi trebuie să salvăm titlul noii note în setările aplicației.
Apoi, putem lansa aplicația implicită pentru cameră în dispozitiv apelând fa poza()
metodă. Această metodă acceptă un obiect care conține setările de imagine. Odată ce utilizatorul a făcut o fotografie și a apăsat pe Salvați în Android sau în utilizați imaginea butonul pe iOS, promisiunea rezolvată și funcția de apel inversă atunci()
se execută.
Imaginea reală este trecută ca argument al funcției și vom folosi aceasta pentru a salva fișierul în calea documentelor. După ce sa terminat, salvăm calea completă a fișierelor la setările aplicației și la starea actuală a aplicației, astfel încât să putem obține valoarea mai târziu, înainte de a salva nota.
exports.openCamera = funcția () appSettings.setString ('new_note_title', pageData.get ('item_title')); cameraModule.takePicture (lățime: 300, înălțimea: 300, keepAspectRatio: true), apoi (funcția (img) var filepath = fs.path.join (fs.knownFolders.documents ("new_note_photo", filepath); pageData.set ('attachment_img', 'new_note_photo', filepath); dateData.set ('attachment_img' filepath););
saveNote ()
Funcţie saveNote ()
funcția este executată atunci când utilizatorul se apasă pe Salvați Notă buton. Aceasta devine valoarea curentă a câmpului de text al titlului notei și a căii imaginii, incrementează CURRENT_INDEX
, și împinge noul element în matricele de note simple și în tablourile cu note observabile. Apoi salvează notele curente și CURRENT_INDEX
în setările aplicației, elimină valorile noii note din setările aplicației, actualizează interfața de utilizare, astfel încât formularul să afișeze starea sa goală și afișează lista în timp ce ascunde noul formular de notă.
exports.saveNote = funcție () var new_note_title = pageData.get ('item_title'); var_new_note_photo = pageData.get ('attachment_img'); curent_index + = 1; var new_index = actual_index; var new_item = index: new_index, title: new_note_title, fotografie: new_note_photo, show_photo: false; notesArr.push (NEW_ITEM); pageArray.push (NEW_ITEM); appSettings.setString ("note", JSON.stringify (notesArr)); appSettings.setNumber ('actual_index', new_index); appSettings.remove ( 'new_note_title'); appSettings.remove ( 'new_note_photo'); paginaData.set ("showForm", falsă); (opacity: 1, duration: 400); view.getViewById ("list_title", " (: translate: x: 0, y: -160, durata: 800,);
deleteNote ()
FuncţieÎn cele din urmă, avem deleteNote ()
care se execută atunci când un utilizator se deconectează pe butonul de ștergere din interiorul unui element de listă. După cum ați văzut deja din funcțiile anterioare, un obiect este transmis ca argument pentru funcțiile care sunt atașate ca un handler de evenimente pentru o componentă specifică. Acest obiect are obiect
proprietate, care se referă la componenta însăși.
De acolo, puteți obține valoarea unui atribut care a fost transferat la acesta. În acest caz, obținem valoarea index
atribut și îl folosim pentru a obține indexul real al elementului pe care dorim să îl ștergem.
exports.deleteNote = funcția (args) var target = args.object; var index_to_delete = notesArr.map (funcție (e) return e.index;) indexOf (target.index); noteArr.map (funcție (element, index) if (index == index_to_delete) notesArr.splice (index_to_delete, 1); pageArray.splice (index_to_delete, 1); appSettings.setString ("note", JSON.stringify (notesArr));
Deschide app.css fișier și adăugați următoarele stiluri globale:
ActionBar background-color: # b898ff; culoare: #fff; . element-cheie text-transform: majuscule; .item padding: 20; font-size: 20px; .form-container background-color: #fff; margin-top: -160px; padding: 20px; z-index: 10; .label font-size: 18px; .link text-aliniere: stânga; fundal-culoare: transparent; culoare: # 0275d8; padding: 5px; margine: 10px 0; text-transform: majuscule; font-size: 15px; .image lățime: 300; marja: 20 0; .primary-button padding: 5px; culoare: #fff; fundal-culoare: # 0723bb; text-transform: majuscule; . butonul de ștergere font-size: 15px; fundal-culoare: # f50029; culoare: #fff;
Dacă doriți să aplicați stiluri specifice unei pagini, puteți crea și un note-page.css fișier și definiți stilurile dvs. acolo.
Puteți rula aplicația pe dispozitivul dvs. executând tns alerga
și apoi platforma pe care doriți să o implementați. Iată un exemplu pentru Android:
tns rula Android
Aceasta instalează automat platforma Android pentru dvs. dacă nu a fost deja instalată și apoi rulează aplicația de pe dispozitiv după ce este instalată. Odată ce aplicația rulează, puteți executa tns livesync android - vizionează
pentru a actualiza automat aplicația de fiecare dată când efectuați modificări ale fișierelor sursă.
La fel ca orice alt cadru de aplicații, NativeScript permite dezvoltatorilor să-și depaneze aplicația. Acest lucru se întâmplă cu instrumentele Google Chrome. Există două modalități de a face acest lucru:
tns debug android -start
pentru a atașa un program de depanare la instanța curentă a aplicației.tns debug-android -debug-brk
pentru a construi o instanță a aplicației cu ajutorul unui depanator atașat la acesta.Indiferent de opțiunea pe care o alegeți, aceasta va deschide o nouă filă în browserul Google Chrome, care vă va permite să depanați aplicația la fel ca o aplicație web obișnuită JavaScript. Acest lucru înseamnă că puteți folosi de fapt console.log
în codul sursă pentru a inspecta conținutul variabilelor cu care lucrați.
În acest articol, ați învățat cum să creați o aplicație cu NativeScript. În mod specific, ați învățat concepte, cum ar fi utilizarea componentelor UI, aranjamentelor, stilului, animațiilor, utilizarea camerei aparatului și menținerea stării aplicației cu setările aplicației.
Acum că ați construit prima aplicație NativeScript, este timpul să vă luați abilitățile și mai mult, verificând ce altceva puteți face cu NativeScript și construindu-i alte aplicații.