What are Widgets?

In Flitter, widgets are the fundamental building blocks of your application’s user interface. Inspired by Flutter, everything you see on the screen in a Flitter app is a widget. Understanding widgets is crucial for effectively using Flitter to create data visualizations and interactive interfaces.

Definition of Widgets

A widget in Flitter is an immutable description of part of a user interface. Widgets can describe:

  • Structural elements (like containers or rows)
  • Stylistic elements (like colors or fonts)
  • Layout aspects (like padding or alignment)
  • And more complex functionalities (like gestures or animations)

Types of Widgets

Flitter provides several types of widgets, broadly categorized as:

  1. Basic Widgets: Such as Container, Text, and Image.
  2. Layout Widgets: Like Row, Column, and Stack.
  3. Interactive Widgets: Including GestureDetector and Button.
  4. Painting and Effect Widgets: For example, Transform and Opacity.
  5. Stateful Widgets: Widgets that can change over time based on user interaction or other factors.

Using Widgets

Here’s a simple example of how widgets are used in Flitter:

import {
  Container,
  Text,
  Center,
  TextStyle,
  Colors,
} from "@meursyphus/flitter";

const MyWidget = Container({
  width: 200,
  height: 100,
  color: Colors.blue[500],
  child: Center({
    child: Text("Hello, Flitter!", {
      style: new TextStyle({ color: Colors.white, fontSize: 20 }),
    }),
  }),
});

In this example, we’re using Container, Center, and Text widgets to create a blue rectangle with centered white text.

Widget Tree

Widgets in Flitter are arranged in a tree structure. This tree represents the hierarchy of your user interface. For example:

       App

    Container

      Center

       Text

Each widget in the tree can have child widgets, creating a nested structure that defines your entire UI.

Composition vs Inheritance

Flitter favors composition over inheritance when it comes to creating custom widgets. This means that instead of subclassing existing widgets, you typically create new widgets by combining existing ones.

Stateless vs Stateful Widgets

Flitter has two main types of widgets:

  1. Stateless Widgets: These are immutable. Once they’re built, their properties can’t change.
  2. Stateful Widgets: These can rebuild themselves when their internal state changes.

Let’s look at examples of both:

Stateless Widget Example

Stateless widgets are simpler and more efficient when you don’t need to manage changing state. Here’s an example:

import {
  StatelessWidget,
  Container,
  Text,
  TextStyle,
  Colors,
} from "@meursyphus/flitter";

class Greeting extends StatelessWidget {
  private name: string;

  constructor(name: string) {
    super();
    this.name = name;
  }

  build() {
    return Container({
      padding: EdgeInsets.all(16),
      color: Colors.blue[100],
      child: Text(`Hello, ${this.name}!`, {
        style: new TextStyle({ color: Colors.black, fontSize: 24 }),
      }),
    });
  }
}

// Usage
const myGreeting = new Greeting("Alice");

In this example, Greeting is a stateless widget that displays a greeting message. It takes a name as a parameter and uses it to create the greeting. Once created, the greeting doesn’t change.

Stateful Widget Example

Stateful widgets are used when the widget needs to maintain some state that can change over time. Here’s an example of a simple counter:

import {
  StatefulWidget,
  State,
  Container,
  Text,
  TextStyle,
  Colors,
  GestureDetector,
} from "@meursyphus/flitter";

class Counter extends StatefulWidget {
  createState() {
    return new CounterState();
  }
}

class CounterState extends State<Counter> {
  private count: number = 0;

  incrementCounter() {
    this.setState(() => {
      this.count++;
    });
  }

  build() {
    return Container({
      padding: EdgeInsets.all(16),
      color: Colors.blue[100],
      child: GestureDetector({
        onTap: () => this.incrementCounter(),
        child: Text(`Count: ${this.count}`, {
          style: new TextStyle({ color: Colors.black, fontSize: 24 }),
        }),
      }),
    });
  }
}

// Usage
const myCounter = new Counter();

In this example, Counter is a stateful widget that maintains a count state. The CounterState class manages the state and provides a method to increment the counter. The build method creates a text display of the current count, wrapped in a GestureDetector that increments the count when tapped.

Conclusion

Understanding the difference between stateless and stateful widgets is crucial for efficient Flitter development. Use stateless widgets for parts of your UI that depend only on their configuration info and the current theme, while stateful widgets are perfect for parts of the UI that need to dynamically change based on user interaction or other factors.

In the next sections, we’ll dive deeper into specific types of widgets and how to manage their state more effectively.

We’ll explore the difference between stateless and stateful widgets in more depth in the State Management section.