// Copyright 2014 The Flutter Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

// Flutter code sample for a [ChangeNotifier] with a [ListenableBuilder].

import 'dart:math' as math;
import 'package:flutter/material.dart';

void main() { runApp(const ListenableBuilderExample()); }

class ListModel with ChangeNotifier {
  final List<int> _values = <int>[];
  List<int> get values => _values.toList(); // O(N), makes a new copy each time.

  void add(int value) {
    _values.add(value);
    notifyListeners();
  }
}

class ListenableBuilderExample extends StatefulWidget {
  const ListenableBuilderExample({super.key});

  @override
  State<ListenableBuilderExample> createState() => _ListenableBuilderExampleState();
}

class _ListenableBuilderExampleState extends State<ListenableBuilderExample> {
  final ListModel _listNotifier = ListModel();
  final math.Random _random = math.Random(0); // fixed seed for reproducability

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: Scaffold(
        appBar: AppBar(title: const Text('ListenableBuilder Example')),
        body: ListBody(listNotifier: _listNotifier),
        floatingActionButton: FloatingActionButton(
          onPressed: () => _listNotifier.add(_random.nextInt(1 << 32)), // 1 << 32 is the maximum supported value
          child: const Icon(Icons.add),
        ),
      ),
    );
  }
}

class ListBody extends StatelessWidget {
  const ListBody({super.key, required this.listNotifier});

  final ListModel listNotifier;

  @override
  Widget build(BuildContext context) {
    return Center(
      child: Column(
        crossAxisAlignment: CrossAxisAlignment.stretch,
        children: <Widget>[
          const Text('Current values:'),
          Expanded(
            child: ListenableBuilder(
              listenable: listNotifier,
              builder: (BuildContext context, Widget? child) {
                // We rebuild the ListView each time the list changes,
                // so that the framework knows to update the rendering.
                final List<int> values = listNotifier.values; // copy the list
                return ListView.builder(
                  itemBuilder: (BuildContext context, int index) => ListTile(
                    title: Text('${values[index]}'),
                  ),
                  itemCount: values.length,
                );
              },
            ),
          ),
        ],
      ),
    );
  }
}
