diff --git a/packages/flutter/lib/src/material/scrollbar.dart b/packages/flutter/lib/src/material/scrollbar.dart index 748030761dd..f7519c8fa80 100644 --- a/packages/flutter/lib/src/material/scrollbar.dart +++ b/packages/flutter/lib/src/material/scrollbar.dart @@ -49,7 +49,9 @@ class _ScrollbarState extends State with TickerProviderStateMixin { void didChangeDependencies() { super.didChangeDependencies(); _painter ??= new _ScrollbarPainter(this); - _painter.color = Theme.of(context).highlightColor; + _painter + ..color = Theme.of(context).highlightColor + ..textDirection = Directionality.of(context); } bool _handleScrollNotification(ScrollNotification notification) { @@ -102,12 +104,22 @@ class _ScrollbarPainter extends ChangeNotifier implements CustomPainter { Color _color; set color(Color value) { assert(value != null); - if (color == value) + if (_color == value) return; _color = value; notifyListeners(); } + TextDirection get textDirection => _textDirection; + TextDirection _textDirection; + set textDirection(TextDirection value) { + assert(value != null); + if (_textDirection == value) + return; + _textDirection = value; + notifyListeners(); + } + @override void dispose() { _fadeOut?.cancel(); @@ -142,8 +154,19 @@ class _ScrollbarPainter extends ChangeNotifier implements CustomPainter { Paint get _paint => new Paint()..color = color.withOpacity(_opacity.value); + double _getThumbX(Size size) { + assert(textDirection != null); + switch (textDirection) { + case TextDirection.rtl: + return 0.0; + case TextDirection.ltr: + return size.width - _kThumbGirth; + } + return null; + } + void _paintVerticalThumb(Canvas canvas, Size size, double thumbOffset, double thumbExtent) { - final Offset thumbOrigin = new Offset(size.width - _kThumbGirth, thumbOffset); + final Offset thumbOrigin = new Offset(_getThumbX(size), thumbOffset); final Size thumbSize = new Size(_kThumbGirth, thumbExtent); canvas.drawRect(thumbOrigin & thumbSize, _paint); } diff --git a/packages/flutter/test/material/scrollbar_paint_test.dart b/packages/flutter/test/material/scrollbar_paint_test.dart index acd7c7823c1..05e080a5750 100644 --- a/packages/flutter/test/material/scrollbar_paint_test.dart +++ b/packages/flutter/test/material/scrollbar_paint_test.dart @@ -8,14 +8,31 @@ import 'package:flutter/material.dart'; import '../rendering/mock_canvas.dart'; void main() { - testWidgets('Viewport basic test', (WidgetTester tester) async { - await tester.pumpWidget(new Scrollbar( - child: new SingleChildScrollView( - child: const SizedBox(width: 4000.0, height: 4000.0), + testWidgets('Viewport basic test (LTR)', (WidgetTester tester) async { + await tester.pumpWidget(new Directionality( + textDirection: TextDirection.ltr, + child: new Scrollbar( + child: new SingleChildScrollView( + child: const SizedBox(width: 4000.0, height: 4000.0), + ), ), )); expect(find.byType(Scrollbar), isNot(paints..rect())); await tester.fling(find.byType(SingleChildScrollView), const Offset(0.0, -10.0), 10.0); - expect(find.byType(Scrollbar), paints..rect()); + expect(find.byType(Scrollbar), paints..rect(rect: new Rect.fromLTRB(800.0 - 6.0, 1.5, 800.0, 91.5))); + }); + + testWidgets('Viewport basic test (RTL)', (WidgetTester tester) async { + await tester.pumpWidget(new Directionality( + textDirection: TextDirection.rtl, + child: new Scrollbar( + child: new SingleChildScrollView( + child: const SizedBox(width: 4000.0, height: 4000.0), + ), + ), + )); + expect(find.byType(Scrollbar), isNot(paints..rect())); + await tester.fling(find.byType(SingleChildScrollView), const Offset(0.0, -10.0), 10.0); + expect(find.byType(Scrollbar), paints..rect(rect: new Rect.fromLTRB(0.0, 1.5, 6.0, 91.5))); }); } diff --git a/packages/flutter/test/material/scrollbar_test.dart b/packages/flutter/test/material/scrollbar_test.dart index a9fbb34d0b2..752c2bff168 100644 --- a/packages/flutter/test/material/scrollbar_test.dart +++ b/packages/flutter/test/material/scrollbar_test.dart @@ -19,8 +19,9 @@ class TestCanvas implements Canvas { void main() { testWidgets('Scrollbar doesn\'t show when tapping list', (WidgetTester tester) async { - await tester.pumpWidget( - new Center( + await tester.pumpWidget(new Directionality( + textDirection: TextDirection.ltr, + child: new Center( child: new Container( decoration: new BoxDecoration( border: new Border.all(color: const Color(0xFFFFFF00)) @@ -38,12 +39,12 @@ void main() { new Container(height: 40.0, child: const Text('5')), new Container(height: 40.0, child: const Text('6')), new Container(height: 40.0, child: const Text('7')), - ] - ) - ) - ) - ) - ); + ], + ), + ), + ), + ), + )); SchedulerBinding.instance.debugAssertNoTransientCallbacks('Building a list with a scrollbar triggered an animation.'); await tester.tap(find.byType(ListView)); @@ -61,19 +62,20 @@ void main() { }); testWidgets('ScrollbarPainter does not divide by zero', (WidgetTester tester) async { - await tester.pumpWidget( - new Container( + await tester.pumpWidget(new Directionality( + textDirection: TextDirection.ltr, + child: new Container( height: 200.0, width: 300.0, child: new Scrollbar( child: new ListView( children: [ new Container(height: 40.0, child: const Text('0')), - ] - ) - ) - ) - ); + ], + ), + ), + ), + )); final CustomPaint custom = tester.widget(find.descendant(of: find.byType(Scrollbar), matching: find.byType(CustomPaint)).first); final dynamic scrollPainter = custom.foregroundPainter; diff --git a/packages/flutter/test/widgets/slivers_evil_test.dart b/packages/flutter/test/widgets/slivers_evil_test.dart index 2a61f8ef63f..8ccc9f6f576 100644 --- a/packages/flutter/test/widgets/slivers_evil_test.dart +++ b/packages/flutter/test/widgets/slivers_evil_test.dart @@ -73,8 +73,9 @@ class TestViewportScrollPosition extends ScrollPositionWithSingleContext { void main() { testWidgets('Evil test of sliver features - 1', (WidgetTester tester) async { final GlobalKey centerKey = new GlobalKey(); - await tester.pumpWidget( - new ScrollConfiguration( + await tester.pumpWidget(new Directionality( + textDirection: TextDirection.ltr, + child: new ScrollConfiguration( behavior: new TestBehavior(), child: new Scrollbar( child: new Scrollable( @@ -159,7 +160,7 @@ void main() { ), ), ), - ); + )); final ScrollPosition position = tester.state(find.byType(Scrollable)).position; position.animateTo(10000.0, curve: Curves.linear, duration: const Duration(minutes: 1));