Unverified Commit 09008e6f authored by Kate Lovett's avatar Kate Lovett Committed by GitHub

Add ScrollbarTheme/ScrollbarThemeData (#72308)

parent cbe72db1
...@@ -115,6 +115,7 @@ export 'src/material/refresh_indicator.dart'; ...@@ -115,6 +115,7 @@ export 'src/material/refresh_indicator.dart';
export 'src/material/reorderable_list.dart'; export 'src/material/reorderable_list.dart';
export 'src/material/scaffold.dart'; export 'src/material/scaffold.dart';
export 'src/material/scrollbar.dart'; export 'src/material/scrollbar.dart';
export 'src/material/scrollbar_theme.dart';
export 'src/material/search.dart'; export 'src/material/search.dart';
export 'src/material/selectable_text.dart'; export 'src/material/selectable_text.dart';
export 'src/material/shadows.dart'; export 'src/material/shadows.dart';
......
...@@ -8,6 +8,7 @@ import 'package:flutter/widgets.dart'; ...@@ -8,6 +8,7 @@ import 'package:flutter/widgets.dart';
import 'color_scheme.dart'; import 'color_scheme.dart';
import 'material_state.dart'; import 'material_state.dart';
import 'scrollbar_theme.dart';
import 'theme.dart'; import 'theme.dart';
const double _kScrollbarThickness = 8.0; const double _kScrollbarThickness = 8.0;
...@@ -37,6 +38,7 @@ const Duration _kScrollbarTimeToFade = Duration(milliseconds: 600); ...@@ -37,6 +38,7 @@ const Duration _kScrollbarTimeToFade = Duration(milliseconds: 600);
/// ///
/// * [RawScrollbar], a basic scrollbar that fades in and out, extended /// * [RawScrollbar], a basic scrollbar that fades in and out, extended
/// by this class to add more animations and behaviors. /// by this class to add more animations and behaviors.
/// * [ScrollbarTheme], which configures the Scrollbar's appearance.
/// * [CupertinoScrollbar], an iOS style scrollbar. /// * [CupertinoScrollbar], an iOS style scrollbar.
/// * [ListView], which displays a linear, scrollable list of children. /// * [ListView], which displays a linear, scrollable list of children.
/// * [GridView], which displays a 2 dimensional, scrollable array of children. /// * [GridView], which displays a 2 dimensional, scrollable array of children.
...@@ -59,8 +61,8 @@ class Scrollbar extends RawScrollbar { ...@@ -59,8 +61,8 @@ class Scrollbar extends RawScrollbar {
Key? key, Key? key,
required Widget child, required Widget child,
ScrollController? controller, ScrollController? controller,
bool isAlwaysShown = false, bool? isAlwaysShown,
this.showTrackOnHover = false, this.showTrackOnHover,
this.hoverThickness, this.hoverThickness,
double? thickness, double? thickness,
Radius? radius, Radius? radius,
...@@ -78,13 +80,17 @@ class Scrollbar extends RawScrollbar { ...@@ -78,13 +80,17 @@ class Scrollbar extends RawScrollbar {
/// Controls if the track will show on hover and remain, including during drag. /// Controls if the track will show on hover and remain, including during drag.
/// ///
/// Defaults to false, cannot be null. /// If this property is null, then [ScrollbarThemeData.showTrackOnHover] of
final bool showTrackOnHover; /// [ThemeData.scrollbarTheme] is used. If that is also null, the default value
/// is false.
final bool? showTrackOnHover;
/// The thickness of the scrollbar when a hover state is active and /// The thickness of the scrollbar when a hover state is active and
/// [showTrackOnHover] is true. /// [showTrackOnHover] is true.
/// ///
/// Defaults to 12.0 dp when null. /// If this property is null, then [ScrollbarThemeData.thickness] of
/// [ThemeData.scrollbarTheme] is used to resolve a thickness. If that is also
/// null, the default value is 12.0 pixels.
final double? hoverThickness; final double? hoverThickness;
@override @override
...@@ -96,9 +102,15 @@ class _ScrollbarState extends RawScrollbarState<Scrollbar> { ...@@ -96,9 +102,15 @@ class _ScrollbarState extends RawScrollbarState<Scrollbar> {
bool _dragIsActive = false; bool _dragIsActive = false;
bool _hoverIsActive = false; bool _hoverIsActive = false;
late ColorScheme _colorScheme; late ColorScheme _colorScheme;
late ScrollbarThemeData _scrollbarTheme;
// On Android, scrollbars should match native appearance. // On Android, scrollbars should match native appearance.
late bool _useAndroidScrollbar; late bool _useAndroidScrollbar;
@override
bool get showScrollbar => widget.isAlwaysShown ?? _scrollbarTheme.isAlwaysShown ?? false;
bool get _showTrackOnHover => widget.showTrackOnHover ?? _scrollbarTheme.showTrackOnHover ?? false;
Set<MaterialState> get _states => <MaterialState>{ Set<MaterialState> get _states => <MaterialState>{
if (_dragIsActive) MaterialState.dragged, if (_dragIsActive) MaterialState.dragged,
if (_hoverIsActive) MaterialState.hovered, if (_hoverIsActive) MaterialState.hovered,
...@@ -125,16 +137,16 @@ class _ScrollbarState extends RawScrollbarState<Scrollbar> { ...@@ -125,16 +137,16 @@ class _ScrollbarState extends RawScrollbarState<Scrollbar> {
return MaterialStateProperty.resolveWith((Set<MaterialState> states) { return MaterialStateProperty.resolveWith((Set<MaterialState> states) {
if (states.contains(MaterialState.dragged)) if (states.contains(MaterialState.dragged))
return dragColor; return _scrollbarTheme.thumbColor?.resolve(states) ?? dragColor;
// If the track is visible, the thumb color hover animation is ignored and // If the track is visible, the thumb color hover animation is ignored and
// changes immediately. // changes immediately.
if (states.contains(MaterialState.hovered) && widget.showTrackOnHover) if (states.contains(MaterialState.hovered) && _showTrackOnHover)
return hoverColor; return _scrollbarTheme.thumbColor?.resolve(states) ?? hoverColor;
return Color.lerp( return Color.lerp(
idleColor, _scrollbarTheme.thumbColor?.resolve(states) ?? idleColor,
hoverColor, _scrollbarTheme.thumbColor?.resolve(states) ?? hoverColor,
_hoverAnimationController.value, _hoverAnimationController.value,
)!; )!;
}); });
...@@ -144,10 +156,11 @@ class _ScrollbarState extends RawScrollbarState<Scrollbar> { ...@@ -144,10 +156,11 @@ class _ScrollbarState extends RawScrollbarState<Scrollbar> {
final Color onSurface = _colorScheme.onSurface; final Color onSurface = _colorScheme.onSurface;
final Brightness brightness = _colorScheme.brightness; final Brightness brightness = _colorScheme.brightness;
return MaterialStateProperty.resolveWith((Set<MaterialState> states) { return MaterialStateProperty.resolveWith((Set<MaterialState> states) {
if (states.contains(MaterialState.hovered) && widget.showTrackOnHover) { if (states.contains(MaterialState.hovered) && _showTrackOnHover) {
return brightness == Brightness.light return _scrollbarTheme.trackColor?.resolve(states)
? onSurface.withOpacity(0.03) ?? (brightness == Brightness.light
: onSurface.withOpacity(0.05); ? onSurface.withOpacity(0.03)
: onSurface.withOpacity(0.05));
} }
return const Color(0x00000000); return const Color(0x00000000);
}); });
...@@ -157,10 +170,11 @@ class _ScrollbarState extends RawScrollbarState<Scrollbar> { ...@@ -157,10 +170,11 @@ class _ScrollbarState extends RawScrollbarState<Scrollbar> {
final Color onSurface = _colorScheme.onSurface; final Color onSurface = _colorScheme.onSurface;
final Brightness brightness = _colorScheme.brightness; final Brightness brightness = _colorScheme.brightness;
return MaterialStateProperty.resolveWith((Set<MaterialState> states) { return MaterialStateProperty.resolveWith((Set<MaterialState> states) {
if (states.contains(MaterialState.hovered) && widget.showTrackOnHover) { if (states.contains(MaterialState.hovered) && _showTrackOnHover) {
return brightness == Brightness.light return _scrollbarTheme.trackBorderColor?.resolve(states)
? onSurface.withOpacity(0.1) ?? (brightness == Brightness.light
: onSurface.withOpacity(0.25); ? onSurface.withOpacity(0.1)
: onSurface.withOpacity(0.25));
} }
return const Color(0x00000000); return const Color(0x00000000);
}); });
...@@ -168,10 +182,14 @@ class _ScrollbarState extends RawScrollbarState<Scrollbar> { ...@@ -168,10 +182,14 @@ class _ScrollbarState extends RawScrollbarState<Scrollbar> {
MaterialStateProperty<double> get _thickness { MaterialStateProperty<double> get _thickness {
return MaterialStateProperty.resolveWith((Set<MaterialState> states) { return MaterialStateProperty.resolveWith((Set<MaterialState> states) {
if (states.contains(MaterialState.hovered) && widget.showTrackOnHover) if (states.contains(MaterialState.hovered) && _showTrackOnHover)
return widget.hoverThickness ?? _kScrollbarThicknessWithTrack; return widget.hoverThickness
?? _scrollbarTheme.thickness?.resolve(states)
?? _kScrollbarThicknessWithTrack;
// The default scrollbar thickness is smaller on mobile. // The default scrollbar thickness is smaller on mobile.
return widget.thickness ?? (_kScrollbarThickness / (_useAndroidScrollbar ? 2 : 1)); return widget.thickness
?? _scrollbarTheme.thickness?.resolve(states)
?? (_kScrollbarThickness / (_useAndroidScrollbar ? 2 : 1));
}); });
} }
...@@ -190,6 +208,8 @@ class _ScrollbarState extends RawScrollbarState<Scrollbar> { ...@@ -190,6 +208,8 @@ class _ScrollbarState extends RawScrollbarState<Scrollbar> {
@override @override
void didChangeDependencies() { void didChangeDependencies() {
final ThemeData theme = Theme.of(context); final ThemeData theme = Theme.of(context);
_colorScheme = theme.colorScheme;
_scrollbarTheme = theme.scrollbarTheme;
switch (theme.platform) { switch (theme.platform) {
case TargetPlatform.android: case TargetPlatform.android:
_useAndroidScrollbar = true; _useAndroidScrollbar = true;
...@@ -207,16 +227,16 @@ class _ScrollbarState extends RawScrollbarState<Scrollbar> { ...@@ -207,16 +227,16 @@ class _ScrollbarState extends RawScrollbarState<Scrollbar> {
@override @override
void updateScrollbarPainter() { void updateScrollbarPainter() {
_colorScheme = Theme.of(context).colorScheme;
scrollbarPainter scrollbarPainter
..color = _thumbColor.resolve(_states) ..color = _thumbColor.resolve(_states)
..trackColor = _trackColor.resolve(_states) ..trackColor = _trackColor.resolve(_states)
..trackBorderColor = _trackBorderColor.resolve(_states) ..trackBorderColor = _trackBorderColor.resolve(_states)
..textDirection = Directionality.of(context) ..textDirection = Directionality.of(context)
..thickness = _thickness.resolve(_states) ..thickness = _thickness.resolve(_states)
..radius = widget.radius ?? (_useAndroidScrollbar ? null : _kScrollbarRadius) ..radius = widget.radius ?? _scrollbarTheme.radius ?? (_useAndroidScrollbar ? null : _kScrollbarRadius)
..crossAxisMargin = (_useAndroidScrollbar ? 0.0 : _kScrollbarMargin) ..crossAxisMargin = _scrollbarTheme.crossAxisMargin ?? (_useAndroidScrollbar ? 0.0 : _kScrollbarMargin)
..minLength = _kScrollbarMinLength ..mainAxisMargin = _scrollbarTheme.mainAxisMargin ?? 0.0
..minLength = _scrollbarTheme.minThumbLength ?? _kScrollbarMinLength
..padding = MediaQuery.of(context).padding; ..padding = MediaQuery.of(context).padding;
} }
......
This diff is collapsed.
...@@ -34,6 +34,7 @@ import 'outlined_button_theme.dart'; ...@@ -34,6 +34,7 @@ import 'outlined_button_theme.dart';
import 'page_transitions_theme.dart'; import 'page_transitions_theme.dart';
import 'popup_menu_theme.dart'; import 'popup_menu_theme.dart';
import 'radio_theme.dart'; import 'radio_theme.dart';
import 'scrollbar_theme.dart';
import 'slider_theme.dart'; import 'slider_theme.dart';
import 'snack_bar_theme.dart'; import 'snack_bar_theme.dart';
import 'switch_theme.dart'; import 'switch_theme.dart';
...@@ -278,6 +279,7 @@ class ThemeData with Diagnosticable { ...@@ -278,6 +279,7 @@ class ThemeData with Diagnosticable {
bool? applyElevationOverlayColor, bool? applyElevationOverlayColor,
PageTransitionsTheme? pageTransitionsTheme, PageTransitionsTheme? pageTransitionsTheme,
AppBarTheme? appBarTheme, AppBarTheme? appBarTheme,
ScrollbarThemeData? scrollbarTheme,
BottomAppBarTheme? bottomAppBarTheme, BottomAppBarTheme? bottomAppBarTheme,
ColorScheme? colorScheme, ColorScheme? colorScheme,
DialogTheme? dialogTheme, DialogTheme? dialogTheme,
...@@ -410,6 +412,7 @@ class ThemeData with Diagnosticable { ...@@ -410,6 +412,7 @@ class ThemeData with Diagnosticable {
tabBarTheme ??= const TabBarTheme(); tabBarTheme ??= const TabBarTheme();
tooltipTheme ??= const TooltipThemeData(); tooltipTheme ??= const TooltipThemeData();
appBarTheme ??= const AppBarTheme(); appBarTheme ??= const AppBarTheme();
scrollbarTheme ??= const ScrollbarThemeData();
bottomAppBarTheme ??= const BottomAppBarTheme(); bottomAppBarTheme ??= const BottomAppBarTheme();
cardTheme ??= const CardTheme(); cardTheme ??= const CardTheme();
chipTheme ??= ChipThemeData.fromDefaults( chipTheme ??= ChipThemeData.fromDefaults(
...@@ -493,6 +496,7 @@ class ThemeData with Diagnosticable { ...@@ -493,6 +496,7 @@ class ThemeData with Diagnosticable {
applyElevationOverlayColor: applyElevationOverlayColor, applyElevationOverlayColor: applyElevationOverlayColor,
pageTransitionsTheme: pageTransitionsTheme, pageTransitionsTheme: pageTransitionsTheme,
appBarTheme: appBarTheme, appBarTheme: appBarTheme,
scrollbarTheme: scrollbarTheme,
bottomAppBarTheme: bottomAppBarTheme, bottomAppBarTheme: bottomAppBarTheme,
colorScheme: colorScheme, colorScheme: colorScheme,
dialogTheme: dialogTheme, dialogTheme: dialogTheme,
...@@ -583,6 +587,7 @@ class ThemeData with Diagnosticable { ...@@ -583,6 +587,7 @@ class ThemeData with Diagnosticable {
required this.applyElevationOverlayColor, required this.applyElevationOverlayColor,
required this.pageTransitionsTheme, required this.pageTransitionsTheme,
required this.appBarTheme, required this.appBarTheme,
required this.scrollbarTheme,
required this.bottomAppBarTheme, required this.bottomAppBarTheme,
required this.colorScheme, required this.colorScheme,
required this.dialogTheme, required this.dialogTheme,
...@@ -657,6 +662,7 @@ class ThemeData with Diagnosticable { ...@@ -657,6 +662,7 @@ class ThemeData with Diagnosticable {
assert(materialTapTargetSize != null), assert(materialTapTargetSize != null),
assert(pageTransitionsTheme != null), assert(pageTransitionsTheme != null),
assert(appBarTheme != null), assert(appBarTheme != null),
assert(scrollbarTheme != null),
assert(bottomAppBarTheme != null), assert(bottomAppBarTheme != null),
assert(colorScheme != null), assert(colorScheme != null),
assert(dialogTheme != null), assert(dialogTheme != null),
...@@ -1085,6 +1091,9 @@ class ThemeData with Diagnosticable { ...@@ -1085,6 +1091,9 @@ class ThemeData with Diagnosticable {
/// textTheme of [AppBar]s. /// textTheme of [AppBar]s.
final AppBarTheme appBarTheme; final AppBarTheme appBarTheme;
/// A theme for customizing the colors, thickness, and shape of [Scrollbar]s.
final ScrollbarThemeData scrollbarTheme;
/// A theme for customizing the shape, elevation, and color of a [BottomAppBar]. /// A theme for customizing the shape, elevation, and color of a [BottomAppBar].
final BottomAppBarTheme bottomAppBarTheme; final BottomAppBarTheme bottomAppBarTheme;
...@@ -1270,6 +1279,7 @@ class ThemeData with Diagnosticable { ...@@ -1270,6 +1279,7 @@ class ThemeData with Diagnosticable {
bool? applyElevationOverlayColor, bool? applyElevationOverlayColor,
PageTransitionsTheme? pageTransitionsTheme, PageTransitionsTheme? pageTransitionsTheme,
AppBarTheme? appBarTheme, AppBarTheme? appBarTheme,
ScrollbarThemeData? scrollbarTheme,
BottomAppBarTheme? bottomAppBarTheme, BottomAppBarTheme? bottomAppBarTheme,
ColorScheme? colorScheme, ColorScheme? colorScheme,
DialogTheme? dialogTheme, DialogTheme? dialogTheme,
...@@ -1353,6 +1363,7 @@ class ThemeData with Diagnosticable { ...@@ -1353,6 +1363,7 @@ class ThemeData with Diagnosticable {
applyElevationOverlayColor: applyElevationOverlayColor ?? this.applyElevationOverlayColor, applyElevationOverlayColor: applyElevationOverlayColor ?? this.applyElevationOverlayColor,
pageTransitionsTheme: pageTransitionsTheme ?? this.pageTransitionsTheme, pageTransitionsTheme: pageTransitionsTheme ?? this.pageTransitionsTheme,
appBarTheme: appBarTheme ?? this.appBarTheme, appBarTheme: appBarTheme ?? this.appBarTheme,
scrollbarTheme: scrollbarTheme ?? this.scrollbarTheme,
bottomAppBarTheme: bottomAppBarTheme ?? this.bottomAppBarTheme, bottomAppBarTheme: bottomAppBarTheme ?? this.bottomAppBarTheme,
colorScheme: (colorScheme ?? this.colorScheme).copyWith(brightness: brightness), colorScheme: (colorScheme ?? this.colorScheme).copyWith(brightness: brightness),
dialogTheme: dialogTheme ?? this.dialogTheme, dialogTheme: dialogTheme ?? this.dialogTheme,
...@@ -1510,6 +1521,7 @@ class ThemeData with Diagnosticable { ...@@ -1510,6 +1521,7 @@ class ThemeData with Diagnosticable {
applyElevationOverlayColor: t < 0.5 ? a.applyElevationOverlayColor : b.applyElevationOverlayColor, applyElevationOverlayColor: t < 0.5 ? a.applyElevationOverlayColor : b.applyElevationOverlayColor,
pageTransitionsTheme: t < 0.5 ? a.pageTransitionsTheme : b.pageTransitionsTheme, pageTransitionsTheme: t < 0.5 ? a.pageTransitionsTheme : b.pageTransitionsTheme,
appBarTheme: AppBarTheme.lerp(a.appBarTheme, b.appBarTheme, t), appBarTheme: AppBarTheme.lerp(a.appBarTheme, b.appBarTheme, t),
scrollbarTheme: ScrollbarThemeData.lerp(a.scrollbarTheme, b.scrollbarTheme, t),
bottomAppBarTheme: BottomAppBarTheme.lerp(a.bottomAppBarTheme, b.bottomAppBarTheme, t), bottomAppBarTheme: BottomAppBarTheme.lerp(a.bottomAppBarTheme, b.bottomAppBarTheme, t),
colorScheme: ColorScheme.lerp(a.colorScheme, b.colorScheme, t), colorScheme: ColorScheme.lerp(a.colorScheme, b.colorScheme, t),
dialogTheme: DialogTheme.lerp(a.dialogTheme, b.dialogTheme, t), dialogTheme: DialogTheme.lerp(a.dialogTheme, b.dialogTheme, t),
...@@ -1595,6 +1607,7 @@ class ThemeData with Diagnosticable { ...@@ -1595,6 +1607,7 @@ class ThemeData with Diagnosticable {
&& other.applyElevationOverlayColor == applyElevationOverlayColor && other.applyElevationOverlayColor == applyElevationOverlayColor
&& other.pageTransitionsTheme == pageTransitionsTheme && other.pageTransitionsTheme == pageTransitionsTheme
&& other.appBarTheme == appBarTheme && other.appBarTheme == appBarTheme
&& other.scrollbarTheme == scrollbarTheme
&& other.bottomAppBarTheme == bottomAppBarTheme && other.bottomAppBarTheme == bottomAppBarTheme
&& other.colorScheme == colorScheme && other.colorScheme == colorScheme
&& other.dialogTheme == dialogTheme && other.dialogTheme == dialogTheme
...@@ -1679,6 +1692,7 @@ class ThemeData with Diagnosticable { ...@@ -1679,6 +1692,7 @@ class ThemeData with Diagnosticable {
applyElevationOverlayColor, applyElevationOverlayColor,
pageTransitionsTheme, pageTransitionsTheme,
appBarTheme, appBarTheme,
scrollbarTheme,
bottomAppBarTheme, bottomAppBarTheme,
colorScheme, colorScheme,
dialogTheme, dialogTheme,
...@@ -1760,6 +1774,7 @@ class ThemeData with Diagnosticable { ...@@ -1760,6 +1774,7 @@ class ThemeData with Diagnosticable {
properties.add(DiagnosticsProperty<bool>('applyElevationOverlayColor', applyElevationOverlayColor, level: DiagnosticLevel.debug)); properties.add(DiagnosticsProperty<bool>('applyElevationOverlayColor', applyElevationOverlayColor, level: DiagnosticLevel.debug));
properties.add(DiagnosticsProperty<PageTransitionsTheme>('pageTransitionsTheme', pageTransitionsTheme, level: DiagnosticLevel.debug)); properties.add(DiagnosticsProperty<PageTransitionsTheme>('pageTransitionsTheme', pageTransitionsTheme, level: DiagnosticLevel.debug));
properties.add(DiagnosticsProperty<AppBarTheme>('appBarTheme', appBarTheme, defaultValue: defaultData.appBarTheme, level: DiagnosticLevel.debug)); properties.add(DiagnosticsProperty<AppBarTheme>('appBarTheme', appBarTheme, defaultValue: defaultData.appBarTheme, level: DiagnosticLevel.debug));
properties.add(DiagnosticsProperty<ScrollbarThemeData>('ScrollbarTheme', scrollbarTheme, defaultValue: defaultData.scrollbarTheme, level: DiagnosticLevel.debug));
properties.add(DiagnosticsProperty<BottomAppBarTheme>('bottomAppBarTheme', bottomAppBarTheme, defaultValue: defaultData.bottomAppBarTheme, level: DiagnosticLevel.debug)); properties.add(DiagnosticsProperty<BottomAppBarTheme>('bottomAppBarTheme', bottomAppBarTheme, defaultValue: defaultData.bottomAppBarTheme, level: DiagnosticLevel.debug));
properties.add(DiagnosticsProperty<ColorScheme>('colorScheme', colorScheme, defaultValue: defaultData.colorScheme, level: DiagnosticLevel.debug)); properties.add(DiagnosticsProperty<ColorScheme>('colorScheme', colorScheme, defaultValue: defaultData.colorScheme, level: DiagnosticLevel.debug));
properties.add(DiagnosticsProperty<DialogTheme>('dialogTheme', dialogTheme, defaultValue: defaultData.dialogTheme, level: DiagnosticLevel.debug)); properties.add(DiagnosticsProperty<DialogTheme>('dialogTheme', dialogTheme, defaultValue: defaultData.dialogTheme, level: DiagnosticLevel.debug));
......
...@@ -600,15 +600,14 @@ class RawScrollbar extends StatefulWidget { ...@@ -600,15 +600,14 @@ class RawScrollbar extends StatefulWidget {
Key? key, Key? key,
required this.child, required this.child,
this.controller, this.controller,
this.isAlwaysShown = false, this.isAlwaysShown,
this.radius, this.radius,
this.thickness, this.thickness,
this.thumbColor, this.thumbColor,
this.fadeDuration = _kScrollbarFadeDuration, this.fadeDuration = _kScrollbarFadeDuration,
this.timeToFade = _kScrollbarTimeToFade, this.timeToFade = _kScrollbarTimeToFade,
this.pressDuration = Duration.zero, this.pressDuration = Duration.zero,
}) : assert(isAlwaysShown != null), }) : assert(child != null),
assert(child != null),
assert(fadeDuration != null), assert(fadeDuration != null),
assert(timeToFade != null), assert(timeToFade != null),
assert(pressDuration != null), assert(pressDuration != null),
...@@ -683,7 +682,7 @@ class RawScrollbar extends StatefulWidget { ...@@ -683,7 +682,7 @@ class RawScrollbar extends StatefulWidget {
/// [controller] property has not been set, the [PrimaryScrollController] will /// [controller] property has not been set, the [PrimaryScrollController] will
/// be used. /// be used.
/// ///
/// Defaults to false. /// Defaults to false when null.
/// ///
/// {@tool snippet} /// {@tool snippet}
/// ///
...@@ -728,7 +727,7 @@ class RawScrollbar extends StatefulWidget { ...@@ -728,7 +727,7 @@ class RawScrollbar extends StatefulWidget {
/// } /// }
/// ``` /// ```
/// {@end-tool} /// {@end-tool}
final bool isAlwaysShown; final bool? isAlwaysShown;
/// The [Radius] of the scrollbar thumb's rounded rectangle corners. /// The [Radius] of the scrollbar thumb's rounded rectangle corners.
/// ///
...@@ -790,6 +789,14 @@ class RawScrollbarState<T extends RawScrollbar> extends State<T> with TickerProv ...@@ -790,6 +789,14 @@ class RawScrollbarState<T extends RawScrollbar> extends State<T> with TickerProv
@protected @protected
late final ScrollbarPainter scrollbarPainter; late final ScrollbarPainter scrollbarPainter;
/// Overridable getter to indicate that the scrollbar should be visible, even
/// when a scroll is not underway.
///
/// Subclasses can override this getter to make its value depend on an inherited
/// theme.
@protected
bool get showScrollbar => widget.isAlwaysShown ?? false;
@override @override
void initState() { void initState() {
super.initState(); super.initState();
...@@ -820,7 +827,7 @@ class RawScrollbarState<T extends RawScrollbar> extends State<T> with TickerProv ...@@ -820,7 +827,7 @@ class RawScrollbarState<T extends RawScrollbar> extends State<T> with TickerProv
// A scroll event is required in order to paint the thumb. // A scroll event is required in order to paint the thumb.
void _maybeTriggerScrollbar() { void _maybeTriggerScrollbar() {
WidgetsBinding.instance!.addPostFrameCallback((Duration duration) { WidgetsBinding.instance!.addPostFrameCallback((Duration duration) {
if (widget.isAlwaysShown) { if (showScrollbar) {
_fadeoutTimer?.cancel(); _fadeoutTimer?.cancel();
// Wait one frame and cause an empty scroll event. This allows the // Wait one frame and cause an empty scroll event. This allows the
// thumb to show immediately when isAlwaysShown is true. A scroll // thumb to show immediately when isAlwaysShown is true. A scroll
...@@ -881,7 +888,7 @@ class RawScrollbarState<T extends RawScrollbar> extends State<T> with TickerProv ...@@ -881,7 +888,7 @@ class RawScrollbarState<T extends RawScrollbar> extends State<T> with TickerProv
} }
void _maybeStartFadeoutTimer() { void _maybeStartFadeoutTimer() {
if (!widget.isAlwaysShown) { if (!showScrollbar) {
_fadeoutTimer?.cancel(); _fadeoutTimer?.cancel();
_fadeoutTimer = Timer(widget.timeToFade, () { _fadeoutTimer = Timer(widget.timeToFade, () {
_fadeoutAnimationController.reverse(); _fadeoutAnimationController.reverse();
......
This diff is collapsed.
...@@ -742,6 +742,7 @@ void main() { ...@@ -742,6 +742,7 @@ void main() {
applyElevationOverlayColor: false, applyElevationOverlayColor: false,
pageTransitionsTheme: pageTransitionTheme, pageTransitionsTheme: pageTransitionTheme,
appBarTheme: const AppBarTheme(color: Colors.black), appBarTheme: const AppBarTheme(color: Colors.black),
scrollbarTheme: const ScrollbarThemeData(radius: Radius.circular(10.0)),
bottomAppBarTheme: const BottomAppBarTheme(color: Colors.black), bottomAppBarTheme: const BottomAppBarTheme(color: Colors.black),
colorScheme: const ColorScheme.light(), colorScheme: const ColorScheme.light(),
dialogTheme: const DialogTheme(backgroundColor: Colors.black), dialogTheme: const DialogTheme(backgroundColor: Colors.black),
......
...@@ -292,6 +292,7 @@ void main() { ...@@ -292,6 +292,7 @@ void main() {
applyElevationOverlayColor: false, applyElevationOverlayColor: false,
pageTransitionsTheme: pageTransitionTheme, pageTransitionsTheme: pageTransitionTheme,
appBarTheme: const AppBarTheme(color: Colors.black), appBarTheme: const AppBarTheme(color: Colors.black),
scrollbarTheme: const ScrollbarThemeData(radius: Radius.circular(10.0)),
bottomAppBarTheme: const BottomAppBarTheme(color: Colors.black), bottomAppBarTheme: const BottomAppBarTheme(color: Colors.black),
colorScheme: const ColorScheme.light(), colorScheme: const ColorScheme.light(),
dialogTheme: const DialogTheme(backgroundColor: Colors.black), dialogTheme: const DialogTheme(backgroundColor: Colors.black),
...@@ -384,6 +385,7 @@ void main() { ...@@ -384,6 +385,7 @@ void main() {
applyElevationOverlayColor: true, applyElevationOverlayColor: true,
pageTransitionsTheme: const PageTransitionsTheme(), pageTransitionsTheme: const PageTransitionsTheme(),
appBarTheme: const AppBarTheme(color: Colors.white), appBarTheme: const AppBarTheme(color: Colors.white),
scrollbarTheme: const ScrollbarThemeData(radius: Radius.circular(10.0)),
bottomAppBarTheme: const BottomAppBarTheme(color: Colors.white), bottomAppBarTheme: const BottomAppBarTheme(color: Colors.white),
colorScheme: const ColorScheme.light(), colorScheme: const ColorScheme.light(),
dialogTheme: const DialogTheme(backgroundColor: Colors.white), dialogTheme: const DialogTheme(backgroundColor: Colors.white),
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment