Unverified Commit 6fc7199d authored by Jonah Williams's avatar Jonah Williams Committed by GitHub

Add outer gesture detector to increase mini-fab size to 48x48 (#17921)

parent 62febaa1
......@@ -38,6 +38,7 @@ class RawMaterialButton extends StatefulWidget {
this.elevation: 2.0,
this.highlightElevation: 8.0,
this.disabledElevation: 0.0,
this.outerPadding,
this.padding: EdgeInsets.zero,
this.constraints: const BoxConstraints(minWidth: 88.0, minHeight: 36.0),
this.shape: const RoundedRectangleBorder(),
......@@ -57,6 +58,10 @@ class RawMaterialButton extends StatefulWidget {
/// If this is set to null, the button will be disabled, see [enabled].
final VoidCallback onPressed;
/// Padding to increase the size of the gesture detector which doesn't
/// increase the visible material of the button.
final EdgeInsets outerPadding;
/// Called by the underlying [InkWell] widget's [InkWell.onHighlightChanged]
/// callback.
final ValueChanged<bool> onHighlightChanged;
......@@ -153,39 +158,53 @@ class _RawMaterialButtonState extends State<RawMaterialButton> {
? (_highlight ? widget.highlightElevation : widget.elevation)
: widget.disabledElevation;
return new Semantics(
container: true,
button: true,
enabled: widget.enabled,
child: new ConstrainedBox(
constraints: widget.constraints,
child: new Material(
elevation: elevation,
textStyle: widget.textStyle,
shape: widget.shape,
color: widget.fillColor,
type: widget.fillColor == null ? MaterialType.transparency : MaterialType.button,
animationDuration: widget.animationDuration,
child: new InkWell(
onHighlightChanged: _handleHighlightChanged,
splashColor: widget.splashColor,
highlightColor: widget.highlightColor,
onTap: widget.onPressed,
child: IconTheme.merge(
data: new IconThemeData(color: widget.textStyle?.color),
child: new Container(
padding: widget.padding,
child: new Center(
widthFactor: 1.0,
heightFactor: 1.0,
child: widget.child,
),
Widget result = new ConstrainedBox(
constraints: widget.constraints,
child: new Material(
elevation: elevation,
textStyle: widget.textStyle,
shape: widget.shape,
color: widget.fillColor,
type: widget.fillColor == null ? MaterialType.transparency : MaterialType.button,
animationDuration: widget.animationDuration,
child: new InkWell(
onHighlightChanged: _handleHighlightChanged,
splashColor: widget.splashColor,
highlightColor: widget.highlightColor,
onTap: widget.onPressed,
child: IconTheme.merge(
data: new IconThemeData(color: widget.textStyle?.color),
child: new Container(
padding: widget.padding,
child: new Center(
widthFactor: 1.0,
heightFactor: 1.0,
child: widget.child,
),
),
),
),
),
);
if (widget.outerPadding != null) {
result = new GestureDetector(
behavior: HitTestBehavior.translucent,
excludeFromSemantics: true,
onTap: widget.onPressed,
child: new Padding(
padding: widget.outerPadding,
child: result
),
);
}
return new Semantics(
container: true,
button: true,
enabled: widget.enabled,
child: result,
);
}
}
......
......@@ -187,7 +187,8 @@ class FloatingActionButton extends StatefulWidget {
///
/// By default, floating action buttons are non-mini and have a height and
/// width of 56.0 logical pixels. Mini floating action buttons have a height
/// and width of 40.0 logical pixels.
/// and width of 40.0 logical pixels with a layout width and height of 48.0
/// logical pixels.
final bool mini;
/// The margin to keep around the floating action button when creating a
......@@ -267,6 +268,7 @@ class _FloatingActionButtonState extends State<FloatingActionButton> {
onHighlightChanged: _handleHighlightChanged,
elevation: _highlight ? widget.highlightElevation : widget.elevation,
constraints: widget._sizeConstraints,
outerPadding: widget.mini ? const EdgeInsets.all(4.0) : null,
fillColor: widget.backgroundColor ?? theme.accentColor,
textStyle: theme.accentTextTheme.button.copyWith(
color: foregroundColor,
......
import 'package:flutter/material.dart';
import 'package:flutter/rendering.dart';
import 'package:flutter_test/flutter_test.dart';
import '../widgets/semantics_tester.dart';
void main() {
testWidgets('outerPadding expands hit test area', (WidgetTester tester) async {
int pressed = 0;
await tester.pumpWidget(new RawMaterialButton(
onPressed: () {
pressed++;
},
constraints: new BoxConstraints.tight(const Size(10.0, 10.0)),
outerPadding: const EdgeInsets.all(50.0),
child: const Text('+', textDirection: TextDirection.ltr),
));
await tester.tapAt(const Offset(100.0, 100.0));
expect(pressed, 1);
});
testWidgets('outerPadding expands semantics area', (WidgetTester tester) async {
final SemanticsTester semantics = new SemanticsTester(tester);
await tester.pumpWidget(
new Center(
child: new RawMaterialButton(
onPressed: () {},
constraints: new BoxConstraints.tight(const Size(10.0, 10.0)),
outerPadding: const EdgeInsets.all(50.0),
child: const Text('+', textDirection: TextDirection.ltr),
),
),
);
expect(semantics, hasSemantics(
new TestSemantics.root(
children: <TestSemantics>[
new TestSemantics(
id: 1,
flags: <SemanticsFlag>[
SemanticsFlag.isButton,
SemanticsFlag.hasEnabledState,
SemanticsFlag.isEnabled,
],
actions: <SemanticsAction>[
SemanticsAction.tap,
],
label: '+',
textDirection: TextDirection.ltr,
rect: Rect.fromLTRB(0.0, 0.0, 110.0, 110.0),
children: <TestSemantics>[],
),
]
), ignoreTransform: true));
semantics.dispose();
});
}
\ No newline at end of file
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