Vitajte na stránke Himdeve development, kde pre Vás pripravujeme tie najlepšie tutoriály, ktoré Vám uľahčia a zefektívnia vývoj mobilných aplikácií.
Najskôr otvoríme našu existujúcu aplikáciu z predchádzajúceho tutoriálu a otvoríme súbor shop_page.dart.
Do horného baru našej existujúcej aplikácie chceme pridať 3 tlačítka:
Prejdeme teda k časti kódu, kde vytvárame Scaffold widget, konkrétne jeho horný bar – AppBar.
Pridáme sem nový atribút actions, do ktorého vložíme navigačné tlačítka. Kedže všetko vo Flutteri je widget, tak navigačné tlačítka môžeme vytvoriť v novej triede NavigationControls, ktorá bude dediť zo Stateless Widgetu a inštanciu tejto triedy vložíme ako hodnotu atribútu actions. Parametrom tejto triedy bude Future objekt WebViewControllera.
Následne v našej štruktúre projektu, pod prezentačnou vrstvou vytvoríme priečinok components a v ňom nový súbor navigation_controls.dart.
Otvoríme novo vytvorený súbor navigation_controls.dart.
A vytvoríme v ňom triedu NavigationControls. Konštruktor tejto triedy bude mať argument Future objekt WebViewControllera.
Následne v build metóde Stateless Widgetu vytvoríme FutureBuilder widget takisto ako v predchádzajúcom tutoriále, kde future bude náš vstupný parameter pre túto triedu. Future tvori info o tom, či je WebView Controller validný.
Následne ak WebView Controller je validný, čiže controller.hasData je pravda, tak v build metóde vrátime Row widget. Row widget je Flutter komponent, ktorý zobrazuje svojich potomkov, čiže ďalšie widgety v tejto hierarchii widgetov, v horizontálnom poli.
Čo je tu dobré si uvedomiť je, že Row widget nie je skrolovateľný. Dokonca mať viac widget – potomkov v Row widgete ako je voľný priestor pre tento widget, je všeobecne považované za error. V takom prípade je dobré použiť Flutter ListView widget a nastaviť mu smer skrolovania horizontálne pomocou ListView atribútu scrollDirection (scrollDirection: Axis.horizontal).
Náš Row widget bude mať 3 ďalšie widgety vo svojej hierarchii widgetov, ktoré budú reprezentovať 3 navigačné tlačítka spomenuté v prvom cieli tohto tutoriálu.
Prvé tlačítko v našom navigačnom poli bude: ísť v histórii prehliadania dozadu. Na to vytvoríme metódu _buildHistoryBackBtn, ktorá vráti FlatButton widget. Táto metóda má parametre BuildContext a Snapshot WebViewControllera.
V tomto prípade chceme aby toto tlačítko bolo tvorené Ikonou reprezentujúcou šípku späť a zároveň textom ‘back’. A preto do child atribútu tohto tlačítka pridáme znovu horizontálny widget Row, kde vložíme danú ikonu a text.
Na onPressed metódu tohto tlačítka, čiže na interakciu kliknutia na toto tlačítko, sa spýtame WebViewControllera či má dáta na to aby mohol ísť v histórii prehliadania dozadu.
A ak má, tak zavoláme metódu WebViewControllera:
Ak nemá, tak zobrazíme Snackbar s informáciou, že nie je žiadna história prehliadania smerom dozadu.
Znovu si treba všimnúť, že metódu WebViewControllera controller.data.canGoBack() je potrebné awaitnuť, čiže počkať, dokým sa vyrieši Future hodnota, ktorú toto volanie vracia.
Táto metóda vyzerá takmer rovnako ako metóda reprezentujúca ísť v histórii dozadu. Akurát sa zmení text a ikona daného tlačítka ako aj info, že nie je žiadna história prehliadania smerom dopredu. A teda použijú sa metódy WebViewControllera – canGoForward() a goForward(). Názov tejto metódy je _buildHistoryForwardBtn.
Pre refresh tlačítko vytvoríme metódu _buildReloadBtn, ktorá bude mať len jeden vstupný parameter a tým je SnapShot WebViewControllera.
Táto metóda vráti IconButton widget, ktorý ako názov naznačuje, zobrazuje len ikonu daného tlačítka. A na jeho kliknutie sa zavolá callback metóda onPressed, kde znovu načítame stránku vo WebView pomocou metódy WebViewControllera:
Následne sa vrátime do shop_page.dart súboru a importneme triedu NavigationControls.
V triede _ShopPageState, v metóde _buildWebView pre widget WebView nastavíme atribút navigationDelegate, ktorý vracia callback metódu reprezentujúcu navigačnú požiadavku zmeny webovej stránky vo WebView.
Na vykonanie tejto požiadavky vytvoríme funkciu _buildNavigationDecision, ktorá reprezentuje ukážku toho, ako je možné selektovať požiadavky na zmenu webovej stránky priamo vo Flutteri.
V našom prípade uvedieme príklad, keď užívateľ v našom eshope klikne na podstránku /my-account, kde my túto požiadavku vo Flutteri zakážeme s tým, že zobrazíme Snackbar s informáciou o tom, že užívateľ nemá práva na zobrazenie tejto podstránky.
Čo je tu zaujímavé si všimnúť je, že zobrazenie SnackBaru nie je možné spraviť klasicky cez Scaffold.of(context).showSnackBar, ktorý by našiel najbližšieho predka Scaffoldu v tejto hierarchii widgetov. Pretože dostaneme exception (chybu), že Scaffold.of bol zavolaný s contextom, ktorý neobsahuje Scaffold. A to je z dôvodu, že sa snažíme použiť context widgetu, ktorý vytvoril inštanciu Scaffoldu, a nie jeho potomka. Scaffold.of(context) funguje len vtedy, ak máme context widget-potomka v tejto hierarchii widgetov pod Scaffoldom.
A preto použijeme iný prístup a to zadefinovaním globálneho kľúča (GlobalKey) pre Scaffold. A následne môžeme použiť príkaz globalKey.currentState.showSnackBar, ktorým zobrazíme želateľný SnackBar.
Na to aby sme ilustrovali ako funguje komunikácia medzi javascriptom stránky načítanej vo WebView a Flutterom, tak do WebView widgetu zadefinujeme ďalší atribút onPageFinished. Je to znovu WebView callback metóda, ktorá sa zavolá vtedy, keď je stránka vo WebView kompletne načítaná.
A našim cieľom bude následne prepísať nadpis v hornom bare našej aplikácie podľa toho aký je názov stránky, ktorú sme práve načítali.
Túto informáciu zistíme pomocou javascript príkazu:
Čiže našou úlohou je zavolať tento javascript príkaz pomocou kódu vo Flutteri a následne zareagovať na výsledok získaného názvu aktuálnej zobrazenej stránky vo Flutteri a použiť ho pre horný bar našej obrazovky.
Vytvoríme si metódu _showPageTitle, ktorú zavoláme, keď je stránka vo WebView kompletne načítaná. A tu zavoláme metódu WebViewControllera webViewController.evaluateJavascript, ktorá vyhodnotí výraz jazyka Javascript. V našom prípade document.title.
A aby sme mohli tento výsledok, čiže ten názov stránky spracovať vo Flutteri, tak musíme použiť triedu z WebView packagu s názvom JavascriptChannel.
Predtým ako sa vrhneme na JavascriptChannel, poďme sa najskôr pozrieť ako sme vôbec dostali WebViewController v metóde _showPageTitle.
Náš zakapsulovaný WebViewController do Completera musíme najskôr vyhodnotiť aby sme získali priamo hodnotu WebViewControllera. Doteraz sme to robili pomocou FutureBuilderu. Avšak v tomto prípade je to zbytočné, keďže nejdeme budovať ďalšie UI widgety v tejto metóde. Takže môžeme použiť ďalší spôsob ako získať hodnotu WebViewControllera a to použitím metódy Then, čo je callback Future objektu a zavolá sa vtedy, keď je vyhodnotená Future daného objektu.
Následne celá metóda _showPageTitle vyzerá takto:
Takže aby sme poslali info o tom aký má stránka názov, získaný pomocou javascriptu vyhodnoteného priamo na aktuálnej stránke zobrazenej vo Webview, použijeme JavascriptChannel.
Na komunikáciu z javascriptu sa použije JavascriptChannel ako komunikačný kanál, ktorý posiela správy pomocou metódy JavascriptChannel.postMessage. A tieto správy sú následne prijímané callback metódou JavascriptChannelu onMessageReceived.
Vytvoríme si teda metódu na vytvorenie JavascriptChannelu a nazveme ju _createTopBarJsChannel.
Trieda JavascriptChannel má 2 atribúty: name, onMessageReceived.
Atribút name nastavíme na hodnotu ‘TopBarJsChannel’ a tento atribút reprezentuje názov JavascriptChannelu, ktorý následne používame na posielanie správ v metóde evaluateJavascript WebViewControllera.
Atribút onMessageReceived reprezentuje teda callback metódu JavascriptChannelu, ktorá vracia správu poslanú z javascriptu.
Textová hodnota tejto JavascriptMessage sa zavolá pomocou príkazu: message.message.
V našom prípade chceme vložiť tento názov do AppBaru nášho Scaffold widgetu. A na to zavoláme setState metódu, ktorá slúži na znovu zavolanie build metódy a nastavíme premennú _title na nový názov získaný z javascript príkazu document.title. Tento názov ešte upravíme podľa nášho konkrétneho príkladu, kde document.title vracia moc dlhý názov a nám stačí len jeho substring do znaku pomlčky ‘–’.
A tým je naša tretia časť tejto prvej série Flutter SK/CZ Tutoriálov ukončená a kompletný zdrojový kód môžete samozrejme nájsť na githube.
Our Himdeve developoment's website uses cookies.