Topic: 2 Understanding widgets in detail

Hello devs, As we decided in the previous blog in this blog we discussed about Different types of widgets that are used to create UI in Flutter and deeply understand the stateful widgets lifecycle.

Types of Stateless Widgets

  1. Basic UI Widgets:

    • Text: Displays a string of text.

    • Image: Displays an image from various sources.

    • Icon: Displays a Material or Cupertino icon.

    • Container: A rectangular visual element used for layout or styling.

    Text('Hello, World!');
    Image.asset('assets/image.png');
    Icon(Icons.favorite);
    Container(
      width: 100,
      height: 100,
      color: Colors.blue,
      child: Text('Container'),
    );
  1. UI Elements:

    • Button: A clickable element used to trigger actions.

    • TextField: Allows users to input text.

    • Checkbox, Radio, Switch: Input widgets for boolean values.

    ElevatedButton(
      onPressed: () {
        // Handle button press
      },
      child: Text('Press Me'),
    );

    TextField(
      decoration: InputDecoration(
        labelText: 'Enter your name',
      ),
    );
  1. Material Design Widgets:

    • Widgets that implement Google's Material Design guidelines, such as AppBar, Card, Drawer, etc.
    AppBar(
      title: Text('My App'),
    );

    Card(
      child: ListTile(
        title: Text('Title'),
        subtitle: Text('Subtitle'),
      ),
    );
  1. Cupertino Widgets:

    • Widgets that implement Apple's iOS design guidelines, such as CupertinoNavigationBar, CupertinoButton, etc.
    CupertinoNavigationBar(
      middle: Text('Title'),
    );

    CupertinoButton(
      onPressed: () {
        // Handle button press
      },
      child: Text('Press Me'),
    );
  1. Layout Widgets:

    • Widgets that help with layout composition, such as Row, Column, ListView, GridView, etc.
    Row(
      children: [
        Icon(Icons.star),
        Text('Star'),
      ],
    );

    ListView(
      children: [
        ListTile(title: Text('Item 1')),
        ListTile(title: Text('Item 2')),
      ],
    );
  1. Styling Widgets:

    • Widgets that apply styling to their children, such as TextStyle, Container (with decoration properties), etc.
    Text(
      'Styled Text',
      style: TextStyle(
        fontSize: 20,
        fontWeight: FontWeight.bold,
        color: Colors.red,
      ),
    );

    Container(
      width: 100,
      height: 100,
      color: Colors.blue,
      child: Center(
        child: Text('Container'),
      ),
    );
  1. Utility Widgets:

    • Widgets that provide utility or convenience, such as AspectRatio, Opacity, etc.
    AspectRatio(
      aspectRatio: 16 / 9,
      child: Image.asset('assets/image.jpg'),
    );

    Opacity(
      opacity: 0.5,
      child: Text('Half Transparent'),
    );

These are the main types of stateless widgets in Flutter, each serving different purposes and contributing to the construction of rich and dynamic user interfaces. By leveraging these widgets effectively, developers can create engaging and responsive Flutter applications.

Types of Stateful Widgets

  1. Basic Stateful Widgets:

    • These are stateful counterparts of basic UI widgets such as Text, Image, Icon, and Container. They maintain a mutable state to enable dynamic updates.
    class CounterWidget extends StatefulWidget {
      @override
      _CounterWidgetState createState() => _CounterWidgetState();
    }

    class _CounterWidgetState extends State<CounterWidget> {
      int _counter = 0;

      @override
      Widget build(BuildContext context) {
        return Column(
          children: [
            Text('Counter: $_counter'),
            ElevatedButton(
              onPressed: () {
                setState(() {
                  _counter++;
                });
              },
              child: Text('Increment'),
            ),
          ],
        );
      }
    }
  1. Form Stateful Widgets:

    • These widgets are used for capturing and validating user input, such as TextField, Checkbox, Radio, Switch, etc.
    class FormWidget extends StatefulWidget {
      @override
      _FormWidgetState createState() => _FormWidgetState();
    }

    class _FormWidgetState extends State<FormWidget> {
      final TextEditingController _controller = TextEditingController();
      String _inputText = '';

      @override
      Widget build(BuildContext context) {
        return Column(
          children: [
            TextField(
              controller: _controller,
              onChanged: (value) {
                setState(() {
                  _inputText = value;
                });
              },
              decoration: InputDecoration(
                labelText: 'Enter text',
              ),
            ),
            Text('Input: $_inputText'),
          ],
        );
      }
    }
  1. List Stateful Widgets:

    • These widgets are used for displaying dynamic lists of items, such as ListView, GridView, etc.
    class ListWidget extends StatefulWidget {
      @override
      _ListWidgetState createState() => _ListWidgetState();
    }

    class _ListWidgetState extends State<ListWidget> {
      List<String> _items = ['Item 1', 'Item 2', 'Item 3'];

      @override
      Widget build(BuildContext context) {
        return ListView.builder(
          itemCount: _items.length,
          itemBuilder: (context, index) {
            return ListTile(
              title: Text(_items[index]),
            );
          },
        );
      }
    }
  1. Navigation Stateful Widgets:

    • These widgets manage navigation within the app and maintain state related to route changes, such as Navigator, BottomNavigationBar, TabBar, etc.
    class NavigationWidget extends StatefulWidget {
      @override
      _NavigationWidgetState createState() => _NavigationWidgetState();
    }

    class _NavigationWidgetState extends State<NavigationWidget> {
      int _selectedIndex = 0;

      void _onItemTapped(int index) {
        setState(() {
          _selectedIndex = index;
        });
      }

      @override
      Widget build(BuildContext context) {
        return Scaffold(
          body: Center(
            child: Text('Selected index: $_selectedIndex'),
          ),
          bottomNavigationBar: BottomNavigationBar(
            items: [
              BottomNavigationBarItem(
                icon: Icon(Icons.home),
                label: 'Home',
              ),
              BottomNavigationBarItem(
                icon: Icon(Icons.search),
                label: 'Search',
              ),
              BottomNavigationBarItem(
                icon: Icon(Icons.person),
                label: 'Profile',
              ),
            ],
            currentIndex: _selectedIndex,
            onTap: _onItemTapped,
          ),
        );
      }
    }
  1. Custom Stateful Widgets:

    • These are custom widgets created by developers to encapsulate complex UI components and behaviors while maintaining their own internal state.
    class CustomWidget extends StatefulWidget {
      @override
      _CustomWidgetState createState() => _CustomWidgetState();
    }

    class _CustomWidgetState extends State<CustomWidget> {
      bool _isActive = false;

      void _toggleState() {
        setState(() {
          _isActive = !_isActive;
        });
      }

      @override
      Widget build(BuildContext context) {
        return GestureDetector(
          onTap: _toggleState,
          child: Container(
            color: _isActive ? Colors.blue : Colors.grey,
            child: Center(
              child: Text(_isActive ? 'Active' : 'Inactive'),
            ),
          ),
        );
      }
    }

These are the main types of stateful widgets in Flutter, each serving different purposes and enabling developers to build dynamic and interactive user interfaces for their applications.

As we see in our previous blog that the stateFul widget has a lifecycle. Let's understand in detail.

Stateful Widget Lifecycle

  1. Constructor:

    • When you create a stateful widget, you set it up with the constructor. This is where you prepare everything before the widget is shown.
  2. createState():

    • Next, Flutter creates the state for your widget. This is like setting up the brain of the widget to handle changes and updates.
  3. initState():

    • Now, the widget's brain (initState()) gets ready. It's called just once and used for setting up things like listening to events or loading data.
  4. build():

    • With everything set up, Flutter builds the widget's UI (build()). It's like drawing what the widget looks like.
  5. setState():

    • When something changes, like a button press, you use setState() to tell Flutter. This makes the widget redraw with the new changes.
  6. didUpdateWidget():

    • If the widget's properties change, Flutter checks didUpdateWidget() to see if it needs to do anything special. It's like a check-up after a change.
  7. dispose():

    • Finally, when the widget is removed, Flutter cleans up with dispose(). It's used for things like stopping listeners or releasing resources.

Understanding this process helps you control how your widgets behave and keep your app running smoothly.

Alright, Devs this is the end of the blog. I hope this blog helps you to understand Widgets and Stateful Widget lifecycle. So In our next blog, we talk about Flutter Tree.


Connect with Me:

Hey there! If you enjoyed reading this blog and found it informative, why not connect with me on LinkedIn? ๐Ÿ˜Š You can also follow my Instagram page for more mobile development-related content. ๐Ÿ“ฒ๐Ÿ‘จโ€๐Ÿ’ป Letโ€™s stay connected, share knowledge and have some fun in the exciting world of app development! ๐ŸŒŸ

Check out my Instagram page

Check out my LinkedIn

0
Subscribe to my newsletter

Read articles from Mayursinh Parmar directly inside your inbox. Subscribe to the newsletter, and don't miss out.

Written by

Mayursinh Parmar
Mayursinh Parmar

๐Ÿ“ฑMobile App Developer | Android & Flutter ๐ŸŒŸ๐Ÿ’ก Passionate about creating intuitive and engaging apps ๐Ÿ’ญโœจ Letโ€™s shape the future of mobile technology!