Flutter Fundamentals: Your Journey to Beautiful App Development

Provider: A Declarative Approach to State Management

Welcome to the fascinating world of state management in Flutter! As your apps grow more complex, managing how data changes and affects your UI becomes crucial. This chapter dives into the essential techniques, and we'll kick things off with one of the most popular and recommended solutions: Provider. Provider is a powerful package that leverages the concept of dependency injection and a declarative approach to make your state management elegant and efficient.

At its core, Provider allows you to expose a value (your 'state') to a subtree of your widget tree. Widgets within that subtree can then easily access and listen to changes in this exposed value. The magic happens because when the value changes, only the widgets that are actively listening to that specific value will rebuild, leading to optimal performance. This is a significant improvement over rebuilding entire widget trees unnecessarily.

graph TD
    A[Widget Tree] --> B{Provider Up}
    B --> C[Consumer Widget]
    C --> D{State Changes}
    D --> C
    C --> E[UI Rebuilds]

Let's start by adding the Provider package to your pubspec.yaml file. Make sure to run flutter pub get afterwards to download the package.

dependencies:
  flutter:
    sdk: flutter
  provider:
    latest_version

The simplest form of Provider is the Provider widget itself. You wrap a part of your widget tree with Provider and tell it what value to expose. This value can be anything – a simple variable, an object, or even a complex model class.

import 'package:flutter/material.dart';
import 'package:provider/provider.dart';

void main() {
  runApp(MyApp());
}

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Provider<int>(
      create: (context) => 10,
      child: MaterialApp(
        title: 'Provider Demo',
        home: MyHomePage(),
      ),
    );
  }
}

class MyHomePage extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    // Accessing the provided value
    final int counter = Provider.of<int>(context);

    return Scaffold(
      appBar: AppBar(title: Text('Provider Demo')),
      body: Center(
        child: Text('The value is: $counter'),
      ),
    );
  }
}

In the code above, we provide an int value of 10 to the MaterialApp. Inside MyHomePage, we use Provider.of<int>(context) to retrieve this value. Notice that Provider.of takes the context and the type of the value you're expecting. By default, Provider.of will listen for changes and trigger a rebuild when the provided value changes.

チャプターへ戻る