Uvod u oblikovanje korisničkog sučelja

  • Objavljeno u Novosti
image

Nakon što smo u prošlom nastavku napravili uvod u najvažnije karakteristike programskog jezika Dart, danas ćemo započeti s uvodom u drugi dio kompleta potrebnog za razvoj mobilnih aplikacija, a to je Flutter. O tome što vam je sve potrebno za razvoj mobilnih aplikacija u navedenim tehnologijama pisali smo prije dva broja, a sad samo ponavljamo najvažnije. Za razvoj mobilnih Android aplikacija na Windows računalu morate imati instalirano razvojno okruženje Android Studio (u trenutku pisanja teksta verzija 3.2.1) s instaliranom dodatnom podrškom za Dart/Flutter projekte. Testiranje vlastitih aplikacija možete izvoditi u emulatoru ili na pravom mobilnom uređaju spojenom na Windows računalo preko USB kabela. O svemu navedenom možete detaljnije pročitati u prije spomenutom broju časopisa.

Spomenimo još samo na kraju uvodnog dijela kako ćemo sve buduće primjere izvoditi pomoću emulatora u virtualnom uređaju s karakteristikama navedenim na pratećoj slici uz tekst (rezolucija 720 x 1280, target: Android 9.0, API: 28). To nikako ne znači kako primjere ne možete izvoditi i na virtualnom (ili pravom mobilnom) uređaju drugačijih karakteristika, ali ako nešto zapne u primjerima iz teksta, onda prvo probajte pokrenuti primjer na preporučenom virtualnom uređaju.

U prvom nastavku priče o Flutteru pozabavit ćemo se korištenjem unaprijed definiranih „malih aplikacija“ (Widgeta) u oblikovanju korisničkog sučelja vlastite aplikacije. Kao prvi korak u tom postupku treba pripremiti odgovarajući projekt u Android Studiju (početna opcija u dijaloškom okviru Start a new Flutter project). U prvom sljedećem dijaloškom okviru u nastavku istog postupka trebate upisati osnovne karakteristike projekta poput njegova naziva, mjesta za spremanje na disku i opisa. Najvažnije je da pravilno definirate vezu prema sistemskom modulu Flutter SDK path jer bez toga projekt jednostavno neće biti upotrebljiv. Primjer popunjavanja početnog dijaloškog okvira prikazan je na pratećoj slici uz tekst.

Na drugom dijaloškom prozoru u nastavku pripreme novog projekta također izaberite Company Domain (kao primjer je upisan vidi.example.com), dok podršku za programske jezike Kotlin ili Swift trebate uključiti samo ako tijekom rada na mobilnoj aplikaciji (Android ili iOS) planirate koristiti i njihove mogućnosti.

Prethodnim korakom dovršena je priprema novog projekta s ugrađenom podrškom za Dart/Flutter. Automatski je pripremljen i osnovni programski kod jednostavne aplikacije te učitan u razvojnu okolinu. Zasada ćemo ga ignorirati i krenuti od vlastitih primjera. Drugim riječima, sve što se automatski pojavilo u datoteci main.dart nakon pripreme projekta, možete obrisati, jer sve pišemo ispočetka.

Budući da u okviru ovog serijala nemamo predviđen prostor za detaljnije upoznavanje sa samom razvojnom okolinom Android Studija, taj ćete dio morati odraditi sami. Za to možete koristiti neki od odgovarajućih vodiča dostupnih na webu ili u samoj razvojnoj okolini izaberite opciju Help > Android Studio Help. Ako to niste nikad radili, predlažemo da na samom početku serijala proučite i dio koji se odnosi na pripreme vlastitog virtualnog uređaja namijenjenog izvođenju aplikacija u emulatoru, odnosno postupka kako se koristi za testiranje vlastitih aplikacija. Bez korištenja virtualnog uređaja jedini smisleni način za razvoj vlastitih mobilnih aplikacija je stalna povezanost pravog mobilnog uređaja na računalo, što nije uvijek baš i najpraktičnije rješenje.

Krenimo sad konačno s objašnjavanjem korištenja Fluttera u oblikovanju korisničkog sučelja mobilne aplikacije. Minimalni primjer Flutter aplikacije (klasični Hello world primjer), koji možete upisati umjesto početno pripremljenog koda u razvojnoj okolini, ima sljedeći oblik:

import ‘package:flutter/material.dart’;

void main() {

  runApp(

    Center(

      child: Text(

        ‘Hello, world!’,

        textDirection: TextDirection.ltr,

      ),

    ),

  );

}

Rezultat izvođenja prethodnog programskog koda pomoću virtualnog uređaja u emulatoru je vrlo jednostavan te prikazuje osnovnu poruku u samom središtu zaslona. Međutim, već i takav osnovni primjer pokazuje osnovne karakteristike u korištenju „malih aplikacija“ ili, u originalnom nazivu, „widgeta“.

Na samom početku programa potrebno je u program uključiti dodatne pakete potrebne za izvođenje aplikacije. Budući da ćemo u ovom (i u sljedećim primjerima) koristiti različite vrste Flutter widgeta, moramo uključiti odgovarajući paket s njihovom implementacijom u Dartu (prva import linija programskog koda).

Izvođenje glavnog dijela programa započinje funkcijom main(), odnosno u okviru nje sljedećom funkcijom runApp. Funkcija runApp povezuje pripremljeno stablo widgeta preko njegova korijena sa samim zaslonom mobilnog uređaja (emuliranog ili pravog). U ovom slučaju čitavo stablo se sastoji od samo dva dijela - početnog Center te njegova potomka Text. Budući da korijenski dio stabla predstavlja upravo widget Center, a u primjeru nije primijenjeno nikakvo dodatno formatiranje u smislu odabira fonta boja i slično, prikazani tekst se tijekom izvođenja programa u svojem osnovnom obliku prikazuje u samom središtu zaslona. U slučaju drugog dijela sučelja (Text), napravljeno je osnovno formatiranje načina prikaza u smislu odabira smjera ispisa slijeva nadesno (TextDirection.ltr).

Probajte na ovom mjestu u programskom kodu osnovnog primjera obrisati dio naveden iza točke za prije spomenuti smjer ispisa teksta, nakon čega će razvojna okolina sama ponuditi moguće vrijednosti za odabir. Kod razvoja ozbiljnijih programa to povećava brzinu pisanja programskog koda uz istovremeno smanjivanje mogućnosti greške kod njegova pisanja. Također, da bi se programeru olakšalo snalaženje u složenim stablima koja reprezentiraju korisničko sučelje stvarne aplikacije, a takve su u pravilu sastavljene od velikog broja osnovnih dijelova, razvojna okolina brine automatski o pravilnom formatiranju svakog pojedinog dijela, odnosno označavanju njegova završetka. To se izvodi automatskim postavljanjem oznaka za kraj svakog widgeta - u ovom slučaju to su (// Text, // Center).

Idemo sada probati napraviti malo dodatnog formatiranja teksta kod njegova prikaza u smislu promjene boje, karakteristika pisma i slično. Izmijenjeni primjer bi nakon takvih dorada trebao imati oblik naveden u nastavku, dok rezultate izvođenja možete vidjeti na pratećoj slici uz tekst ili u emulatoru na vlastitom računalu (ako sami upisujete primjer).

import ‘package:flutter/material.dart’;

void main() {

  runApp(

    Center(

      child: Text(

        ‘Hello, world! Hello, world! Hello, world! Hello, world! Hello, world! Hello, world!’,

        textDirection: TextDirection.ltr,

        textAlign: TextAlign.center,

        overflow: TextOverflow.ellipsis,

        style: TextStyle(fontWeight: FontWeight.bold, color: Colors.lightGreen),

      ),

    ),

  );

}

Osnovni tekst poruke ponovili smo više puta zaredom kako bismo demonstrirali što će se dogoditi kada njezin sadržaj premašuje unaprijed rezervirano mjesto za prikaz. Očekivano - na kraju vidljivog dijela teksta prikazuju se tri točke.

Iako smo u odnosu na početni primjer u njegovu proširenom obliku dodali nekoliko novih mogućnosti u formatiranju teksta, i dalje smo zadržali početnu vrijednost koja određuje smjer ispisa teksta. Što bi se dogodilo kada bismo izostavili taj dio? Probajmo to napraviti pretvaranjem odgovarajućeg retka programskog koda u komentar. Nešto kao:

//        textDirection: TextDirection.ltr,

Posljedica prethodne promjene je, sasvim očekivano, greška kod prevođenja programskog koda te nemogućnost izvođenja aplikacije. Tijekom prevođenja sam uzrok greške je prilično detaljno objašnjen, pa ne biste trebali imati nedoumica u rješavanju problema:

...

I/flutter ( 2817): No Directionality widget found.

I/flutter ( 2817): RichText widgets require a Directionality widget ancestor.

I/flutter ( 2817): The specific widget that could not find a Directionality ancestor was:

...

Da bi sve skupa izgledalo još uočljivije, greška se prikazuje i u samom emulatoru. Ponovo smo je prikazali na odgovarajućoj slici priloženoj uz tekst. Drugim riječima, iako je korištenje widgeta tijekom razvoja vlastite aplikacije prilično fleksibilno, ponekad postoje obavezne stvari koje jednostavno morate navesti da bi sve skupa uopće proradilo.

U slučaju da mogućnosti osnovnog widgeta za prikaz teksta nisu dovoljne za prikaz podataka u vlastitoj aplikaciji, možete koristiti njegov unaprijeđeni oblik RichText. Pomoću njega se prikaz teksta može podijeliti na veći broj različito formatiranih dijelova. Na primjer, nešto kao:

import ‘package:flutter/material.dart’;

void main() {

  runApp(

    Center(

      child: RichText(

        textDirection: TextDirection.ltr,

        text: TextSpan(

          text: ‘Hello ‘,

          children: [

            TextSpan(text: ‘bold’, style: TextStyle(fontWeight: FontWeight.bold)),

            TextSpan(text: ‘ world!’),

          ],

        ),

      ),

    ),

  );

}

Od sljedećeg broja prelazimo na znatno ozbiljnije primjere u pogledu ukupne veličine programskog koda, pa ćemo ih zato redovito objavljivati kao priloge na mediju ili webu, kako ne biste nepotrebno gubili vrijeme na njihovo prepisivanje. Istina je da razvojna okolina Android Studija olakšava i ubrzava postupak unosa programskog koda, ali ni u samom pisanom izdanju nemamo neograničeno mjesto za njegovo objavljivanje. Do tada vas ostavljamo da se upoznate s korištenjem razvojne okoline ili (ako još niste) da ponovite sve korake oko instalacije Android Studija, Darta i Fluttera kako biste mogli pratiti buduće nastavke serijala.

Podijeli