diff --git a/packages/flutter/lib/src/painting/gradient.dart b/packages/flutter/lib/src/painting/gradient.dart index 4d0c4702364e0..e35bbfd71640d 100644 --- a/packages/flutter/lib/src/painting/gradient.dart +++ b/packages/flutter/lib/src/painting/gradient.dart @@ -240,6 +240,9 @@ abstract class Gradient { /// Typically this is the same as interpolating from null (with [lerp]). Gradient scale(double factor); + /// Returns a new [Gradient] with each color set to the given opacity. + Gradient withOpacity(double opacity); + /// Linearly interpolates from another [Gradient] to `this`. /// /// When implementing this method in subclasses, return null if this class @@ -556,6 +559,19 @@ class LinearGradient extends Gradient { return '${objectRuntimeType(this, 'LinearGradient')}(${description.join(', ')})'; } + + @override + LinearGradient withOpacity(double opacity) { + return LinearGradient( + begin: begin, + end: end, + colors: [ + for (final Color color in colors) color.withOpacity(opacity) + ], + stops: stops, + tileMode: tileMode, + ); + } } /// A 2D radial gradient. @@ -843,6 +859,21 @@ class RadialGradient extends Gradient { return '${objectRuntimeType(this, 'RadialGradient')}(${description.join(', ')})'; } + + @override + RadialGradient withOpacity(double opacity) { + return RadialGradient( + center: center, + radius: radius, + colors: [ + for (final Color color in colors) color.withOpacity(opacity) + ], + stops: stops, + tileMode: tileMode, + focal: focal, + focalRadius: focalRadius, + ); + } } /// A 2D sweep gradient. @@ -1106,4 +1137,18 @@ class SweepGradient extends Gradient { return '${objectRuntimeType(this, 'SweepGradient')}(${description.join(', ')})'; } + + @override + SweepGradient withOpacity(double opacity) { + return SweepGradient( + center: center, + startAngle: startAngle, + endAngle: endAngle, + colors: [ + for (final Color color in colors) color.withOpacity(opacity) + ], + stops: stops, + tileMode: tileMode, + ); + } } diff --git a/packages/flutter/test/painting/gradient_test.dart b/packages/flutter/test/painting/gradient_test.dart index 9accb119eddf6..012315843821b 100644 --- a/packages/flutter/test/painting/gradient_test.dart +++ b/packages/flutter/test/painting/gradient_test.dart @@ -306,6 +306,29 @@ void main() { ); }); + test('LinearGradient withOpacity test', () { + const LinearGradient testGradient = LinearGradient( + begin: Alignment.bottomRight, + end: Alignment.topCenter, + colors: [ + Color(0xFFFFFFFF), + Color(0xAF777777), + Color(0x44444444), + ], + ); + final LinearGradient actual = testGradient.withOpacity(0.5); + + expect(actual, const LinearGradient( + begin: Alignment.bottomRight, + end: Alignment.topCenter, + colors: [ + Color(0x80FFFFFF), + Color(0x80777777), + Color(0x80444444), + ], + ),); + }); + test('RadialGradient with AlignmentDirectional', () { expect( () { @@ -596,6 +619,33 @@ void main() { )); }); + + test('RadialGradient withOpacity test', () { + const RadialGradient testGradient = RadialGradient( + center: Alignment.topLeft, + focal: Alignment.centerLeft, + radius: 20.0, + focalRadius: 10.0, + colors: [ + Color(0xFFFFFFFF), + Color(0xAF777777), + Color(0x44444444), + ], + ); + final RadialGradient actual = testGradient.withOpacity(0.5); + + expect(actual, const RadialGradient( + center: Alignment.topLeft, + focal: Alignment.centerLeft, + radius: 20.0, + focalRadius: 10.0, + colors: [ + Color(0x80FFFFFF), + Color(0x80777777), + Color(0x80444444), + ], + )); + }); test('SweepGradient lerp test', () { const SweepGradient testGradient1 = SweepGradient( center: Alignment.topLeft, @@ -806,6 +856,28 @@ void main() { )); }); + test('SweepGradient withOpacity test', () { + const SweepGradient testGradient = SweepGradient( + center: Alignment.topLeft, + endAngle: math.pi / 2, + colors: [ + Color(0xFFFFFFFF), + Color(0xAF777777), + Color(0x44444444), + ], + ); + final SweepGradient actual = testGradient.withOpacity(0.5); + + expect(actual, const SweepGradient( + center: Alignment.topLeft, + endAngle: math.pi / 2, + colors: [ + Color(0x80FFFFFF), + Color(0x80777777), + Color(0x80444444), + ], + )); + }); test('Gradient lerp test (with RadialGradient)', () { const RadialGradient testGradient1 = RadialGradient( center: Alignment.topLeft,