// 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.

import 'package:flutter/material.dart';

/// Flutter code sample for [ScrollNotificationObserver].

void main() => runApp(const ScrollNotificationObserverApp());

class ScrollNotificationObserverApp extends StatelessWidget {
  const ScrollNotificationObserverApp({super.key});

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      theme: ThemeData(useMaterial3: true),
      // The Scaffold widget contains a [ScrollNotificationObserver].
      // This is used by [AppBar] for its scrolled under behavior.
      //
      // We can use [ScrollNotificationObserver.maybeOf] to get the
      // state of this [ScrollNotificationObserver] from descendants
      // of the Scaffold widget.
      //
      // If you're not using a [Scaffold] widget, you can create a  [ScrollNotificationObserver]
      // to notify its descendants of scroll notifications by adding it to the subtree.
      home: Scaffold(
        appBar: AppBar(
          title: const Text('ScrollNotificationObserver Sample'),
        ),
        body: const ScrollNotificationObserverExample(),
      ),
    );
  }
}

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

  @override
  State<ScrollNotificationObserverExample> createState() => _ScrollNotificationObserverExampleState();
}

class _ScrollNotificationObserverExampleState extends State<ScrollNotificationObserverExample> {
  ScrollNotificationObserverState? _scrollNotificationObserver;
  ScrollController controller = ScrollController();
  bool _scrolledDown = false;

  @override
  void didChangeDependencies() {
    super.didChangeDependencies();
    // Remove any previous listener.
    _scrollNotificationObserver?.removeListener(_handleScrollNotification);
    // Get the ScrollNotificationObserverState from the Scaffold widget.
    _scrollNotificationObserver = ScrollNotificationObserver.maybeOf(context);
    // Add a new listener.
    _scrollNotificationObserver?.addListener(_handleScrollNotification);
  }

  @override
  void dispose() {
    if (_scrollNotificationObserver != null) {
      _scrollNotificationObserver!.removeListener(_handleScrollNotification);
      _scrollNotificationObserver = null;
    }
    controller.dispose();
    super.dispose();
  }

  void _handleScrollNotification(ScrollNotification notification) {
    // Check if the notification is a scroll update notification and if the
    // `notification.depth` is 0. This way we only listen to the scroll
    // notifications from the closest scrollable, instead of those that may be nested.
    if (notification is ScrollUpdateNotification && defaultScrollNotificationPredicate(notification)) {
      final ScrollMetrics metrics = notification.metrics;
      // Check if the user scrolled down.
      if (_scrolledDown != metrics.extentBefore > 0) {
        setState(() {
          _scrolledDown = metrics.extentBefore > 0;
        });
      }
    }
  }

  @override
  Widget build(BuildContext context) {
    return Stack(
      children: <Widget>[
        SampleList(controller: controller),
        // Show the button only if the user scrolled down.
        if (_scrolledDown)
          Positioned(
            right: 25,
            bottom: 20,
            child: Center(
              child: GestureDetector(
                onTap: () {
                  // Scroll to the top when the user taps the button.
                  controller.animateTo(0, duration: const Duration(milliseconds: 200), curve:Curves.fastOutSlowIn);
                },
                child: const Card(
                  child: Padding(
                    padding: EdgeInsets.all(8.0),
                    child: Column(
                      children: <Widget>[
                        Icon(Icons.arrow_upward_rounded),
                        Text('Scroll to top')
                      ],
                    ),
                  ),
                ),
              ),
            ),
          ),
      ],
    );
  }
}

class SampleList extends StatelessWidget {
  const SampleList({super.key, required this.controller});

  final ScrollController controller;

  @override
  Widget build(BuildContext context) {
    return ListView.builder(
      controller: controller,
      itemCount: 30,
      itemBuilder: (BuildContext context, int index) {
        return ListTile(title: Text('Item $index'));
      },
    );
  }
}
