Fix RangeSlider renders track when track colors are transparent (#162386)

### Description 

Fixes [`Slider` with transparent track colors and custom `trackHeight`
cannot reach the extreme
ends](https://github.com/flutter/flutter/issues/161210) but for
`RangeSlider`.

### Code Sample

<details>
<summary>expand to view the code sample</summary> 

```dart
import 'package:flutter/material.dart';

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

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

  @override
  State<MyApp> createState() => _MyAppState();
}

class _MyAppState extends State<MyApp> {
  RangeValues _values = const RangeValues(0, 100);

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      debugShowCheckedModeBanner: false,
      home: Scaffold(
        body: Center(
          child: Column(
            spacing: 20,
            mainAxisSize: MainAxisSize.min,
            children: <Widget>[
              SliderTheme(
                data: const SliderThemeData(
                  trackHeight: 100,
                  activeTrackColor: Colors.transparent,
                  inactiveTrackColor: Colors.transparent,
                ),
                child: RangeSlider(
                  values: _values,
                  max: 100,
                  onChanged: (RangeValues values) {
                    setState(() {
                      _values = values;
                    });
                  },
                ),
              ),
            ],
          ),
        ),
      ),
    );
  }
}

```

</details>


### Before

<img width="755" alt="Screenshot 2025-02-12 at 15 56 21"
src="https://github.com/user-attachments/assets/e8c88bd8-3c87-46e2-9f29-b945128ae93a"
/>


### After

<img width="755" alt="Screenshot 2025-02-12 at 15 56 09"
src="https://github.com/user-attachments/assets/5f9244e8-4d51-40f3-a3fc-afdf9dff9b35"
/>


## Pre-launch Checklist

- [x] I read the [Contributor Guide] and followed the process outlined
there for submitting PRs.
- [x] I read the [Tree Hygiene] wiki page, which explains my
responsibilities.
- [x] I read and followed the [Flutter Style Guide], including [Features
we expect every widget to implement].
- [x] I signed the [CLA].
- [x] I listed at least one issue that this PR fixes in the description
above.
- [x] I updated/added relevant documentation (doc comments with `///`).
- [x] I added new tests to check the change I am making, or this PR is
[test-exempt].
- [ ] I followed the [breaking change policy] and added [Data Driven
Fixes] where supported.
- [x] All existing and new tests are passing.

If you need help, consider asking for advice on the #hackers-new channel
on [Discord].

<!-- Links -->
[Contributor Guide]:
https://github.com/flutter/flutter/blob/main/docs/contributing/Tree-hygiene.md#overview
[Tree Hygiene]:
https://github.com/flutter/flutter/blob/main/docs/contributing/Tree-hygiene.md
[test-exempt]:
https://github.com/flutter/flutter/blob/main/docs/contributing/Tree-hygiene.md#tests
[Flutter Style Guide]:
https://github.com/flutter/flutter/blob/main/docs/contributing/Style-guide-for-Flutter-repo.md
[Features we expect every widget to implement]:
https://github.com/flutter/flutter/blob/main/docs/contributing/Style-guide-for-Flutter-repo.md#features-we-expect-every-widget-to-implement
[CLA]: https://cla.developers.google.com/
[flutter/tests]: https://github.com/flutter/tests
[breaking change policy]:
https://github.com/flutter/flutter/blob/main/docs/contributing/Tree-hygiene.md#handling-breaking-changes
[Discord]:
https://github.com/flutter/flutter/blob/main/docs/contributing/Chat.md
[Data Driven Fixes]:
https://github.com/flutter/flutter/blob/main/docs/contributing/Data-driven-Fixes.md
This commit is contained in:
Taha Tesser 2025-02-25 09:32:03 +02:00 committed by GitHub
parent 271cb8c8c5
commit 8cf41e9b4f
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
2 changed files with 47 additions and 1 deletions

View File

@ -2199,10 +2199,17 @@ mixin BaseRangeSliderTrackShape {
sliderTheme.rangeThumbShape!.getPreferredSize(isEnabled, isDiscrete).width; sliderTheme.rangeThumbShape!.getPreferredSize(isEnabled, isDiscrete).width;
final double overlayWidth = final double overlayWidth =
sliderTheme.overlayShape!.getPreferredSize(isEnabled, isDiscrete).width; sliderTheme.overlayShape!.getPreferredSize(isEnabled, isDiscrete).width;
final double trackHeight = sliderTheme.trackHeight!; double trackHeight = sliderTheme.trackHeight!;
assert(overlayWidth >= 0); assert(overlayWidth >= 0);
assert(trackHeight >= 0); assert(trackHeight >= 0);
// If the track colors are transparent, then override only the track height
// to maintain overall Slider width.
if (sliderTheme.activeTrackColor == Colors.transparent &&
sliderTheme.inactiveTrackColor == Colors.transparent) {
trackHeight = 0;
}
final double trackLeft = offset.dx + math.max(overlayWidth / 2, thumbWidth / 2); final double trackLeft = offset.dx + math.max(overlayWidth / 2, thumbWidth / 2);
final double trackTop = offset.dy + (parentBox.size.height - trackHeight) / 2; final double trackTop = offset.dy + (parentBox.size.height - trackHeight) / 2;
final double trackRight = trackLeft + parentBox.size.width - math.max(thumbWidth, overlayWidth); final double trackRight = trackLeft + parentBox.size.width - math.max(thumbWidth, overlayWidth);

View File

@ -3050,6 +3050,45 @@ void main() {
}, },
); );
// Regression test for https://github.com/flutter/flutter/issues/161210
testWidgets(
'RangeSlider with transparent track colors and custom track height can reach extreme ends',
(WidgetTester tester) async {
const double sliderPadding = 24.0;
final ThemeData theme = ThemeData(
sliderTheme: const SliderThemeData(
trackHeight: 100,
activeTrackColor: Colors.transparent,
inactiveTrackColor: Colors.transparent,
),
);
await tester.pumpWidget(
MaterialApp(
theme: theme,
home: Material(
child: SizedBox(
width: 300,
child: RangeSlider(
values: const RangeValues(0, 1),
onChanged: (RangeValues values) {},
),
),
),
),
);
final MaterialInkController material = Material.of(tester.element(find.byType(RangeSlider)));
expect(
material,
paints
..circle(x: sliderPadding, y: 300.0, color: theme.colorScheme.primary)
..circle(x: 800.0 - sliderPadding, y: 300.0, color: theme.colorScheme.primary),
);
},
);
group('Material 2', () { group('Material 2', () {
// These tests are only relevant for Material 2. Once Material 2 // These tests are only relevant for Material 2. Once Material 2
// support is deprecated and the APIs are removed, these tests // support is deprecated and the APIs are removed, these tests