1. 25 Aug, 2023 2 commits
  2. 17 Aug, 2023 1 commit
  3. 10 Aug, 2023 1 commit
  4. 08 Aug, 2023 1 commit
  5. 04 Aug, 2023 1 commit
    • Justin McCandless's avatar
      Predictive back support for root routes (#120385) · dedd100e
      Justin McCandless authored
      This PR aims to support Android's predictive back gesture when popping the entire Flutter app.  Predictive route transitions between routes inside of a Flutter app will come later.
      
      <img width="200" src="https://user-images.githubusercontent.com/389558/217918109-945febaa-9086-41cc-a476-1a189c7831d8.gif" />
      
      ### Trying it out
      
      If you want to try this feature yourself, here are the necessary steps:
      
        1. Run Android 33 or above.
        1. Enable the feature flag for predictive back on the device under "Developer
           options".
        1. Create a Flutter project, or clone [my example project](https://github.com/justinmc/flutter_predictive_back_examples).
        1. Set `android:enableOnBackInvokedCallback="true"` in
           android/app/src/main/AndroidManifest.xml (already done in the example project).
        1. Check out this branch.
        1. Run the app. Perform a back gesture (swipe from the left side of the
           screen).
      
      You should see the predictive back animation like in the animation above and be able to commit or cancel it.
      
      ### go_router support
      
      go_router works with predictive back out of the box because it uses a Navigator internally that dispatches NavigationNotifications!
      
      ~~go_router can be supported by adding a listener to the router and updating SystemNavigator.setFrameworkHandlesBack.~~
      
      Similar to with nested Navigators, nested go_routers is supported by using a PopScope widget.
      
      <details>
      
      <summary>Full example of nested go_routers</summary>
      
      ```dart
      // 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:go_router/go_router.dart';
      
      import 'package:flutter/material.dart';
      import 'package:flutter/scheduler.dart';
      
      void main() => runApp(_MyApp());
      
      class _MyApp extends StatelessWidget {
        final GoRouter router = GoRouter(
          routes: <RouteBase>[
            GoRoute(
              path: '/',
              builder: (BuildContext context, GoRouterState state) => _HomePage(),
            ),
            GoRoute(
              path: '/nested_navigators',
              builder: (BuildContext context, GoRouterState state) => _NestedGoRoutersPage(),
            ),
          ],
        );
      
        @override
        Widget build(BuildContext context) {
          return MaterialApp.router(
            routerConfig: router,
          );
        }
      }
      
      class _HomePage extends StatelessWidget {
        @override
        Widget build(BuildContext context) {
          return Scaffold(
            appBar: AppBar(
              title: const Text('Nested Navigators Example'),
            ),
            body: Center(
              child: Column(
                mainAxisAlignment: MainAxisAlignment.center,
                children: <Widget>[
                  const Text('Home Page'),
                  const Text('A system back gesture here will exit the app.'),
                  const SizedBox(height: 20.0),
                  ListTile(
                    title: const Text('Nested go_router route'),
                    subtitle: const Text('This route has another go_router in addition to the one used with MaterialApp above.'),
                    onTap: () {
                      context.push('/nested_navigators');
                    },
                  ),
                ],
              ),
            ),
          );
        }
      }
      
      class _NestedGoRoutersPage extends StatefulWidget {
        @override
        State<_NestedGoRoutersPage> createState() => _NestedGoRoutersPageState();
      }
      
      class _NestedGoRoutersPageState extends State<_NestedGoRoutersPage> {
        late final GoRouter _router;
        final GlobalKey<NavigatorState> _nestedNavigatorKey = GlobalKey<NavigatorState>();
      
        // If the nested navigator has routes that can be popped, then we want to
        // block the root navigator from handling the pop so that the nested navigator
        // can handle it instead.
        bool get _popEnabled {
          // canPop will throw an error if called before build. Is this the best way
          // to avoid that?
          return _nestedNavigatorKey.currentState == null ? true : !_router.canPop();
        }
      
        void _onRouterChanged() {
          // Here the _router reports the location correctly, but canPop is still out
          // of date.  Hence the post frame callback.
          SchedulerBinding.instance.addPostFrameCallback((Duration duration) {
            setState(() {});
          });
        }
      
        @override
        void initState() {
          super.initState();
      
          final BuildContext rootContext = context;
          _router = GoRouter(
            navigatorKey: _nestedNavigatorKey,
            routes: [
              GoRoute(
                path: '/',
                builder: (BuildContext context, GoRouterState state) => _LinksPage(
                  title: 'Nested once - home route',
                  backgroundColor: Colors.indigo,
                  onBack: () {
                    rootContext.pop();
                  },
                  buttons: <Widget>[
                    TextButton(
                      onPressed: () {
                        context.push('/two');
                      },
                      child: const Text('Go to another route in this nested Navigator'),
                    ),
                  ],
                ),
              ),
              GoRoute(
                path: '/two',
                builder: (BuildContext context, GoRouterState state) => _LinksPage(
                  backgroundColor: Colors.indigo.withBlue(255),
                  title: 'Nested once - page two',
                ),
              ),
            ],
          );
      
          _router.addListener(_onRouterChanged);
        }
      
        @override
        void dispose() {
          _router.removeListener(_onRouterChanged);
          super.dispose();
        }
      
        @override
        Widget build(BuildContext context) {
          return PopScope(
            popEnabled: _popEnabled,
            onPopped: (bool success) {
              if (success) {
                return;
              }
              _router.pop();
            },
            child: Router<Object>.withConfig(
              restorationScopeId: 'router-2',
              config: _router,
            ),
          );
        }
      }
      
      class _LinksPage extends StatelessWidget {
        const _LinksPage ({
          required this.backgroundColor,
          this.buttons = const <Widget>[],
          this.onBack,
          required this.title,
        });
      
        final Color backgroundColor;
        final List<Widget> buttons;
        final VoidCallback? onBack;
        final String title;
      
        @override
        Widget build(BuildContext context) {
          return Scaffold(
            backgroundColor: backgroundColor,
            body: Center(
              child: Column(
                mainAxisAlignment: MainAxisAlignment.center,
                children: <Widget>[
                  Text(title),
                  //const Text('A system back here will go back to Nested Navigators Page One'),
                  ...buttons,
                  TextButton(
                    onPressed: onBack ?? () {
                      context.pop();
                    },
                    child: const Text('Go back'),
                  ),
                ],
              ),
            ),
          );
        }
      }
      ```
      
      </details>
      
      ### Resources
      
      Fixes https://github.com/flutter/flutter/issues/109513
      Depends on engine PR https://github.com/flutter/engine/pull/39208 :heavy_check_mark: 
      Design doc: https://docs.google.com/document/d/1BGCWy1_LRrXEB6qeqTAKlk-U2CZlKJ5xI97g45U7azk/edit#
      Migration guide: https://github.com/flutter/website/pull/8952
      dedd100e
  6. 17 Jul, 2023 1 commit
  7. 28 Jun, 2023 1 commit
  8. 26 Jun, 2023 1 commit
  9. 20 Jun, 2023 1 commit
    • Tae Hyung Kim's avatar
      DecoratedSliver (#127823) · 541fdd60
      Tae Hyung Kim authored
      This is a second attempt to merge #107269. Currently I've fixed two of the issues:
      1. Fixed horizontal scrollview by using a switch statement to consider vertical/horizontal case.
      2. Fixed issue of `paintExtent` not being the right extent for painting. Rather using a `scrollExtent` for the main axis length of the decoration box and painting it offsetted by the `scrollOffset`.
      3. If the sliver child has inifinite scrollExtent, then we only draw the decoration down to the bottom of the `cacheExtent`. The developer is expected to ensure that the border does not creep up above the cache area.
      
      This PR includes a test that checks that the correct rectangle is drawn at a certain scrollOffset for both the horizontal and vertical case which should be sufficient for checking that `SliverDecoration` works properly now.
      
      Fixes https://github.com/flutter/flutter/issues/107498.
      541fdd60
  10. 15 Jun, 2023 1 commit
  11. 13 Jun, 2023 1 commit
  12. 08 Jun, 2023 2 commits
  13. 26 May, 2023 1 commit
  14. 25 May, 2023 1 commit
  15. 16 May, 2023 1 commit
    • Ian Hickson's avatar
      Make SlottedMultiChildRenderObjectWidgetMixin a concrete class (#126108) · 027bb844
      Ian Hickson authored
      This is a proof of concept for renaming SlottedMultiChildRenderObjectWidgetMixin to SlottedMultiChildRenderObjectWidget and making it a concrete class.
      
      I also made SlottedContainerRenderObjectMixin generic instead of being specialized to RenderBox.
      
      I don't think this is something we can easily automigrate, but we may not need to, I don't know how common this is...
      027bb844
  16. 15 May, 2023 1 commit
  17. 11 May, 2023 1 commit
  18. 09 May, 2023 1 commit
  19. 28 Apr, 2023 1 commit
  20. 24 Apr, 2023 1 commit
  21. 20 Apr, 2023 1 commit
  22. 10 Apr, 2023 1 commit
  23. 05 Apr, 2023 1 commit
  24. 04 Apr, 2023 1 commit
  25. 30 Mar, 2023 1 commit
  26. 22 Mar, 2023 2 commits
  27. 08 Mar, 2023 2 commits
  28. 02 Mar, 2023 1 commit
  29. 27 Feb, 2023 1 commit
  30. 23 Feb, 2023 1 commit
  31. 17 Feb, 2023 1 commit
  32. 03 Feb, 2023 1 commit
  33. 02 Feb, 2023 1 commit
  34. 31 Jan, 2023 1 commit
    • Tanay Neotia's avatar
      Add support for image insertion on Android (#110052) · 0e22aca7
      Tanay Neotia authored
      * Add support for image insertion on Android
      
      * Fix checks
      
      * Use proper Dart syntax on snippet
      
      * Specify type annotation on list
      
      * Fix nits, add some asserts, and improve example code
      
      * Add missing import
      
      * Fix nullsafety error
      
      * Fix nullsafety error
      
      * Remove reference to contentCommitMimeTypes in docs
      
      * Fix nits
      
      * Fix warnings and import
      
      * Add test for content commit in editable_text_test.dart
      
      * Check that URIs are equal in test
      
      * Fix nits and rename functions / classes to be more self-explanatory
      
      * Fix failing debugFillProperties tests
      
      * Add empty implementation to `insertContent` in TextInputClient
      
      * Tweak documentation slightly
      
      * Improve docs for contentInsertionMimeTypes and fix assert
      
      * Rework contentInsertionMimeType asserts
      
      * Add test for onContentInserted example
      
      * Switch implementation to a configuration class for more granularity in setting mime types
      
      * Fix nits
      
      * Improve docs and fix doc tests
      
      * Fix more nits (LongCatIsLooong)
      
      * Fix failing tests
      
      * Make parameters (guaranteed by platform to be non-nullable) non-nullable
      
      * Fix analysis issues
      0e22aca7
  35. 24 Jan, 2023 1 commit
  36. 18 Jan, 2023 1 commit