Egyéni gomb Widget a legjobb megoldás arra, ha egy újrahasznosítható és egyénileg testre szabott gombot szeretnénk használni az alkalmazásban.
Amint már tudjuk egy Flutter appot widgetekből építünk fel, hasonlóan egy LEGO városhoz :). Tehát kisebb „építő elemekből” állítjuk össze a futtatható alkalmazásunkat.
Mit akarunk megvalósítani?
Egy gombot szeretnénk készíteni, amit aztán több helyen is fel tudunk majd használni az alkalmazáson belül.
A cél tehát az, hogy egy olyan widgetet készítünk, ami egy ilyen gombot ad vissza:
ElevatedButton(
onPressed: () {},
child: const Text('Gomb felirat'),
),
Az egyéni widgetnek egy külön .dart fájlt készítünk és nagyjából így fog kinézni:
import 'package:flutter/material.dart';
class AnswerButton extends StatelessWidget {
@override
Widget build(BuildContext context) {
return ElevatedButton(
onPressed: () {},
style: ElevatedButton.styleFrom(),
child: const Text('Gomb felirat'),
);
}
}
Maga a widget a StatelessWidget osztályt fogja kiterjeszteni, mert nem kell state változókat kezelni.
Egyéni gomb widget kialakítása
Vannak olyan részei a gombnak, amik minden gomb példánynál mások lesznek. Ilyen például a gombon megjelenő szöveg, azaz a gomb felirata. Ez egy paraméter lesz tehát, amit a widget kívülről fog megkapni. Szintén paramétert használunk arra, hogy a gomb kezelje a „kattintást”, akarom mondani érintést, amikor a gombra nyomunk a képernyőn.
A gomb megjelenése most minden gomb esetében azonos lesz, így azt a widgeten belül fogjuk megadni.
Ahhoz, hogy a gomb felirat és érintés vezérlő funkció kívülről paraméterezhető lehessen két dolog kell. Az egyik, hogy meg kell hívnunk a widgetünk konstruktorát, valamint osztályváltozók kellenek a paramétereknek:
AnswerButton(this.answerText, this.onTap, {super.key});
final String answerText;
final void Function() onTap;
A másik dolog pedig, hogy ezeket használni is akarjuk az ElevatedButton onPressed és child tulajdonságában:
onPressed: onTap,
child: Text(answerText),
Nevesített vagy pozíció argumentumok?
Az argumentumok / paraméterek ezen két típusáról itt esett már szó: Pozíció és nevesített paraméterek
Hogy melyiket használjuk az mindegy. A teljesség kedvéért így kellene megoldanunk, ha névvel akarnánk hivatkozni a paraméterekre:
AnswerButton({
super.key,
required this.answerText,
required this.onTap,
});
A required kulcsszó használatára szükség van, mert mindenképpen számítunk ezeknek a paramétereknek a megadására annak érdekében, hogy a gomb widget megfelelően működjön.
Egyéni widget használata
Ha már egyszer megírtuk a widgetet, akkor használni is akarjuk. A használat helyén importálni kell a .dart fájlt, amibe a widgetet írtuk:
import 'package:flutter_quiz_app/answer_button.dart';
Majd pedig meghívjuk a widgetet annyiszor, ahányszor akarjuk:
AnswerButton(
answerText: 'Answer 1',
onTap: () {},
),
AnswerButton(
answerText: 'Answer 2',
onTap: () {},
),
AnswerButton(
answerText: 'Answer 3',
onTap: () {},
)
Gomb stílusa
A gomb stílusa többféle módon állítható. legegyszerűbben a styleFrom() metódussal, ami egy paraméterezhető stílus objektumot generál:
style: ElevatedButton.styleFrom(),
Háttér és betűszín beállítása így történik az objektumon belül:
style: ElevatedButton.styleFrom(
backgroundColor: const Color.fromARGB(255, 33, 1, 95),
foregroundColor: Colors.white,
A gomb alakjának és körvonalának beállítása pedig a shape tulajdonságon keresztül valósul meg. Hogy milyen lehetőségeink vannak, megtudjuk, ha a shape tulajdonságot követő kettőspont után CTRL+SPACE billentyű kombinációt nyomunk:
Például egy lekerekített sarkot így tudunk megadni:
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(40),
),
Némi eltartás (padding) a gomb szélei és a gomb felirat között:
padding: const EdgeInsets.symmetric(
vertical: 10,
horizontal: 40,
),
Az eredmény egy ehhez hasonló gomb stílus lesz:
A gomb stílusa egyben:
style: ElevatedButton.styleFrom(
backgroundColor: const Color.fromARGB(255, 33, 1, 95),
foregroundColor: Colors.white,
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(40),
),
padding: const EdgeInsets.symmetric(
vertical: 10,
horizontal: 40,
),
),