App Features

ikona aplikácie, class based komponent, inštalácia modulov tretích strán

Záznam z prednášky

Project Torch Overview

  • (slide) Pokračujeme vo výrobe baterky, ktorá bude na svetlo využívať blesk zadnej kamery/fotoaparátu.

Application Icon

  • (slide) nastaviť ikonu aplikácie

    Application Icon (zdroj)
  • licencia: tango icons (https://commons.wikimedia.org/wiki/Tango_icons)

  • nahrat do assets/

  • aktualizovat app.json

  • reštartnúť/znovu načítať aplikáciu v Expo kliente na zariadení/v emulátore

Class Component

  • (slide) ešte kým máme toho kódu málo, pozrieme sa na to, ako bude vyzerať ako trieda

  • takto vyzerali komponenty v React-e aj React Native donedávna

    import React, { Component } from "react";
    import { 
      StyleSheet, View, Button, Image, Pressable 
    } from "react-native";
    
    export default class App extends Component {
        constructor(props) {
            super(props);
            this.state = {
                isOn: false,
            };
        }
    
        toggleState() {
            const { isOn } = this.state;
            console.log(">> state change...");
            this.setState({ isOn: !isOn });
        }
    
        render() {
            const image = this.state.isOn
                ? require("./assets/bulb_on.png")
                : require("./assets/bulb_off.png");
    
            return (
               <View style={styles.container}>
                  <Pressable onPress={this.toggleState.bind(this)}>
                      <Image source={image} />
                  </Pressable>
                  <Button
                      onPress={this.toggleState.bind(this)}
                      title={this.state.isOn === true ? 
                          "Turn Off" : "Turn On"}
                  />
               </View>
            );
        }
    }

Houston, We Have a Problem!

  • (slide) Expo nemá možnosť pracovať s bleskom foťáku

    • expo-camera, ale robí náhľad z foťáku + ovláda blesk, ale nejde len samostatne ovládať blesk
  • (slide) Kedy sa teda oplatí používať Expo? Aké výhody ponúka?

    • Fastest way to build React Native Apps
    • You don’t need to know Native Mobile coding
    • No Xcode, No Android Studio
    • Publish Over The Air (OTA) Updates Instantly
    • In-built access to Native APIs
    • It is FREE and Open Source
  • (slide) A kedy sa naopak neoplatí Expo používať? Aké sú nevýhody Expa?

    • Not all iOS and Android APIs are available yet
  • Ak to zhrnieme, tak Expo je výborné, ak ste noví vo vývoji aplikácií pre chytré zariadenia a nemáte (alebo nechcete mať) skúsenosti s natívnym vývojom aplikácií. Ak naopak skúsenosti s natívnym vývojom máte alebo potrebujete vo svojej aplikácii pracovať so súčasťami, ktoré nie sú zatiaľ podporované v Expo SDK, Expu sa vyhnite.

Ejecting from Expo

  • Nemusíme začínať projekt odznova, ale môžeme spraviť tzv. “eject” z Expa. To vykonáme spustením nasledovného príkazu z koreňového priečinku projektu:

    $ expo eject
  • Následne prejdeme krátkym dialógom, kde sa nás systém opýta na balík, v ktorom sa bude novovytváraná aplikácia pre Android aj iOS nachádzať. Ako balík uvedieme sk.tuke.smart.torch.

Running the Project

  • Podobne, ako v prípade Expo, je aj tu odporúčanie nespúšťať príkazy priamo cez npm, ale pomocou nástroja npx.

  • Najprv spustíme Metro Bundler príkazom:

    $ npx react-native start
  • Jeho podoba síce aktuálne nebude taká sexi ako v prípade Expo-a, ale rovnako bude Metro spustené na pozadí a bude sledovať zmeny v projekte.

  • V novom termináli spustíme príkaz:

    $ npx react-native run-android

    Tým dôjde:

    • k spusteniu emulátora, ak nie je pripojené Android zariadenie
    • k zostaveniu aplikácie pre Android
    • nainštalovaniu a spusteniu aplikácie na Android zariadení.

Understanding the Android Configuration

  • na pozadí sa však stalo niečo, čo hneď nevidieť:

    • stiahlo sa Android API 29
    • aplikácia sa zostavila na základe Android API 29
  • (slide) pozrime sa teda na konfiguráciu Android projektu

compileSdkVersion, minSdkVersion and targetSdkVersion

  • (slide) Prvý súbor, ktorý nás bude zaujímať je konfiguračný súbor build.gradle v priečinku android/. Zaujímať nás bude časť označená ako buildscript:

    buildscript {
        ext {
            buildToolsVersion = "30.0.2"
            minSdkVersion = 23
            compileSdkVersion = 29
            targetSdkVersion = 29
        }
    }
  • Význam jednotlivých volieb je nasledovný:

    • compileSdkVersion - Táto voľba hovorí, akú verziu Android SDKGradle použiť pri preklade vašej aplikácie. Odporúča sa používať vždy najnovšiu verziu SDK.

    • minSdkVersion - Označuje minimálnu verziu Android SDK, ktorú má vaša aplikácia podporovať. Rámec React Native podporuje všetky verzie Android-u od 4.1 (od API 16).

    • targetSdkVersion - Označuje verziu Android-u, na ktorú svoju aplikáciu cielite.

  • To teda znamená, že:

    • hodnota compileSdkVersion by mala vždy byť najnovšia dostupná (alebo aspoň nie veľmi pozadu)

    • hodnota minSdkVersion by mala reprezentovať verziu najstaršieho Android-u, pre ktorý chceme, aby bola aplikácia spätne kompatibilná, v našom prípade teda 23

    • (slide) hodnota targetSdkVersion by mala reprezentovať verziu systému, na ktorú je aplikácia cielená. A keďže spoločnosť Google stanovila, že do novembra 2020 musia mať aplikácie, ktoré sú publikované na Play Store, nastavenú cieľovú verziu SDK na hodnotu 29 a vyššie, nemáme o čom špekulovať ;)

      Apps must target API level 29 (Zdroj)

AndroidManifest.xml

  • (slide)

  • Hodnota targetSdkVersion a minSdkVersion sa budú nachádzať aj vo finálnej aplikácii v súbore AndroidManifest.xml. Ak ich tam pridáte ručne, budú ignorované, nakoľko ich hodnoty budú prepísané nástrojom Gradle na základe konfiguračného súboru build.gradle.

Application Icon Again

  • Aplikácia sa teraz spustí bez Expo klienta. Jej funkcionalita zostala síce zachovaná, ale ak sa pozrieme na to, ako tentokrát vyzerá ikona aplikácie, tak v závislosti od rozlíšenia zariadenia môže vyzerať rozlične. To je spôsobené tým, že v prípade Android-a už záleží na tom, na akom zariadení je aplikácia spustená.

  • V priečinku android/ sa okrem konfigurácie a zdrojových kódov nachádzajú aj zdroje (resources) aplikácie. Medzi zdroje patrí aj ikona aplikácie, tzv. spúšťača aplikácie. Tie sa nachádzajú v priečinku android/app/src/main/res/.

  • V tomto priečinku sa nachádzajú priečinky s rozličnými postfixmi na základe rozlíšení cieľových zariadení:

    • xxxhdpi (extra-extra-extra-high) ~ 640dpi
    • xxhdpi (extra-extra-high) ~ 480dpi
    • xhdpi (extra-high) ~ 320dpi
    • hdpi (high) ~ 240dpi
    • mdpi (medium) ~ 160dpi
    • ldpi (low) ~ 120dpi
  • Aby sme sa veľmi nenamakali a neupravovali ikonu pre každý jeden typ zvlášť, môžeme na to použiť on-line nástroj Android Asset Studio. Ten obsahuje niekoľko nástrojov, pričom jedným z nich je práve nástroj na tvorbu ikon spúšťačov. Zrejme po vzore tohto online nástroja vzniklo Asset Studio, ktoré je súčasťou aj Android Studia.

  • Prejdeme teda do Launcher Icon Generator-a, kde nahráme vlastnú ikonu:

    Launcher Icon (zdroj)
  • Keď budeme spokojní so všetkými úpravami, klikneme na tlačidlo Download ZIP. Stiahneme k sebe balík s upravenými ikonami pre jednotlivé rozlíšenia. Vo vnútri balíka sa nachádza priečinok res/, ktorý rozbalíme cez res/ priečinok v našom projekte.

    android:icon="@mipmap/ic_launcher"

Let There be Light!

  • (slide) React Native nevie priamo ovládať baterku

  • skúsime vyhľadať vhodný modul cez https://www.npmjs.com/

    • react native flashlight
  • pouzijeme modul react-native-torch

  • inštalácia modulu

    $ npm install --save react-native-torch
    $ react-native link react-native-torch
  • môžeme skúsiť teraz aplikáciu preložiť a spustiť

  • aktualizovanie kódu pre ošetrenie stlačenia tlačidla:

    import Torch from 'react-native-torch';
    
    ...
    
    const toggleState = function () {
        Torch.switchState(!isOn);
        setIsOn(!isOn);
    };

Complete Solution

  • Dnes zmien priamo v kóde veľa nebolo, pretože sme sa venovali viac projektu a jeho nastavení. Kód výsledného komponentu bude teda vyzerať nasledovne:

    import React, { useState } from "react";
    import { 
        StyleSheet, View, Button, Image, Pressable 
    } from "react-native";
    import Torch from "react-native-torch";
    
    export default function App() {
        const [isOn, setIsOn] = useState(false);
    
        var image = isOn
            ? require("./assets/bulb_on.png")
            : require("./assets/bulb_off.png");
    
        const toggleState = function () {
            Torch.switchState(!isOn);
            setIsOn(!isOn);
        };
    
        return (
            <View style={styles.container}>
                <Pressable onPress={toggleState}>
                    <Image source={image} />
                </Pressable>
                <Button
                    onPress={toggleState}
                    title={isOn === true ? "Turn Off" : "Turn On"}
                />
            </View>
        );
    }
    
    const styles = StyleSheet.create({
        container: {
            flex: 1,
            backgroundColor: "#fff",
            alignItems: "center",
            justifyContent: "center",
        },
    });