parent
9cdfb95b1f
commit
9b5599a4a7
@ -69,7 +69,7 @@ class Drawer extends StatelessWidget {
|
|||||||
const Drawer({
|
const Drawer({
|
||||||
Key key,
|
Key key,
|
||||||
this.elevation: 16.0,
|
this.elevation: 16.0,
|
||||||
this.child
|
this.child,
|
||||||
}) : super(key: key);
|
}) : super(key: key);
|
||||||
|
|
||||||
/// The z-coordinate at which to place this drawer. This controls the size of
|
/// The z-coordinate at which to place this drawer. This controls the size of
|
||||||
@ -89,8 +89,8 @@ class Drawer extends StatelessWidget {
|
|||||||
constraints: const BoxConstraints.expand(width: _kWidth),
|
constraints: const BoxConstraints.expand(width: _kWidth),
|
||||||
child: new Material(
|
child: new Material(
|
||||||
elevation: elevation,
|
elevation: elevation,
|
||||||
child: child
|
child: child,
|
||||||
)
|
),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -117,7 +117,7 @@ class DrawerController extends StatefulWidget {
|
|||||||
/// The [child] argument must not be null and is typically a [Drawer].
|
/// The [child] argument must not be null and is typically a [Drawer].
|
||||||
const DrawerController({
|
const DrawerController({
|
||||||
GlobalKey key,
|
GlobalKey key,
|
||||||
@required this.child
|
@required this.child,
|
||||||
}) : assert(child != null),
|
}) : assert(child != null),
|
||||||
super(key: key);
|
super(key: key);
|
||||||
|
|
||||||
@ -217,14 +217,31 @@ class DrawerControllerState extends State<DrawerController> with SingleTickerPro
|
|||||||
}
|
}
|
||||||
|
|
||||||
void _move(DragUpdateDetails details) {
|
void _move(DragUpdateDetails details) {
|
||||||
_controller.value += details.primaryDelta / _width;
|
final double delta = details.primaryDelta / _width;
|
||||||
|
switch (Directionality.of(context)) {
|
||||||
|
case TextDirection.rtl:
|
||||||
|
_controller.value -= delta;
|
||||||
|
break;
|
||||||
|
case TextDirection.ltr:
|
||||||
|
_controller.value += delta;
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void _settle(DragEndDetails details) {
|
void _settle(DragEndDetails details) {
|
||||||
if (_controller.isDismissed)
|
if (_controller.isDismissed)
|
||||||
return;
|
return;
|
||||||
if (details.velocity.pixelsPerSecond.dx.abs() >= _kMinFlingVelocity) {
|
if (details.velocity.pixelsPerSecond.dx.abs() >= _kMinFlingVelocity) {
|
||||||
_controller.fling(velocity: details.velocity.pixelsPerSecond.dx / _width);
|
final double visualVelocity = details.velocity.pixelsPerSecond.dx / _width;
|
||||||
|
switch (Directionality.of(context)) {
|
||||||
|
case TextDirection.rtl:
|
||||||
|
_controller.fling(velocity: -visualVelocity);
|
||||||
|
break;
|
||||||
|
case TextDirection.ltr:
|
||||||
|
_controller.fling(velocity: visualVelocity);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
} else if (_controller.value < 0.5) {
|
} else if (_controller.value < 0.5) {
|
||||||
close();
|
close();
|
||||||
} else {
|
} else {
|
||||||
@ -250,7 +267,7 @@ class DrawerControllerState extends State<DrawerController> with SingleTickerPro
|
|||||||
Widget _buildDrawer(BuildContext context) {
|
Widget _buildDrawer(BuildContext context) {
|
||||||
if (_controller.status == AnimationStatus.dismissed) {
|
if (_controller.status == AnimationStatus.dismissed) {
|
||||||
return new Align(
|
return new Align(
|
||||||
alignment: FractionalOffset.centerLeft,
|
alignment: FractionalOffsetDirectional.centerStart,
|
||||||
child: new GestureDetector(
|
child: new GestureDetector(
|
||||||
key: _gestureDetectorKey,
|
key: _gestureDetectorKey,
|
||||||
onHorizontalDragUpdate: _move,
|
onHorizontalDragUpdate: _move,
|
||||||
@ -282,9 +299,9 @@ class DrawerControllerState extends State<DrawerController> with SingleTickerPro
|
|||||||
),
|
),
|
||||||
),
|
),
|
||||||
new Align(
|
new Align(
|
||||||
alignment: FractionalOffset.centerLeft,
|
alignment: FractionalOffsetDirectional.centerStart,
|
||||||
child: new Align(
|
child: new Align(
|
||||||
alignment: FractionalOffset.centerRight,
|
alignment: FractionalOffsetDirectional.centerEnd,
|
||||||
widthFactor: _controller.value,
|
widthFactor: _controller.value,
|
||||||
child: new RepaintBoundary(
|
child: new RepaintBoundary(
|
||||||
child: new FocusScope(
|
child: new FocusScope(
|
||||||
|
@ -23,11 +23,11 @@ void main() {
|
|||||||
return new Scaffold(
|
return new Scaffold(
|
||||||
key: scaffoldKey,
|
key: scaffoldKey,
|
||||||
drawer: const Text('drawer'),
|
drawer: const Text('drawer'),
|
||||||
body: new Container()
|
body: new Container(),
|
||||||
);
|
);
|
||||||
}
|
},
|
||||||
)
|
),
|
||||||
)
|
),
|
||||||
);
|
);
|
||||||
await tester.pump(); // no effect
|
await tester.pump(); // no effect
|
||||||
expect(find.text('drawer'), findsNothing);
|
expect(find.text('drawer'), findsNothing);
|
||||||
@ -50,9 +50,9 @@ void main() {
|
|||||||
home: new Scaffold(
|
home: new Scaffold(
|
||||||
key: scaffoldKey,
|
key: scaffoldKey,
|
||||||
drawer: const Text('drawer'),
|
drawer: const Text('drawer'),
|
||||||
body: new Container()
|
body: new Container(),
|
||||||
)
|
),
|
||||||
)
|
),
|
||||||
);
|
);
|
||||||
await tester.pump(); // no effect
|
await tester.pump(); // no effect
|
||||||
expect(find.text('drawer'), findsNothing);
|
expect(find.text('drawer'), findsNothing);
|
||||||
@ -75,7 +75,7 @@ void main() {
|
|||||||
expect(find.text('drawer'), findsNothing);
|
expect(find.text('drawer'), findsNothing);
|
||||||
});
|
});
|
||||||
|
|
||||||
testWidgets('Drawer drag cancel resume', (WidgetTester tester) async {
|
testWidgets('Drawer drag cancel resume (LTR)', (WidgetTester tester) async {
|
||||||
final GlobalKey<ScaffoldState> scaffoldKey = new GlobalKey<ScaffoldState>();
|
final GlobalKey<ScaffoldState> scaffoldKey = new GlobalKey<ScaffoldState>();
|
||||||
await tester.pumpWidget(
|
await tester.pumpWidget(
|
||||||
new MaterialApp(
|
new MaterialApp(
|
||||||
@ -89,12 +89,12 @@ void main() {
|
|||||||
height: 1000.0,
|
height: 1000.0,
|
||||||
color: Colors.blue[500],
|
color: Colors.blue[500],
|
||||||
),
|
),
|
||||||
]
|
],
|
||||||
)
|
),
|
||||||
),
|
),
|
||||||
body: new Container()
|
body: new Container(),
|
||||||
)
|
),
|
||||||
)
|
),
|
||||||
);
|
);
|
||||||
expect(find.text('drawer'), findsNothing);
|
expect(find.text('drawer'), findsNothing);
|
||||||
scaffoldKey.currentState.openDrawer();
|
scaffoldKey.currentState.openDrawer();
|
||||||
@ -107,21 +107,73 @@ void main() {
|
|||||||
await tester.pump();
|
await tester.pump();
|
||||||
await tester.pump(const Duration(milliseconds: 10));
|
await tester.pump(const Duration(milliseconds: 10));
|
||||||
// drawer should be starting to animate away
|
// drawer should be starting to animate away
|
||||||
final RenderBox textBox = tester.renderObject(find.text('drawer'));
|
final double textLeft = tester.getTopLeft(find.text('drawer')).dx;
|
||||||
final double textLeft = textBox.localToGlobal(Offset.zero).dx;
|
|
||||||
expect(textLeft, lessThan(0.0));
|
expect(textLeft, lessThan(0.0));
|
||||||
|
|
||||||
final TestGesture gesture = await tester.startGesture(const Offset(100.0, 100.0));
|
final TestGesture gesture = await tester.startGesture(const Offset(100.0, 100.0));
|
||||||
// drawer should be stopped.
|
// drawer should be stopped.
|
||||||
await tester.pump();
|
await tester.pump();
|
||||||
await tester.pump(const Duration(milliseconds: 10));
|
await tester.pump(const Duration(milliseconds: 10));
|
||||||
expect(textBox.localToGlobal(Offset.zero).dx, equals(textLeft));
|
expect(tester.getTopLeft(find.text('drawer')).dx, equals(textLeft));
|
||||||
|
|
||||||
await gesture.moveBy(const Offset(0.0, 50.0));
|
await gesture.moveBy(const Offset(50.0, 0.0));
|
||||||
// drawer should be returning to visible
|
// drawer should be returning to visible
|
||||||
await tester.pump();
|
await tester.pump();
|
||||||
await tester.pump(const Duration(seconds: 1));
|
await tester.pump(const Duration(seconds: 1));
|
||||||
expect(textBox.localToGlobal(Offset.zero).dx, equals(0.0));
|
expect(tester.getTopLeft(find.text('drawer')).dx, equals(0.0));
|
||||||
|
|
||||||
|
await gesture.up();
|
||||||
|
});
|
||||||
|
|
||||||
|
testWidgets('Drawer drag cancel resume (RTL)', (WidgetTester tester) async {
|
||||||
|
final GlobalKey<ScaffoldState> scaffoldKey = new GlobalKey<ScaffoldState>();
|
||||||
|
await tester.pumpWidget(
|
||||||
|
new MaterialApp(
|
||||||
|
home: new Directionality(
|
||||||
|
textDirection: TextDirection.rtl,
|
||||||
|
child: new Scaffold(
|
||||||
|
key: scaffoldKey,
|
||||||
|
drawer: new Drawer(
|
||||||
|
child: new ListView(
|
||||||
|
children: <Widget>[
|
||||||
|
const Text('drawer'),
|
||||||
|
new Container(
|
||||||
|
height: 1000.0,
|
||||||
|
color: Colors.blue[500],
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
body: new Container(),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
expect(find.text('drawer'), findsNothing);
|
||||||
|
scaffoldKey.currentState.openDrawer();
|
||||||
|
await tester.pump(); // drawer should be starting to animate in
|
||||||
|
expect(find.text('drawer'), findsOneWidget);
|
||||||
|
await tester.pump(const Duration(seconds: 1)); // animation done
|
||||||
|
expect(find.text('drawer'), findsOneWidget);
|
||||||
|
|
||||||
|
await tester.tapAt(const Offset(50.0, 100.0)); // on the mask
|
||||||
|
await tester.pump();
|
||||||
|
await tester.pump(const Duration(milliseconds: 10));
|
||||||
|
// drawer should be starting to animate away
|
||||||
|
final double textRight = tester.getTopRight(find.text('drawer')).dx;
|
||||||
|
expect(textRight, greaterThan(800.0));
|
||||||
|
|
||||||
|
final TestGesture gesture = await tester.startGesture(const Offset(700.0, 100.0));
|
||||||
|
// drawer should be stopped.
|
||||||
|
await tester.pump();
|
||||||
|
await tester.pump(const Duration(milliseconds: 10));
|
||||||
|
expect(tester.getTopRight(find.text('drawer')).dx, equals(textRight));
|
||||||
|
|
||||||
|
await gesture.moveBy(const Offset(-50.0, 0.0));
|
||||||
|
// drawer should be returning to visible
|
||||||
|
await tester.pump();
|
||||||
|
await tester.pump(const Duration(seconds: 1));
|
||||||
|
expect(tester.getTopRight(find.text('drawer')).dx, equals(800.0));
|
||||||
|
|
||||||
await gesture.up();
|
await gesture.up();
|
||||||
});
|
});
|
||||||
@ -142,21 +194,21 @@ void main() {
|
|||||||
const Text('drawer'),
|
const Text('drawer'),
|
||||||
new FlatButton(
|
new FlatButton(
|
||||||
child: const Text('close'),
|
child: const Text('close'),
|
||||||
onPressed: () => Navigator.pop(context)
|
onPressed: () => Navigator.pop(context),
|
||||||
),
|
),
|
||||||
]
|
],
|
||||||
)
|
),
|
||||||
),
|
),
|
||||||
body: new Container(
|
body: new Container(
|
||||||
child: new FlatButton(
|
child: new FlatButton(
|
||||||
child: const Text('button'),
|
child: const Text('button'),
|
||||||
onPressed: () { buttonPressed = true; }
|
onPressed: () { buttonPressed = true; },
|
||||||
)
|
),
|
||||||
)
|
),
|
||||||
);
|
);
|
||||||
}
|
},
|
||||||
)
|
),
|
||||||
)
|
),
|
||||||
);
|
);
|
||||||
|
|
||||||
// Open the drawer.
|
// Open the drawer.
|
||||||
@ -183,16 +235,16 @@ void main() {
|
|||||||
final GlobalKey<ScaffoldState> scaffoldKey = new GlobalKey<ScaffoldState>();
|
final GlobalKey<ScaffoldState> scaffoldKey = new GlobalKey<ScaffoldState>();
|
||||||
|
|
||||||
await tester.pumpWidget(
|
await tester.pumpWidget(
|
||||||
new MaterialApp(
|
new MaterialApp(
|
||||||
home: new Builder(
|
home: new Builder(
|
||||||
builder: (BuildContext context) {
|
builder: (BuildContext context) {
|
||||||
return new Scaffold(
|
return new Scaffold(
|
||||||
key: scaffoldKey,
|
key: scaffoldKey,
|
||||||
drawer: const Drawer(),
|
drawer: const Drawer(),
|
||||||
);
|
);
|
||||||
}
|
},
|
||||||
)
|
),
|
||||||
)
|
),
|
||||||
);
|
);
|
||||||
|
|
||||||
// Open the drawer.
|
// Open the drawer.
|
||||||
@ -211,17 +263,17 @@ void main() {
|
|||||||
final GlobalKey<ScaffoldState> scaffoldKey = new GlobalKey<ScaffoldState>();
|
final GlobalKey<ScaffoldState> scaffoldKey = new GlobalKey<ScaffoldState>();
|
||||||
|
|
||||||
await tester.pumpWidget(
|
await tester.pumpWidget(
|
||||||
new MaterialApp(
|
new MaterialApp(
|
||||||
home: new Builder(
|
home: new Builder(
|
||||||
builder: (BuildContext context) {
|
builder: (BuildContext context) {
|
||||||
return new Scaffold(
|
return new Scaffold(
|
||||||
key: scaffoldKey,
|
key: scaffoldKey,
|
||||||
drawer: const Drawer(),
|
drawer: const Drawer(),
|
||||||
body: new Container()
|
body: new Container(),
|
||||||
);
|
);
|
||||||
}
|
},
|
||||||
)
|
),
|
||||||
)
|
),
|
||||||
);
|
);
|
||||||
|
|
||||||
// Open the drawer.
|
// Open the drawer.
|
||||||
|
Loading…
x
Reference in New Issue
Block a user