1. 02 Aug, 2023 3 commits
    • Taha Tesser's avatar
      Fix Scrollable `TabBar` for Material 3 (#131409) · 2c71881f
      Taha Tesser authored
      fixes [Material 3 `TabBar` does not take full width when `isScrollable: true`](https://github.com/flutter/flutter/issues/117722)
      
      ### Description
      1. Fixed the divider doesn't stretch to take all the available width in the scrollable tab bar in M3
      2. Added `dividerHeight` property.
      
      ### Code sample
      
      <details> 
      <summary>expand to view the code sample</summary> 
      
      ```dart
      import 'package:flutter/material.dart';
      
      /// Flutter code sample for [TabBar].
      
      void main() => runApp(const TabBarApp());
      
      class TabBarApp extends StatelessWidget {
        const TabBarApp({super.key});
      
        @override
        Widget build(BuildContext context) {
          return const MaterialApp(
            debugShowCheckedModeBanner: false,
            home: TabBarExample(),
          );
        }
      }
      
      class TabBarExample extends StatefulWidget {
        const TabBarExample({super.key});
      
        @override
        State<TabBarExample> createState() => _TabBarExampleState();
      }
      
      class _TabBarExampleState extends State<TabBarExample> {
        bool rtl = false;
        bool customColors = false;
        bool removeDivider = false;
        Color dividerColor = Colors.amber;
        Color indicatorColor = Colors.red;
      
        @override
        Widget build(BuildContext context) {
          return DefaultTabController(
            initialIndex: 1,
            length: 3,
            child: Directionality(
              textDirection: rtl ? TextDirection.rtl : TextDirection.ltr,
              child: Scaffold(
                appBar: AppBar(
                  title: const Text('TabBar Sample'),
                  actions: <Widget>[
                    IconButton.filledTonal(
                      tooltip: 'Switch direction',
                      icon: const Icon(Icons.swap_horiz),
                      onPressed: () {
                        setState(() {
                          rtl = !rtl;
                        });
                      },
                    ),
                    IconButton.filledTonal(
                      tooltip: 'Use custom colors',
                      icon: const Icon(Icons.color_lens),
                      onPressed: () {
                        setState(() {
                          customColors = !customColors;
                        });
                      },
                    ),
                    IconButton.filledTonal(
                      tooltip: 'Show/hide divider',
                      icon: const Icon(Icons.remove_rounded),
                      onPressed: () {
                        setState(() {
                          removeDivider = !removeDivider;
                        });
                      },
                    ),
                  ],
                ),
                body: Column(
                  children: <Widget>[
                    const Spacer(),
                    const Text('Scrollable - TabAlignment.start'),
                    TabBar(
                      isScrollable: true,
                      tabAlignment: TabAlignment.start,
                      dividerColor: customColors ? dividerColor : null,
                      indicatorColor: customColors ? indicatorColor : null,
                      dividerHeight: removeDivider ? 0 : null,
                      tabs: const <Widget>[
                        Tab(
                          icon: Icon(Icons.cloud_outlined),
                        ),
                        Tab(
                          icon: Icon(Icons.beach_access_sharp),
                        ),
                        Tab(
                          icon: Icon(Icons.brightness_5_sharp),
                        ),
                      ],
                    ),
                    const Text('Scrollable - TabAlignment.startOffset'),
                    TabBar(
                      isScrollable: true,
                      tabAlignment: TabAlignment.startOffset,
                      dividerColor: customColors ? dividerColor : null,
                      indicatorColor: customColors ? indicatorColor : null,
                      dividerHeight: removeDivider ? 0 : null,
                      tabs: const <Widget>[
                        Tab(
                          icon: Icon(Icons.cloud_outlined),
                        ),
                        Tab(
                          icon: Icon(Icons.beach_access_sharp),
                        ),
                        Tab(
                          icon: Icon(Icons.brightness_5_sharp),
                        ),
                      ],
                    ),
                    const Text('Scrollable - TabAlignment.center'),
                    TabBar(
                      isScrollable: true,
                      tabAlignment: TabAlignment.center,
                      dividerColor: customColors ? dividerColor : null,
                      indicatorColor: customColors ? indicatorColor : null,
                      dividerHeight: removeDivider ? 0 : null,
                      tabs: const <Widget>[
                        Tab(
                          icon: Icon(Icons.cloud_outlined),
                        ),
                        Tab(
                          icon: Icon(Icons.beach_access_sharp),
                        ),
                        Tab(
                          icon: Icon(Icons.brightness_5_sharp),
                        ),
                      ],
                    ),
                    const Spacer(),
                    const Text('Non-scrollable - TabAlignment.fill'),
                    TabBar(
                      tabAlignment: TabAlignment.fill,
                      dividerColor: customColors ? dividerColor : null,
                      indicatorColor: customColors ? indicatorColor : null,
                      dividerHeight: removeDivider ? 0 : null,
                      tabs: const <Widget>[
                        Tab(
                          icon: Icon(Icons.cloud_outlined),
                        ),
                        Tab(
                          icon: Icon(Icons.beach_access_sharp),
                        ),
                        Tab(
                          icon: Icon(Icons.brightness_5_sharp),
                        ),
                      ],
                    ),
                    const Text('Non-scrollable - TabAlignment.center'),
                    TabBar(
                      tabAlignment: TabAlignment.center,
                      dividerColor: customColors ? dividerColor : null,
                      indicatorColor: customColors ? indicatorColor : null,
                      dividerHeight: removeDivider ? 0 : null,
                      tabs: const <Widget>[
                        Tab(
                          icon: Icon(Icons.cloud_outlined),
                        ),
                        Tab(
                          icon: Icon(Icons.beach_access_sharp),
                        ),
                        Tab(
                          icon: Icon(Icons.brightness_5_sharp),
                        ),
                      ],
                    ),
                    const Spacer(),
                    const Text('Secondary - TabAlignment.fill'),
                    TabBar.secondary(
                      tabAlignment: TabAlignment.fill,
                      dividerColor: customColors ? dividerColor : null,
                      indicatorColor: customColors ? indicatorColor : null,
                      dividerHeight: removeDivider ? 0 : null,
                      tabs: const <Widget>[
                        Tab(
                          icon: Icon(Icons.cloud_outlined),
                        ),
                        Tab(
                          icon: Icon(Icons.beach_access_sharp),
                        ),
                        Tab(
                          icon: Icon(Icons.brightness_5_sharp),
                        ),
                      ],
                    ),
                    const Text('Secondary - TabAlignment.center'),
                    TabBar.secondary(
                      tabAlignment: TabAlignment.center,
                      dividerColor: customColors ? dividerColor : null,
                      indicatorColor: customColors ? indicatorColor : null,
                      dividerHeight: removeDivider ? 0 : null,
                      tabs: const <Widget>[
                        Tab(
                          icon: Icon(Icons.cloud_outlined),
                        ),
                        Tab(
                          icon: Icon(Icons.beach_access_sharp),
                        ),
                        Tab(
                          icon: Icon(Icons.brightness_5_sharp),
                        ),
                      ],
                    ),
                    const Spacer(),
                  ],
                ),
              ),
            ),
          );
        }
      }
      ``` 
      	
      </details>
      
      ### Before
      
      ![Screenshot 2023-07-27 at 14 12 36](https://github.com/flutter/flutter/assets/48603081/1c08a9d2-ac15-4d33-8fa1-c765b4b10f92)
      
      ### After 
      
      ![Screenshot 2023-07-27 at 14 13 12](https://github.com/flutter/flutter/assets/48603081/7e662dfe-9f32-46c9-a128-3024a4782882)
      
      This also contains regression test for https://github.com/flutter/flutter/pull/125974#discussion_r1239089151
      
      ```dart
        // This is a regression test for https://github.com/flutter/flutter/pull/125974#discussion_r1239089151.
        testWidgets('Divider can be constrained', (WidgetTester tester) async {
      ```
      
      ![Screenshot 2023-07-27 at 14 16 37](https://github.com/flutter/flutter/assets/48603081/ac2ef49b-2410-46d0-8ae2-d9b77236abba)
      2c71881f
    • Ian Hickson's avatar
      ImageProvider.toString uses double.toStringAsFixed (#131348) · 9c471a94
      Ian Hickson authored
      This provides consistency for web vs VM (and is more consistent with how we do doubles everywhere else in toStrings).
      9c471a94
    • engine-flutter-autoroll's avatar
      Roll Flutter Engine from 10a1f9cb74c9 to 9dae7b708bda (4 revisions) (#131706) · f5f36ec0
      engine-flutter-autoroll authored
      https://github.com/flutter/engine/compare/10a1f9cb74c9...9dae7b708bda
      
      2023-08-01 30870216+gaaclarke@users.noreply.github.com Made the licenses script output all problems (flutter/engine#44223)
      2023-08-01 skia-flutter-autoroll@skia.org Roll Skia from a7a3646c2c8a to d53f7b880651 (6 revisions) (flutter/engine#44226)
      2023-08-01 skia-flutter-autoroll@skia.org Roll Clang from ebd0b8a0472b to 07c592048780 (flutter/engine#44224)
      2023-08-01 ychris@google.com [iOS] Add darwin_extension_safe flag and use UIScene api when building for extensions (flutter/engine#43449)
      
      If this roll has caused a breakage, revert this CL and stop the roller
      using the controls here:
      https://autoroll.skia.org/r/flutter-engine-flutter-autoroll
      Please CC jacksongardner@google.com,rmistry@google.com,zra@google.com on the revert to ensure that a human
      is aware of the problem.
      
      To file a bug in Flutter: https://github.com/flutter/flutter/issues/new/choose
      
      To report a problem with the AutoRoller itself, please file a bug:
      https://bugs.chromium.org/p/skia/issues/entry?template=Autoroller+Bug
      
      Documentation for the AutoRoller is here:
      https://skia.googlesource.com/buildbot/+doc/main/autoroll/README.md
      f5f36ec0
  2. 01 Aug, 2023 16 commits
  3. 31 Jul, 2023 19 commits
  4. 30 Jul, 2023 2 commits