Razvoj višeplatformskih mobilnih aplikacija …2 1. Višeplatformski razvoj mobilnih aplikacija...

42
SVEUČILIŠTE U ZAGREBU FAKULTET ELEKTROTEHNIKE I RAČUNARSTVA DIPLOMSKI RAD br. 1258 Razvoj višeplatformskih mobilnih aplikacija korištenjem radnog okvira Flutter Neven Pavelić Zagreb, lipanj 2019.

Transcript of Razvoj višeplatformskih mobilnih aplikacija …2 1. Višeplatformski razvoj mobilnih aplikacija...

Page 1: Razvoj višeplatformskih mobilnih aplikacija …2 1. Višeplatformski razvoj mobilnih aplikacija Mobilne aplikacije nisu prve koje koriste višeplatformski razvoj. Prenosivost programa

SVEUČILIŠTE U ZAGREBU FAKULTET ELEKTROTEHNIKE I RAČUNARSTVA

DIPLOMSKI RAD br. 1258

Razvoj višeplatformskih mobilnih aplikacija korištenjem radnog okvira

Flutter Neven Pavelić

Zagreb, lipanj 2019.

Page 2: Razvoj višeplatformskih mobilnih aplikacija …2 1. Višeplatformski razvoj mobilnih aplikacija Mobilne aplikacije nisu prve koje koriste višeplatformski razvoj. Prenosivost programa
Page 3: Razvoj višeplatformskih mobilnih aplikacija …2 1. Višeplatformski razvoj mobilnih aplikacija Mobilne aplikacije nisu prve koje koriste višeplatformski razvoj. Prenosivost programa
Page 4: Razvoj višeplatformskih mobilnih aplikacija …2 1. Višeplatformski razvoj mobilnih aplikacija Mobilne aplikacije nisu prve koje koriste višeplatformski razvoj. Prenosivost programa

Sadržaj Uvod ................................................................................................................................. 1

1. Višeplatformski razvoj mobilnih aplikacija ................................................................ 2

1.1. Arhitektura okvira baziranih na web tehnologijama ............................................ 2

1.2. Arhitektura okvira baziranih na preslikavanju .................................................... 3

1.3. Arhitektura okvira baziranih na vlastitom iscrtavanju ......................................... 3

2. Radni okvir Flutter ..................................................................................................... 5

2.1. Arhitektura radnog okvira Flutter ....................................................................... 7

2.2. Programski jezik Dart......................................................................................... 8

2.3. Grafičke komponente radnog okvira Flutter ....................................................... 9

2.4. Razvojni alati radnog okvira Flutter ................................................................. 13

3. Implementacija višeplatformske aplikacije ............................................................... 14

3.1. Implementacija uvodnog ekrana ....................................................................... 17

3.2. Implementacija ekrana liste gradova ................................................................. 22

3.3. Implementacija ekrana s kartom lokacija .......................................................... 27

3.4. Implementacija ekrana s detaljima lokacije ...................................................... 31

Zaključak ........................................................................................................................ 33

Literatura ......................................................................................................................... 34

Sažetak ............................................................................................................................ 35

Summary ......................................................................................................................... 36

Skraćenice ....................................................................................................................... 37

Privitak ............................................................................................................................ 38

Page 5: Razvoj višeplatformskih mobilnih aplikacija …2 1. Višeplatformski razvoj mobilnih aplikacija Mobilne aplikacije nisu prve koje koriste višeplatformski razvoj. Prenosivost programa

1

Uvod

Mobilne aplikacije su vrlo popularne u današnje vrijeme. Dva operacijska sustava koja

trenutno dominiraju na tržištu mobilnih uređaja su mobilni operacijski sustavi Android i

iOS te ako mobilna aplikacija želi biti uspješna ona mora biti dostupna na oba navedena

sustava. No, svaki mobilni operacijski sustav ima posebne alate, programske jezike te

načine izrade aplikacije. Zbog toga je za klasičan razvoj aplikacija za Android i iOS

potrebno napraviti dvije različite aplikacije koje rade istu stvar, ali na specifičan način koji

ovisi o operacijskom sustavu. To dovodi do značajnog povećanja napora i troškova koji su

potrebni za razvoj jedne takve aplikacije. Zbog toga, tijekom godina je razvijen velik broj

radnih okvira koji su pokušali ublažiti ili riješiti taj problem pomoću višeplatformskog

razvoja aplikacija. Jedan od modernijih višeplatformskih mobilnih radnih okvira je Flutter,

koji će se istraživati u ovom radu. Flutter omogućava razvoj aplikacija za Android i iOS na

moderan i brz način te ima odlične alate za razvoj i razvojnu dokumentaciju. Također,

Flutter se fokusira na poboljšanje performansi i izgleda mobilnih višeplatformskih

aplikacija. Svim time Flutter pokušava ubrzati i poboljšati razvoj mobilnih aplikacija te

postati dominantan radni okvir za razvoj mobilnih aplikacija.

Page 6: Razvoj višeplatformskih mobilnih aplikacija …2 1. Višeplatformski razvoj mobilnih aplikacija Mobilne aplikacije nisu prve koje koriste višeplatformski razvoj. Prenosivost programa

2

1. Višeplatformski razvoj mobilnih aplikacija

Mobilne aplikacije nisu prve koje koriste višeplatformski razvoj. Prenosivost programa na

različite sustave bio je cilj mnogim programskim jezicima, operacijskim sustavima i

radnim okvirima, kao što su operacijski sustav Linux i programski jezik Java.

1.1. Arhitektura okvira baziranih na web tehnologijama

Među prvim radnim okvirima za razvoj višeplatformskih mobilnih aplikacija bili su

PhoneGap, Apache Cordova i Ionic. Oni su bili bazirani na web tehnologijama te su

pomoću HTML-a i JavaScripta definirali web stranice koje se prikazuju korištenjem

komponente za prikaz weba u mobilnim aplikacijama - WebView. To omogućava

jednostavnost upotrebe te iskoristivost postojećih web stranica za razvoj mobilne

aplikacije. No, jedna od loših strana takvog pristupa je otežano korištenje autohtonih

mobilnih komponenata koje nisu prisutne na webu kao što su kamera, Bluetooth, GPS,

senzori itd. Za pristup tim komponentama potrebno je koristiti most (engl. bridge) između

JavaScripta i autohtonih mobilnih komponenata što stvara probleme s performansama. Još

jedna loša strana tog pristupa je što su takve aplikacije izgledale i imale osjećaj web

aplikacija, a ne mobilnih aplikacija koje su korisnici navikli koristiti na svojim mobilnim

uređajima.

Slika 1.1 Arhitektura višeplatformskih mobilnih radnih okvira baziranih na web tehnologijama [6]

Page 7: Razvoj višeplatformskih mobilnih aplikacija …2 1. Višeplatformski razvoj mobilnih aplikacija Mobilne aplikacije nisu prve koje koriste višeplatformski razvoj. Prenosivost programa

3

1.2. Arhitektura okvira baziranih na preslikavanju

Druga vrsta mobilnih višeplatformskih radnih okvira su radni okviri koji preslikavaju svoje

komponente u autohtone komponente mobilnog operacijskog sustava. Primjer takvih

radnih okvira su Xamarin i ReactNative. Oni ne koriste HTML za prikaz već imaju

definirane svoje komponente prikaza pisane u programskom jeziku tog radnog okvira (C#

za Xamarin i JavaScript za ReactNative). Te komponente se preko mosta između radnog

okvira i autohtonog sustava preslikavaju u autohtone komponente prikaza iOS ili Android

mobilnog operacijskog sustava. To poboljšava izgled i osjećaj (engl. look and feel)

aplikacije u odnosu na radne okvire bazirane na web tehnologijama, no loša strana je što

cijela komunikacija ide preko mosta, što negativno utječe na performanse.

Slika 1.2 Arhitektura višeplatformskih mobilnih radnih okvira baziranih na preslikavanju [6]

1.3. Arhitektura okvira baziranih na vlastitom iscrtavanju

Radni okvir Flutter ima drugačiji pristup. On sam iscrtava grafičke elemente korištenjem

autohtone mobilne komponente platna za iscrtavanje (engl. canvas). Prednost je što Flutter

ima potpunu kontrolu nad grafičkim elementima čime može postići poboljšan look and feel

i poboljšane performanse. Za komunikaciju s ostalim autohtonim mobilnim komponentama

Flutter koristi optimiziranu implementaciju mosta koja se zove platformski kanal (engl.

Page 8: Razvoj višeplatformskih mobilnih aplikacija …2 1. Višeplatformski razvoj mobilnih aplikacija Mobilne aplikacije nisu prve koje koriste višeplatformski razvoj. Prenosivost programa

4

platform channel). Pošto se Flutter aplikacija prevodi u kod niske razine, korištenje mosta

u platformskom kanalu ne utječe toliko na performanse, kao ranije navedeni radni okviri

koji preko mosta komuniciraju s autohtonim komponentama koristeći programske jezike

kao što su JavaScript i C#.

Slika 1.3 Arhitektura radnog okvira baziranog na vlastitom iscrtavanju [6]

Page 9: Razvoj višeplatformskih mobilnih aplikacija …2 1. Višeplatformski razvoj mobilnih aplikacija Mobilne aplikacije nisu prve koje koriste višeplatformski razvoj. Prenosivost programa

5

2. Radni okvir Flutter

Flutter je višeplatformski radni okvir otvorenog koda razvijen u kompaniji Google. Prvi

put je objavljen u svibnju 2017. godine, a prva stabilna distribucija objavljena je u prosincu

2018. godine. Flutter je prvotno bio namijenjen za razvoj Android i iOS mobilnih

aplikacija, ali najavljena je i podrška za web i desktop platforme. Također, predviđa se da

će se u budućnosti na Flutteru temeljiti razvoj aplikacija za Googleov novi nadolazeći

mobilni operacijski sustav Fuchsia.

Na službenoj web stranici radnog okvira Flutter, Google ističe 3 glavne prednosti:

Brz razvoj Flutter sadrži niz alata koji naveliko pomažu programeru i ubrzavaju razvoj. Najznačajniji

od tih alata je alat „vrućeg ponovnog učitavanja“ (engl. hot reload). Taj alat omogućava

programeru da nakon promjene programskog koda aplikacije u manje od sekunde ponovno

učita aplikaciju i primjeni svoje promjene bez gubitka stanja aplikacije. U usporedbi s

nekim drugim radnim okvirima kod kojih to može trajati i po nekoliko minuta, hot reload

značajno ubrzava proces razvoja aplikacije i povećava koncentraciju i produktivnost

programera koji odmah može vidjeti promjene koje je napravio. Jedna od glavnih stvari

koja čini tako nešto mogućim je uporaba programskog jezika Dart u radnom okviru Flutter.

Neki od ostalih dostupnih razvojnih alata su Flutter inspektor, Dart razvojni alati, Flutter

alati komandne linije te odlična podrška za nekoliko razvojnih okolina (IntelliJ Idea,

Android Studio, Visual Studio Code).

Izražajno i lijepo grafičko sučelje Iako sam iscrtava sve grafičke komponente, Flutter sadrži vjerne kopije autohtonih

mobilnih grafičkih komponenti koje je jako teško ili nemoguće razlikovati od pravih

autohtonih mobilnih grafičkih komponenti. Flutterova biblioteka je bogata raznim

grafičkim komponentama različitih stilova dizajna kao što su materijalni dizajn (engl.

material design) i iOS stilovi. Sve grafičke komponente također je moguće opsežno

uređivati i personalizirati i time napraviti vlastiti stil dizajna. Također, postoje i brojne

vanjske biblioteke s grafičkim elementima ako Flutterova kolekcija nije dovoljna. Sve

grafičke komponente, kao i ostatak Fluttera, su vrlo lake za korištenje i odlično

dokumentirane.

Page 10: Razvoj višeplatformskih mobilnih aplikacija …2 1. Višeplatformski razvoj mobilnih aplikacija Mobilne aplikacije nisu prve koje koriste višeplatformski razvoj. Prenosivost programa

6

Odlične performanse Pošto Flutter sam iscrtava grafičke elemente koristeći grafičku knjižnicu za iscrtavanje 2D

grafike Skia, to omogućuje Flutter timu da optimizira performanse za brzo izvođenje.

Također, sam programski jezik Dart je isto u vlasništvu Googlea, tako da je moguće

nadograđivati programski jezik kako bi dodatno poboljšali performanse. Jedna od

funkcionalnosti programskog jezika Dart koja poboljšava performanse je korištenje AOT

(engl. ahead of time) kompajlera za prevođenje produkcijskih verzija aplikacije uz

primjenu tehnike „protresanja stabla“ (engl. tree shaking) u kojem se izbacuje nekorišteni

kod iz aplikacije.

Osim navedenih prednosti, istaknuo bih i odličnu Flutter zajednicu koja pruža mnogo

materijala za učenje i istraživanje kao što su instrukcijski članci i video materijali i velik

broj korisnih biblioteka koje mogu znatno pomoći u razvoju. To i je jedan od glavnih

razloga zašto je Flutter omiljen među programerima i lak za naučiti i koristiti. U Flutter

zajednici aktivno sudjeluju članovi Flutter tima, ali i velik broj vanjskih članova zajednice

koji znatno doprinose zajednici. Također, istaknuo bih vrhunsku dokumentaciju svih

dijelova Flutter radnog okvira, od službene dokumentacije na Flutterovoj stranici do

dokumentacije svih biblioteka.

Page 11: Razvoj višeplatformskih mobilnih aplikacija …2 1. Višeplatformski razvoj mobilnih aplikacija Mobilne aplikacije nisu prve koje koriste višeplatformski razvoj. Prenosivost programa

7

2.1. Arhitektura radnog okvira Flutter

Arhitektura radnog okvira Flutter sastoji se od više slojeva. Na dnu se nalazi ugradbeno

sučelje (engl. Embedder) koje se ugrađuje u različite operacijske sustave podržane od

strane Fluttera, npr. mobilni operacijski sustavi Android i iOS. Ugradbeno sučelje

omogućava da se ostatak Flutterovog radnog okvira može bez problema koristiti na

autohtonim platformama na kojima se radi aplikacija te da Flutter se na tim platformama

Flutter može koristiti kao vanjska programska knjižnica. Povrh sloja ugradbenog sučelja

nalazi se Engine sloj koji koristi programske jezike C i C++ te grafičku knjižnicu za

iscrtavanje 2D grafike Skia pomoću koje Flutter iscrtava svoje komponente grafičkog

sučelja. Na vrhu se nalazi sloj okosnice (engl. Framework) napisan u programskom jeziku

Dart koji sadrži implementaciju komponenti na visokoj razini te omogućava programeru

korištenje Flutterovog sučelja koristeći programski jezik Dart.

Slika 2.1 Arhitektura radnog okvira Flutter [4]

Page 12: Razvoj višeplatformskih mobilnih aplikacija …2 1. Višeplatformski razvoj mobilnih aplikacija Mobilne aplikacije nisu prve koje koriste višeplatformski razvoj. Prenosivost programa

8

2.2. Programski jezik Dart

Dart je objektno-orijentirani programski jezik koji kao i mnogi drugi poznati jezici koristi

sintaksu u stilu programskog jezika C. Dart je razvijen u Googleu, a njegova prva stabilna

1.0 verzija je izašla u studenom 2013. godine. Trenutno najnovija stabilna verzija je 2.3.0

koja je izašla u svibnju 2019. godine.

I Dart i Flutter su razvijeni od Googlea što omogućava Googleu da prilagođava jezik

samom radnom okviru Flutter i njegovim potrebama, čemu smo bili svjedoci u posljednjim

verzijama Darta. Jedna od Dartovih funkcionalnosti koja je jako važna za Flutter je to što

se Dart može prevoditi AOT (engl. ahead of time) ili JIT (engl. just in time). JIT

prevoditelj omogućava Flutteru jako brze promjene koda u aplikaciji tijekom razvoja

aplikacije, dok AOT prevoditelj omogućava prevođenje u kod niske razine za produkcijske

verzije aplikacije što znatno poboljšava performanse. Također, Dart ima vrlo brz garbage

collector što omogućava brzo uništavanje starih i stvaranje novih objekata, što kao rezultat

ima uglađenije animacije i stalnu brzinu od 60 okvira u sekundi (engl. frames per second,

fps). Također, Dartova sintaksa omogućava Flutteru da izbjegne korištenje XML-a ili

nekog sličnog jezika za označavanje (engl. markup language), što opet rezultira boljim

performansama te lakšem razvoju. Uz sve to, Dartova sintaksa je slična mnogim poznatim

programskim jezicima kao što su C, Java, C#, Swift, Kotlin, JavaScript te zbog toga većina

programera može jako brzo naučiti programirati u Dartu.

Page 13: Razvoj višeplatformskih mobilnih aplikacija …2 1. Višeplatformski razvoj mobilnih aplikacija Mobilne aplikacije nisu prve koje koriste višeplatformski razvoj. Prenosivost programa

9

2.3. Grafičke komponente radnog okvira Flutter

Flutterova implementacija grafičkih komponenti uzima inspiraciju iz modernih okvira

grafičkih komponenti kao što je React. Kod tih okvira grafičko sučelje se deklarira

deklarativno, a ne imperativno. Zbog toga, moguće je napraviti grafičko sučelje koje je

funkcija stanja aplikacije, a stanje aplikacije se može pohraniti u objektu. I tada se svakom

promjenom objekta stanja aplikacije, aplikacija može ponovno iscrtati i prikazati promjene

koje su se dogodile u objektu stanja aplikacije. Poanta je ne koristiti kompliciranu logiku

da bi se prikazala neka promjena na grafičkom sučelju, nego postići da grafičko sučelje

promatra promjene stanja te se ažurira na temelju tih promjena. Naravno, u tom slučaju

nije efikasno ponovno iscrtati cijeli ekran. Zato su moderni okviri kao Flutter i React

razvili sustav virtualnog stabla grafičkih komponenti koje može izračunati koji dio stabla

se promijenio i ažurirati samo te grafičke komponente koje su se doista promijenile i koje

bi se trebale ponovno iscrtati.

Glavna grafička komponenta u Flutteru se zove Widget i ona je gradivni element za cijelu

aplikaciju. Sve grafičke komponente U Flutteru od jednostavnih tekstova i gumbi pa do

cijelih ekrana su Widget-i. Čak je i sama Flutter aplikacija Widget. Na temelju Widget-a

Flutter računa koje dijelove aplikacije treba ponovno iscrtati kada se dogodi promjena

stanja aplikacije.

Flutter, iako sam iscrtava cijelo grafičko sučelje, sadrži bogatu kolekciju raznih vrsta

grafičkih komponenti iz raznih dizajnerskih stilova kao što su materijalni dizajn i iOS

dizajn. Također, sve grafičke komponente moguće je detaljno uređivati i nadograđivati.

Sljedeći kod je primjer minimalne Flutter aplikacije:

import 'package:flutter/material.dart';

void main() {

runApp(

MaterialApp(

home: Scaffold(body: Center(child: Text('Hello, world!'))),

),

);

Kôd 1.1 – Minimalna Flutter aplikacija

Page 14: Razvoj višeplatformskih mobilnih aplikacija …2 1. Višeplatformski razvoj mobilnih aplikacija Mobilne aplikacije nisu prve koje koriste višeplatformski razvoj. Prenosivost programa

10

Sljedeća slika prikazuje izgled te minimalne Flutter aplikacije:

Slika 2.2 Izgled minimalne Flutter aplikacije

Sljedeći primjer koda prikazuje Flutter aplikacije brojača

import 'package:flutter/material.dart';

void main() => runApp(MyApp());

class MyApp extends StatelessWidget {

@override

Widget build(BuildContext context) {

return MaterialApp(

title: 'Flutter Demo',

theme: ThemeData(

primarySwatch: Colors.blue,

),

home: MyHomePage(title: 'Flutter Demo Home Page'),

);

}

}

Page 15: Razvoj višeplatformskih mobilnih aplikacija …2 1. Višeplatformski razvoj mobilnih aplikacija Mobilne aplikacije nisu prve koje koriste višeplatformski razvoj. Prenosivost programa

11

class MyHomePage extends StatefulWidget {

MyHomePage({Key key, this.title}) : super(key: key);

final String title;

@override

_MyHomePageState createState() => _MyHomePageState();

}

class _MyHomePageState extends State<MyHomePage> {

int _counter = 0;

void _incrementCounter() {

setState(() {

_counter++;

});

}

@override

Widget build(BuildContext context) {

return Scaffold(

appBar: AppBar(

title: Text(widget.title),

),

body: Center(

child: Column(

mainAxisAlignment: MainAxisAlignment.center,

children: <Widget>[

Text('You have pushed the button this many times:',),

Text(

'$_counter',

style: Theme.of(context).textTheme.display1,

),

],

),

),

floatingActionButton: FloatingActionButton(

onPressed: _incrementCounter,

tooltip: 'Increment',

child: Icon(Icons.add),

),

);

}

}

Kôd 1.1 – Minimalna Flutter aplikacija

Page 16: Razvoj višeplatformskih mobilnih aplikacija …2 1. Višeplatformski razvoj mobilnih aplikacija Mobilne aplikacije nisu prve koje koriste višeplatformski razvoj. Prenosivost programa

12

A sljedeća slika prikazuje izgled aplikacije brojača:

Slika 2.3 Izgled jednostavne aplikacije brojača

Page 17: Razvoj višeplatformskih mobilnih aplikacija …2 1. Višeplatformski razvoj mobilnih aplikacija Mobilne aplikacije nisu prve koje koriste višeplatformski razvoj. Prenosivost programa

13

2.4. Razvojni alati radnog okvira Flutter

Za razvoj Flutter aplikacija moguće je koristiti razvojna okruženja Android Studio, IntelliJ

Idea ili Visual Studio Code te svi imaju odličnu podršku. Uz sve to, Flutter ima odlične

alate komandne linije te je moguće razvijati aplikacija u tekstualnom editoru te je

izgrađivati koristeći alate komandne linije. Još neki od razvojnih alata koji pomažu u

svakodnevnom razvoju su Flutter Inspector koji omogućuje pregledavanje stabla Widget-a

te Dart DevTools koji omogućavaju pregledavanje izvještaja performansi aplikacije i

debugiranje.

Ja sam za potrebe ovog rada koristio Android Studio razvojnu okolinu te iOS simulator i

Android emulator i funkcioniralo je odlično.

Slika 2.4 Android Studio razvojno okruženje

Page 18: Razvoj višeplatformskih mobilnih aplikacija …2 1. Višeplatformski razvoj mobilnih aplikacija Mobilne aplikacije nisu prve koje koriste višeplatformski razvoj. Prenosivost programa

14

3. Implementacija višeplatformske aplikacije

U sklopu ovog rada izrađena je višeplatformska mobilna aplikacija koja opisuje život

Nikole Tesle te gradove i lokacije povezane s njim. Aplikacija je razvijena korištenjem

radnog okvira Flutter te ju je moguće pokrenuti na Android i iOS mobilnim operacijskih

sustavima. Na sljedećoj slici (Slika 3.1) vidljiv je izgled implementirane aplikacije.

Slika 3.1 Izgled implementirane aplikacije

Page 19: Razvoj višeplatformskih mobilnih aplikacija …2 1. Višeplatformski razvoj mobilnih aplikacija Mobilne aplikacije nisu prve koje koriste višeplatformski razvoj. Prenosivost programa

15

Implementirana aplikacija sastoji se od četiri glavna ekrana:

1. Uvodni ekran

2. Ekran liste gradova

3. Ekran s kartom lokacija

4. Ekran s detaljima lokacije

Uvodni ekran sadrži nekoliko stranica koje uvode korisnika u aplikaciju te opisuju kako se

aplikacija koristi te koje dijelove sadrži. Nakon uvoda dolazi ekran s listom gradova koji

prikazuje važne gradove u životu Nikole Tesla te njihov kratki opis. Ako prikazani grad

sadrži lokacije povezane s Nikolom Teslom, moguće je otvoriti ekran s kartom lokacija tog

grada. Na tom ekranu su na karti označene sve lokacije tog grada povezane s Nikolom

Teslom te njihove adrese. Za svaku lokaciju moguće je otvoriti ekran s detaljima lokacije

koji prikazuje detaljnije informacije o toj lokaciji kao što su ime lokacije, adresa, slika

lokacije te poglavlja teksta o toj lokaciji koja mogu sadržavati niz slika. Grafički dizajn

aplikacije, sustav za unošenje podataka te sučelje za dohvat podataka su bili zadani te se

neće obrađivati u ovom radu.

import 'package:flutter/material.dart';

import 'package:tesla_app/shared/colors.dart';

import 'package:tesla_app/shared/strings.dart';

import

'package:tesla_app/ui/onboarding/onboarding_screen.dart';

void main() => runApp(TeslaApp());

class TeslaApp extends StatelessWidget {

@override

Widget build(BuildContext context) {

return MaterialApp(

title: Strings.appName,

theme: ThemeData(fontFamily: 'Montserrat',

primaryColor: AppColors.colorPrimary),

home: OnboardingScreen(),

);

}

}

Kôd 3.1 – Kôd ulaznog dijela aplikacije – main.dart

Page 20: Razvoj višeplatformskih mobilnih aplikacija …2 1. Višeplatformski razvoj mobilnih aplikacija Mobilne aplikacije nisu prve koje koriste višeplatformski razvoj. Prenosivost programa

16

Svaka Flutter aplikacija mora imati ulaznu točku kao što je prikazano u prethodnom kôdu

(Kôd 3.1). Svaka aplikacija je zapravo Widget komponenta. U Flutteru postoji nekoliko

već definiranih komponenti ta Widget aplikacije, a u ovom slučaju se koristi MaterialApp

pošto je aplikacija dizajnirana po uzoru na materijalni dizajn. Widget aplikacije utječe na to

kako će izgledati i ponašati se Widget komponente unutar aplikacije. MaterialApp

komponenta sadrži brojne parametre koji omogućuju promjenu raznih vrsta ponašanja

aplikacije, no u ovom slučaju se koristi samo nekoliko osnovnih. title predstavlja

naslov aplikacije koji će biti vidljiv u operacijskom sustavu. theme definira vizualnu temu

aplikacije pomoću parametara za izgled boja, teksta, pozadina i sličnih parametara. home

parametar aplikacije označava koji ekran će biti početni ekran aplikacije, a to je u ovom

slučaju uvodni ekran (OnboardingScreen).

Strings i AppColors su primjer programskih razreda koje sadržavaju neku vrstu

resursa. Moguće je i resurse kao što su boje i tekstovi koristiti izravno, no to nije dobra

praksa jer ako npr. promijenimo neku boju, bit će potrebno mijenjati boju na mnogim

mjestima. No, ako resurse pobrojimo u posebnom programskom razredu i onda koristimo

te definirane resurse umjesto izravnog korištenja, promjenu ćemo moći napraviti samo na

jednom mjestu i utjecati na sva mjesta koja koriste taj resurs. Također, na ovaj način je

lako moguće zamijeniti skup resursa, npr. u slučaju promjene jezika zamijeniti tekstove ili

u slučaju promjene teme zamijeniti boje – samo je potrebno promijeniti korišteni

programski razred s resursima. Primjer jednog takvog jednostavnog razreda vidljiv je u

nastavku (Kôd 3.1).

import 'dart:ui';

class AppColors {

static Color colorPrimary = Color(0xFF29476C);

}

Kôd 3.2 – Programski razred resursa za boje

Page 21: Razvoj višeplatformskih mobilnih aplikacija …2 1. Višeplatformski razvoj mobilnih aplikacija Mobilne aplikacije nisu prve koje koriste višeplatformski razvoj. Prenosivost programa

17

3.1. Implementacija uvodnog ekrana

Uvodni ekran je ekran koji se otvara kada korisnik prvi puta otvori aplikaciju. Ekran se

sastoji od 3 stranice koje uvode korisnika u aplikaciju te objašnjavaju kako koristiti

aplikaciju te što ona sve omogućuje.

Slika 3.2 Izgled uvodnog ekrana aplikacije

Glavni dio svake stranice uvodnog ekrana su naslov stranice, opis stranice koji objašnjava

kako koristiti aplikaciju te slika koja ilustrira kako izgledaju glavni dijelovi aplikacije.

Osim toga, u gornjem desnom uglu nalazi se gumb za preskakanje koji preskače sve

stranice uvodnog ekrana i izravno ulazi u glavni dio aplikacije. Taj gumb je tu za slučaj da

korisnik ne želi gledati uvodni dio aplikacije. Na dnu uvodnog ekrana nalazi se gumb za

nastavak na sljedeću stranicu uvodnog ekrana. Izmjena stranica uvodnog ekrana također je

moguća povlačenjem prsta preko ekrana u lijevu (sljedeći ekran) ili desnu stranu

(prethodni ekran). Na zadnjoj stranici uvodnog ekrana gumb za nastavak na sljedeću

stranicu postaje gumb za ulazak u glavni dio aplikacije kojim korisnik zatvara uvodni

ekran i otvara prvi ekran glavnog dijela aplikacije, a to je ekran liste gradova.

Page 22: Razvoj višeplatformskih mobilnih aplikacija …2 1. Višeplatformski razvoj mobilnih aplikacija Mobilne aplikacije nisu prve koje koriste višeplatformski razvoj. Prenosivost programa

18

U duhu objektno-orijentiranog programiranja, dobra je praksa modelirati podatke u

programske razrede. Stoga je i u ovom primjeru stranica uvodnog ekrana modelirana s

programskim razredom koji sadrži podatke o slici, naslovu i opisu stranice. Taj razred se

može vidjeti u Kôdu 3.3.

class OnboardingPage {

final String imagePath;

final String title;

final String description;

OnboardingPage(this.imagePath, this.title,

this.description);

}

Kôd 3.3 – Model stranice uvodnog ekrana

Slično kao i u slučaju Widget-a aplikacije, ekran je također samo još jedan Widget koji se

sastoji od jednostavnijih Widget-a koji sačinjavaju komponente tog ekrana. Prema tome,

potrebno je definirati Widget komponentu koja će predstavljati uvodni ekran. Definicija

uvodnog ekrana prikazana je u sljedećem isječku kôda (Kôd 3.4).

import 'package:flutter/material.dart';

import 'package:flutter_svg/svg.dart';

import 'package:tesla_app/model/onboarding_page.dart';

import 'package:tesla_app/shared/colors.dart';

import 'package:tesla_app/shared/strings.dart';

import 'package:tesla_app/ui/cities/cities_screen.dart';

class OnboardingScreen extends StatelessWidget {

@override

Widget build(BuildContext context) {

}

}

Kôd 3.4 – Widget uvodnog ekrana

Page 23: Razvoj višeplatformskih mobilnih aplikacija …2 1. Višeplatformski razvoj mobilnih aplikacija Mobilne aplikacije nisu prve koje koriste višeplatformski razvoj. Prenosivost programa

19

Pošto su u ovoj aplikaciji podaci stranice uvodnog ekrana statički, a ne dohvaćaju se

dinamički preko mrežnog poziva, njih je moguće definirati izravno u Widget-u ekrana na

sljedeći način:

class OnboardingScreen extends StatelessWidget {

final List<OnboardingPage> onboardingPages = [

OnboardingPage("assets/onboarding_01.svg", Strings.onboardingTitle1,

Strings.onboardingDescription1),

OnboardingPage("assets/onboarding_02.svg", Strings.onboardingTitle2,

Strings.onboardingDescription2),

OnboardingPage("assets/onboarding_03.svg", Strings.onboardingTitle3,

Strings.onboardingDescription3),

];

}

Kôd 3.5 – Definicija podataka uvodnih stranica

Osnovnu strukturu uvodnog ekrana moguće je dobiti sljedećim programskim kôdom:

final PageController pageController = PageController();

@override

Widget build(BuildContext context) {

return Scaffold(

backgroundColor: AppColors.grey,

body: SafeArea(

child: Stack(

children: <Widget>[

PageView.builder(

itemBuilder: (context, position) {

return buildOnboardingPage(context, position);

},

itemCount: onboardingPages.length,

controller: pageController,

),

buildSkipButton(context),

],

),

),

);

}

Kôd 3.6 – Osnovna struktura uvodnog ekrana

Page 24: Razvoj višeplatformskih mobilnih aplikacija …2 1. Višeplatformski razvoj mobilnih aplikacija Mobilne aplikacije nisu prve koje koriste višeplatformski razvoj. Prenosivost programa

20

Prvi element koje se koristi je Scaffold . To je komponenta koja se najčešće koristi kao

korijenska komponenta ekrana u Flutteru, a omogućava dodavanje nekih standardnih

komponenata mobilnih aplikacija kao što je navigacijska traka na vrhu aplikacije. Sljedeći

Widget koji se koristi je SafeArea koji se isto često koristi kao korijenski element i služi

da ograniči prostor za iscrtavanje tako da izbaci neželjeni prostor kao što su izrezi na

ekranu mobilnih uređaja, tako da se sve ostale komponente iscrtavaju ispod izreza, a ne

preko njega jer se dio aplikacije u tom slučaju ne bi vidio. Sljedeća komponenta je Stack

koji služi za iscrtavanje više komponenti jedne preko druge. To je u ovom slučaju

iskorišteno za iscrtavanje komponente za izmjenu stranica te iznad nje gumb za

preskakanje koji je prikazan preko stranica uvodnog ekrana i ne mijenja se sa stranicama.

Za izmjenu stranica iskorištena je komponenta PageView . Stranice uvodnog ekrana su

izgrađene pomoću buildOnboardingPage metode, dok je gumb za preskakanje

izgrađen pomoću buildSkipButton metode. U Flutteru je dobra praksa izdvajati

manje cjeline grafičkog sučelja u izdvojene metode, jer bi protivnom, ako bi sav kod bio u

jednoj velikoj cjelini, on postao vrlo nečitak. Također, ako se pojedini dijelovi grafičkog

sučelja izdvajaju u zasebne metode, moguće je ponovno iskoristiti tu metodu ako postoji

ista ili slična komponenta na tom ekranu, čime bi se spriječilo dupliciranje koda. Kod

metode za izgradnju stranice uvodnog ekrana prikazan je u nastavku:

Widget buildOnboardingPage(BuildContext context, int position) {

OnboardingPage onboardingPage = onboardingPages[position];

return Stack(children: <Widget>[

SvgPicture.asset(onboardingPage.imagePath, alignment:

Alignment.topCenter),

SizedBox.expand(

child: Column(

mainAxisAlignment: MainAxisAlignment.end,

crossAxisAlignment: CrossAxisAlignment.center,

children: <Widget>[

buildTitleText(onboardingPage),

buildDescriptionText(onboardingPage),

Container(margin: EdgeInsets.only(bottom: 24),

child: SizedBox(height: 40,

child: position != onboardingPages.length - 1 ?

buildNextButton() : buildGoButton(context),

))]))]);}

Kôd 3.7 – Metoda za izgradnju stranice uvodnog ekrana

Page 25: Razvoj višeplatformskih mobilnih aplikacija …2 1. Višeplatformski razvoj mobilnih aplikacija Mobilne aplikacije nisu prve koje koriste višeplatformski razvoj. Prenosivost programa

21

Iz prikazane metode vidljivo je da se koristi model stranice uvodnog ekrana da bi se dobili

podaci o stranici na pojedinoj poziciji. Također je vidljivo da se koriste razne komponente

kao Stack, SizedBox, Column i Container kako bi se ostale komponente

razmjestile unutar ekrana te definirala njihova veličina i pozicija. Za prikaz slika koristi se

komponenta SvgPicture iz programske knjižnice flutter_svg. To je programska

knjižnica za iscrtavanje vektorske grafike iz datoteka vektorske grafike tipa SVG, koje se

koriste za prikaz ikona i ilustracija jer za njihov prikaz zauzimaju manje memorijskog

prostora od bitmap slika i bolje skaliraju svoju veličinu. Također se koristi još nekoliko

build metoda kako bi se izgradile komponente za prikaz teksta naslova i opisa te gumbi za

nastavak i završetak. U nastavku je prikazana metoda za izgradnju gumba za završetak:

RaisedButton buildGoButton(BuildContext context) {

return RaisedButton(

child: Text(

Strings.goButton.toUpperCase(),

style: TextStyle(

fontFamily: 'MontserratAlternates', fontWeight:

FontWeight.bold, fontSize: 12, color: Colors.white),

),

onPressed: () => openCitiesScreen(context),

shape: new RoundedRectangleBorder(borderRadius: new

BorderRadius.circular(20.0)),

color: AppColors.colorAccent,

);

}

void openCitiesScreen(BuildContext context) {

Navigator.pushReplacement(context, MaterialPageRoute(builder:

(context) => CitiesScreen()));

}

Kôd 3.7 – Metoda za izgradnju gumba za završetak uvoda

U izgradnji gumba za završetak koriste se komponente kao što su RaisedButton i

Text koje su završne komponente koje će iscrtati komponente gumbi i teksta. Također,

koriste se parametri i komponente za stiliziranje gumba (promjena veličine teksta, boje…).

Pritiskom na gumb za završetak poziva se metoda openCitiesScreen koja koristeći

komponentu Navigator navigira na sljedeći ekran izbacujući ekran uvoda iz povijesti

ekrana kako se ne bi mogli na njega ponovno vratiti, jer se on prikazuje samo na početku.

Page 26: Razvoj višeplatformskih mobilnih aplikacija …2 1. Višeplatformski razvoj mobilnih aplikacija Mobilne aplikacije nisu prve koje koriste višeplatformski razvoj. Prenosivost programa

22

3.2. Implementacija ekrana liste gradova

Poslije uvodnog ekrana slijedi ekran liste gradova. Na tom ekranu su prikazani gradovi

povezani s Nikolom Teslom u nizu stranica tog ekrana. Stranice je moguć izmjenjivati

povlačenjem prsta preko ekrana u lijevu (sljedeći grad) ili desnu stranu (prethodni grad).

Glavni dijelovi stranica grada su slika koja predstavlja veličinu i važnost grada, naziv

grada te opis poveznice tog grada s Nikolom Teslom. Ako prikazani grad posjeduje

lokacije povezane s Nikolom Teslom, na stranici tog grada bit će vidljiv gumb za pregled

tih lokacija. Izgled ekrana liste gradova može se vidjeti na sljedećoj slici:

Slika 3.3 Izgled ekrana liste gradova

Page 27: Razvoj višeplatformskih mobilnih aplikacija …2 1. Višeplatformski razvoj mobilnih aplikacija Mobilne aplikacije nisu prve koje koriste višeplatformski razvoj. Prenosivost programa

23

Na ovom ekranu ćemo također modelirati podatke grada u programski razred. Jedna

razlika u odnosu na uvodni ekran je ta da će na ovom ekranu podaci stizati dinamički preko

mrežnog poziva. Zbog toga je važno da taj model posjeduje metodu za deserijalizaciju, jer

će podaci stići serijalizirani u JSON formatu. Stoga će model grada biti modeliran na

sljedeći način:

class City {

final String id;

final String name;

final String description;

final bool hasData;

final int size;

final int position;

City(this.id, this.name, this.description, this.hasData, this.size,

this.position);

City.fromJson(Map<String, dynamic> json)

: id = json["id"],

name = json["name"],

description = json["description"],

hasData = json["hasData"],

size = int.parse(json["size"]),

position = int.parse(json["position"]);

}

Kôd 3.8 – Model grada s metodom za deserijalizaciju

import 'dart:convert';

import 'package:http/http.dart' as http;

import 'package:tesla_app/model/city.dart';

final String baseUrl = "https://teslaapp-31457.firebaseio.com";

Future<List<City>> fetchCities() async {

final response = await http.get("$baseUrl/persons/Tesla/cities.json");

if (response.statusCode == 200) {

Map<String, dynamic> responseMap = json.decode(response.body);

List<City> cities = responseMap.values.map((json) =>

City.fromJson(json)).toList();

Page 28: Razvoj višeplatformskih mobilnih aplikacija …2 1. Višeplatformski razvoj mobilnih aplikacija Mobilne aplikacije nisu prve koje koriste višeplatformski razvoj. Prenosivost programa

24

cities.sort((a, b) => a.position.compareTo(b.position));

return cities;

} else {

throw Exception('Failed to load cities');

}

}

Kôd 3.9 – Dohvat gradova preko mrežnog poziva

U gornjem kodu (Kôd 3.9) nalazi se isječak koda za dohvat gradova preko mrežnog

poziva. U tu svrhu koristimo knjižnice dart:http za rađenje mrežnog poziva koristeći

protokol HTTP te dart:convert za pretvaranje teksta u JSON formatu u dinamički

objekt. U isječku koda također je definiran bazni URI sučelja za dohvat podataka te put do

podataka o gradovima u JSON formatu. Zbog specifičnog oblika u kojem su podaci

pohranjeni na poslužitelju, potrebno je napraviti mapiranje i sortiranje dobivene liste

gradova. Na posljetku, ako je došlo do greške metoda baca iznimku, a ako je sve prošlo u

redu, metoda vraća listu gradova. Također, pošto mrežni poziv traje dosta vremena, metoda

za dohvat mora biti asinkrona (async) kako ne bi blokirala dretvu i grafičko sučelje dok

mrežni poziv ne završi.

class CitiesScreen extends StatelessWidget {

@override

Widget build(BuildContext context) {

return Scaffold(

backgroundColor: AppColors.colorPrimary,

body: SafeArea(

child: FutureBuilder<List<City>>(

future: apiService.fetchCities(),

builder: (context, snapshot) {

if (snapshot.hasData) {

List<City> cities = snapshot.data;

return buildCityPages(cities);

}

return Center(child: CircularProgressIndicator());

})),

);

}

Kôd 3.10 – Osnovna struktura ekrana liste gradova

Page 29: Razvoj višeplatformskih mobilnih aplikacija …2 1. Višeplatformski razvoj mobilnih aplikacija Mobilne aplikacije nisu prve koje koriste višeplatformski razvoj. Prenosivost programa

25

Pošto je metoda za dohvat gradova asinkrona, nije moguće koristiti Widget-e na standardan

način kao u slučaju statičke liste podataka. Jedno od rješenja za asinkrone metode je

korištenje FutureBuilder Widget-a. On kao jedan od parametara prima asinkronu

metodu (future) te definira kako će se sučelje izgraditi u slučaju da nema podataka i u

slučaju da su podaci stigli. U ovom slučaju, ako ima podataka uzima se lista gradova i iz

nje se rade stranice gradova, a u slučaju da nema podataka prikazuje se komponenta

pokazatelja učitavanja CircularProgressIndicator koja je centrirana preko

cijelog ekrana.

Stack buildCityPages(List<City> cities) {

return Stack(children: <Widget>[

PageIndicatorContainer(

length: cities.length,

shape: IndicatorShape.circle(size: 6),

indicatorSpace: 4,

indicatorSelectorColor: Colors.white,

indicatorColor: Colors.grey,

pageView: PageView.builder(

itemBuilder: (context, position) {

return buildCitiesPage(context, cities[position], position);

},

itemCount: cities.length,

controller: pageController,

),

),

]);

}

Kôd 3.11 – Metoda za izgradnju stranica gradova

Metoda za izgradnju stranica gradova slična je metodi izgradnje stranica uvodnog ekrana,

no glavna razlika je da stranice gradova imaju kružne pokazatelje broja stranice na kojoj se

korisnik nalazi. To je postignuto korištenjem komponente PageIndicatorContainer

iz vanjske programske knjižnice page_indicator. Također, kao i uvodni ekran, ekran

liste gradova prikazuje slike korištenjem vanjske programske knjižnice flutter_svg .

Page 30: Razvoj višeplatformskih mobilnih aplikacija …2 1. Višeplatformski razvoj mobilnih aplikacija Mobilne aplikacije nisu prve koje koriste višeplatformski razvoj. Prenosivost programa

26

String getImagePath(City city, int position) {

if (position == 0) {

if (city.hasData) {

return "assets/cities/first_city_with_locations.svg";

} else {

return "assets/cities/first_city_no_locations.svg";

}

} else {

if (city.hasData) {

if (city.size <= 1) {

return "assets/cities/small_city_with_locations.svg";

} else if (city.size == 2) {

return "assets/cities/medium_city_with_locations.svg";

} else {

return "assets/cities/large_city_with_locations.svg";

}

} else {

if (city.size <= 1) {

return "assets/cities/small_city_no_locations.svg";

} else if (city.size == 2) {

return "assets/cities/medium_city_no_locations.svg";

} else {

return "assets/cities/large_city_no_locations.svg";

}

}

}

}

Kôd 3.12 – Metoda za odabir slike grada

Za razliku od uvodnog ekrana koji ima 3 statički definirane slike s poznatim redoslijedom,

ekran liste gradova podatke dobiva dinamički preko mrežnog poziva te mora na temelju

podataka grada dinamički odrediti koju sliku upotrijebiti za taj grad u ovisnosti o veličini

grada, lokacijama grada te pozicijom grada unutar liste gradova.

Page 31: Razvoj višeplatformskih mobilnih aplikacija …2 1. Višeplatformski razvoj mobilnih aplikacija Mobilne aplikacije nisu prve koje koriste višeplatformski razvoj. Prenosivost programa

27

3.3. Implementacija ekrana s kartom lokacija

Ako neki grad sadrži lokacije povezane s Nikolom Teslom, korisniku će za taj grad biti

prikazan gumb za pregled lokacija koji otvara ekran s kartom lokacija. Ovaj ekran

prikazuje kartu grada s označenim lokacijama povezanim s Nikolom Teslom. Za prikaz

karata koristi se usluga Google Maps. Osim karte s označenim lokacijama, na dnu ekrana

je prikazana kartica s osnovnim podacima trenutno odabrane lokacije. Kartice je također

moguće izmjenjivati povlačenjem prsta preko ekrana u lijevu (sljedeća lokacija) ili desnu

stranu (prethodni lokacija). Isto tako je moguće odabrati oznaku lokacije na karti da bi se

prikazala kartica te lokacije. Na karticama lokacije je prikazano ime lokacije, njena adresa

te gumb za otvaranje detalja te lokacije.

Slika 3.4 Izgled ekrana s kartom lokacija

Page 32: Razvoj višeplatformskih mobilnih aplikacija …2 1. Višeplatformski razvoj mobilnih aplikacija Mobilne aplikacije nisu prve koje koriste višeplatformski razvoj. Prenosivost programa

28

Ekran s kartom lokacije, kao i ekran s listom gradova, dobiva podatke dinamički preko

mrežnog poziva. Prema tome, na isti način je potrebno definirati programski razred modela

s definiranom metodom za deserijalizaciju te kôd za dohvaćanje podataka putem mreže.

class Location {

final String id;

final String name;

final String address;

final String city;

final String type;

final double latitude;

final double longitude;

final String mainImage;

Location(this.id, this.name, this.address, this.city, this.type,

this.latitude, this.longitude, this.mainImage);

Location.fromJson(Map<String, dynamic> json)

: id = json["id"],

name = json["name"],

address = json["address"],

city = json["city"],

type = json["type"],

latitude = json["latitude"],

longitude = json["longitude"],

mainImage = json["mainImage"];}

Future<List<Location>> fetchLocationsForCity(String cityId) async {

final response = await

http.get("$baseUrl/persons/Tesla/locations/$cityId.json");

if (response.statusCode == 200) {

Map<String, dynamic> responseMap = json.decode(response.body);

List<Location> locations = responseMap.values.map((json) =>

Location.fromJson(json)).toList();

return locations;

} else {

throw Exception('Failed to load locations');

}

}

Kôd 3.13 – Model lokacije i dohvat preko mreže

Page 33: Razvoj višeplatformskih mobilnih aplikacija …2 1. Višeplatformski razvoj mobilnih aplikacija Mobilne aplikacije nisu prve koje koriste višeplatformski razvoj. Prenosivost programa

29

Isto kao i kod ekrana liste gradova, koristi se FutureBuilder kako bi se riješio problem

asinkrone funkcije dohvata podataka putem mreže te se isto koristi vanjska programska

knjižnica page_indicator u kombinaciji s komponentom PageView kako bi se

ostvarila mogućnost promjene kartica. Jedna novost na ovom ekranu je to što na njemu

prosljeđujemo model objekt grada s prethodnog ekrana liste gradova. To se jednostavno

postiže tako da se u razredu ekrana s kartom lokacija definira članska varijabla grada te

konstruktor koji prima model objekt grada i postavlja vrijednost članske varijable grada.

class LocationsScreen extends StatelessWidget {

final City city;

LocationsScreen({Key key, @required this.city}) : super(key: key);

@override

Widget build(BuildContext context) {

return Scaffold(

appBar: AppBar(

title: Text(city.name, style: TextStyle(fontFamily:

'MontserratAlternates', color: Colors.white)),

),

body: SafeArea(

bottom: false,

child: FutureBuilder<List<Location>>(

future: apiService.fetchLocationsForCity(city.id),

builder: (futureContext, snapshot) {

if (snapshot.hasData && snapshot.data.isNotEmpty) {

List<Location> locations = snapshot.data;

return _buildLocationsScreen(context, locations);

}

return Center(child: CircularProgressIndicator());

}),

),

);

}

Kôd 3.14 – Osnovna struktura ekrana s kartom lokacija

Page 34: Razvoj višeplatformskih mobilnih aplikacija …2 1. Višeplatformski razvoj mobilnih aplikacija Mobilne aplikacije nisu prve koje koriste višeplatformski razvoj. Prenosivost programa

30

Najveća novost na ekranu s kartom lokacija je korištenje vanjske programske knjižnice

google_maps_flutter kako bi se prikazala karta grada koristeći uslugu Google

Maps. Ta knjižnica sadrži Widget GoogleMap kojeg je uz definiranje nekoliko

parametara vrlo jednostavno ubaciti u stablo komponenti ekrana. Definirani su parametri

za početnu lokaciju, postavke povećanja karte, isključivanje 3D funkcionalnosti,

postavljanje oznaka lokacija te postavljanje kontrolora (GoogleMapController) za

kasnije upravljanje kartama.

GoogleMap buildMapView(Location firstLocation, List<Location>

locations) {

return GoogleMap(

minMaxZoomPreference: MinMaxZoomPreference(14.0, 18.0),

initialCameraPosition:

CameraPosition(target: LatLng(firstLocation.latitude,

firstLocation.longitude), zoom: 15.0),

myLocationButtonEnabled: false,

rotateGesturesEnabled: false,

tiltGesturesEnabled: false,

myLocationEnabled: true,

onMapCreated: (GoogleMapController controller) {

_mapsController.complete(controller);

},

markers: locations

.map((location) => Marker(

markerId: MarkerId(location.id),

position: LatLng(location.latitude, location.longitude),

onTap: () =>

pageController.jumpToPage(locations.indexOf(location)),

))

.toSet(),

);

}

GoogleMapController controller = await _mapsController.future;

Location location = locations[position];

CameraPosition cameraPosition =

CameraPosition(target:LatLng(location.latitude, location.longitude));

controller.animateCamera(CameraUpdate.newCameraPosition(cameraPosition));

Kôd 3.15 – Korištenje GoogleMap widgeta

Page 35: Razvoj višeplatformskih mobilnih aplikacija …2 1. Višeplatformski razvoj mobilnih aplikacija Mobilne aplikacije nisu prve koje koriste višeplatformski razvoj. Prenosivost programa

31

3.4. Implementacija ekrana s detaljima lokacije

Svaka kartica lokacije sadrži gumb za pregled detalja lokacije. Ako korisnik pritisne taj

gumb, otvara se ekran s detaljima lokacije. Na ekranu s detaljima lokacije u gornjem dijelu

ekrana nalazi se velika slika lokacije na kojoj se nalaze naziv lokacije, adresa lokacije te

tekstualne oznake vezane za lokaciju (iz kojeg grada dolazi, na koju poznatu osobu je

vezana i kojeg je tipa lokacije). Ispod slike lokacije nalazi se lista od jednog ili više

poglavlja opisa lokacije. Svako poglavlje opisa lokacije ima svoj naslov, tekst te može ili

ne mora imati jednu ili više slika. Ako postoji više slika na jednom poglavlju, slike su

horizontalno poredane jedna do druge te se mogu pomicati (engl. scroll) lijevo i desno.

Poglavlja se prikazuju jedno ispod drugog i ako ih ima više nego što se može prikazati na

ekranu, ekran se može pomicati gore i dolje. Također, u gornjem desnom uglu ekrana

nalaze se gumbi za podijeliti lokaciju preko društvenih mreža (engl. share) te za otvoriti

lokaciju u vanjskoj aplikaciji specijaliziranoj za prikaz karata i navigaciju (npr. Google

Maps ili Apple Maps). S gornje lijeve strane nalazi se gumb za izlazak s ekrana detalja

lokacije i povratak na ekran s kartom lokacija.

Slika 3.5 Izgled ekrana s detaljima lokacije

Page 36: Razvoj višeplatformskih mobilnih aplikacija …2 1. Višeplatformski razvoj mobilnih aplikacija Mobilne aplikacije nisu prve koje koriste višeplatformski razvoj. Prenosivost programa

32

Ekran s detaljima lokacije dinamički dohvaća podatke o poglavljima preko mreže na isti

način kao i prethodni ekrani. Posebnost ovog ekrana je korištenje vanjskih biblioteka za

dijeljenje podataka preko društvenih mreža te za otvaranje vanjske aplikacije

specijalizirane za karte i navigaciju. Za dijeljenje podataka preko društvenih mreža koristi

se vanjska programska knjižnica share, dok se za pokretanje vanjskih aplikacija koristi

programska knjižnica url_launcher.

IconButton(

icon: Icon(

Icons.share,

color: Colors.white,

),

onPressed: () => Share.share("Check out ${location.name}.

It's located at ${location.address}"),

)

IconButton(

icon: Icon(

Icons.directions,

color: Colors.white,

),

onPressed: launchDirectionsUrl,

)

launchDirectionsUrl() async {

String googleUrl =

'https://www.google.com/maps/dir/?api=1${location.latitude},${location.lo

ngitude}';

String appleUrl =

'https://maps.apple.com/?sll=${location.latitude},${location.longitude}';

if (await canLaunch("comgooglemaps://")) {

print('launching com googleUrl');

await launch(googleUrl);

} else if (await canLaunch(appleUrl)) {

print('launching apple url');

await launch(appleUrl);

} else {

throw 'Could not launch url';

}}

Kôd 3.16 – Korištenje programskih knjižnica share i url_launcher

Page 37: Razvoj višeplatformskih mobilnih aplikacija …2 1. Višeplatformski razvoj mobilnih aplikacija Mobilne aplikacije nisu prve koje koriste višeplatformski razvoj. Prenosivost programa

33

Zaključak

Iako je još relativno mlad radni okvir, Flutter je na mene ostavio jako dobar dojam. Najviše

mi se svidjela lakoća razvoja aplikacija. Tu lakoću razvoja omogućuju odlični razvojni

alati te odličan dizajn samog radnog okvira. Uz sve to, iz istog koda se može napraviti i

Android i iOS aplikacija, što znatno smanjuje trud potreban za razvitak aplikacije za obje

mobilne platforme. Također, pošto je to ista aplikacija, nema problema s različitom

implementacijom i nekonzistentnostima između Androida i iOS-a, uz poštivanje potrebnih

razlika između platformi. Osim toga, aktivno se radi i na podršci za nove platforme kao što

su desktop ili web i Googleov novi operacijski sustav Fuchsia. Flutter također ima odličnu

podršku zajednice, kako od Flutter razvojnog tima iz Googlea tako i iz vanjske zajednice

programera iz cijelog svijeta. No, iako je zajednica donijela dosta vanjskih programskih

knjižnica i komponente, ipak još neke stvari fale ili nisu do kraja implementirane. Ali,

vjerujem da je to zbog toga što je okvir još uvijek mlad i mislim da će se s vremenom

situacija samo poboljšavati. Moje mišljenje je da će Flutter kroz nekoliko godina postati

respektabilan način za razvoj višeplatformskih mobilnih i drugih aplikacija.

Page 38: Razvoj višeplatformskih mobilnih aplikacija …2 1. Višeplatformski razvoj mobilnih aplikacija Mobilne aplikacije nisu prve koje koriste višeplatformski razvoj. Prenosivost programa

34

Literatura

[1] FLUTTER, Flutter, https://flutter.dev/ , 20.06.2019.

[2] FLUTTER, Flutter Documentation, https://flutter.dev/docs , 20.06.2019. [3] HACKERNOON, Why Flutter uses Dart,

https://hackernoon.com/why-flutter-uses-dart-dd635a054ebf, 20.06.2019. [4] GITHUB, The Engine architecture,

https://github.com/flutter/flutter/wiki/The-Engine-architecture , 20.06.2019. [5] MEDIUM, Multi vs Cross Platform in the age of Flutter,

https://medium.com/snapp-mobile/multi-vs-cross-platform-in-the-age-of-flutter-6e76920028b6 , 20.06.2019.

[6] HACKERNOON, What’s Revolutionary about Flutter, https://hackernoon.com/whats-revolutionary-about-flutter-946915b09514 , 20.06.2019.

[7] FLUTTER, Introduction to widgets, https://flutter.dev/docs/development/ui/widgets-intro , 20.06.2019.

[8] FLUTTER, Tools & techniques, https://flutter.dev/docs/development/tools , 20.06.2019.

Page 39: Razvoj višeplatformskih mobilnih aplikacija …2 1. Višeplatformski razvoj mobilnih aplikacija Mobilne aplikacije nisu prve koje koriste višeplatformski razvoj. Prenosivost programa

35

Sažetak

Razvoj višeplatformskih mobilnih aplikacija korištenjem radnog okvira Flutter

Ovaj rad istražuje radni okvir Flutter za razvoj višeplatformskih mobilnih aplikacija koje se

mogu koristiti na više različitih mobilnih operacijskih sustava. Također, u sklopu rada je

osmišljena, razvijena i testirana višeplatformska mobilna aplikacija za mobilne operacijske

sustave Android i iOS koristeći navedeni radni okvir Flutter.

Ključne riječi: višeplatformski razvoj, mobilna aplikacija, Flutter, Android, iOS, Dart

Page 40: Razvoj višeplatformskih mobilnih aplikacija …2 1. Višeplatformski razvoj mobilnih aplikacija Mobilne aplikacije nisu prve koje koriste višeplatformski razvoj. Prenosivost programa

36

Summary

Cross-platform mobile application development using the Flutter framework

This thesis explores the Flutter framework for development of cross-platform mobile

applications that can be used on multiple mobile operating systems. Also, as a part of the

thesis, a cross-platform mobile application for mobile operating systems Android and iOS

is designed, developed and tested using the Flutter framework.

Keywords: cross-platform development, mobile application, Flutter, Android, iOS, Dart

Page 41: Razvoj višeplatformskih mobilnih aplikacija …2 1. Višeplatformski razvoj mobilnih aplikacija Mobilne aplikacije nisu prve koje koriste višeplatformski razvoj. Prenosivost programa

37

Skraćenice

HTML Hypertext Markup Language Hipertekst označni jezik AOT Ahead Of Time Prije vremena

JIT Just In Time Pravovremeno XML eXtensible Markup Language Proširivi označni jezik

fps frames per second Okviri u sekundi HTTP Hypertext Transfer Protocol Protokol prijenosa hiperteksta

SVG Scalable Vector Graphic Skalabilna vektorska grafika JSON JavaScript Object Notation JavaScript notacija objekta

URL Uniform Resource Locator Jedinstveni lokator resursa

Page 42: Razvoj višeplatformskih mobilnih aplikacija …2 1. Višeplatformski razvoj mobilnih aplikacija Mobilne aplikacije nisu prve koje koriste višeplatformski razvoj. Prenosivost programa

38

Privitak

Instalacija programske podrške

Da bi se instalirali razvojni alati potrebni za razvoj Flutter aplikacije, potrebno je posjetiti

web-stranicu s adresom https://flutter.dev/docs/get-started/install i slijediti upute za

instalaciju potrebnih alata.

Prvo je potrebno instalirati Flutter SDK. Zatim je u komandnoj liniji potrebno pokrenuti

naredbu flutter doctor koja će nas obavijestiti o razvojnim alatima koji nedostaju.

Zatim je potrebno instalirati Android i iOS razvojne okoline ovisno o tome za koju

platformu želimo razvijati aplikaciju i na kojoj platformi želimo testirati aplikaciju. Na

poslijetku, potrebno je instalirati razvojno okruženje Android Studio / IntelliJ Idea ili

Visual Studio Code.

Nakon instalacije razvojnog okruženja i ostalih razvojnih alata spremni smo za pokretanje

aplikacije. Prvi je potrebno postaviti programski kod na odgovarajuće mjesto unutar

projekta otvorenog u razvojnoj okolini. Zatim je potrebno slijediti upute s web-stranice na

adresi https://flutter.dev/docs/get-started/test-drive?tab=vscode za pokretanje aplikacije.