[[oktatas:telefon:flutter|< Flutter]] ====== Flutter kezdés ====== * **Szerző:** Sallai András * Copyright (c) 2023, Sallai András * Licenc: [[https://creativecommons.org/licenses/by-sa/4.0/|CC Attribution-Share Alike 4.0 International]] * Web: https://szit.hu ===== A Flutter-ről ===== A Flutter a Google kezdeményezése 2015 környékéről. Az 1.0 verzió 2018-ban jött ki. A [[oktatas:web:dart|Dart]] programozási nyelven használható, a Flutter is ebben let elkészítve. Előnye, hogy nem szükséges külön fejlesztőket alkalmazni a különböző platformokra. Egyszerre fejleszthetünk vele Windows, Linux macOS és mobil operációs rendszerekre. Fordítási módok: * debug * release ===== Kezdő fájl ===== import 'package:flutter/material.dart'; void main() { runApp(const MaterialApp( home: Scaffold( body: Text('Helló Világ!') ) )); } Minden Flutter alkalmazásnak tartalmaznia kell egy tervező csomagot. Ilyenek lehetnek: * material - Google fejlesztése * cuperino - iOS-hez fejlesztve * fluent_ui - Windowshoz fejlesztve Ha használjuk valamelyik csomagot, csak egyszer szerepeljen az alkalmazásban! ===== Futtatás ===== ==== A futtatás ==== * Kattintsunk a megnyitott main.dart állomány esetén a jobb felső sarokban a Run and Debug gombra. Vagy: * A forráskódban kattintsunk a lebegő "Run" gombra. ==== Futtatási módok VSCode-ban ==== A Státusz sor jobb oldali részen, operációs rendszertől függően láthatjuk milyen módban vagyunk. Linux mód például: * Linux (linux-x64) Erre kattintva egyéb módok is választhatók. Ha az Android Studio-val van egy vagy több emulált Android, azok megjelennek ebben a listában. ==== Linux módban Debian GNU/Linuxon ==== apt install cmake ninja-build clang Ha a snap csomagkezelőt használjuk, nincs ilyen teendő. Egy hibaüzenet kiküszöbölése: Az **GDBus.Error:org.freedesktop.portal.Error.NotFound** hiba esetén, tegyünk a **/etc/environment** fájlba a következőt: GTK_USE_PORTAL=1 A fejlesztett alkalmazás következő indításakor a hibaüzenet megszűnik. ===== VSCode wrapper ===== Szeretnénk a szöveget középre igazítani. * A szövegkurzort vigyük a Text widget-re. * Ctrl + . * Válasszuk ki, a Center widgetet Az eredmény: import 'package:flutter/material.dart'; void main() { runApp(const MaterialApp( home: Scaffold( body: Center(child: Text('Helló Világ!')) ) )); } ===== Hot reload ===== Eddig mindig újra kellett indítani a nézet frissítéséhez az alkalmazást. Azt szeretnénk, hogy mentésre azonnal frissüljön az alkalmazás nézete. Ehhez egy saját widget létrehozása szükséges. Hozzuk létre az osztályunkat: class MyApp extends StatelessWidget { } Vigyük az osztály nevére a szövegkurzort, majd Ctrl + . billentyűkombinációt használjuk. Válasszuk: * Create 1 missing override Tegyük át az alkalmazásunkat a runApp() hívásból build() hívásba, egy return után. import 'package:flutter/material.dart'; void main() { runApp(const MyApp()); } class MyApp extends StatelessWidget { const MyApp({super.key}); @override Widget build(BuildContext context) { return const MaterialApp( home: Scaffold( body: Center(child: Text('Helló Világ!')) ) ); } } A return beszúrása és a ; pontosvessző beszúrása szükséges. ===== AppBar ===== import 'package:flutter/material.dart'; void main() { runApp(const MyApp()); } class MyApp extends StatelessWidget { const MyApp({super.key}); @override Widget build(BuildContext context) { return MaterialApp( home: Scaffold( appBar: AppBar(title: const Text('Lorem')), body: const Text('Lorem ipsum dolor est amat') ) ); } } ===== Sorok és oszlopok ===== A Column widget segítségével egymás alatt jeleníthetjük meg a beépített widgeteket. A Row widget egy sorban teszi lehetővé a megjelenítést. import 'package:flutter/material.dart'; void main() { runApp(const MyApp()); } class MyApp extends StatelessWidget { const MyApp({super.key}); @override Widget build(BuildContext context) { return MaterialApp( home: Scaffold( appBar: AppBar(title: const Text('Lorem')), body: Column( children: [ Row( children: [ Container( color: Colors.yellow, padding: const EdgeInsets.all(10), child: const Text('Lorem ipsum dolor est amat')), Container( color: Colors.yellow, padding: const EdgeInsets.all(10), child: const Text('Lorem ipsum dolor est amat')), ], ), Container( color: Colors.yellow, padding: const EdgeInsets.all(10), child: const Text('Lorem ipsum dolor est amat')), ], ) ) ); } } ===== Több fájl ===== import 'package:flutter/material.dart'; class Mainwindow extends StatelessWidget { const Mainwindow({super.key}); @override Widget build(BuildContext context) { return Scaffold( appBar: AppBar(title: const Text('Lorem')), body: Container( color: Colors.yellow, padding: const EdgeInsets.all(10), child: const Text('Lorem ipsum dolor est amat')) ); } } import 'package:app01/screens/mainwindow.dart'; import 'package:flutter/material.dart'; void main() { runApp(const MyApp()); } class MyApp extends StatelessWidget { const MyApp({super.key}); @override Widget build(BuildContext context) { return const MaterialApp( home: Mainwindow(), ); } } ===== Számláló ===== A számlálót **StatefulWidget** segítségével készítjük el, mivel ezzel lehet állapotot tárolni. import 'package:flutter/material.dart'; class Mainwindow extends StatefulWidget { const Mainwindow({super.key}); @override State createState() { return Mainstate(); } } class Mainstate extends State{ int counter = 0; @override Widget build(BuildContext context) { return Scaffold( floatingActionButton: FloatingActionButton( child: const Icon(Icons.add), onPressed: () { setState(() { counter++; }); }, ), appBar: AppBar(title: const Text('Számláló')), body: Container( color: Colors.yellow, padding: const EdgeInsets.all(10), child: Center(child: Text( counter.toString(), style: const TextStyle(fontSize: 34) ))) ); } } import 'package:app01/screens/mainwindow.dart'; import 'package:flutter/material.dart'; void main() { runApp(const MyApp()); } class MyApp extends StatelessWidget { const MyApp({super.key}); @override Widget build(BuildContext context) { return const MaterialApp( home: Mainwindow(), ); } } {{:oktatas:telefon:flutter:szamlalo.png?300|}}