How to create a custom widget in Flutter

Flutter provides a wide variety of built-in widgets to create rich user interfaces. However, sometimes you might need your widget to cater to some specific design requirements. For this purpose, Flutter also gives the option of making custom widgets and using them to encapsulate a particular functionality.

Custom widgets in Flutter refer to user-defined classes or UI components that are used to meet specific requirements of the app that the built-in widgets cannot efficiently meet.

The custom widgets can belong to either of the two types of states, which are

  • Stateless widgets

  • Stateful widgets

How does a custom widget work in Flutter

The custom widgets act as a building block for constructing an efficient and reusable user interface. It allows the encapsulation of a set of related widgets, properties, and behaviors into a reusable component.

This allows you to reuse your custom widget by importing it wherever you want, thus, promoting code reusability and maintainability.

Types of custom widgets

Custom widgets can range from simple built-in Flutter components, such as buttons or icons, to lengthy compound widgets that are made by combining multiple existing Flutter widgets.

This enables you to create unique, reusable widgets that meet the specific criteria of your mobile application.

Creating a custom widget in your Flutter app

To create your very own customized widget in Flutter, make a new project or open an existing one and import all the necessary packages in your dart file.

After that, choose whether you want a stateless widget or a stateful widget. According to that, you can extend either one of the two classes based on your own requirements.

To learn about the differences between stateless and stateful widgets, read this.

Structure of a stateless custom widget

class CustomWidget extends StatelessWidget {
@override
Widget build(BuildContext context) {
// Widget implementation goes here
}
}
Stateless custom widget

Inside the custom widget class, you can implement the build method according to your own specifications.

This method specifies how your widget should be rendered on the screen. It's where you define the structure and appearance of your custom widget.

Structure of a stateful custom widget

class CustomWidget extends StatefulWidget {
@override
_CustomWidgetState createState() => _CustomWidgetState();
}
class _CustomWidgetState extends State<CustomWidget> {
@override
Widget build(BuildContext context) {
// Widget properties and styling go here
}
}
Stateful custom widget

In this example, we have a custom widget named CustomWidget that extends the StatefulWidget class. The stateful widget has two classes: CustomWidget and _CustomWidgetState.

The _CustomWidgetState class is responsible for managing the internal state of the widget. However, in this case, the method is left empty since no specific functionality is defined.

Code demonstration of custom widgets in Flutter

In this context, we will be taking an example of a stateful custom widget and incorporating that into our own Flutter app.

import 'package:flutter/material.dart';

class MyCustomWidget extends StatefulWidget {
  @override
  _MyCustomWidgetState createState() => _MyCustomWidgetState();
}

class _MyCustomWidgetState extends State<MyCustomWidget>
    with SingleTickerProviderStateMixin {
  AnimationController _animationController;
  Animation<Color> _colorAnimation;

  @override
  void initState() {
    super.initState();
    _animationController = AnimationController(
      vsync: this,
      duration: Duration(seconds: 2),
    );

    _colorAnimation = ColorTween(
      begin: Colors.blue,
      end: Colors.orange,
    ).animate(_animationController);

    _animationController.repeat(reverse: true);
  }

  @override
  void dispose() {
    _animationController.dispose();
    super.dispose();
  }

  @override
  Widget build(BuildContext context) {
    return GestureDetector(
      onTap: () {
        if (_animationController.isAnimating) {
          _animationController.stop();
        } else {
          _animationController.repeat(reverse: true);
        }
      },
      child: AnimatedBuilder(
        animation: _colorAnimation,
        builder: (context, child) {
          return Container(
            width: 200.0,
            height: 100.0,
            color: _colorAnimation.value,
            child: Center(
              child: Text(
                'Educative.io',
                style: TextStyle(
                  fontSize: 30.0,
                  color: Colors.white,
                  fontWeight: FontWeight.bold,
                ),
              ),
            ),
          );
        },
      ),
    );
  }
}


Stateful Custom widget

The illustration outputted above could not be achieved by any built-in widgets of the Flutter. However, creating our very own custom widget named, MyCustomWidget, we managed to create a reusable and customized widget that can be incorporated anywhere in our app.

Code explanation

The stateful widget has two classes: MyCustomWidget and _MyCustomWidgetState. The _MyCustomWidgetState class is responsible for managing the internal state of the widget. It includes an AnimationController and an Animation<Color> to control the color animation.

  • Lines 14–19: In the initState method, we initialize the animation controller and define the color animation using a ColorTween. The animation controller is set to repeat with a duration of 2 seconds and reverse direction when reaching the end.

  • Lines 30–33: The dispose method is used to dispose of the animation controller when the widget is removed from the widget tree.

  • Lines 36–44: The build method sets up a GestureDetector to handle tap events. When the widget is tapped, it stops or starts the animation depending on the current animation state.

  • Lines 45–66: The AnimatedBuilder defines the visual representation of the widget and rebuilds whenever the color animation changes. The container's color is set to the current value of the animation, creating the effect of animated color changes.

To use this interactive custom widget, we can import the file where it is defined, and place it in the widget tree like any other Flutter widget.

Free Resources

Copyright ©2025 Educative, Inc. All rights reserved