Flutter widgetek működése és egyedi komponensek létrehozása

Tippek hatékony felhasználói felületek készítéséhez Flutterrel, a widgetek testreszabásának segítségével
LogiNet Mobile Dev Team

LogiNet Mobile Dev Team

Natív iOS, Android és cross-platform mobil szakértők

A Flutter fejlesztés legnagyobb előnye, hogy a létrehozott alkalmazás teljes szerkezete widgetekből épül fel. Ezek alkotják a Flutter alkalmazások minden vizuális és funkcionális elemét – a legegyszerűbb gomboktól a komplex dizájnig. Cikkünkben bemutatunk néhány alapvető Flutter widgetet és azok használatát, valamint példákon keresztül szemléltetjük az egyedi widgetek létrehozásának lehetőségét.


A Flutter Widget jelentése

A widget a Flutter alkalmazások alapvető építőeleme. Minden vizuális komponens – legyen az gomb, szövegdoboz, kép vagy lista – widget. A Flutter két fő widget típust különböztet meg:

  • StatelessWidget: olyan widget, amelynek állapota nem változik futás közben. Ezek statikus elemek, például szövegek vagy ikonok.
  • StatefulWidget: olyan widget, amely dinamikus állapotot kezel, azaz az alkalmazás futása közben változhatnak a megjelenített adatok, például egy űrlap bemeneti mezője, vagy egy gomb állapota.

Alapvető Flutter Widgetek

Következzen néhány alapvető widget, amelyekkel találkozhatsz a Flutterben:

1. Text

A Text widget az egyik legegyszerűbb, mégis alapvető elem a Flutter alkalmazásokban. Szövegek megjelenítésére szolgál, és könnyen testreszabható különböző stílusokkal, színekkel és formázásokkal.

Használata:

Text(
  'Hello, Flutter!',
  style: TextStyle(
    fontSize: 20,
    color: Colors.blue,
  ),
);

 

Eredménye:

Flutter widget - Text widget

2. Container

A Container az egyik legfontosabb layout widget a Flutterben, amely szinte minden UI elemhez használható. Rugalmasan állítható be a mérete, színe, margói, alakja, árnyéka és egyéb vizuális paraméterei.

Használata:

Container(
  width: 150,
  height: 150,
  padding: const EdgeInsets.symmetric(
    horizontal: 10,
    vertical: 6,
  ),
  decoration: BoxDecoration(
    color: Colors.red,
    borderRadius: BorderRadius.circular(10),
  ),
  child: const Text('Hello, Flutter!'),
);

 

Eredménye:

Flutter widget - Container widget

3. Row és Column

A Row és Column layout widgetek sorba, illetve oszlopba rendezik a gyermek widgeteket, így rugalmasan helyezhetünk el különböző elemeket a képernyőn. A mainAxisAlignment és crossAxisAlignment paramétereik változatos igazítási lehetőségeket kínálnak.

Használata:

Row(
  mainAxisAlignment: MainAxisAlignment.center,
  crossAxisAlignment: CrossAxisAlignment.center,
  children: [
    Text('First item'),
    FlutterLogo(size: 50),
    Text('Third item'),
  ],
);

 

Eredménye:

Flutter widget - Row widget

 

Használata:

 

Column(
  mainAxisAlignment: MainAxisAlignment.center,
  crossAxisAlignment: CrossAxisAlignment.center,
  children: [
    Text('First item'),
    FlutterLogo(size: 50),
    Text('Third item'),
  ],
);

 

4. ListView

A ListView egy görgethető listát biztosít, amely különösen hasznos hosszú tartalmak megjelenítésére, mint például hírek, bevásárlólisták vagy üzenetek.

Használata:

ListView(

  children: [

    Container(
      height: 50,
      alignment: Alignment.center,
      color: Colors.blue[300],
      child: Text('First item'),
    ),

    Container(
      height: 50,
      alignment: Alignment.center,
      color: Colors.blue[200],
      child: Text('Second item'),
    ),

    Container(
      height: 50,
      alignment: Alignment.center,
      color: Colors.blue[100],
      child: Text('Third item'),
    ),

  ],

);

 

Eredménye:

Flutter widget - ListView widget

Az alapértelmezett ListView konstruktor kis méretű listákhoz ideális. Ha azonban sok elemmel dolgozol, érdemes a ListView.builder konstruktor használata mellett dönteni. Ez ugyanis - az alapértelmezettel ellentétben -, nem hozza létre egyszerre az összes elemet, hanem csak akkor generálja őket, amikor a görgetés során a képernyőn megjelennek.

final items = ['First item', 'Second item', 'Third item'];

final colorCodes = [300, 200, 100];

Widget build(BuildContext context) {
  return ListView.builder(
    itemCount: items.length,
    itemBuilder: (context, index) {
      return Container(
        height: 50,
        alignment: Alignment.center,
        color: Colors.blue[colorCodes[index]],
        child: Text(items[index]),
      );
    },
  );
}

 

5. Scaffold

A Scaffold egy alapvető struktúra widget, amely egy tipikus képernyő vázát biztosítja, és olyan elemeket tartalmaz, mint például az appbar (fejléc), floating action button, drawer (oldalsó menü), body.

Használata:

Scaffold(

  appBar: AppBar(
    title: Text('Flutter App'),
    leading: BackButton(),
  ),

  body: Center(
    child: Text('Hello, Flutter!'),
  ),

  floatingActionButton: FloatingActionButton(
    onPressed: () {},
    child: Icon(Icons.add),
  ),

);

 

Eredménye:

Flutter widget - Scaffold widget

6. Stack

A Stack widget segítségével egymásra helyezhetünk több elemet, hasonlóan a rétegezéshez. Ez lehetővé teszi az elemek szabadabb elrendezését, például átfedések vagy widgetek áthelyezését a képernyő különböző pontjaira. A pontos pozicionálás a Positioned widget használatával érhető el.

Használata:

Stack(

  children: [

    Container(
      color: Colors.blue,
      width: 100,
      height: 100,
    ),

    Positioned(
      top: 10,
      left: 10,
      child: Container(
        color: Colors.red,
        width: 50,
        height: 50,
      ),
    ),

  ],

);

 

Eredménye:

Flutter widget - Stack widget


Egyedi Widgetek létrehozása

A Flutter fejlesztés egyik fő előnye, hogy egyszerűen hozhatsz létre egyedi widgeteket, ha a meglévők nem felelnek meg az igényeidnek. Emellett a kódszervezés és a következetes megjelenés érdekében is kulcsfontosságú elkülöníteni azokat a UI elemeket, amelyek gyakran megjelennek több képernyőn is. Ilyenkor eldöntheted, hogy statikus vagy dinamikus elemeket hozol létre – előbbihez a StatelessWidget, utóbbihoz a StatefulWidget osztályt használhatod.

Stateless Widget példa

Kezdjünk egy egyszerű, statikus egyedi widgettel, amely egy testreszabott gombot hoz létre:

class CustomButton extends StatelessWidget {

  final String text;
  final Color color;
  final VoidCallback onPressed;

  const CustomButton({
    super.key,
    required this.text,
    required this.color,
    required this.onPressed,
  });

  @override
  Widget build(BuildContext context) {
    return ElevatedButton(
      style: ElevatedButton.styleFrom(
        backgroundColor: color,
      ),
      onPressed: onPressed,
      child: Text(
        text,
        style: TextStyle(color: Colors.white),
      ),
    );
  }
}

 

Ez a CustomButton widget egy gombot reprezentál, aminek beállítható a szövege, a színe és a gomb megnyomásakor végrehajtandó művelete a text, color és onPressed paraméterek segítségével. Egy egyszerű felhasználása így néz ki:

CustomButton(

  text: 'Custom Button',
  color: Colors.blue,
  onPressed: () {
    print('Button pressed');
  },

);

 

Eredménye:

Flutter widget: CustomButtom widget

Stateful Widget példa

Most nézzünk meg egy olyan widgetet, amely kívülről kap olyan paramétert, amivel testreszabható, valamint belső állapottal rendelkezik és ennek megfelelően változik.

class PasswordFieldWidget extends StatefulWidget {

  final String label;

  const PasswordFieldWidget({
    super.key,
    required this.label,
  });

  @override
  State<StatefulWidget> createState() => PasswordFieldState();
}

class PasswordFieldState extends State<PasswordFieldWidget> {

  bool hiddenPassword = true;

  @override
  Widget build(BuildContext context) {
    return TextFormField(
      obscureText: hiddenPassword,
      decoration: InputDecoration(
        label: Text(widget.label),
        suffixIcon: IconButton(
          icon: Icon(hiddenPassword ? Icons.visibility : Icons.visibility_off),
          onPressed: () {
            setState(() => hiddenPassword = !hiddenPassword);
          },
        ),
      ),
    );
  }
}

 

A példában lévő PasswordFieldWidget egy jelszó beviteli mező, ami label paraméterként kapja a mező nevét, illetve hiddenPassword változó vezérli a mező tartalmának láthatóságát. Egy valós használati eset, amikor jelszóváltoztatás funkciót szeretnénk implementálni az applikációnkba. Ilyenkor két ilyen beviteli mezőt kell használnunk különböző paraméterekkel.

Column(

  children: [

    PasswordFieldWidget(label: 'Current password'),

    PasswordFieldWidget(label: 'New password'),

  ],

);

 

Eredménye:

Flutter widget - PasswordFieldWidget

További gyakori példák

  • CustomItemCard: Egy testreszabott kártya widget, amely általában képeket, szövegeket és gombokat tartalmaz meghatározott stílusban. Ezeket a widgeteket gyakran használjuk listaelemek megjelenítésére.
  • CustomInputField: Egy egyedi beviteli mező, amely túlmutat az alapértelmezett TextField funkcióin. Jellemzői a speciális validáció, egyedi ikonok, testreszabott háttér és sajátos megjelenés.
  • CustomAppBar: Egy app dizájn implementációja során gyakran hozunk létre egy specifikus appbar widgetet, amely egységes megjelenést biztosít minden képernyőn. Az ilyen widget gyakori paraméterei közé tartozik a képernyő neve, vagy a vissza gomb megnyomásakor végrehajtandó művelet.

Hasznos tippek

  • Kisebb komponensek: Ne félj a kisebb elemeket külön widgetekbe kiemelni. Az egyedi widgetek így könnyen újrafelhasználhatók és karbantarthatók lesznek.
  • Belső állapot kezelése: Amikor állapotot kezelő widgetet hozol létre, gondolj a teljesítményre is. Csak akkor frissítsd a widgetet, ha valóban szükséges.
  • Kompozíció: A Flutter fejlesztés során ajánlott a kompozíciót használni az öröklés helyett, ezért inkább több kis widgetet komponálj egymásba.

A beépített Flutter widgetekre építve gyorsan hozhatsz létre UI elemeket, míg az egyedi widgetek lehetővé teszik, hogy testreszabott és konzisztens felhasználói élményt nyújts. 

A LogiNetnél natív és flutter mobil applikációk fejlesztésében is a segítségedre vagyunk. Vedd fel kollégáinkkal a kapcsolatot, beszéljünk róla mi lehet számodra a legideálisabb megoldás!
LogiNet Mobile Dev Team

LogiNet Mobile Dev Team LogiNet Mobile Dev Team LinkedIn profilja

Natív iOS, Android és cross-platform mobil szakértők
Mobil app fejlesztői csapatunk tagjai komoly tapasztalattal rendelkeznek új, egyedi mobil applikáció készítésében, a meglévő mobil app továbbfejlesztésében, refaktorálásban. Naprakészek a legújabb technológiák terén. Céljuk, hogy a legmodernebb megoldásokat az elsők között építsék be a fejlesztett alkalmazásokba.