// 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';
import 'package:flutter/rendering.dart';

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

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

  @override
  Widget build(BuildContext context) {
    return const MaterialApp(home: SettingsAppBarExample());
  }
}

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

  @override
  State<SettingsAppBarExample> createState() => _SettingsAppBarExampleState();
}

class _SettingsAppBarExampleState extends State<SettingsAppBarExample> {
  final GlobalKey headerSliverKey = GlobalKey();
  final GlobalKey titleSliverKey = GlobalKey();
  late final ScrollController scrollController;
  double headerOpacity = 0;

  @override
  void initState() {
    super.initState();
    scrollController = ScrollController();
  }

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

  // The key must be for a widget _below_ a RenderSliver so that
  // findAncestorRenderObjectOfType can find the RenderSliver when it searches
  // the key widget's renderer ancesotrs.
  RenderSliver? keyToSliver(GlobalKey key) => key.currentContext?.findAncestorRenderObjectOfType<RenderSliver>();

  // Each time the app's list scrolls: if the Title sliver has scrolled completely behind
  // the (pinned) header sliver, then change the header's opacity from 0 to 1.
  //
  // The header RenderSliver's SliverConstraints.scrollOffset is the distance
  // above the top of the viewport where the top of header sliver would appear
  // if it were laid out normally. Since it's a pinned sliver, it's unconditionally
  // painted at the top of the viewport, even though its scrollOffset constraint
  // increases as the user scrolls upwards. The "Settings" title RenderSliver's
  // scrollExtent is the vertical space it wants to occupy. It doesn't change as
  // the user scrolls.
  bool handleScrollNotification(ScrollNotification notification) {
    final RenderSliver? headerSliver = keyToSliver(headerSliverKey);
    final RenderSliver? titleSliver = keyToSliver(titleSliverKey);
    if (headerSliver != null && titleSliver != null && titleSliver.geometry != null) {
      final double opacity = headerSliver.constraints.scrollOffset > titleSliver.geometry!.scrollExtent ? 1 : 0;
      if (opacity != headerOpacity) {
        setState(() {
          headerOpacity = opacity;
        });
      }
    }
    return false;
  }

  @override
  Widget build(BuildContext context) {
    const EdgeInsets horizontalPadding = EdgeInsets.symmetric(horizontal: 8);
    final ThemeData theme = Theme.of(context);
    final TextTheme textTheme = theme.textTheme;
    final ColorScheme colorScheme = theme.colorScheme;

    return Scaffold(
      backgroundColor: colorScheme.surfaceContainer,
      body: SafeArea(
        child: NotificationListener<ScrollNotification>(
          onNotification: handleScrollNotification,
          child: CustomScrollView(
            controller: scrollController,
            slivers: <Widget>[
              PinnedHeaderSliver(
                child: Header(
                  key: headerSliverKey,
                  opacity: headerOpacity,
                  child: Text('Settings', style: textTheme.titleMedium),
                ),
              ),
              SliverPadding(
                padding: horizontalPadding,
                sliver: SliverToBoxAdapter(
                  child: TitleItem(
                    key: titleSliverKey,
                    child: Text(
                      'Settings',
                      style: textTheme.titleLarge!.copyWith(
                        fontWeight: FontWeight.bold,
                        fontSize: 32,
                      ),
                    ),
                  ),
                ),
              ),
              const SliverPadding(
                padding: horizontalPadding,
                sliver: ItemList(),
              ),
            ],
          ),
        ),
      ),
    );
  }
}

// The pinned item at the top of the list. This is an implicitly
// animated widget: when the opacity changes the title and divider
// fade in or out.
class Header extends StatelessWidget {
  const Header({ super.key, required this.opacity, required this.child });

  final double opacity;
  final Widget child;

  @override
  Widget build(BuildContext context) {
    final ThemeData theme = Theme.of(context);
    final ColorScheme colorScheme = theme.colorScheme;

    return AnimatedContainer(
      duration: const Duration(milliseconds: 300),
      padding: const EdgeInsets.symmetric(vertical: 12),
      decoration: ShapeDecoration(
        color: opacity == 0 ? colorScheme.surfaceContainer : colorScheme.surfaceContainerLowest,
        shape: LinearBorder.bottom(
          side: BorderSide(
            color: opacity == 0 ? colorScheme.surfaceContainer : colorScheme.surfaceContainerHighest,
          ),
        ),
      ),
      alignment: Alignment.center,
      child: AnimatedOpacity(
        opacity: opacity,
        duration: const Duration(milliseconds: 300),
        child: child,
      ),
    );
  }
}

// The second item in the list. It scrolls normally. When it has scrolled
// completely out of view behind the first, pinned, Header item, the Header
// fades in.
class TitleItem extends StatelessWidget {
  const TitleItem({ super.key, required this.child });

  final Widget child;

  @override
  Widget build(BuildContext context) {
    return Container(
      alignment: AlignmentDirectional.bottomStart,
      padding: const EdgeInsets.symmetric(vertical: 8),
      child: child,
    );
  }
}

// A placeholder SliverList of 50 items.
class ItemList extends StatelessWidget {
  const ItemList({
    super.key,
    this.itemCount = 50,
  });

  final int itemCount;

  @override
  Widget build(BuildContext context) {
    final ColorScheme colorScheme = Theme.of(context).colorScheme;
    return SliverList(
      delegate: SliverChildBuilderDelegate(
        (BuildContext context, int index) {
          return Card(
            color: colorScheme.onSecondary,
            child: ListTile(
              textColor: colorScheme.secondary,
              title: Text('Item $index'),
            ),
          );
        },
        childCount: itemCount,
      ),
    );
  }
}
