Fix Scrollable `TabBar` for Material 3 (#131409)

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)
diff --git a/dev/tools/gen_defaults/generated/used_tokens.csv b/dev/tools/gen_defaults/generated/used_tokens.csv
index c7eb2a3..1275486 100644
--- a/dev/tools/gen_defaults/generated/used_tokens.csv
+++ b/dev/tools/gen_defaults/generated/used_tokens.csv
@@ -530,6 +530,7 @@
 md.comp.primary-navigation-tab.active.pressed.state-layer.color,
 md.comp.primary-navigation-tab.active.pressed.state-layer.opacity,
 md.comp.primary-navigation-tab.divider.color,
+md.comp.primary-navigation-tab.divider.height,
 md.comp.primary-navigation-tab.inactive.focus.state-layer.color,
 md.comp.primary-navigation-tab.inactive.focus.state-layer.opacity,
 md.comp.primary-navigation-tab.inactive.hover.state-layer.color,
@@ -589,6 +590,7 @@
 md.comp.search-view.header.supporting-text.text-style,
 md.comp.secondary-navigation-tab.active.label-text.color,
 md.comp.secondary-navigation-tab.divider.color,
+md.comp.secondary-navigation-tab.divider.height,
 md.comp.secondary-navigation-tab.focus.state-layer.color,
 md.comp.secondary-navigation-tab.focus.state-layer.opacity,
 md.comp.secondary-navigation-tab.hover.state-layer.color,
diff --git a/dev/tools/gen_defaults/lib/tabs_template.dart b/dev/tools/gen_defaults/lib/tabs_template.dart
index f6388a8..f520f61 100644
--- a/dev/tools/gen_defaults/lib/tabs_template.dart
+++ b/dev/tools/gen_defaults/lib/tabs_template.dart
@@ -25,6 +25,9 @@
   Color? get dividerColor => ${componentColor("md.comp.primary-navigation-tab.divider")};
 
   @override
+  double? get dividerHeight => ${getToken('md.comp.primary-navigation-tab.divider.height')};
+
+  @override
   Color? get indicatorColor => ${componentColor("md.comp.primary-navigation-tab.active-indicator")};
 
   @override
@@ -71,7 +74,7 @@
   InteractiveInkFeatureFactory? get splashFactory => Theme.of(context).splashFactory;
 
   @override
-  TabAlignment? get tabAlignment => isScrollable ? TabAlignment.start : TabAlignment.fill;
+  TabAlignment? get tabAlignment => isScrollable ? TabAlignment.startOffset : TabAlignment.fill;
 
   static double indicatorWeight = ${getToken('md.comp.primary-navigation-tab.active-indicator.height')};
 }
@@ -89,6 +92,9 @@
   Color? get dividerColor => ${componentColor("md.comp.secondary-navigation-tab.divider")};
 
   @override
+  double? get dividerHeight => ${getToken('md.comp.secondary-navigation-tab.divider.height')};
+
+  @override
   Color? get indicatorColor => ${componentColor("md.comp.primary-navigation-tab.active-indicator")};
 
   @override
@@ -135,7 +141,7 @@
   InteractiveInkFeatureFactory? get splashFactory => Theme.of(context).splashFactory;
 
   @override
-  TabAlignment? get tabAlignment => isScrollable ? TabAlignment.start : TabAlignment.fill;
+  TabAlignment? get tabAlignment => isScrollable ? TabAlignment.startOffset : TabAlignment.fill;
 }
 ''';
 
diff --git a/packages/flutter/lib/src/material/tab_bar_theme.dart b/packages/flutter/lib/src/material/tab_bar_theme.dart
index 87c43d7..e65e8b3 100644
--- a/packages/flutter/lib/src/material/tab_bar_theme.dart
+++ b/packages/flutter/lib/src/material/tab_bar_theme.dart
@@ -32,6 +32,7 @@
     this.indicatorColor,
     this.indicatorSize,
     this.dividerColor,
+    this.dividerHeight,
     this.labelColor,
     this.labelPadding,
     this.labelStyle,
@@ -55,6 +56,9 @@
   /// Overrides the default value for [TabBar.dividerColor].
   final Color? dividerColor;
 
+  /// Overrides the default value for [TabBar.dividerHeight].
+  final double? dividerHeight;
+
   /// Overrides the default value for [TabBar.labelColor].
   ///
   /// If [labelColor] is a [MaterialStateColor], then the effective color will
@@ -101,6 +105,7 @@
     Color? indicatorColor,
     TabBarIndicatorSize? indicatorSize,
     Color? dividerColor,
+    double? dividerHeight,
     Color? labelColor,
     EdgeInsetsGeometry? labelPadding,
     TextStyle? labelStyle,
@@ -116,6 +121,7 @@
       indicatorColor: indicatorColor ?? this.indicatorColor,
       indicatorSize: indicatorSize ?? this.indicatorSize,
       dividerColor: dividerColor ?? this.dividerColor,
+      dividerHeight: dividerHeight ?? this.dividerHeight,
       labelColor: labelColor ?? this.labelColor,
       labelPadding: labelPadding ?? this.labelPadding,
       labelStyle: labelStyle ?? this.labelStyle,
@@ -147,6 +153,7 @@
       indicatorColor: Color.lerp(a.indicatorColor, b.indicatorColor, t),
       indicatorSize: t < 0.5 ? a.indicatorSize : b.indicatorSize,
       dividerColor: Color.lerp(a.dividerColor, b.dividerColor, t),
+      dividerHeight: t < 0.5 ? a.dividerHeight : b.dividerHeight,
       labelColor: Color.lerp(a.labelColor, b.labelColor, t),
       labelPadding: EdgeInsetsGeometry.lerp(a.labelPadding, b.labelPadding, t),
       labelStyle: TextStyle.lerp(a.labelStyle, b.labelStyle, t),
@@ -165,6 +172,7 @@
     indicatorColor,
     indicatorSize,
     dividerColor,
+    dividerHeight,
     labelColor,
     labelPadding,
     labelStyle,
@@ -189,6 +197,7 @@
         && other.indicatorColor == indicatorColor
         && other.indicatorSize == indicatorSize
         && other.dividerColor == dividerColor
+        && other.dividerHeight == dividerHeight
         && other.labelColor == labelColor
         && other.labelPadding == labelPadding
         && other.labelStyle == labelStyle
diff --git a/packages/flutter/lib/src/material/tabs.dart b/packages/flutter/lib/src/material/tabs.dart
index 756e61c..2bb5f44 100644
--- a/packages/flutter/lib/src/material/tabs.dart
+++ b/packages/flutter/lib/src/material/tabs.dart
@@ -387,6 +387,39 @@
   return (controllerValue - currentIndex).abs() / (currentIndex - previousIndex).abs();
 }
 
+class _DividerPainter extends CustomPainter {
+  _DividerPainter({
+    required this.dividerColor,
+    required this.dividerHeight,
+  });
+
+  final Color dividerColor;
+  final double dividerHeight;
+
+  @override
+  void paint(Canvas canvas, Size size) {
+    if (dividerHeight <= 0.0) {
+      return;
+    }
+
+    final Paint paint = Paint()
+      ..color = dividerColor
+      ..strokeWidth = dividerHeight;
+
+    canvas.drawLine(
+      Offset(0, size.height - (paint.strokeWidth / 2)),
+      Offset(size.width, size.height - (paint.strokeWidth / 2)),
+      paint,
+    );
+  }
+
+  @override
+  bool shouldRepaint(_DividerPainter oldDelegate) {
+    return oldDelegate.dividerColor != dividerColor
+      || oldDelegate.dividerHeight != dividerHeight;
+  }
+}
+
 class _IndicatorPainter extends CustomPainter {
   _IndicatorPainter({
     required this.controller,
@@ -397,6 +430,8 @@
     required this.indicatorPadding,
     required this.labelPaddings,
     this.dividerColor,
+    this.dividerHeight,
+    required this.showDivider,
   }) : super(repaint: controller.animation) {
     if (old != null) {
       saveTabOffsets(old._currentTabOffsets, old._currentTextDirection);
@@ -408,8 +443,10 @@
   final TabBarIndicatorSize? indicatorSize;
   final EdgeInsetsGeometry indicatorPadding;
   final List<GlobalKey> tabKeys;
-  final Color? dividerColor;
   final List<EdgeInsetsGeometry> labelPaddings;
+  final Color? dividerColor;
+  final double? dividerHeight;
+  final bool showDivider;
 
   // _currentTabOffsets and _currentTextDirection are set each time TabBar
   // layout is completed. These values can be null when TabBar contains no
@@ -501,9 +538,11 @@
       size: _currentRect!.size,
       textDirection: _currentTextDirection,
     );
-    if (dividerColor != null) {
-      final Paint dividerPaint = Paint()..color = dividerColor!..strokeWidth = 1;
-      canvas.drawLine(Offset(0, size.height), Offset(size.width, size.height), dividerPaint);
+    if (showDivider && dividerHeight !> 0) {
+      final Paint dividerPaint = Paint()..color = dividerColor!..strokeWidth = dividerHeight!;
+      final Offset dividerP1 = Offset(0, size.height - (dividerPaint.strokeWidth / 2));
+      final Offset dividerP2 = Offset(size.width, size.height - (dividerPaint.strokeWidth / 2));
+      canvas.drawLine(dividerP1, dividerP2, dividerPaint);
     }
     _painter!.paint(canvas, _currentRect!.topLeft, configuration);
   }
@@ -718,6 +757,7 @@
     this.indicator,
     this.indicatorSize,
     this.dividerColor,
+    this.dividerHeight,
     this.labelColor,
     this.labelStyle,
     this.labelPadding,
@@ -768,6 +808,7 @@
     this.indicator,
     this.indicatorSize,
     this.dividerColor,
+    this.dividerHeight,
     this.labelColor,
     this.labelStyle,
     this.labelPadding,
@@ -895,6 +936,13 @@
   /// [ColorScheme.surfaceVariant] will be used, otherwise divider will not be drawn.
   final Color? dividerColor;
 
+  /// The height of the divider.
+  ///
+  /// If null and [ThemeData.useMaterial3] is true, [TabBarTheme.dividerHeight] is used.
+  /// If that is also null and [ThemeData.useMaterial3] is true, 1.0 will be used.
+  /// Otherwise divider will not be drawn.
+  final double? dividerHeight;
+
   /// The color of selected tab labels.
   ///
   /// If null, then [TabBarTheme.labelColor] is used. If that is also null and
@@ -1154,8 +1202,8 @@
   TabBarTheme get _defaults {
     if (Theme.of(context).useMaterial3) {
       return widget._isPrimary
-          ? _TabsPrimaryDefaultsM3(context, widget.isScrollable)
-          : _TabsSecondaryDefaultsM3(context, widget.isScrollable);
+        ? _TabsPrimaryDefaultsM3(context, widget.isScrollable)
+        : _TabsSecondaryDefaultsM3(context, widget.isScrollable);
     } else {
       return _TabsDefaultsM2(context, widget.isScrollable);
     }
@@ -1269,8 +1317,10 @@
       indicatorPadding: widget.indicatorPadding,
       tabKeys: _tabKeys,
       old: _indicatorPainter,
-      dividerColor: theme.useMaterial3 ? widget.dividerColor ?? tabBarTheme.dividerColor ?? _defaults.dividerColor : null,
       labelPaddings: _labelPaddings,
+      dividerColor: widget.dividerColor ?? tabBarTheme.dividerColor ?? _defaults.dividerColor,
+      dividerHeight: widget.dividerHeight ?? tabBarTheme.dividerHeight ?? _defaults.dividerHeight,
+      showDivider: theme.useMaterial3 && !widget.isScrollable,
     );
   }
 
@@ -1299,7 +1349,9 @@
         widget.indicatorWeight != oldWidget.indicatorWeight ||
         widget.indicatorSize != oldWidget.indicatorSize ||
         widget.indicatorPadding != oldWidget.indicatorPadding ||
-        widget.indicator != oldWidget.indicator) {
+        widget.indicator != oldWidget.indicator ||
+        widget.dividerColor != oldWidget.dividerColor ||
+        widget.dividerHeight != oldWidget.dividerHeight) {
       _initIndicatorPainter();
     }
 
@@ -1475,6 +1527,7 @@
   Widget build(BuildContext context) {
     assert(debugCheckHasMaterialLocalizations(context));
     assert(_debugScheduleCheckHasValidTabsCount());
+    final ThemeData theme = Theme.of(context);
     final TabBarTheme tabBarTheme = TabBarTheme.of(context);
     final TabAlignment effectiveTabAlignment = widget.tabAlignment ?? tabBarTheme.tabAlignment ?? _defaults.tabAlignment!;
     assert(_debugTabAlignmentIsValid(effectiveTabAlignment));
@@ -1486,7 +1539,6 @@
       );
     }
 
-
     final List<Widget> wrappedTabs = List<Widget>.generate(widget.tabs.length, (int index) {
       const double verticalAdjustment = (_kTextAndIconTabHeight - _kTabHeight)/2.0;
       EdgeInsetsGeometry? adjustedPadding;
@@ -1627,6 +1679,24 @@
           child: tabBar,
         ),
       );
+      if (theme.useMaterial3) {
+        final AlignmentGeometry effectiveAlignment = switch (effectiveTabAlignment) {
+          TabAlignment.center => Alignment.center,
+          TabAlignment.start || TabAlignment.startOffset || TabAlignment.fill => AlignmentDirectional.centerStart,
+        };
+
+        tabBar = CustomPaint(
+          painter: _DividerPainter(
+            dividerColor: widget.dividerColor ?? tabBarTheme.dividerColor ?? _defaults.dividerColor!,
+            dividerHeight: widget.dividerHeight ?? tabBarTheme.dividerHeight ?? _defaults.dividerHeight!,
+          ),
+          child: Align(
+            heightFactor: 1.0,
+            alignment: effectiveAlignment,
+            child: tabBar,
+          ),
+        );
+      }
     } else if (widget.padding != null) {
       tabBar = Padding(
         padding: widget.padding!,
@@ -2178,6 +2248,9 @@
   Color? get dividerColor => _colors.surfaceVariant;
 
   @override
+  double? get dividerHeight => 1.0;
+
+  @override
   Color? get indicatorColor => _colors.primary;
 
   @override
@@ -2224,7 +2297,7 @@
   InteractiveInkFeatureFactory? get splashFactory => Theme.of(context).splashFactory;
 
   @override
-  TabAlignment? get tabAlignment => isScrollable ? TabAlignment.start : TabAlignment.fill;
+  TabAlignment? get tabAlignment => isScrollable ? TabAlignment.startOffset : TabAlignment.fill;
 
   static double indicatorWeight = 3.0;
 }
@@ -2242,6 +2315,9 @@
   Color? get dividerColor => _colors.surfaceVariant;
 
   @override
+  double? get dividerHeight => 1.0;
+
+  @override
   Color? get indicatorColor => _colors.primary;
 
   @override
@@ -2288,7 +2364,7 @@
   InteractiveInkFeatureFactory? get splashFactory => Theme.of(context).splashFactory;
 
   @override
-  TabAlignment? get tabAlignment => isScrollable ? TabAlignment.start : TabAlignment.fill;
+  TabAlignment? get tabAlignment => isScrollable ? TabAlignment.startOffset : TabAlignment.fill;
 }
 
 // END GENERATED TOKEN PROPERTIES - Tabs
diff --git a/packages/flutter/test/material/tab_bar_theme_test.dart b/packages/flutter/test/material/tab_bar_theme_test.dart
index 3b686c1..0f69b10 100644
--- a/packages/flutter/test/material/tab_bar_theme_test.dart
+++ b/packages/flutter/test/material/tab_bar_theme_test.dart
@@ -90,6 +90,7 @@
     expect(const TabBarTheme().indicatorColor, null);
     expect(const TabBarTheme().indicatorSize, null);
     expect(const TabBarTheme().dividerColor, null);
+    expect(const TabBarTheme().dividerHeight, null);
     expect(const TabBarTheme().labelColor, null);
     expect(const TabBarTheme().labelPadding, null);
     expect(const TabBarTheme().labelStyle, null);
@@ -127,27 +128,32 @@
     final Rect tabBar = tester.getRect(find.byType(TabBar));
     final Rect tabOneRect = tester.getRect(find.byKey(_sizedTabs[0].key!));
     final Rect tabTwoRect = tester.getRect(find.byKey(_sizedTabs[1].key!));
+    const double tabStartOffset = 52.0;
 
     // Verify tabOne coordinates.
-    expect(tabOneRect.left, equals(kTabLabelPadding.left));
+    expect(tabOneRect.left, equals(kTabLabelPadding.left + tabStartOffset));
     expect(tabOneRect.top, equals(kTabLabelPadding.top));
     expect(tabOneRect.bottom, equals(tabBar.bottom - kTabLabelPadding.bottom - indicatorWeight));
 
     // Verify tabTwo coordinates.
-    expect(tabTwoRect.right, equals(tabBar.width - kTabLabelPadding.right));
+    final double tabTwoRight = tabStartOffset + kTabLabelPadding.horizontal + tabOneRect.width
+      + kTabLabelPadding.left + tabTwoRect.width;
+    expect(tabTwoRect.right, tabTwoRight);
     expect(tabTwoRect.top, equals(kTabLabelPadding.top));
     expect(tabTwoRect.bottom, equals(tabBar.bottom - kTabLabelPadding.bottom - indicatorWeight));
 
-    // Verify tabOne and tabTwo is separated by right padding of tabOne and left padding of tabTwo.
+    // Verify tabOne and tabTwo are separated by right padding of tabOne and left padding of tabTwo.
     expect(tabOneRect.right, equals(tabTwoRect.left - kTabLabelPadding.left - kTabLabelPadding.right));
 
-    // Test default indicator color and divider color.
+    // Test default indicator & divider color.
     final RenderBox tabBarBox = tester.firstRenderObject<RenderBox>(find.byType(TabBar));
     expect(
       tabBarBox,
       paints
-        ..line(color: theme.colorScheme.surfaceVariant)
-        // Indicator is a rrect in the primary tab bar.
+        ..line(
+          color: theme.colorScheme.surfaceVariant,
+          strokeWidth: 1.0,
+        )
         ..rrect(color: theme.colorScheme.primary),
     );
   });
@@ -178,29 +184,34 @@
     final Rect tabBar = tester.getRect(find.byType(TabBar));
     final Rect tabOneRect = tester.getRect(find.byKey(_sizedTabs[0].key!));
     final Rect tabTwoRect = tester.getRect(find.byKey(_sizedTabs[1].key!));
+    const double tabStartOffset = 52.0;
 
     // Verify tabOne coordinates.
-    expect(tabOneRect.left, equals(kTabLabelPadding.left));
+    expect(tabOneRect.left, equals(kTabLabelPadding.left + tabStartOffset));
     expect(tabOneRect.top, equals(kTabLabelPadding.top));
     expect(tabOneRect.bottom, equals(tabBar.bottom - kTabLabelPadding.bottom - indicatorWeight));
 
     // Verify tabTwo coordinates.
-    expect(tabTwoRect.right, equals(tabBar.width - kTabLabelPadding.right));
+    final double tabTwoRight = tabStartOffset + kTabLabelPadding.horizontal + tabOneRect.width
+      + kTabLabelPadding.left + tabTwoRect.width;
+    expect(tabTwoRect.right, tabTwoRight);
     expect(tabTwoRect.top, equals(kTabLabelPadding.top));
     expect(tabTwoRect.bottom, equals(tabBar.bottom - kTabLabelPadding.bottom - indicatorWeight));
 
-    // Verify tabOne and tabTwo is separated by right padding of tabOne and left padding of tabTwo.
+    // Verify tabOne and tabTwo are separated by right padding of tabOne and left padding of tabTwo.
     expect(tabOneRect.right, equals(tabTwoRect.left - kTabLabelPadding.left - kTabLabelPadding.right));
 
-    // Test default indicator color and divider color.
+    // Test default indicator & divider color.
     final RenderBox tabBarBox = tester.firstRenderObject<RenderBox>(find.byType(TabBar));
     expect(
       tabBarBox,
       paints
-        ..line(color: theme.colorScheme.surfaceVariant)
-        // Indicator is a line in the secondary tab bar.
+        ..line(
+          color: theme.colorScheme.surfaceVariant,
+          strokeWidth: 1.0,
+        )
         ..line(color: theme.colorScheme.primary),
-    );
+      );
   });
 
   testWidgets('Tab bar theme overrides label color (selected)', (WidgetTester tester) async {
@@ -315,7 +326,7 @@
     expect(unselectedLabel.text.style!.fontFamily, equals(unselectedLabelStyle.fontFamily));
   });
 
-  testWidgets('Tab bar label padding overrides theme label padding', (WidgetTester tester) async {
+  testWidgets('Material2 - Tab bar label padding overrides theme label padding', (WidgetTester tester) async {
     const double verticalPadding = 10.0;
     const double horizontalPadding = 10.0;
     const EdgeInsetsGeometry labelPadding = EdgeInsets.symmetric(
@@ -336,7 +347,7 @@
 
     await tester.pumpWidget(
       MaterialApp(
-        theme: ThemeData(tabBarTheme: tabBarTheme),
+        theme: ThemeData(tabBarTheme: tabBarTheme, useMaterial3: false),
         home: Scaffold(body:
           RepaintBoundary(
             key: _painterKey,
@@ -369,6 +380,61 @@
     expect(tabOneRect.right, equals(tabTwoRect.left - (2 * horizontalPadding)));
   });
 
+  testWidgets('Material3 - Tab bar label padding overrides theme label padding', (WidgetTester tester) async {
+    const double tabStartOffset = 52.0;
+    const double verticalPadding = 10.0;
+    const double horizontalPadding = 10.0;
+    const EdgeInsetsGeometry labelPadding = EdgeInsets.symmetric(
+      vertical: verticalPadding,
+      horizontal: horizontalPadding,
+    );
+
+    const double verticalThemePadding = 20.0;
+    const double horizontalThemePadding = 20.0;
+    const EdgeInsetsGeometry themeLabelPadding = EdgeInsets.symmetric(
+      vertical: verticalThemePadding,
+      horizontal: horizontalThemePadding,
+    );
+
+    const double indicatorWeight = 2.0; // default value
+
+    const TabBarTheme tabBarTheme = TabBarTheme(labelPadding: themeLabelPadding);
+
+    await tester.pumpWidget(
+      MaterialApp(
+        theme: ThemeData(tabBarTheme: tabBarTheme, useMaterial3: true),
+        home: Scaffold(body:
+          RepaintBoundary(
+            key: _painterKey,
+            child: TabBar(
+              tabs: _sizedTabs,
+              isScrollable: true,
+              controller: TabController(length: _sizedTabs.length, vsync: const TestVSync()),
+              labelPadding: labelPadding,
+            ),
+          ),
+        ),
+      ),
+    );
+
+    final Rect tabBar = tester.getRect(find.byType(TabBar));
+    final Rect tabOneRect = tester.getRect(find.byKey(_sizedTabs[0].key!));
+    final Rect tabTwoRect = tester.getRect(find.byKey(_sizedTabs[1].key!));
+
+    // verify coordinates of tabOne
+    expect(tabOneRect.left, equals(horizontalPadding + tabStartOffset));
+    expect(tabOneRect.top, equals(verticalPadding));
+    expect(tabOneRect.bottom, equals(tabBar.bottom - verticalPadding - indicatorWeight));
+
+    // verify coordinates of tabTwo
+    expect(tabTwoRect.right, equals(tabStartOffset + horizontalThemePadding + tabOneRect.width + tabTwoRect.width + (horizontalThemePadding / 2)));
+    expect(tabTwoRect.top, equals(verticalPadding));
+    expect(tabTwoRect.bottom, equals(tabBar.bottom - verticalPadding - indicatorWeight));
+
+    // verify tabOne and tabTwo are separated by 2x horizontalPadding
+    expect(tabOneRect.right, equals(tabTwoRect.left - (2 * horizontalPadding)));
+  });
+
   testWidgets('Tab bar theme overrides label color (unselected)', (WidgetTester tester) async {
     const Color unselectedLabelColor = Colors.black;
     const TabBarTheme tabBarTheme = TabBarTheme(unselectedLabelColor: unselectedLabelColor);
@@ -381,7 +447,7 @@
     expect(iconRenderObject.text.style!.color, equals(unselectedLabelColor));
   });
 
-  testWidgets('Tab bar default tab indicator size', (WidgetTester tester) async {
+  testWidgets('Tab bar default tab indicator size (primary)', (WidgetTester tester) async {
     await tester.pumpWidget(buildTabBar(useMaterial3: true, isScrollable: true));
 
     await expectLater(
@@ -390,12 +456,12 @@
     );
   });
 
-  testWidgets('Tab bar default tab indicator size', (WidgetTester tester) async {
+  testWidgets('Tab bar default tab indicator size (secondary)', (WidgetTester tester) async {
     await tester.pumpWidget(buildTabBar(useMaterial3: true, isScrollable: true));
 
     await expectLater(
       find.byKey(_painterKey),
-      matchesGoldenFile('tab_bar.default.tab_indicator_size.png'),
+      matchesGoldenFile('tab_bar_secondary.default.tab_indicator_size.png'),
     );
   });
 
@@ -549,11 +615,12 @@
     expect(
       tabBarBox,
       paints
-        // Divider
+        // Divider.
         ..line(
           color: theme.colorScheme.surfaceVariant,
+          strokeWidth: 1.0,
         )
-        // Tab indicator
+        // Tab indicator.
         ..line(
           color: theme.colorScheme.primary,
           strokeWidth: indicatorWeight,
@@ -601,9 +668,10 @@
     expect(
       tabBarBox,
       paints
-        // Divider
+        // Divider.
         ..line(
           color: theme.colorScheme.surfaceVariant,
+          strokeWidth: 1.0,
         )
         // Tab indicator
         ..line(
@@ -615,6 +683,202 @@
     );
   });
 
+  testWidgets('TabBar divider can use TabBarTheme.dividerColor & TabBarTheme.dividerHeight', (WidgetTester tester) async {
+    const Color dividerColor = Color(0xff00ff00);
+    const double dividerHeight = 10.0;
+
+    await tester.pumpWidget(
+      MaterialApp(
+        theme: ThemeData(
+          tabBarTheme: const TabBarTheme(
+            dividerColor: dividerColor,
+            dividerHeight: dividerHeight,
+          ),
+          useMaterial3: true,
+        ),
+        home: Scaffold(
+          appBar: AppBar(
+            bottom: TabBar(
+              controller: TabController(length: 3, vsync: const TestVSync()),
+              tabs: const <Widget>[
+                Tab(text: 'Tab 1'),
+                Tab(text: 'Tab 2'),
+                Tab(text: 'Tab 3'),
+              ],
+            ),
+          ),
+        ),
+      ),
+    );
+
+    final RenderBox tabBarBox = tester.firstRenderObject<RenderBox>(find.byType(TabBar));
+    // Test divider color.
+    expect(tabBarBox, paints..line(color: dividerColor, strokeWidth: dividerHeight));
+  });
+
+  testWidgets('dividerColor & dividerHeight overrides TabBarTheme.dividerColor', (WidgetTester tester) async {
+    const Color dividerColor = Color(0xff0000ff);
+    const double dividerHeight = 8.0;
+
+    await tester.pumpWidget(
+      MaterialApp(
+        theme: ThemeData(
+          useMaterial3: true,
+          tabBarTheme: const TabBarTheme(
+            dividerColor: Colors.pink,
+            dividerHeight: 5.0,
+          ),
+        ),
+        home: Scaffold(
+          appBar: AppBar(
+            bottom: TabBar(
+              dividerColor: dividerColor,
+              dividerHeight: dividerHeight,
+              controller: TabController(length: 3, vsync: const TestVSync()),
+              tabs: const <Widget>[
+                Tab(text: 'Tab 1'),
+                Tab(text: 'Tab 2'),
+                Tab(text: 'Tab 3'),
+              ],
+            ),
+          ),
+        ),
+      ),
+    );
+
+    final RenderBox tabBarBox = tester.firstRenderObject<RenderBox>(find.byType(TabBar));
+    // Test divider color.
+    expect(tabBarBox, paints..line(color: dividerColor, strokeWidth: dividerHeight));
+  });
+
+  testWidgets('TabBar respects TabBarTheme.tabAlignment', (WidgetTester tester) async {
+    // Test non-scrollable tab bar.
+    await tester.pumpWidget(
+      MaterialApp(
+        theme: ThemeData(
+          tabBarTheme: const TabBarTheme(tabAlignment: TabAlignment.center),
+          useMaterial3: true,
+        ),
+        home: Scaffold(
+          appBar: AppBar(
+            bottom: TabBar(
+              controller: TabController(length: 2, vsync: const TestVSync()),
+              tabs: const <Widget>[
+                Tab(text: 'Tab 1'),
+                Tab(text: 'Tab 3'),
+              ],
+            ),
+          ),
+        ),
+      ),
+    );
+
+    const double availableWidth = 800.0;
+    Rect tabOneRect = tester.getRect(find.byType(Tab).first);
+    Rect tabTwoRect = tester.getRect(find.byType(Tab).last);
+
+    double tabOneLeft = (availableWidth / 2) - tabOneRect.width - kTabLabelPadding.left;
+    expect(tabOneRect.left, equals(tabOneLeft));
+    double tabTwoRight = (availableWidth / 2) + tabTwoRect.width + kTabLabelPadding.right;
+    expect(tabTwoRect.right, equals(tabTwoRight));
+
+    // Test scrollable tab bar.
+    await tester.pumpWidget(
+      MaterialApp(
+        theme: ThemeData(
+          tabBarTheme: const TabBarTheme(tabAlignment: TabAlignment.start),
+          useMaterial3: true,
+        ),
+        home: Scaffold(
+          appBar: AppBar(
+            bottom: TabBar(
+              isScrollable: true,
+              controller: TabController(length: 2, vsync: const TestVSync()),
+              tabs: const <Widget>[
+                Tab(text: 'Tab 1'),
+                Tab(text: 'Tab 3'),
+              ],
+            ),
+          ),
+        ),
+      ),
+    );
+    await tester.pumpAndSettle();
+
+    tabOneRect = tester.getRect(find.byType(Tab).first);
+    tabTwoRect = tester.getRect(find.byType(Tab).last);
+
+    tabOneLeft = kTabLabelPadding.left;
+    expect(tabOneRect.left, equals(tabOneLeft));
+    tabTwoRight = kTabLabelPadding.horizontal + tabOneRect.width + kTabLabelPadding.left + tabTwoRect.width;
+    expect(tabTwoRect.right, equals(tabTwoRight));
+  });
+
+  testWidgets('TabBar.tabAlignment overrides TabBarTheme.tabAlignment', (WidgetTester tester) async {
+    /// Test non-scrollable tab bar.
+    await tester.pumpWidget(
+      MaterialApp(
+        theme: ThemeData(
+          tabBarTheme: const TabBarTheme(tabAlignment: TabAlignment.fill),
+          useMaterial3: true,
+        ),
+        home: Scaffold(
+          appBar: AppBar(
+            bottom: TabBar(
+              tabAlignment: TabAlignment.center,
+              controller: TabController(length: 2, vsync: const TestVSync()),
+              tabs: const <Widget>[
+                Tab(text: 'Tab 1'),
+                Tab(text: 'Tab 3'),
+              ],
+            ),
+          ),
+        ),
+      ),
+    );
+
+    const double availableWidth = 800.0;
+    Rect tabOneRect = tester.getRect(find.byType(Tab).first);
+    Rect tabTwoRect = tester.getRect(find.byType(Tab).last);
+
+    double tabOneLeft = (availableWidth / 2) - tabOneRect.width - kTabLabelPadding.left;
+    expect(tabOneRect.left, equals(tabOneLeft));
+    double tabTwoRight = (availableWidth / 2) + tabTwoRect.width + kTabLabelPadding.right;
+    expect(tabTwoRect.right, equals(tabTwoRight));
+
+    /// Test scrollable tab bar.
+    await tester.pumpWidget(
+      MaterialApp(
+        theme: ThemeData(
+          tabBarTheme: const TabBarTheme(tabAlignment: TabAlignment.center),
+          useMaterial3: true,
+        ),
+        home: Scaffold(
+          appBar: AppBar(
+            bottom: TabBar(
+              isScrollable: true,
+              tabAlignment: TabAlignment.start,
+              controller: TabController(length: 2, vsync: const TestVSync()),
+              tabs: const <Widget>[
+                Tab(text: 'Tab 1'),
+                Tab(text: 'Tab 3'),
+              ],
+            ),
+          ),
+        ),
+      ),
+    );
+    await tester.pumpAndSettle();
+
+    tabOneRect = tester.getRect(find.byType(Tab).first);
+    tabTwoRect = tester.getRect(find.byType(Tab).last);
+
+    tabOneLeft = kTabLabelPadding.left;
+    expect(tabOneRect.left, equals(tabOneLeft));
+    tabTwoRight = kTabLabelPadding.horizontal + tabOneRect.width + kTabLabelPadding.left + tabTwoRect.width;
+    expect(tabTwoRect.right, equals(tabTwoRight));
+  });
+
   group('Material 2', () {
     // These tests are only relevant for Material 2. Once Material 2
     // support is deprecated and the APIs are removed, these tests
@@ -692,7 +956,7 @@
       expect(tabTwoRect.top, equals(kTabLabelPadding.top));
       expect(tabTwoRect.bottom, equals(tabBar.bottom - kTabLabelPadding.bottom - indicatorWeight));
 
-      // Verify tabOne and tabTwo is separated by right padding of tabOne and left padding of tabTwo.
+      // Verify tabOne and tabTwo are separated by right padding of tabOne and left padding of tabTwo.
       expect(tabOneRect.right, equals(tabTwoRect.left - kTabLabelPadding.left - kTabLabelPadding.right));
 
       // Test default indicator color.
@@ -806,5 +1070,68 @@
           ),
       );
     });
+
+    testWidgets('TabBar respects TabBarTheme.tabAlignment', (WidgetTester tester) async {
+      // Test non-scrollable tab bar.
+      await tester.pumpWidget(
+        MaterialApp(
+          theme: ThemeData(
+            tabBarTheme: const TabBarTheme(tabAlignment: TabAlignment.center),
+            useMaterial3: false,
+          ),
+          home: Scaffold(
+            appBar: AppBar(
+              bottom: TabBar(
+                controller: TabController(length: 2, vsync: const TestVSync()),
+                tabs: const <Widget>[
+                  Tab(text: 'Tab 1'),
+                  Tab(text: 'Tab 3'),
+                ],
+              ),
+            ),
+          ),
+        ),
+      );
+
+      final Rect tabOneRect = tester.getRect(find.byType(Tab).first);
+      final Rect tabTwoRect = tester.getRect(find.byType(Tab).last);
+
+      final double tabOneLeft = (800 / 2) - tabOneRect.width - kTabLabelPadding.left;
+      expect(tabOneRect.left, equals(tabOneLeft));
+      final double tabTwoRight = (800 / 2) + tabTwoRect.width + kTabLabelPadding.right;
+      expect(tabTwoRect.right, equals(tabTwoRight));
+    });
+
+    testWidgets('TabBar.tabAlignment overrides TabBarTheme.tabAlignment', (WidgetTester tester) async {
+      // Test non-scrollable tab bar.
+      await tester.pumpWidget(
+        MaterialApp(
+          theme: ThemeData(
+            tabBarTheme: const TabBarTheme(tabAlignment: TabAlignment.fill),
+            useMaterial3: false,
+          ),
+          home: Scaffold(
+            appBar: AppBar(
+              bottom: TabBar(
+                tabAlignment: TabAlignment.center,
+                controller: TabController(length: 2, vsync: const TestVSync()),
+                tabs: const <Widget>[
+                  Tab(text: 'Tab 1'),
+                  Tab(text: 'Tab 3'),
+                ],
+              ),
+            ),
+          ),
+        ),
+      );
+
+      final Rect tabOneRect = tester.getRect(find.byType(Tab).first);
+      final Rect tabTwoRect = tester.getRect(find.byType(Tab).last);
+
+      final double tabOneLeft = (800 / 2) - tabOneRect.width - kTabLabelPadding.left;
+      expect(tabOneRect.left, equals(tabOneLeft));
+      final double tabTwoRight = (800 / 2) + tabTwoRect.width + kTabLabelPadding.right;
+      expect(tabTwoRect.right, equals(tabTwoRight));
+    });
   });
 }
diff --git a/packages/flutter/test/material/tabs_test.dart b/packages/flutter/test/material/tabs_test.dart
index 62e4f17..df4d34c 100644
--- a/packages/flutter/test/material/tabs_test.dart
+++ b/packages/flutter/test/material/tabs_test.dart
@@ -701,10 +701,16 @@
     expect(controller.index, 0);
   });
 
-  testWidgets('Scrollable TabBar tap centers selected tab', (WidgetTester tester) async {
+  testWidgets('Material2 - Scrollable TabBar tap centers selected tab', (WidgetTester tester) async {
     final List<String> tabs = <String>['AAAAAA', 'BBBBBB', 'CCCCCC', 'DDDDDD', 'EEEEEE', 'FFFFFF', 'GGGGGG', 'HHHHHH', 'IIIIII', 'JJJJJJ', 'KKKKKK', 'LLLLLL'];
     const Key tabBarKey = Key('TabBar');
-    await tester.pumpWidget(buildFrame(tabs: tabs, value: 'AAAAAA', isScrollable: true, tabBarKey: tabBarKey));
+    await tester.pumpWidget(buildFrame(
+      tabs: tabs,
+      value: 'AAAAAA',
+      isScrollable: true,
+      tabBarKey: tabBarKey,
+      useMaterial3: false,
+    ));
     final TabController controller = DefaultTabController.of(tester.element(find.text('AAAAAA')));
     expect(controller, isNotNull);
     expect(controller.index, 0);
@@ -720,12 +726,44 @@
     expect(tester.getCenter(find.text('FFFFFF')).dx, moreOrLessEquals(400.0, epsilon: 1.0));
   });
 
-  testWidgets('Scrollable TabBar, with padding, tap centers selected tab', (WidgetTester tester) async {
+  testWidgets('Material3 - Scrollable TabBar tap centers selected tab', (WidgetTester tester) async {
+    final List<String> tabs = <String>['AAAAAA', 'BBBBBB', 'CCCCCC', 'DDDDDD', 'EEEEEE', 'FFFFFF', 'GGGGGG', 'HHHHHH', 'IIIIII', 'JJJJJJ', 'KKKKKK', 'LLLLLL'];
+    const Key tabBarKey = Key('TabBar');
+    await tester.pumpWidget(buildFrame(
+      tabs: tabs,
+      value: 'AAAAAA',
+      isScrollable: true,
+      tabBarKey: tabBarKey,
+      useMaterial3: true,
+    ));
+    final TabController controller = DefaultTabController.of(tester.element(find.text('AAAAAA')));
+    expect(controller, isNotNull);
+    expect(controller.index, 0);
+
+    expect(tester.getSize(find.byKey(tabBarKey)).width, equals(800.0));
+    // The center of the FFFFFF item is to the right of the TabBar's center
+    expect(tester.getCenter(find.text('FFFFFF')).dx, greaterThan(401.0));
+
+    await tester.tap(find.text('FFFFFF'));
+    await tester.pumpAndSettle();
+    expect(controller.index, 5);
+    // The center of the FFFFFF item is now at the TabBar's center
+    expect(tester.getCenter(find.text('FFFFFF')).dx, moreOrLessEquals(452.0, epsilon: 1.0));
+  });
+
+  testWidgets('Material2 - Scrollable TabBar, with padding, tap centers selected tab', (WidgetTester tester) async {
     // Regression test for https://github.com/flutter/flutter/issues/112776
     final List<String> tabs = <String>['AAAAAA', 'BBBBBB', 'CCCCCC', 'DDDDDD', 'EEEEEE', 'FFFFFF', 'GGGGGG', 'HHHHHH', 'IIIIII', 'JJJJJJ', 'KKKKKK', 'LLLLLL'];
     const Key tabBarKey = Key('TabBar');
     const EdgeInsetsGeometry padding = EdgeInsets.only(right: 30, left: 60);
-    await tester.pumpWidget(buildFrame(tabs: tabs, value: 'AAAAAA', isScrollable: true, tabBarKey: tabBarKey, padding: padding));
+    await tester.pumpWidget(buildFrame(
+      tabs: tabs,
+      value: 'AAAAAA',
+      isScrollable: true,
+      tabBarKey: tabBarKey,
+      padding: padding,
+      useMaterial3: false,
+    ));
     final TabController controller = DefaultTabController.of(tester.element(find.text('AAAAAA')));
     expect(controller, isNotNull);
     expect(controller.index, 0);
@@ -741,7 +779,35 @@
     expect(tester.getCenter(find.text('FFFFFF')).dx, moreOrLessEquals(400.0, epsilon: 1.0));
   });
 
-  testWidgets('Scrollable TabBar, with padding and TextDirection.rtl, tap centers selected tab', (WidgetTester tester) async {
+  testWidgets('Material3 - Scrollable TabBar, with padding, tap centers selected tab', (WidgetTester tester) async {
+    // Regression test for https://github.com/flutter/flutter/issues/112776
+    final List<String> tabs = <String>['AAAAAA', 'BBBBBB', 'CCCCCC', 'DDDDDD', 'EEEEEE', 'FFFFFF', 'GGGGGG', 'HHHHHH', 'IIIIII', 'JJJJJJ', 'KKKKKK', 'LLLLLL'];
+    const Key tabBarKey = Key('TabBar');
+    const EdgeInsetsGeometry padding = EdgeInsets.only(right: 30, left: 60);
+    await tester.pumpWidget(buildFrame(
+      tabs: tabs,
+      value: 'AAAAAA',
+      isScrollable: true,
+      tabBarKey: tabBarKey,
+      padding: padding,
+      useMaterial3: true,
+    ));
+    final TabController controller = DefaultTabController.of(tester.element(find.text('AAAAAA')));
+    expect(controller, isNotNull);
+    expect(controller.index, 0);
+
+    expect(tester.getSize(find.byKey(tabBarKey)).width, equals(800.0));
+    // The center of the FFFFFF item is to the right of the TabBar's center
+    expect(tester.getCenter(find.text('FFFFFF')).dx, greaterThan(401.0));
+
+    await tester.tap(find.text('FFFFFF'));
+    await tester.pumpAndSettle();
+    expect(controller.index, 5);
+    // The center of the FFFFFF item is now at the TabBar's center
+    expect(tester.getCenter(find.text('FFFFFF')).dx, moreOrLessEquals(452.0, epsilon: 1.0));
+  });
+
+  testWidgets('Material2 - Scrollable TabBar, with padding and TextDirection.rtl, tap centers selected tab', (WidgetTester tester) async {
     // Regression test for https://github.com/flutter/flutter/issues/112776
     final List<String> tabs = <String>['AAAAAA', 'BBBBBB', 'CCCCCC', 'DDDDDD', 'EEEEEE', 'FFFFFF', 'GGGGGG', 'HHHHHH', 'IIIIII', 'JJJJJJ', 'KKKKKK', 'LLLLLL'];
     const Key tabBarKey = Key('TabBar');
@@ -753,6 +819,7 @@
       tabBarKey: tabBarKey,
       padding: padding,
       textDirection: TextDirection.rtl,
+      useMaterial3: false,
     ));
     final TabController controller = DefaultTabController.of(tester.element(find.text('AAAAAA')));
     expect(controller, isNotNull);
@@ -769,10 +836,45 @@
     expect(tester.getCenter(find.text('FFFFFF')).dx, moreOrLessEquals(400.0, epsilon: 1.0));
   });
 
-  testWidgets('TabBar can be scrolled independent of the selection', (WidgetTester tester) async {
+  testWidgets('Material3 - Scrollable TabBar, with padding and TextDirection.rtl, tap centers selected tab', (WidgetTester tester) async {
+    // Regression test for https://github.com/flutter/flutter/issues/112776
+    final List<String> tabs = <String>['AAAAAA', 'BBBBBB', 'CCCCCC', 'DDDDDD', 'EEEEEE', 'FFFFFF', 'GGGGGG', 'HHHHHH', 'IIIIII', 'JJJJJJ', 'KKKKKK', 'LLLLLL'];
+    const Key tabBarKey = Key('TabBar');
+    const EdgeInsetsGeometry padding = EdgeInsets.only(right: 30, left: 60);
+    await tester.pumpWidget(buildFrame(
+      tabs: tabs,
+      value: 'AAAAAA',
+      isScrollable: true,
+      tabBarKey: tabBarKey,
+      padding: padding,
+      textDirection: TextDirection.rtl,
+      useMaterial3: true,
+    ));
+    final TabController controller = DefaultTabController.of(tester.element(find.text('AAAAAA')));
+    expect(controller, isNotNull);
+    expect(controller.index, 0);
+
+    expect(tester.getSize(find.byKey(tabBarKey)).width, equals(800.0));
+    // The center of the FFFFFF item is to the left of the TabBar's center
+    expect(tester.getCenter(find.text('FFFFFF')).dx, lessThan(401.0));
+
+    await tester.tap(find.text('FFFFFF'));
+    await tester.pumpAndSettle();
+    expect(controller.index, 5);
+    // The center of the FFFFFF item is now at the TabBar's center
+    expect(tester.getCenter(find.text('FFFFFF')).dx, moreOrLessEquals(348.0, epsilon: 1.0));
+  });
+
+  testWidgets('Material2 - TabBar can be scrolled independent of the selection', (WidgetTester tester) async {
     final List<String> tabs = <String>['AAAA', 'BBBB', 'CCCC', 'DDDD', 'EEEE', 'FFFF', 'GGGG', 'HHHH', 'IIII', 'JJJJ', 'KKKK', 'LLLL'];
     const Key tabBarKey = Key('TabBar');
-    await tester.pumpWidget(buildFrame(tabs: tabs, value: 'AAAA', isScrollable: true, tabBarKey: tabBarKey));
+    await tester.pumpWidget(buildFrame(
+      tabs: tabs,
+      value: 'AAAA',
+      isScrollable: true,
+      tabBarKey: tabBarKey,
+      useMaterial3: false,
+    ));
     final TabController controller = DefaultTabController.of(tester.element(find.text('AAAA')));
     expect(controller, isNotNull);
     expect(controller.index, 0);
@@ -788,6 +890,31 @@
     expect(controller.index, 0);
   });
 
+  testWidgets('Material3 - TabBar can be scrolled independent of the selection', (WidgetTester tester) async {
+    final List<String> tabs = <String>['AAAA', 'BBBB', 'CCCC', 'DDDD', 'EEEE', 'FFFF', 'GGGG', 'HHHH', 'IIII', 'JJJJ', 'KKKK', 'LLLL'];
+    const Key tabBarKey = Key('TabBar');
+    await tester.pumpWidget(buildFrame(
+      tabs: tabs,
+      value: 'AAAA',
+      isScrollable: true,
+      tabBarKey: tabBarKey,
+      useMaterial3: true,
+    ));
+    final TabController controller = DefaultTabController.of(tester.element(find.text('AAAA')));
+    expect(controller, isNotNull);
+    expect(controller.index, 0);
+
+    // Fling-scroll the TabBar to the left
+    expect(tester.getCenter(find.text('HHHH')).dx, lessThan(720.0));
+    await tester.fling(find.byKey(tabBarKey), const Offset(-200.0, 0.0), 10000.0);
+    await tester.pump();
+    await tester.pump(const Duration(seconds: 1)); // finish the scroll animation
+    expect(tester.getCenter(find.text('HHHH')).dx, lessThan(500.0));
+
+    // Scrolling the TabBar doesn't change the selection
+    expect(controller.index, 0);
+  });
+
   testWidgets('TabBarView maintains state', (WidgetTester tester) async {
     final List<String> tabs = <String>['AAAAAA', 'BBBBBB', 'CCCCCC', 'DDDDDD', 'EEEEEE'];
     String value = tabs[0];
@@ -2981,9 +3108,10 @@
     expect(tabBarBox.size.width, tabRight);
   });
 
-  testWidgets('TabBar with padding isScrollable: true', (WidgetTester tester) async {
+  testWidgets('Material3 - TabBar with padding isScrollable: true', (WidgetTester tester) async {
     const double indicatorWeight = 2.0; // default indicator weight
     const EdgeInsets padding = EdgeInsets.only(left: 3.0, top: 7.0, right: 5.0, bottom: 3.0);
+    const double tabStartOffset = 52.0;
 
     final List<Widget> tabs = <Widget>[
       SizedBox(key: UniqueKey(), width: 130.0, height: 30.0),
@@ -3008,6 +3136,7 @@
             tabs: tabs,
           ),
         ),
+        useMaterial3: true,
       ),
     );
 
@@ -3016,7 +3145,7 @@
     expect(tabBarBox.size.height, tabBarHeight);
 
     // Tab0 width = 130, height = 30
-    double tabLeft = padding.left;
+    double tabLeft = padding.left + tabStartOffset;
     double tabRight = tabLeft + 130.0;
     double tabTop = (tabBarHeight - indicatorWeight + (padding.top - padding.bottom) - 30.0) / 2.0;
     double tabBottom = tabTop + 30.0;
@@ -3040,7 +3169,7 @@
     expect(tester.getRect(find.byKey(tabs[2].key!)), tabRect);
 
     tabRight += padding.right;
-    expect(tabBarBox.size.width, tabRight);
+    expect(tabBarBox.size.width, tabRight + 320.0); // Right tab + remaining space of the stretched tab bar.
   });
 
   testWidgets('TabBar with labelPadding', (WidgetTester tester) async {
@@ -5950,15 +6079,12 @@
     );
   });
 
-  testWidgets('Default TabAlignment', (WidgetTester tester) async {
-    final ThemeData theme = ThemeData(useMaterial3: true);
+  testWidgets('Material3 - Default TabAlignment', (WidgetTester tester) async {
     final List<String> tabs = <String>['A', 'B'];
+    const double tabStartOffset = 52.0;
 
     // Test default TabAlignment when isScrollable is false.
-    await tester.pumpWidget(MaterialApp(
-      theme: theme,
-      home: buildFrame(tabs: tabs,  value: 'B'),
-    ));
+    await tester.pumpWidget(buildFrame(tabs: tabs, value: 'B', useMaterial3: true));
 
     final Rect tabBar = tester.getRect(find.byType(TabBar));
     Rect tabOneRect = tester.getRect(find.byType(Tab).first);
@@ -5971,18 +6097,20 @@
     expect(tabTwoRect.right, equals(tabTwoRight));
 
     // Test default TabAlignment when isScrollable is true.
-    await tester.pumpWidget(MaterialApp(
-      theme: theme,
-      home: buildFrame(tabs: tabs,  value: 'B', isScrollable: true),
+    await tester.pumpWidget(buildFrame(
+      tabs: tabs,
+      value: 'B',
+      isScrollable: true,
+      useMaterial3: true,
     ));
 
     tabOneRect = tester.getRect(find.byType(Tab).first);
     tabTwoRect = tester.getRect(find.byType(Tab).last);
 
     // Tabs should be aligned to the start of the TabBar.
-    tabOneLeft = kTabLabelPadding.left;
+    tabOneLeft = kTabLabelPadding.left + tabStartOffset;
     expect(tabOneRect.left, equals(tabOneLeft));
-    tabTwoRight = kTabLabelPadding.horizontal + tabOneRect.width + kTabLabelPadding.left + tabTwoRect.width;
+    tabTwoRight = kTabLabelPadding.horizontal + tabStartOffset + tabOneRect.width + kTabLabelPadding.left + tabTwoRect.width;
     expect(tabTwoRect.right, equals(tabTwoRight));
   });
 
@@ -6044,6 +6172,262 @@
     expect(tester.takeException(), isAssertionError);
   });
 
+  testWidgets('Material3 - TabAlignment updates tabs alignment (non-scrollable TabBar)', (WidgetTester tester) async {
+    final List<String> tabs = <String>['A', 'B'];
+
+    // Test TabAlignment.fill (default) when isScrollable is false.
+    await tester.pumpWidget(buildFrame(tabs: tabs,  value: 'B', useMaterial3: true));
+
+    const double availableWidth = 800.0;
+    Rect tabOneRect = tester.getRect(find.byType(Tab).first);
+    Rect tabTwoRect = tester.getRect(find.byType(Tab).last);
+
+    // By defaults tabs should fill the width of the TabBar.
+    double tabOneLeft = ((availableWidth / 2) - tabOneRect.width) / 2;
+    expect(tabOneRect.left, equals(tabOneLeft));
+    double tabTwoRight = availableWidth - ((availableWidth / 2) - tabTwoRect.width) / 2;
+    expect(tabTwoRect.right, equals(tabTwoRight));
+
+    // Test TabAlignment.center when isScrollable is false.
+    await tester.pumpWidget(buildFrame(
+      tabs: tabs,
+      value: 'B',
+      tabAlignment: TabAlignment.center,
+      useMaterial3: true,
+    ));
+    await tester.pumpAndSettle();
+
+    tabOneRect = tester.getRect(find.byType(Tab).first);
+    tabTwoRect = tester.getRect(find.byType(Tab).last);
+
+    // Tabs should not fill the width of the TabBar.
+    tabOneLeft = kTabLabelPadding.left;
+    expect(tabOneRect.left, equals(tabOneLeft));
+    tabTwoRight = kTabLabelPadding.horizontal + tabOneRect.width + kTabLabelPadding.left + tabTwoRect.width;
+    expect(tabTwoRect.right, equals(tabTwoRight));
+  });
+
+  testWidgets('Material3 - TabAlignment updates tabs alignment (scrollable TabBar)', (WidgetTester tester) async {
+    final List<String> tabs = <String>['A', 'B'];
+    const double tabStartOffset = 52.0;
+
+    // Test TabAlignment.startOffset (default) when isScrollable is true.
+    await tester.pumpWidget(buildFrame(
+      tabs: tabs,
+      value: 'B',
+      isScrollable: true,
+      useMaterial3: true,
+    ));
+
+    final Rect tabBar = tester.getRect(find.byType(TabBar));
+    Rect tabOneRect = tester.getRect(find.byType(Tab).first);
+    Rect tabTwoRect = tester.getRect(find.byType(Tab).last);
+
+    // By default tabs should be aligned to the start of the TabBar with
+    // an horizontal offset of 52.0 pixels.
+    double tabOneLeft = kTabLabelPadding.left + tabStartOffset;
+    expect(tabOneRect.left, equals(tabOneLeft));
+    double tabTwoRight = tabStartOffset + kTabLabelPadding.horizontal + tabOneRect.width
+      + kTabLabelPadding.left + tabTwoRect.width;
+    expect(tabTwoRect.right, equals(tabTwoRight));
+
+    // Test TabAlignment.start when isScrollable is true.
+    await tester.pumpWidget(buildFrame(
+      tabs: tabs,
+      value: 'B',
+      isScrollable: true,
+      tabAlignment: TabAlignment.start,
+      useMaterial3: true,
+    ));
+    await tester.pumpAndSettle();
+
+    tabOneRect = tester.getRect(find.byType(Tab).first);
+    tabTwoRect = tester.getRect(find.byType(Tab).last);
+
+    // Tabs should be aligned to the start of the TabBar.
+    tabOneLeft = kTabLabelPadding.left;
+    expect(tabOneRect.left, equals(tabOneLeft));
+    tabTwoRight = kTabLabelPadding.horizontal + tabOneRect.width + kTabLabelPadding.left + tabTwoRect.width;
+    expect(tabTwoRect.right, equals(tabTwoRight));
+
+    // Test TabAlignment.center when isScrollable is true.
+    await tester.pumpWidget(buildFrame(
+      tabs: tabs,
+      value: 'B',
+      isScrollable: true,
+      tabAlignment: TabAlignment.center,
+      useMaterial3: true,
+    ));
+    await tester.pumpAndSettle();
+
+    tabOneRect = tester.getRect(find.byType(Tab).first);
+    tabTwoRect = tester.getRect(find.byType(Tab).last);
+
+    // Tabs should be centered in the TabBar.
+    tabOneLeft = (tabBar.width / 2) - tabOneRect.width - kTabLabelPadding.right;
+    expect(tabOneRect.left, equals(tabOneLeft));
+    tabTwoRight = (tabBar.width / 2) + tabTwoRect.width + kTabLabelPadding.left;
+    expect(tabTwoRect.right, equals(tabTwoRight));
+
+    // Test TabAlignment.startOffset when isScrollable is true.
+    await tester.pumpWidget(buildFrame(
+      tabs: tabs,
+      value: 'B',
+      isScrollable: true,
+      tabAlignment: TabAlignment.startOffset,
+      useMaterial3: true,
+    ));
+    await tester.pumpAndSettle();
+
+    tabOneRect = tester.getRect(find.byType(Tab).first);
+    tabTwoRect = tester.getRect(find.byType(Tab).last);
+
+    // Tabs should be aligned to the start of the TabBar with an
+    // horizontal offset of 52.0 pixels.
+    tabOneLeft = kTabLabelPadding.left + tabStartOffset;
+    expect(tabOneRect.left, equals(tabOneLeft));
+    tabTwoRight = tabStartOffset + kTabLabelPadding.horizontal + tabOneRect.width
+      + kTabLabelPadding.left + tabTwoRect.width;
+    expect(tabTwoRect.right, equals(tabTwoRight));
+  });
+
+  testWidgets('Material3 - TabAlignment.start & TabAlignment.startOffset respects TextDirection.rtl', (WidgetTester tester) async {
+    final List<String> tabs = <String>['A', 'B'];
+    const double tabStartOffset = 52.0;
+
+    // Test TabAlignment.startOffset (default) when isScrollable is true.
+    await tester.pumpWidget(buildFrame(
+      tabs: tabs,
+      value: 'B',
+      isScrollable: true,
+      textDirection: TextDirection.rtl,
+      useMaterial3: true,
+    ));
+
+    final Rect tabBar = tester.getRect(find.byType(TabBar));
+    Rect tabOneRect = tester.getRect(find.byType(Tab).first);
+    Rect tabTwoRect = tester.getRect(find.byType(Tab).last);
+
+    // Tabs should be aligned to the start of the TabBar with an
+    // horizontal offset of 52.0 pixels.
+    double tabOneRight = tabBar.width - kTabLabelPadding.right - tabStartOffset;
+    expect(tabOneRect.right, equals(tabOneRight));
+    double tabTwoLeft = tabBar.width - tabStartOffset - kTabLabelPadding.horizontal - tabOneRect.width
+      - kTabLabelPadding.right - tabTwoRect.width;
+    expect(tabTwoRect.left, equals(tabTwoLeft));
+
+    // Test TabAlignment.start when isScrollable is true.
+    await tester.pumpWidget(buildFrame(
+      tabs: tabs,
+      value: 'B',
+      isScrollable: true,
+      tabAlignment: TabAlignment.start,
+      textDirection: TextDirection.rtl,
+      useMaterial3: true,
+    ));
+    await tester.pumpAndSettle();
+
+    tabOneRect = tester.getRect(find.byType(Tab).first);
+    tabTwoRect = tester.getRect(find.byType(Tab).last);
+
+    // Tabs should be aligned to the start of the TabBar.
+    tabOneRight = tabBar.width - kTabLabelPadding.right;
+    expect(tabOneRect.right, equals(tabOneRight));
+    tabTwoLeft = tabBar.width - kTabLabelPadding.horizontal - tabOneRect.width
+      - kTabLabelPadding.left - tabTwoRect.width;
+    expect(tabTwoRect.left, equals(tabTwoLeft));
+
+    // Test TabAlignment.startOffset when isScrollable is true.
+    await tester.pumpWidget(buildFrame(
+      tabs: tabs,
+      value: 'B',
+      isScrollable: true,
+      tabAlignment: TabAlignment.startOffset,
+      textDirection: TextDirection.rtl,
+      useMaterial3: true,
+    ));
+    await tester.pumpAndSettle();
+
+    tabOneRect = tester.getRect(find.byType(Tab).first);
+    tabTwoRect = tester.getRect(find.byType(Tab).last);
+
+    // Tabs should be aligned to the start of the TabBar with an
+    // horizontal offset of 52.0 pixels.
+    tabOneRight = tabBar.width - kTabLabelPadding.right - tabStartOffset;
+    expect(tabOneRect.right, equals(tabOneRight));
+    tabTwoLeft = tabBar.width - tabStartOffset - kTabLabelPadding.horizontal - tabOneRect.width
+      - kTabLabelPadding.right - tabTwoRect.width;
+    expect(tabTwoRect.left, equals(tabTwoLeft));
+  });
+
+  testWidgets('Material3 - TabBar inherits the dividerColor of TabBarTheme', (WidgetTester tester) async {
+    const Color dividerColor = Colors.yellow;
+    await tester.pumpWidget(
+      MaterialApp(
+        theme: ThemeData(
+          useMaterial3: true,
+          tabBarTheme: const TabBarTheme(dividerColor: dividerColor),
+        ),
+        home: Scaffold(
+          appBar: AppBar(
+            bottom: TabBar(
+              controller: TabController(length: 3, vsync: const TestVSync()),
+              tabs: const <Widget>[
+                Tab(text: 'Tab 1'),
+                Tab(text: 'Tab 2'),
+                Tab(text: 'Tab 3'),
+              ],
+            ),
+          ),
+        ),
+      ),
+    );
+
+    // Test painter's divider color.
+    final CustomPaint paint = tester.widget<CustomPaint>(find.byType(CustomPaint).last);
+    // ignore: avoid_dynamic_calls
+    expect((paint.painter as dynamic).dividerColor, dividerColor);
+  });
+
+  // This is a regression test for https://github.com/flutter/flutter/pull/125974#discussion_r1239089151.
+  testWidgets('Divider can be constrained', (WidgetTester tester) async {
+    const Color dividerColor = Colors.yellow;
+    await tester.pumpWidget(
+      MaterialApp(
+        theme: ThemeData(
+          useMaterial3: true,
+          tabBarTheme: const TabBarTheme(dividerColor: dividerColor),
+        ),
+        home: Scaffold(
+          body: DefaultTabController(
+            length: 2,
+            child: Center(
+              child: ConstrainedBox(
+                constraints: const BoxConstraints(maxWidth: 360),
+                child: ColoredBox(
+                  color: Colors.grey[200]!,
+                  child: const TabBar.secondary(
+                    tabAlignment: TabAlignment.start,
+                    isScrollable: true,
+                    tabs: <Widget>[
+                      Tab(text: 'Test 1'),
+                      Tab(text: 'Test 2'),
+                    ],
+                  ),
+                )
+              ),
+            ),
+          ),
+        ),
+      ),
+    );
+
+    // Test tab bar width.
+    expect(tester.getSize(find.byType(TabBar)).width, 360);
+    // Test divider width.
+    expect(tester.getSize(find.byType(CustomPaint).at(1)).width, 360);
+  });
+
   group('Material 2', () {
     // These tests are only relevant for Material 2. Once Material 2
     // support is deprecated and the APIs are removed, these tests
@@ -6104,45 +6488,11 @@
       );
     });
 
-    testWidgets('Material3 - TabBar inherits the dividerColor of TabBarTheme', (WidgetTester tester) async {
-      const Color dividerColor = Colors.yellow;
-
-      await tester.pumpWidget(
-        MaterialApp(
-          theme: ThemeData(
-            useMaterial3: true,
-            tabBarTheme: const TabBarTheme(dividerColor: dividerColor),
-          ),
-          home: Scaffold(
-            appBar: AppBar(
-              bottom: TabBar(
-                controller: TabController(length: 3, vsync: const TestVSync()),
-                tabs: const <Widget>[
-                  Tab(text: 'Tab 1'),
-                  Tab(text: 'Tab 2'),
-                  Tab(text: 'Tab 3'),
-                ],
-              ),
-            ),
-          ),
-        ),
-      );
-
-      // Test painter's divider color.
-      final CustomPaint paint = tester.widget<CustomPaint>(find.byType(CustomPaint).last);
-      // ignore: avoid_dynamic_calls
-      expect((paint.painter as dynamic).dividerColor, dividerColor);
-    });
-
-    testWidgets('Default TabAlignment', (WidgetTester tester) async {
-      final ThemeData theme = ThemeData(useMaterial3: false);
+    testWidgets('Material2 - Default TabAlignment', (WidgetTester tester) async {
       final List<String> tabs = <String>['A', 'B'];
 
       // Test default TabAlignment when isScrollable is false.
-      await tester.pumpWidget(MaterialApp(
-        theme: theme,
-        home: buildFrame(tabs: tabs,  value: 'B'),
-      ));
+      await tester.pumpWidget(buildFrame(tabs: tabs,  value: 'B', useMaterial3: false));
 
       final Rect tabBar = tester.getRect(find.byType(TabBar));
       Rect tabOneRect = tester.getRect(find.byType(Tab).first);
@@ -6155,9 +6505,11 @@
       expect(tabTwoRect.right, equals(tabTwoRight));
 
       // Test default TabAlignment when isScrollable is true.
-      await tester.pumpWidget(MaterialApp(
-        theme: theme,
-        home: buildFrame(tabs: tabs,  value: 'B', isScrollable: true),
+      await tester.pumpWidget(buildFrame(
+        tabs: tabs,
+        value: 'B',
+        isScrollable: true,
+        useMaterial3: false,
       ));
 
       tabOneRect = tester.getRect(find.byType(Tab).first);
@@ -6261,6 +6613,106 @@
             ),
       );
     });
+
+    testWidgets('Material2 - TabBar with padding isScrollable: true', (WidgetTester tester) async {
+      const double indicatorWeight = 2.0; // default indicator weight
+      const EdgeInsets padding = EdgeInsets.only(left: 3.0, top: 7.0, right: 5.0, bottom: 3.0);
+
+      final List<Widget> tabs = <Widget>[
+        SizedBox(key: UniqueKey(), width: 130.0, height: 30.0),
+        SizedBox(key: UniqueKey(), width: 140.0, height: 40.0),
+        SizedBox(key: UniqueKey(), width: 150.0, height: 50.0),
+      ];
+
+      final TabController controller = TabController(
+        vsync: const TestVSync(),
+        length: tabs.length,
+      );
+
+      await tester.pumpWidget(
+        boilerplate(
+          child: Container(
+            alignment: Alignment.topLeft,
+            child: TabBar(
+              padding: padding,
+              labelPadding: EdgeInsets.zero,
+              isScrollable: true,
+              controller: controller,
+              tabs: tabs,
+            ),
+          ),
+          useMaterial3: false,
+        ),
+      );
+
+      final RenderBox tabBarBox = tester.firstRenderObject<RenderBox>(find.byType(TabBar));
+      final double tabBarHeight = 50.0 + indicatorWeight + padding.top + padding.bottom;  // 50 = max tab height
+      expect(tabBarBox.size.height, tabBarHeight);
+
+      // Tab0 width = 130, height = 30
+      double tabLeft = padding.left;
+      double tabRight = tabLeft + 130.0;
+      double tabTop = (tabBarHeight - indicatorWeight + (padding.top - padding.bottom) - 30.0) / 2.0;
+      double tabBottom = tabTop + 30.0;
+      Rect tabRect = Rect.fromLTRB(tabLeft, tabTop, tabRight, tabBottom);
+      expect(tester.getRect(find.byKey(tabs[0].key!)), tabRect);
+
+      // Tab1 width = 140, height = 40
+      tabLeft = tabRight;
+      tabRight = tabLeft + 140.0;
+      tabTop = (tabBarHeight - indicatorWeight + (padding.top - padding.bottom) - 40.0) / 2.0;
+      tabBottom = tabTop + 40.0;
+      tabRect = Rect.fromLTRB(tabLeft, tabTop, tabRight, tabBottom);
+      expect(tester.getRect(find.byKey(tabs[1].key!)), tabRect);
+
+      // Tab2 width = 150, height = 50
+      tabLeft = tabRight;
+      tabRight = tabLeft + 150.0;
+      tabTop = (tabBarHeight - indicatorWeight + (padding.top - padding.bottom) - 50.0) / 2.0;
+      tabBottom = tabTop + 50.0;
+      tabRect = Rect.fromLTRB(tabLeft, tabTop, tabRight, tabBottom);
+      expect(tester.getRect(find.byKey(tabs[2].key!)), tabRect);
+
+      tabRight += padding.right;
+      expect(tabBarBox.size.width, tabRight);
+    });
+
+    testWidgets('Material2 - TabAlignment updates tabs alignment (non-scrollable TabBar)', (WidgetTester tester) async {
+      final ThemeData theme = ThemeData(useMaterial3: false);
+      final List<String> tabs = <String>['A', 'B'];
+
+      // Test TabAlignment.fill (default) when isScrollable is false.
+      await tester.pumpWidget(MaterialApp(
+        theme: theme,
+        home: buildFrame(tabs: tabs,  value: 'B'),
+      ));
+
+      final Rect tabBar = tester.getRect(find.byType(TabBar));
+      Rect tabOneRect = tester.getRect(find.byType(Tab).first);
+      Rect tabTwoRect = tester.getRect(find.byType(Tab).last);
+
+      // By default tabs should fill the width of the TabBar.
+      double tabOneLeft = ((tabBar.width / 2) - tabOneRect.width) / 2;
+      expect(tabOneRect.left, equals(tabOneLeft));
+      double tabTwoRight = tabBar.width - ((tabBar.width / 2) - tabTwoRect.width) / 2;
+      expect(tabTwoRect.right, equals(tabTwoRight));
+
+      // Test TabAlignment.center when isScrollable is false.
+      await tester.pumpWidget(MaterialApp(
+        theme: theme,
+        home: buildFrame(tabs: tabs, value: 'B', tabAlignment: TabAlignment.center),
+      ));
+      await tester.pumpAndSettle();
+
+      tabOneRect = tester.getRect(find.byType(Tab).first);
+      tabTwoRect = tester.getRect(find.byType(Tab).last);
+
+      // Tabs should not fill the width of the TabBar.
+      tabOneLeft = kTabLabelPadding.left;
+      expect(tabOneRect.left, equals(tabOneLeft));
+      tabTwoRight = kTabLabelPadding.horizontal + tabOneRect.width + kTabLabelPadding.left + tabTwoRect.width;
+      expect(tabTwoRect.right, equals(tabTwoRight));
+    });
   });
 }