A TextField a Flutter egyik beépített widget-e, ami megjelenít egy szövegbeviteli mezőt, vagy más néven input mezőt.
Ez az input mező lehetővé teszi, hogy a felhasználó beleírjon valamit.
A TextField konfigurálása
A TextField widgetnek nagyon sok paramétere van:
Sok van, amit ritkán vagy egyáltalán nem fogunk használni, de vannak nagyon hasznos paraméterek is. Ilyen például a maxLength, amivel meghatározhatjuk, hogy a beviteli mezőbe összesen hány karakter írható:
TextField(maxLength: 50,
Aztán itt van nekünk a keyboardType, amivel különböző billentyűzet típusok rendelhetők az adott szövegmezőhöz.
Beállítás után a kiválasztott billentyűzet típus jelenik meg, amikor a felhasználó a TextField-re bök. Az alapértelmezés szerinti beállítása a TextInputType.text, ezért ezt külön nem szükséges megadni.
Címke (felirat) hozzáadása
Ez sem kötelező, de olykor hozzáadunk a szövegmezőhöz egy címkét / feliratot, utalva arra, hogy milyen jellegű adatot várunk a felhasználótól.
Erre való a decoration tulajdonság. Talán azonnal label-t vártunk volna (türelem, mindjárt jön az is :)), de valószínűleg azért döntöttek a Guglinál a decoration mellett, mert a címkére gondolhatunk úgy, mint egy dekorációs elemre, ami az input mezőhöz tartozik.
A decoration, értékként vár egy InputDecoration objektumot. És ennek az objektumnak / osztálynak már van egy label tulajdonsága. Ez a label egy widgetet vár és mi sem kézenfekvőbb, mint mondjuk egy Text widget használata:
TextField(
maxLength: 50,
decoration: InputDecoration(
label: Text('Title'),
),
),
TextField működés közben
Így néz ki a fenti paraméterekkel létrehozott szövegbeviteli mező:
Ez a szövegmező a példában egy modal-on belül jelenik meg, amiről itt lehet bővebben olvasni. Még az is látszik a képen a TextField alatt a jobb oldali sarokban, hogy a maxLength-nek köszönhetően megjelent az, hogy mennyi karaktert vittünk be a mezőbe az engedélyezettből.
Amikor pedig a szövegmezőre bökünk, akkor felugrik a billentyűzet, amin keresztül bepötyöghetjük, amit szeretnénk:
Beírt érték tárolása – onChange
Az egyik megoldás, hogy megadjuk a TextField-nek az onChange paraméterét is. Ez egy függvényt vár, ami paraméterként automatikusan megkapja a Fluttertől a mezőbe írt értéket, valahányszor annak tartalma megváltozik.
Tehát egyrészt meg kell írni a függvényt, valahol a StatefulWidget osztályon belül:
void _saveTitleInput(String inputValue) {
}
Másrészt meg kell azt hívni:
TextField(
onChanged: _saveTitleInput,
Természetesen valahol meg is kell jegyezni a mező tartalmát. Erre kell egy változó, ami kezdetben üres. És ezt a változót frissítgetjük mindig a mezőbe vitt értékkel:
var _enteredTitle = '';
void _saveTitleInput(String inputValue) {
_enteredTitle = inputValue;
}
Azért sem kell most setState-et használni, mert az értékkel nem frissítjük vissza a felhasználó felületet. Helyette majd inkább elküldjük az adatot (submit).
Mező értékének elküldése
Hogy a kör teljes legyen megmutatom, hogyan kell „submit”-olni a mezőbe vitt értéket egy gomb segítségével. Elég tehát csak egy gombot összedobni, aminek onPressed tulajdonságában egy névtelen függvény törzsében egyszerűen csak a konzolba iratjuk a szövegmező tartalmát abban a pillanatban, amikor a gombra bökünk:
ElevatedButton(
onPressed: () {
print(_enteredTitle);
},
child: const Text('Submit'),
)
És az eredmény a konzolban is látszik:
Összefoglalva tehát a figyelése a karakter bevitelnek, a szövegmező értékének eltárolása és frissítése egy változóban, az egyik lehetséges módja a felhasználó adatbevitel kezelésének.
User input kezelés – ahogy a Flutter csinálja
Akkor, amikor már túl sok inputot kell kezelni, akkor a Flutter ad a kezünkbe egy sokkal kényelmesebb megoldást a fentiek helyett.
Kell egy final változó (objektum) a szövegmező értékének kezeléséhez:
final _titleController = TextEditingController();
A TextEditingController osztályt a Flutter biztosítja. Ez létrehoz egy objektumot, ami egyszerűsíti és optimalizálja a felhasználói input kezelést. Ennek az osztálynak a használata során van egy fontos dolog: töröljük ezt a kontrollert, amikor már a widgetnek nincs rá szüksége. Ugyanis a kontroller még akkor is élni fog a memóriában, amikor a widget már nem látható. Főleg, ha a TextField egy modal panelen van például.
Ezért mindig meg kell írni a dispose() metódust is, ami csak StatefulWidget-ek esetében létezik és annak is a második (State-et kiterjesztő) osztályában.
Maga a dispose is a widget életciklusának részét képezi. Automatikusan meghívódik akkor, amikor a Widget már nincs a felhasználó felületen:
@override
void dispose() {
_titleController.dispose();
super.dispose();
}
Mindenképpen a super.dispose() hívása előtt kell egyes kontrollereinket „diszpózolni” (pl: _titleController.dispose())!
Ennél a megközelítésnél nem kell a beviteli mezőnél az onChange paraméter, helyette a controller-t kell megadni:
TextField(
controller: _titleController,
És mivel a _titleController egy objektum, a szöveget (vagyis a beviteli mező tartalmát) a .text tulajdonságon keresztül érjük el:
print(_titleController.text);
A megoldás nagy előnye, hogy sok beviteli mező esetén nem kell manuálisan kezelni a bevitt értékeket, mert ezt a Flutter megcsinálja helyettünk a kontrollerekkel.