Improve RTL support (#12008)

Fix a bunch of obvious RTL bugs from code inspection.
This commit is contained in:
Adam Barth 2017-09-11 12:58:12 -07:00 committed by GitHub
parent 11de1a516f
commit 2d949ab69d
13 changed files with 53 additions and 34 deletions

View file

@ -61,7 +61,7 @@ class CupertinoButton extends StatefulWidget {
/// The amount of space to surround the child inside the bounds of the button.
///
/// Defaults to 16.0 pixels.
final EdgeInsets padding;
final EdgeInsetsGeometry padding;
/// The color of the button's background.
///

View file

@ -405,7 +405,7 @@ class _LicensePageState extends State<LicensePage> {
} else {
assert(paragraph.indent >= 0);
_licenses.add(new Padding(
padding: new EdgeInsets.only(top: 8.0, left: 16.0 * paragraph.indent),
padding: new EdgeInsetsDirectional.only(top: 8.0, start: 16.0 * paragraph.indent),
child: new Text(paragraph.text)
));
}

View file

@ -362,7 +362,7 @@ class DataTable extends StatelessWidget {
ValueChanged<bool> onCheckboxChanged
}) {
Widget contents = new Padding(
padding: const EdgeInsets.fromLTRB(_kTablePadding, 0.0, _kTablePadding / 2.0, 0.0),
padding: const EdgeInsetsDirectional.only(start: _kTablePadding, end: _kTablePadding / 2.0),
child: new Center(
child: new Checkbox(
activeColor: color,
@ -385,7 +385,7 @@ class DataTable extends StatelessWidget {
Widget _buildHeadingCell({
BuildContext context,
EdgeInsets padding,
EdgeInsetsGeometry padding,
Widget label,
String tooltip,
bool numeric,
@ -408,7 +408,7 @@ class DataTable extends StatelessWidget {
label = new Container(
padding: padding,
height: _kHeadingRowHeight,
alignment: new FractionalOffset(numeric ? 1.0 : 0.0, 0.5), // TODO(ianh): RTL for non-numeric
alignment: numeric ? FractionalOffset.centerRight : FractionalOffsetDirectional.centerStart,
child: new AnimatedDefaultTextStyle(
style: new TextStyle(
// TODO(ianh): font family should be Roboto; see https://github.com/flutter/flutter/issues/3116
@ -441,7 +441,7 @@ class DataTable extends StatelessWidget {
Widget _buildDataCell({
BuildContext context,
EdgeInsets padding,
EdgeInsetsGeometry padding,
Widget label,
bool numeric,
bool placeholder,
@ -458,7 +458,7 @@ class DataTable extends StatelessWidget {
label = new Container(
padding: padding,
height: _kDataRowHeight,
alignment: new FractionalOffset(numeric ? 1.0 : 0.0, 0.5), // TODO(ianh): RTL for non-numeric
alignment: numeric ? FractionalOffset.centerRight : FractionalOffsetDirectional.centerStart,
child: new DefaultTextStyle(
style: new TextStyle(
// TODO(ianh): font family should be Roboto; see https://github.com/flutter/flutter/issues/3116
@ -544,11 +544,9 @@ class DataTable extends StatelessWidget {
for (int dataColumnIndex = 0; dataColumnIndex < columns.length; dataColumnIndex += 1) {
final DataColumn column = columns[dataColumnIndex];
final EdgeInsets padding = new EdgeInsets.fromLTRB(
dataColumnIndex == 0 ? showCheckboxColumn ? _kTablePadding / 2.0 : _kTablePadding : _kColumnSpacing / 2.0,
0.0,
dataColumnIndex == columns.length - 1 ? _kTablePadding : _kColumnSpacing / 2.0,
0.0
final EdgeInsetsDirectional padding = new EdgeInsetsDirectional.only(
start: dataColumnIndex == 0 ? showCheckboxColumn ? _kTablePadding / 2.0 : _kTablePadding : _kColumnSpacing / 2.0,
end: dataColumnIndex == columns.length - 1 ? _kTablePadding : _kColumnSpacing / 2.0,
);
if (dataColumnIndex == _onlyTextColumn) {
tableColumns[displayColumnIndex] = const IntrinsicColumnWidth(flex: 1.0);

View file

@ -66,7 +66,7 @@ class Divider extends StatelessWidget {
child: new Center(
child: new Container(
height: 0.0,
margin: new EdgeInsets.only(left: indent),
margin: new EdgeInsetsDirectional.only(start: indent),
decoration: new BoxDecoration(
border: new Border(
bottom: new BorderSide(

View file

@ -128,7 +128,7 @@ class ExpansionPanelList extends StatelessWidget {
)
),
new Container(
margin: const EdgeInsets.only(right: 8.0),
margin: const EdgeInsetsDirectional.only(end: 8.0),
child: new ExpandIcon(
isExpanded: _isChildExpanded(i),
padding: const EdgeInsets.all(16.0),

View file

@ -92,6 +92,20 @@ class _FlexibleSpaceBarState extends State<FlexibleSpaceBar> {
return null;
}
FractionalOffset _getTitleAlignment(bool effectiveCenterTitle) {
if (effectiveCenterTitle)
return FractionalOffset.bottomCenter;
final TextDirection textDirection = Directionality.of(context);
assert(textDirection != null);
switch (textDirection) {
case TextDirection.rtl:
return FractionalOffset.bottomRight;
case TextDirection.ltr:
return FractionalOffset.bottomLeft;
}
return null;
}
@override
Widget build(BuildContext context) {
final _FlexibleSpaceBarSettings settings = context.inheritFromWidgetOfExactType(_FlexibleSpaceBarSettings);
@ -138,10 +152,10 @@ class _FlexibleSpaceBarState extends State<FlexibleSpaceBar> {
final double scaleValue = new Tween<double>(begin: 1.5, end: 1.0).lerp(t);
final Matrix4 scaleTransform = new Matrix4.identity()
..scale(scaleValue, scaleValue, 1.0);
final FractionalOffset titleAlignment = effectiveCenterTitle ? FractionalOffset.bottomCenter : FractionalOffset.bottomLeft;
final FractionalOffset titleAlignment = _getTitleAlignment(effectiveCenterTitle);
children.add(new Container(
padding: new EdgeInsets.only(
left: effectiveCenterTitle ? 0.0 : 72.0,
padding: new EdgeInsetsDirectional.only(
start: effectiveCenterTitle ? 0.0 : 72.0,
bottom: 16.0
),
child: new Transform(

View file

@ -288,7 +288,7 @@ class PaginatedDataTableState extends State<PaginatedDataTable> {
final ThemeData themeData = Theme.of(context);
// HEADER
final List<Widget> headerWidgets = <Widget>[];
double leftPadding = 24.0;
double startPadding = 24.0;
if (_selectedRowCount == 0) {
headerWidgets.add(new Expanded(child: widget.header));
if (widget.header is ButtonBar) {
@ -298,7 +298,7 @@ class PaginatedDataTableState extends State<PaginatedDataTable> {
// pixels internally on each side, yet we want the left edge of the
// inside of the button to line up with the 24.0 left inset.
// TODO(ianh): Better magic. See https://github.com/flutter/flutter/issues/4460
leftPadding = 12.0;
startPadding = 12.0;
}
} else if (_selectedRowCount == 1) {
// TODO(ianh): Real l10n.
@ -311,7 +311,7 @@ class PaginatedDataTableState extends State<PaginatedDataTable> {
widget.actions.map<Widget>((Widget action) {
return new Padding(
// 8.0 is the default padding of an icon button
padding: const EdgeInsets.only(left: 24.0 - 8.0 * 2.0),
padding: const EdgeInsetsDirectional.only(start: 24.0 - 8.0 * 2.0),
child: action,
);
}).toList()
@ -384,7 +384,7 @@ class PaginatedDataTableState extends State<PaginatedDataTable> {
child: new ButtonTheme.bar(
child: new Container(
height: 64.0,
padding: new EdgeInsets.fromLTRB(leftPadding, 0.0, 14.0, 0.0),
padding: new EdgeInsetsDirectional.only(start: startPadding, end: 14.0),
// TODO(ianh): This decoration will prevent ink splashes from being visible.
// Instead, we should have a widget that prints the decoration on the material.
// See https://github.com/flutter/flutter/issues/3782

View file

@ -707,7 +707,7 @@ class PopupMenuButton<T> extends StatefulWidget {
/// Matches IconButton's 8 dps padding by default. In some cases, notably where
/// this button appears as the trailing element of a list item, it's useful to be able
/// to set the padding to zero.
final EdgeInsets padding;
final EdgeInsetsGeometry padding;
/// If provided, the widget used for this button.
final Widget child;

View file

@ -954,7 +954,7 @@ class _PersistentBottomSheetState extends State<_PersistentBottomSheet> {
animation: widget.animationController,
builder: (BuildContext context, Widget child) {
return new Align(
alignment: FractionalOffset.topLeft,
alignment: FractionalOffsetDirectional.topStart,
heightFactor: widget.animationController.value,
child: child
);

View file

@ -222,7 +222,7 @@ class SnackBar extends StatelessWidget {
animation: heightAnimation,
builder: (BuildContext context, Widget child) {
return new Align(
alignment: FractionalOffset.topLeft,
alignment: FractionalOffsetDirectional.topStart,
heightFactor: heightAnimation.value,
child: child
);

View file

@ -26,13 +26,13 @@ class _AccountPictures extends StatelessWidget {
Widget build(BuildContext context) {
return new Stack(
children: <Widget>[
new Positioned(
new PositionedDirectional(
top: 0.0,
right: 0.0,
end: 0.0,
child: new Row(
children: (otherAccountsPictures ?? <Widget>[]).take(3).map((Widget picture) {
return new Container(
margin: const EdgeInsets.only(left: 16.0),
margin: const EdgeInsetsDirectional.only(start: 16.0),
width: 40.0,
height: 40.0,
child: picture
@ -70,7 +70,7 @@ class _AccountDetails extends StatelessWidget {
Widget addDropdownIcon(Widget line) {
final Widget icon = new Expanded(
child: new Align(
alignment: FractionalOffset.centerRight,
alignment: FractionalOffsetDirectional.centerEnd,
child: new Icon(
isOpen ? Icons.arrow_drop_up : Icons.arrow_drop_down,
color: Colors.white

View file

@ -103,7 +103,7 @@ class SlideTransition extends AnimatedWidget {
/// The [position] argument must not be null.
const SlideTransition({
Key key,
@required Animation<FractionalOffset> position,
@required Animation<FractionalOffsetGeometry> position,
this.transformHitTests: true,
this.child,
}) : super(key: key, listenable: position);
@ -112,7 +112,7 @@ class SlideTransition extends AnimatedWidget {
///
/// If the current value of the position animation is (dx, dy), the child will
/// be translated horizontally by width * dx and vertically by height * dy.
Animation<FractionalOffset> get position => listenable;
Animation<FractionalOffsetGeometry> get position => listenable;
/// Whether hit testing should be affected by the slide animation.
///
@ -244,11 +244,11 @@ class SizeTransition extends AnimatedWidget {
@override
Widget build(BuildContext context) {
FractionalOffset alignment;
FractionalOffsetDirectional alignment;
if (axis == Axis.vertical)
alignment = new FractionalOffset(0.0, axisAlignment);
alignment = new FractionalOffsetDirectional(0.0, axisAlignment);
else
alignment = new FractionalOffset(axisAlignment, 0.0);
alignment = new FractionalOffsetDirectional(axisAlignment, 0.0);
return new ClipRect(
child: new Align(
alignment: alignment,

View file

@ -8,7 +8,14 @@ import '../rendering/mock_canvas.dart';
void main() {
testWidgets('Divider control test', (WidgetTester tester) async {
await tester.pumpWidget(const Center(child: const Divider()));
await tester.pumpWidget(
const Directionality(
textDirection: TextDirection.ltr,
child: const Center(
child: const Divider(),
),
),
);
final RenderBox box = tester.firstRenderObject(find.byType(Divider));
expect(box.size.height, 16.0);
expect(find.byType(Divider), paints..path(strokeWidth: 0.0));