flutter/examples
Vincent Velociter 6e246ac854
Cupertino transparent navigation bars (#149102)
This PR is making the `CupertinoNavigationBar` and `CupertinoSliverNavigationBar` appear transparent as long as the content is not scrolled under them, so they look like standard iOS apps nav bars.

https://github.com/flutter/flutter/assets/423393/eee2700b-2a91-4577-922c-6163d47cb357

https://github.com/flutter/flutter/assets/423393/3847f2b5-0dac-4d5e-aa6f-03c1d2893e30

<details>
  <summary>Demo app code</summary>
  
  ```dart
import 'package:flutter/cupertino.dart';

/// Flutter code sample for [CupertinoTabScaffold].

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

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

  @override
  State<TabScaffoldApp> createState() => _TabScaffoldAppState();
}

class _TabScaffoldAppState extends State<TabScaffoldApp> {
  Brightness _brightness = Brightness.light;

  @override
  Widget build(BuildContext context) {
    return CupertinoApp(
      theme: CupertinoThemeData(brightness: _brightness),
      home: TabScaffoldExample(
          brightness: _brightness, onBrightnessToggle: _toggleBrightness),
    );
  }

  void _toggleBrightness() {
    setState(() {
      _brightness =
          _brightness == Brightness.light ? Brightness.dark : Brightness.light;
    });
  }
}

class TabScaffoldExample extends StatefulWidget {
  const TabScaffoldExample(
      {required this.brightness, required this.onBrightnessToggle, super.key});

  final VoidCallback onBrightnessToggle;
  final Brightness brightness;

  @override
  State<TabScaffoldExample> createState() => _TabScaffoldExampleState();
}

class _TabScaffoldExampleState extends State<TabScaffoldExample> {
  @override
  Widget build(BuildContext context) {
    return CupertinoTabScaffold(
      tabBar: CupertinoTabBar(
        items: const <BottomNavigationBarItem>[
          BottomNavigationBarItem(
            icon: Icon(CupertinoIcons.home),
            label: 'Home',
          ),
          BottomNavigationBarItem(
            icon: Icon(CupertinoIcons.search_circle_fill),
            label: 'Explore',
          ),
          BottomNavigationBarItem(
            icon: Icon(CupertinoIcons.person_fill),
            label: 'Profile',
          ),
          BottomNavigationBarItem(
            icon: Icon(CupertinoIcons.settings_solid),
            label: 'Settings',
          ),
        ],
      ),
      tabBuilder: (BuildContext context, int index) {
        return CupertinoTabView(
          builder: (BuildContext context) {
            return CupertinoPageScaffold(
              backgroundColor: index == 3
                  ? CupertinoColors.secondarySystemBackground
                      .resolveFrom(context)
                  : null,
              child: CustomScrollView(
                slivers: [
                  CupertinoSliverNavigationBar(
                    largeTitle: Text('Tab $index'),
                    initiallyTransparent: index != 2,
                    trailing: CupertinoButton(
                      padding: EdgeInsets.zero,
                      onPressed: widget.onBrightnessToggle,
                      child: Icon(
                        widget.brightness == Brightness.light
                            ? CupertinoIcons.moon_stars
                            : CupertinoIcons.sun_max,
                      ),
                    ),
                  ),
                  SliverSafeArea(
                    top: false,
                    sliver: SliverList.list(
                      children: [
                        CupertinoButton(
                          child: const Text('Next page'),
                          onPressed: () {
                            Navigator.of(context).push(
                              CupertinoPageRoute<void>(
                                builder: (BuildContext context) {
                                  return CupertinoPageScaffold(
                                    navigationBar: CupertinoNavigationBar(
                                      middle: Text('Inner page of tab $index'),
                                    ),
                                    child: ListView(
                                      children: [
                                        Center(
                                          child: CupertinoButton(
                                            child: const Text('Back'),
                                            onPressed: () {
                                              Navigator.of(context).pop();
                                            },
                                          ),
                                        ),
                                        if (index == 0) const _LongList(),
                                        const SizedBox(height: 20),
                                      ],
                                    ),
                                  );
                                },
                              ),
                            );
                          },
                        ),
                        if (index == 1) const _LongList(),
                        const SizedBox(height: 20),
                      ],
                    ),
                  ),
                ],
              ),
            );
          },
        );
      },
    );
  }
}

class _LongList extends StatelessWidget {
  const _LongList();

  @override
  Widget build(BuildContext context) {
    return Column(
      children: [
        for (int i = 0; i < 50; i++) ...[
          CupertinoListTile(
            leading: const Icon(CupertinoIcons.book),
            title: Text('Bookstore item $i'),
          ),
        ],
      ],
    );
  }
}
  ```
</details>

This is the continuation of https://github.com/flutter/flutter/pull/142439.

I tried to keep the simplest API possible, so it's only introducing a new `automaticBackgroundVisibility` boolean parameter. 

In the implementation I had to use the `CupertinoPageScaffold` background color to make it look transparent instead of a 0 opacity, because of issues with route transitions.

I used an `InheritedWidget` so the nav bar is always getting the right background color from the parent scaffold, whether it is overridden or not. It would probably be better to make the inherited widget private but we'd need to move all the nav bar code to the same file as the scaffold, so for now I've just hidden it from the export. Let me know if it is okay to do that.

This PR is not dealing with the bottom tab bar, because the same [straightforward approach](dde8ec6dc7) doesn't work here. The problem is that the scroll notification is sent only when the scroll view is created or updated, so it doesn't work if one pushes a screen and navigates back.

Issues:
- #78607 
- #60411
2024-07-03 20:35:27 +00:00
..
api Cupertino transparent navigation bars (#149102) 2024-07-03 20:35:27 +00:00
flutter_view Manual engine roll to ddd4814 (#150952) 2024-06-27 21:57:32 +00:00
hello_world Manual engine roll to ddd4814 (#150952) 2024-06-27 21:57:32 +00:00
image_list Manual engine roll to ddd4814 (#150952) 2024-06-27 21:57:32 +00:00
layers Manual engine roll to ddd4814 (#150952) 2024-06-27 21:57:32 +00:00
platform_channel Manual engine roll to ddd4814 (#150952) 2024-06-27 21:57:32 +00:00
platform_channel_swift Remove discontinued device_info and connectivity plugins from flutter_gallery, roll pub packages (#150585) 2024-06-21 23:10:24 +00:00
platform_view Manual engine roll to ddd4814 (#150952) 2024-06-27 21:57:32 +00:00
splash Roll pub packages (#150267) 2024-06-14 18:19:41 +00:00
texture Remove discontinued device_info and connectivity plugins from flutter_gallery, roll pub packages (#150585) 2024-06-21 23:10:24 +00:00
.clang-format Implement Linux part of examples (#108068) 2022-12-08 08:44:11 +13:00
flutter_gallery.readme Move flutter_gallery to the testing folder (#52532) 2020-03-16 10:31:42 +01:00
README.md Update flutter.dev links from misc packages to more permanent destinations (#150532) 2024-06-20 23:09:08 +00:00

Flutter Examples

This directory contains several examples of using Flutter. To run an example, use flutter run inside that example's directory. See the getting started guide to install the flutter tool.

For additional samples, see the flutter/samples repo.

Available examples include:

Notes

Note on Gradle wrapper files in .gitignore:

Gradle wrapper files should normally be checked into source control. The example projects don't do that to avoid having several copies of the wrapper binary in the Flutter repo. Instead, the Gradle wrapper is injected by Flutter tooling, and the wrapper files are .gitignore'd to avoid making the Flutter repository dirty as a side effect of running the examples.