Enable extended FAB hero transition resizing (#19534)
This commit is contained in:
parent
6016882a56
commit
a960b870cc
@ -2,7 +2,10 @@
|
|||||||
// Use of this source code is governed by a BSD-style license that can be
|
// Use of this source code is governed by a BSD-style license that can be
|
||||||
// found in the LICENSE file.
|
// found in the LICENSE file.
|
||||||
|
|
||||||
|
import 'dart:math' as math;
|
||||||
|
|
||||||
import 'package:flutter/painting.dart';
|
import 'package:flutter/painting.dart';
|
||||||
|
import 'package:flutter/rendering.dart';
|
||||||
import 'package:flutter/widgets.dart';
|
import 'package:flutter/widgets.dart';
|
||||||
|
|
||||||
import 'button.dart';
|
import 'button.dart';
|
||||||
@ -103,7 +106,8 @@ class FloatingActionButton extends StatefulWidget {
|
|||||||
assert(isExtended != null),
|
assert(isExtended != null),
|
||||||
_sizeConstraints = _kExtendedSizeConstraints,
|
_sizeConstraints = _kExtendedSizeConstraints,
|
||||||
mini = false,
|
mini = false,
|
||||||
child = new Row(
|
child = new _ChildOverflowBox(
|
||||||
|
child: new Row(
|
||||||
mainAxisSize: MainAxisSize.min,
|
mainAxisSize: MainAxisSize.min,
|
||||||
children: <Widget>[
|
children: <Widget>[
|
||||||
const SizedBox(width: 16.0),
|
const SizedBox(width: 16.0),
|
||||||
@ -113,6 +117,7 @@ class FloatingActionButton extends StatefulWidget {
|
|||||||
const SizedBox(width: 20.0),
|
const SizedBox(width: 20.0),
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
|
),
|
||||||
super(key: key);
|
super(key: key);
|
||||||
|
|
||||||
/// The widget below this widget in the tree.
|
/// The widget below this widget in the tree.
|
||||||
@ -273,3 +278,55 @@ class _FloatingActionButtonState extends State<FloatingActionButton> {
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// This widget's size matches its child's size unless its constraints
|
||||||
|
// force it to be larger or smaller. The child is centered.
|
||||||
|
//
|
||||||
|
// Used to encapsulate extended FABs whose size is fixed, using Row
|
||||||
|
// and MainAxisSize.min, to be as wide as their label and icon.
|
||||||
|
class _ChildOverflowBox extends SingleChildRenderObjectWidget {
|
||||||
|
const _ChildOverflowBox({
|
||||||
|
Key key,
|
||||||
|
Widget child,
|
||||||
|
}) : super(key: key, child: child);
|
||||||
|
|
||||||
|
@override
|
||||||
|
_RenderChildOverflowBox createRenderObject(BuildContext context) {
|
||||||
|
return new _RenderChildOverflowBox(
|
||||||
|
textDirection: Directionality.of(context),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
void updateRenderObject(BuildContext context, _RenderChildOverflowBox renderObject) {
|
||||||
|
renderObject
|
||||||
|
..textDirection = Directionality.of(context);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class _RenderChildOverflowBox extends RenderAligningShiftedBox {
|
||||||
|
_RenderChildOverflowBox({
|
||||||
|
RenderBox child,
|
||||||
|
TextDirection textDirection,
|
||||||
|
}) : super(child: child, alignment: Alignment.center, textDirection: textDirection);
|
||||||
|
|
||||||
|
@override
|
||||||
|
double computeMinIntrinsicWidth(double height) => 0.0;
|
||||||
|
|
||||||
|
@override
|
||||||
|
double computeMinIntrinsicHeight(double width) => 0.0;
|
||||||
|
|
||||||
|
@override
|
||||||
|
void performLayout() {
|
||||||
|
if (child != null) {
|
||||||
|
child.layout(const BoxConstraints(), parentUsesSize: true);
|
||||||
|
size = new Size(
|
||||||
|
math.max(constraints.minWidth, math.min(constraints.maxWidth, child.size.width)),
|
||||||
|
math.max(constraints.minHeight, math.min(constraints.maxHeight, child.size.height)),
|
||||||
|
);
|
||||||
|
alignChild();
|
||||||
|
} else {
|
||||||
|
size = constraints.biggest;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@ -344,5 +344,68 @@ void main() {
|
|||||||
semantics.dispose();
|
semantics.dispose();
|
||||||
});
|
});
|
||||||
|
|
||||||
|
testWidgets('extended FAB hero transitions succeed', (WidgetTester tester) async {
|
||||||
|
// Regression test for https://github.com/flutter/flutter/issues/18782
|
||||||
|
|
||||||
|
await tester.pumpWidget(
|
||||||
|
new MaterialApp(
|
||||||
|
home: new Scaffold(
|
||||||
|
floatingActionButton: new Builder(
|
||||||
|
builder: (BuildContext context) { // define context of Navigator.push()
|
||||||
|
return new FloatingActionButton.extended(
|
||||||
|
icon: const Icon(Icons.add),
|
||||||
|
label: const Text('A long FAB label'),
|
||||||
|
onPressed: () {
|
||||||
|
Navigator.push(context, new MaterialPageRoute<void>(
|
||||||
|
builder: (BuildContext context) {
|
||||||
|
return new Scaffold(
|
||||||
|
floatingActionButton: new FloatingActionButton.extended(
|
||||||
|
icon: const Icon(Icons.add),
|
||||||
|
label: const Text('X'),
|
||||||
|
onPressed: () { },
|
||||||
|
),
|
||||||
|
body: new Center(
|
||||||
|
child: new RaisedButton(
|
||||||
|
child: const Text('POP'),
|
||||||
|
onPressed: () {
|
||||||
|
Navigator.pop(context);
|
||||||
|
},
|
||||||
|
),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
},
|
||||||
|
));
|
||||||
|
},
|
||||||
|
);
|
||||||
|
},
|
||||||
|
),
|
||||||
|
body: const Center(
|
||||||
|
child: const Text('Hello World'),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
|
||||||
|
final Finder longFAB = find.text('A long FAB label');
|
||||||
|
final Finder shortFAB = find.text('X');
|
||||||
|
final Finder helloWorld = find.text('Hello World');
|
||||||
|
|
||||||
|
expect(longFAB, findsOneWidget);
|
||||||
|
expect(shortFAB, findsNothing);
|
||||||
|
expect(helloWorld, findsOneWidget);
|
||||||
|
|
||||||
|
await tester.tap(longFAB);
|
||||||
|
await tester.pumpAndSettle();
|
||||||
|
|
||||||
|
expect(shortFAB, findsOneWidget);
|
||||||
|
expect(longFAB, findsNothing);
|
||||||
|
|
||||||
|
// Trigger a hero transition from shortFAB to longFAB.
|
||||||
|
await tester.tap(find.text('POP'));
|
||||||
|
await tester.pumpAndSettle();
|
||||||
|
|
||||||
|
expect(longFAB, findsOneWidget);
|
||||||
|
expect(shortFAB, findsNothing);
|
||||||
|
expect(helloWorld, findsOneWidget);
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user