mirror of
https://github.com/flutter/flutter
synced 2024-10-14 04:02:56 +00:00
Improve RTL support (#12008)
Fix a bunch of obvious RTL bugs from code inspection.
This commit is contained in:
parent
11de1a516f
commit
2d949ab69d
|
@ -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.
|
||||
///
|
||||
|
|
|
@ -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)
|
||||
));
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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(
|
||||
|
|
|
@ -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),
|
||||
|
|
|
@ -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(
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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
|
||||
);
|
||||
|
|
|
@ -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
|
||||
);
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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));
|
||||
|
|
Loading…
Reference in a new issue