Unverified Commit 73194cd9 authored by xubaolin's avatar xubaolin Committed by GitHub

Fix bug when updating the `divisions` and `value` of the slider at the same time (#65998)

parent 9618e10a
...@@ -731,8 +731,10 @@ class _RangeSliderRenderObjectWidget extends LeafRenderObjectWidget { ...@@ -731,8 +731,10 @@ class _RangeSliderRenderObjectWidget extends LeafRenderObjectWidget {
@override @override
void updateRenderObject(BuildContext context, _RenderRangeSlider renderObject) { void updateRenderObject(BuildContext context, _RenderRangeSlider renderObject) {
renderObject renderObject
..values = values // We should update the `divisions` ahead of `values`, because the `values`
// setter dependent on the `divisions`.
..divisions = divisions ..divisions = divisions
..values = values
..labels = labels ..labels = labels
..sliderTheme = sliderTheme ..sliderTheme = sliderTheme
..theme = Theme.of(context) ..theme = Theme.of(context)
......
...@@ -839,8 +839,10 @@ class _SliderRenderObjectWidget extends LeafRenderObjectWidget { ...@@ -839,8 +839,10 @@ class _SliderRenderObjectWidget extends LeafRenderObjectWidget {
@override @override
void updateRenderObject(BuildContext context, _RenderSlider renderObject) { void updateRenderObject(BuildContext context, _RenderSlider renderObject) {
renderObject renderObject
..value = value // We should update the `divisions` ahead of `value`, because the `value`
// setter dependent on the `divisions`.
..divisions = divisions ..divisions = divisions
..value = value
..label = label ..label = label
..sliderTheme = sliderTheme ..sliderTheme = sliderTheme
..theme = Theme.of(context) ..theme = Theme.of(context)
......
...@@ -10,6 +10,7 @@ import 'package:flutter/cupertino.dart'; ...@@ -10,6 +10,7 @@ import 'package:flutter/cupertino.dart';
import 'package:flutter/foundation.dart'; import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:flutter/rendering.dart'; import 'package:flutter/rendering.dart';
import 'package:flutter/src/physics/utils.dart' show nearEqual;
import 'package:flutter_test/flutter_test.dart'; import 'package:flutter_test/flutter_test.dart';
import '../rendering/mock_canvas.dart'; import '../rendering/mock_canvas.dart';
...@@ -1915,4 +1916,47 @@ void main() { ...@@ -1915,4 +1916,47 @@ void main() {
..circle(x: 0.0, y: 5.0, radius: 10.0,) ..circle(x: 0.0, y: 5.0, radius: 10.0,)
); );
}); });
testWidgets('Update the divisions and values at the same time for RangeSlider', (WidgetTester tester) async {
// Regress test for https://github.com/flutter/flutter/issues/65943
Widget buildFrame(double maxValue) {
return MaterialApp(
home: Material(
child: Center(
child: RangeSlider(
values: const RangeValues(5, 8),
max: maxValue,
divisions: maxValue.toInt(),
onChanged: (RangeValues newValue) {},
),
),
),
);
}
await tester.pumpWidget(buildFrame(10));
// _RenderRangeSlider is the last render object in the tree.
final RenderObject renderObject = tester.allRenderObjects.last;
// Update the divisions from 10 to 15, the thumbs should be paint at the correct position.
await tester.pumpWidget(buildFrame(15));
await tester.pumpAndSettle(); // Finish the animation.
Rect activeTrackRect;
expect(renderObject, paints..something((Symbol method, List<dynamic> arguments) {
if (method != #drawRect)
return false;
activeTrackRect = arguments[0] as Rect;
return true;
}));
// The 1st thumb should at one-third(5 / 15) of the Slider.
// The 2nd thumb should at (8 / 15) of the Slider.
// The left of the active track shape is the position of the 1st thumb.
// The right of the active track shape is the position of the 2nd thumb.
// 24.0 is the default margin, (800.0 - 24.0 - 24.0) is the slider's width.
expect(nearEqual(activeTrackRect.left, (800.0 - 24.0 - 24.0) * (5 / 15) + 24.0, 0.01), true);
expect(nearEqual(activeTrackRect.right, (800.0 - 24.0 - 24.0) * (8 / 15) + 24.0, 0.01), true);
});
} }
...@@ -12,6 +12,7 @@ import 'package:flutter/material.dart'; ...@@ -12,6 +12,7 @@ import 'package:flutter/material.dart';
import 'package:flutter/rendering.dart'; import 'package:flutter/rendering.dart';
import 'package:flutter/scheduler.dart'; import 'package:flutter/scheduler.dart';
import 'package:flutter/services.dart'; import 'package:flutter/services.dart';
import 'package:flutter/src/physics/utils.dart' show nearEqual;
import 'package:flutter_test/flutter_test.dart'; import 'package:flutter_test/flutter_test.dart';
import '../rendering/mock_canvas.dart'; import '../rendering/mock_canvas.dart';
...@@ -2431,4 +2432,44 @@ void main() { ...@@ -2431,4 +2432,44 @@ void main() {
..circle(x: 5.0, y: 5.0, radius: 10.0, ) ..circle(x: 5.0, y: 5.0, radius: 10.0, )
); );
}); });
testWidgets('Update the divisions and value at the same time for Slider', (WidgetTester tester) async {
// Regress test for https://github.com/flutter/flutter/issues/65943
Widget buildFrame(double maxValue) {
return MaterialApp(
home: Material(
child: Center(
child: Slider.adaptive(
value: 5,
max: maxValue,
divisions: maxValue.toInt(),
onChanged: (double newValue) {},
),
),
),
);
}
await tester.pumpWidget(buildFrame(10));
// _RenderSlider is the last render object in the tree.
final RenderObject renderObject = tester.allRenderObjects.last;
// Update the divisions from 10 to 15, the thumb should be paint at the correct position.
await tester.pumpWidget(buildFrame(15));
await tester.pumpAndSettle(); // Finish the animation.
RRect activeTrackRRect;
expect(renderObject, paints..something((Symbol method, List<dynamic> arguments) {
if (method != #drawRRect)
return false;
activeTrackRRect = arguments[0] as RRect;
return true;
}));
// The thumb should at one-third(5 / 15) of the Slider.
// The right of the active track shape is the position of the thumb.
// 24.0 is the default margin, (800.0 - 24.0 - 24.0) is the slider's width.
expect(nearEqual(activeTrackRRect.right, (800.0 - 24.0 - 24.0) * (5 / 15) + 24.0, 0.01), true);
});
} }
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