Merge pull request #1484 from abarth/snackbar_route
Use Navigator to drive SnackBar
This commit is contained in:
commit
5a359dce9f
@ -58,11 +58,9 @@ class FeedFragment extends StatefulComponent {
|
|||||||
}
|
}
|
||||||
|
|
||||||
class FeedFragmentState extends State<FeedFragment> {
|
class FeedFragmentState extends State<FeedFragment> {
|
||||||
|
final GlobalKey<PlaceholderState> _snackBarPlaceholderKey = new GlobalKey<PlaceholderState>();
|
||||||
FitnessMode _fitnessMode = FitnessMode.feed;
|
FitnessMode _fitnessMode = FitnessMode.feed;
|
||||||
|
|
||||||
PerformanceStatus _snackBarStatus = PerformanceStatus.dismissed;
|
|
||||||
bool _isShowingSnackBar = false;
|
|
||||||
|
|
||||||
void _handleFitnessModeChange(FitnessMode value) {
|
void _handleFitnessModeChange(FitnessMode value) {
|
||||||
setState(() {
|
setState(() {
|
||||||
_fitnessMode = value;
|
_fitnessMode = value;
|
||||||
@ -119,15 +117,17 @@ class FeedFragmentState extends State<FeedFragment> {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
FitnessItem _undoItem;
|
|
||||||
|
|
||||||
void _handleItemDismissed(FitnessItem item) {
|
void _handleItemDismissed(FitnessItem item) {
|
||||||
config.onItemDeleted(item);
|
config.onItemDeleted(item);
|
||||||
setState(() {
|
showSnackBar(
|
||||||
_undoItem = item;
|
navigator: config.navigator,
|
||||||
_isShowingSnackBar = true;
|
placeholderKey: _snackBarPlaceholderKey,
|
||||||
_snackBarStatus = PerformanceStatus.forward;
|
content: new Text("Item deleted."),
|
||||||
});
|
actions: [new SnackBarAction(label: "UNDO", onPressed: () {
|
||||||
|
config.onItemCreated(item);
|
||||||
|
config.navigator.pop();
|
||||||
|
})]
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
Widget buildChart() {
|
Widget buildChart() {
|
||||||
@ -198,25 +198,6 @@ class FeedFragmentState extends State<FeedFragment> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void _handleUndo() {
|
|
||||||
config.onItemCreated(_undoItem);
|
|
||||||
setState(() {
|
|
||||||
_undoItem = null;
|
|
||||||
_isShowingSnackBar = false;
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
Widget buildSnackBar() {
|
|
||||||
if (_snackBarStatus == PerformanceStatus.dismissed)
|
|
||||||
return null;
|
|
||||||
return new SnackBar(
|
|
||||||
showing: _isShowingSnackBar,
|
|
||||||
content: new Text("Item deleted."),
|
|
||||||
actions: [new SnackBarAction(label: "UNDO", onPressed: _handleUndo)],
|
|
||||||
onDismissed: () { setState(() { _snackBarStatus = PerformanceStatus.dismissed; }); }
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
void _handleActionButtonPressed() {
|
void _handleActionButtonPressed() {
|
||||||
showDialog(config.navigator, (NavigatorState navigator) => new AddItemDialog(navigator)).then((routeName) {
|
showDialog(config.navigator, (NavigatorState navigator) => new AddItemDialog(navigator)).then((routeName) {
|
||||||
if (routeName != null)
|
if (routeName != null)
|
||||||
@ -240,7 +221,7 @@ class FeedFragmentState extends State<FeedFragment> {
|
|||||||
return new Scaffold(
|
return new Scaffold(
|
||||||
toolbar: buildToolBar(),
|
toolbar: buildToolBar(),
|
||||||
body: buildBody(),
|
body: buildBody(),
|
||||||
snackBar: buildSnackBar(),
|
snackBar: new Placeholder(key: _snackBarPlaceholderKey),
|
||||||
floatingActionButton: buildFloatingActionButton()
|
floatingActionButton: buildFloatingActionButton()
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
@ -5,7 +5,6 @@
|
|||||||
library fitness;
|
library fitness;
|
||||||
|
|
||||||
import 'package:playfair/playfair.dart' as playfair;
|
import 'package:playfair/playfair.dart' as playfair;
|
||||||
import 'package:sky/animation.dart';
|
|
||||||
import 'package:sky/material.dart';
|
import 'package:sky/material.dart';
|
||||||
import 'package:sky/painting.dart';
|
import 'package:sky/painting.dart';
|
||||||
import 'package:sky/widgets.dart';
|
import 'package:sky/widgets.dart';
|
||||||
|
@ -112,9 +112,10 @@ class MeasurementFragment extends StatefulComponent {
|
|||||||
}
|
}
|
||||||
|
|
||||||
class MeasurementFragmentState extends State<MeasurementFragment> {
|
class MeasurementFragmentState extends State<MeasurementFragment> {
|
||||||
|
final GlobalKey<PlaceholderState> _snackBarPlaceholderKey = new GlobalKey<PlaceholderState>();
|
||||||
|
|
||||||
String _weight = "";
|
String _weight = "";
|
||||||
DateTime _when = new DateTime.now();
|
DateTime _when = new DateTime.now();
|
||||||
String _errorMessage = null;
|
|
||||||
|
|
||||||
void _handleSave() {
|
void _handleSave() {
|
||||||
double parsedWeight;
|
double parsedWeight;
|
||||||
@ -122,9 +123,11 @@ class MeasurementFragmentState extends State<MeasurementFragment> {
|
|||||||
parsedWeight = double.parse(_weight);
|
parsedWeight = double.parse(_weight);
|
||||||
} on FormatException catch(e) {
|
} on FormatException catch(e) {
|
||||||
print("Exception $e");
|
print("Exception $e");
|
||||||
setState(() {
|
showSnackBar(
|
||||||
_errorMessage = "Save failed";
|
navigator: config.navigator,
|
||||||
});
|
placeholderKey: _snackBarPlaceholderKey,
|
||||||
|
content: new Text('Save failed')
|
||||||
|
);
|
||||||
}
|
}
|
||||||
config.onCreated(new Measurement(when: _when, weight: parsedWeight));
|
config.onCreated(new Measurement(when: _when, weight: parsedWeight));
|
||||||
config.navigator.pop();
|
config.navigator.pop();
|
||||||
@ -195,18 +198,11 @@ class MeasurementFragmentState extends State<MeasurementFragment> {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
Widget buildSnackBar() {
|
|
||||||
if (_errorMessage == null)
|
|
||||||
return null;
|
|
||||||
// TODO(jackson): This doesn't show up, unclear why.
|
|
||||||
return new SnackBar(content: new Text(_errorMessage), showing: true);
|
|
||||||
}
|
|
||||||
|
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
return new Scaffold(
|
return new Scaffold(
|
||||||
toolbar: buildToolBar(),
|
toolbar: buildToolBar(),
|
||||||
body: buildBody(context),
|
body: buildBody(context),
|
||||||
snackBar: buildSnackBar()
|
snackBar: new Placeholder(key: _snackBarPlaceholderKey)
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -8,7 +8,6 @@ import 'dart:async';
|
|||||||
import 'dart:math' as math;
|
import 'dart:math' as math;
|
||||||
import 'dart:sky' as sky;
|
import 'dart:sky' as sky;
|
||||||
|
|
||||||
import 'package:sky/animation.dart';
|
|
||||||
import 'package:sky/gestures.dart';
|
import 'package:sky/gestures.dart';
|
||||||
import 'package:sky/material.dart';
|
import 'package:sky/material.dart';
|
||||||
import 'package:sky/painting.dart';
|
import 'package:sky/painting.dart';
|
||||||
|
@ -6,8 +6,6 @@ part of stocks;
|
|||||||
|
|
||||||
typedef void ModeUpdater(StockMode mode);
|
typedef void ModeUpdater(StockMode mode);
|
||||||
|
|
||||||
const Duration _kSnackbarSlideDuration = const Duration(milliseconds: 200);
|
|
||||||
|
|
||||||
class StockHome extends StatefulComponent {
|
class StockHome extends StatefulComponent {
|
||||||
StockHome(this.navigator, this.stocks, this.symbols, this.stockMode, this.modeUpdater);
|
StockHome(this.navigator, this.stocks, this.symbols, this.stockMode, this.modeUpdater);
|
||||||
|
|
||||||
@ -22,12 +20,10 @@ class StockHome extends StatefulComponent {
|
|||||||
|
|
||||||
class StockHomeState extends State<StockHome> {
|
class StockHomeState extends State<StockHome> {
|
||||||
|
|
||||||
|
final GlobalKey<PlaceholderState> _snackBarPlaceholderKey = new GlobalKey<PlaceholderState>();
|
||||||
bool _isSearching = false;
|
bool _isSearching = false;
|
||||||
String _searchQuery;
|
String _searchQuery;
|
||||||
|
|
||||||
PerformanceStatus _snackBarStatus = PerformanceStatus.dismissed;
|
|
||||||
bool _isSnackBarShowing = false;
|
|
||||||
|
|
||||||
void _handleSearchBegin() {
|
void _handleSearchBegin() {
|
||||||
config.navigator.pushState(this, (_) {
|
config.navigator.pushState(this, (_) {
|
||||||
setState(() {
|
setState(() {
|
||||||
@ -217,28 +213,18 @@ class StockHomeState extends State<StockHome> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void _handleUndo() {
|
void _handleUndo() {
|
||||||
setState(() {
|
config.navigator.pop();
|
||||||
_isSnackBarShowing = false;
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
GlobalKey snackBarKey = new GlobalKey(label: 'snackbar');
|
|
||||||
Widget buildSnackBar() {
|
|
||||||
if (_snackBarStatus == PerformanceStatus.dismissed)
|
|
||||||
return null;
|
|
||||||
return new SnackBar(
|
|
||||||
showing: _isSnackBarShowing,
|
|
||||||
content: new Text("Stock purchased!"),
|
|
||||||
actions: [new SnackBarAction(label: "UNDO", onPressed: _handleUndo)],
|
|
||||||
onDismissed: () { setState(() { _snackBarStatus = PerformanceStatus.dismissed; }); }
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void _handleStockPurchased() {
|
void _handleStockPurchased() {
|
||||||
setState(() {
|
showSnackBar(
|
||||||
_isSnackBarShowing = true;
|
navigator: config.navigator,
|
||||||
_snackBarStatus = PerformanceStatus.forward;
|
placeholderKey: _snackBarPlaceholderKey,
|
||||||
});
|
content: new Text("Stock purchased!"),
|
||||||
|
actions: [
|
||||||
|
new SnackBarAction(label: "UNDO", onPressed: _handleUndo)
|
||||||
|
]
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
Widget buildFloatingActionButton() {
|
Widget buildFloatingActionButton() {
|
||||||
@ -253,7 +239,7 @@ class StockHomeState extends State<StockHome> {
|
|||||||
return new Scaffold(
|
return new Scaffold(
|
||||||
toolbar: _isSearching ? buildSearchBar() : buildToolBar(),
|
toolbar: _isSearching ? buildSearchBar() : buildToolBar(),
|
||||||
body: buildTabNavigator(),
|
body: buildTabNavigator(),
|
||||||
snackBar: buildSnackBar(),
|
snackBar: new Placeholder(key: _snackBarPlaceholderKey),
|
||||||
floatingActionButton: buildFloatingActionButton()
|
floatingActionButton: buildFloatingActionButton()
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
@ -50,7 +50,7 @@ typedef void GlobalKeyRemoveListener(GlobalKey key);
|
|||||||
/// A GlobalKey is one that must be unique across the entire application. It is
|
/// A GlobalKey is one that must be unique across the entire application. It is
|
||||||
/// used by components that need to communicate with other components across the
|
/// used by components that need to communicate with other components across the
|
||||||
/// application's element tree.
|
/// application's element tree.
|
||||||
abstract class GlobalKey extends Key {
|
abstract class GlobalKey<T extends State> extends Key {
|
||||||
const GlobalKey.constructor() : super.constructor(); // so that subclasses can call us, since the Key() factory constructor shadows the implicit constructor
|
const GlobalKey.constructor() : super.constructor(); // so that subclasses can call us, since the Key() factory constructor shadows the implicit constructor
|
||||||
|
|
||||||
/// Constructs a LabeledGlobalKey, which is a GlobalKey with a label used for debugging.
|
/// Constructs a LabeledGlobalKey, which is a GlobalKey with a label used for debugging.
|
||||||
@ -96,9 +96,9 @@ abstract class GlobalKey extends Key {
|
|||||||
Element get _currentElement => _registry[this];
|
Element get _currentElement => _registry[this];
|
||||||
BuildContext get currentContext => _currentElement;
|
BuildContext get currentContext => _currentElement;
|
||||||
Widget get currentWidget => _currentElement?.widget;
|
Widget get currentWidget => _currentElement?.widget;
|
||||||
State get currentState {
|
T get currentState {
|
||||||
Element element = _currentElement;
|
Element element = _currentElement;
|
||||||
if (element is StatefulComponentElement)
|
if (element is StatefulComponentElement<dynamic, T>)
|
||||||
return element.state;
|
return element.state;
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
@ -114,10 +114,6 @@ class NavigatorState extends State<Navigator> {
|
|||||||
|
|
||||||
void pop([dynamic result]) {
|
void pop([dynamic result]) {
|
||||||
setState(() {
|
setState(() {
|
||||||
while (currentRoute.ephemeral) {
|
|
||||||
currentRoute.didPop(null);
|
|
||||||
_currentPosition -= 1;
|
|
||||||
}
|
|
||||||
assert(_currentPosition > 0);
|
assert(_currentPosition > 0);
|
||||||
currentRoute.didPop(result);
|
currentRoute.didPop(result);
|
||||||
_currentPosition -= 1;
|
_currentPosition -= 1;
|
||||||
|
30
packages/flutter/lib/src/widgets/placeholder.dart
Normal file
30
packages/flutter/lib/src/widgets/placeholder.dart
Normal file
@ -0,0 +1,30 @@
|
|||||||
|
// Copyright 2015 The Chromium Authors. All rights reserved.
|
||||||
|
// Use of this source code is governed by a BSD-style license that can be
|
||||||
|
// found in the LICENSE file.
|
||||||
|
|
||||||
|
import 'package:sky/src/widgets/basic.dart';
|
||||||
|
import 'package:sky/src/widgets/framework.dart';
|
||||||
|
|
||||||
|
class Placeholder extends StatefulComponent {
|
||||||
|
Placeholder({ Key key }) : super(key: key);
|
||||||
|
|
||||||
|
PlaceholderState createState() => new PlaceholderState();
|
||||||
|
}
|
||||||
|
|
||||||
|
class PlaceholderState extends State<Placeholder> {
|
||||||
|
Widget get child => _child;
|
||||||
|
Widget _child;
|
||||||
|
void set child(Widget child) {
|
||||||
|
if (_child == child)
|
||||||
|
return;
|
||||||
|
setState(() {
|
||||||
|
_child = child;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
Widget build(BuildContext context) {
|
||||||
|
if (_child != null)
|
||||||
|
return child;
|
||||||
|
return new SizedBox(width: 0.0, height: 0.0);
|
||||||
|
}
|
||||||
|
}
|
@ -137,7 +137,7 @@ class MenuRoute extends Route {
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool get ephemeral => false; // we could make this true, but then we'd have to use popRoute(), not pop(), in menus
|
bool get ephemeral => true;
|
||||||
bool get modal => true;
|
bool get modal => true;
|
||||||
bool get opaque => false;
|
bool get opaque => false;
|
||||||
Duration get transitionDuration => _kMenuDuration;
|
Duration get transitionDuration => _kMenuDuration;
|
||||||
|
@ -6,21 +6,20 @@ import 'package:sky/animation.dart';
|
|||||||
import 'package:sky/gestures.dart';
|
import 'package:sky/gestures.dart';
|
||||||
import 'package:sky/material.dart';
|
import 'package:sky/material.dart';
|
||||||
import 'package:sky/painting.dart';
|
import 'package:sky/painting.dart';
|
||||||
import 'package:sky/src/widgets/animated_component.dart';
|
|
||||||
import 'package:sky/src/widgets/basic.dart';
|
import 'package:sky/src/widgets/basic.dart';
|
||||||
import 'package:sky/src/widgets/framework.dart';
|
import 'package:sky/src/widgets/framework.dart';
|
||||||
import 'package:sky/src/widgets/gesture_detector.dart';
|
import 'package:sky/src/widgets/gesture_detector.dart';
|
||||||
import 'package:sky/src/widgets/material.dart';
|
import 'package:sky/src/widgets/material.dart';
|
||||||
|
import 'package:sky/src/widgets/navigator.dart';
|
||||||
|
import 'package:sky/src/widgets/placeholder.dart';
|
||||||
import 'package:sky/src/widgets/theme.dart';
|
import 'package:sky/src/widgets/theme.dart';
|
||||||
import 'package:sky/src/widgets/transitions.dart';
|
import 'package:sky/src/widgets/transitions.dart';
|
||||||
|
|
||||||
typedef void SnackBarDismissedCallback();
|
|
||||||
|
|
||||||
const Duration _kSlideInDuration = const Duration(milliseconds: 200);
|
const Duration _kSlideInDuration = const Duration(milliseconds: 200);
|
||||||
const double kSnackHeight = 52.0;
|
const double _kSnackHeight = 52.0;
|
||||||
const double kSideMargins = 24.0;
|
const double _kSideMargins = 24.0;
|
||||||
const double kVerticalPadding = 14.0;
|
const double _kVerticalPadding = 14.0;
|
||||||
const Color kSnackBackground = const Color(0xFF323232);
|
const Color _kSnackBackground = const Color(0xFF323232);
|
||||||
|
|
||||||
class SnackBarAction extends StatelessComponent {
|
class SnackBarAction extends StatelessComponent {
|
||||||
SnackBarAction({Key key, this.label, this.onPressed }) : super(key: key) {
|
SnackBarAction({Key key, this.label, this.onPressed }) : super(key: key) {
|
||||||
@ -34,70 +33,60 @@ class SnackBarAction extends StatelessComponent {
|
|||||||
return new GestureDetector(
|
return new GestureDetector(
|
||||||
onTap: onPressed,
|
onTap: onPressed,
|
||||||
child: new Container(
|
child: new Container(
|
||||||
margin: const EdgeDims.only(left: kSideMargins),
|
margin: const EdgeDims.only(left: _kSideMargins),
|
||||||
padding: const EdgeDims.symmetric(vertical: kVerticalPadding),
|
padding: const EdgeDims.symmetric(vertical: _kVerticalPadding),
|
||||||
child: new Text(label)
|
child: new Text(label)
|
||||||
)
|
)
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
class SnackBar extends AnimatedComponent {
|
class SnackBar extends StatelessComponent {
|
||||||
SnackBar({
|
SnackBar({
|
||||||
Key key,
|
Key key,
|
||||||
this.content,
|
this.content,
|
||||||
this.actions,
|
this.actions,
|
||||||
bool showing,
|
this.performance
|
||||||
this.onDismissed
|
}) : super(key: key) {
|
||||||
}) : super(key: key, direction: showing ? AnimationDirection.forward : AnimationDirection.reverse, duration: _kSlideInDuration) {
|
|
||||||
assert(content != null);
|
assert(content != null);
|
||||||
}
|
}
|
||||||
|
|
||||||
final Widget content;
|
final Widget content;
|
||||||
final List<SnackBarAction> actions;
|
final List<SnackBarAction> actions;
|
||||||
final SnackBarDismissedCallback onDismissed;
|
final PerformanceView performance;
|
||||||
|
|
||||||
SnackBarState createState() => new SnackBarState();
|
|
||||||
}
|
|
||||||
|
|
||||||
class SnackBarState extends AnimatedState<SnackBar> {
|
|
||||||
void handleDismissed() {
|
|
||||||
if (config.onDismissed != null)
|
|
||||||
config.onDismissed();
|
|
||||||
}
|
|
||||||
|
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
List<Widget> children = [
|
List<Widget> children = [
|
||||||
new Flexible(
|
new Flexible(
|
||||||
child: new Container(
|
child: new Container(
|
||||||
margin: const EdgeDims.symmetric(vertical: kVerticalPadding),
|
margin: const EdgeDims.symmetric(vertical: _kVerticalPadding),
|
||||||
child: new DefaultTextStyle(
|
child: new DefaultTextStyle(
|
||||||
style: Typography.white.subhead,
|
style: Typography.white.subhead,
|
||||||
child: config.content
|
child: content
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
];
|
];
|
||||||
if (config.actions != null)
|
if (actions != null)
|
||||||
children.addAll(config.actions);
|
children.addAll(actions);
|
||||||
return new SquashTransition(
|
return new SquashTransition(
|
||||||
performance: performance.view,
|
performance: performance,
|
||||||
height: new AnimatedValue<double>(
|
height: new AnimatedValue<double>(
|
||||||
0.0,
|
0.0,
|
||||||
end: kSnackHeight,
|
end: _kSnackHeight,
|
||||||
curve: easeIn,
|
curve: easeIn,
|
||||||
reverseCurve: easeOut
|
reverseCurve: easeOut
|
||||||
),
|
),
|
||||||
child: new ClipRect(
|
child: new ClipRect(
|
||||||
child: new OverflowBox(
|
child: new OverflowBox(
|
||||||
minHeight: kSnackHeight,
|
minHeight: _kSnackHeight,
|
||||||
maxHeight: kSnackHeight,
|
maxHeight: _kSnackHeight,
|
||||||
child: new Material(
|
child: new Material(
|
||||||
level: 2,
|
level: 2,
|
||||||
color: kSnackBackground,
|
color: _kSnackBackground,
|
||||||
type: MaterialType.canvas,
|
type: MaterialType.canvas,
|
||||||
child: new Container(
|
child: new Container(
|
||||||
margin: const EdgeDims.symmetric(horizontal: kSideMargins),
|
margin: const EdgeDims.symmetric(horizontal: _kSideMargins),
|
||||||
child: new DefaultTextStyle(
|
child: new DefaultTextStyle(
|
||||||
style: new TextStyle(color: Theme.of(context).accentColor),
|
style: new TextStyle(color: Theme.of(context).accentColor),
|
||||||
child: new Row(children)
|
child: new Row(children)
|
||||||
@ -109,3 +98,28 @@ class SnackBarState extends AnimatedState<SnackBar> {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
class _SnackBarRoute extends Route {
|
||||||
|
_SnackBarRoute({ this.content, this.actions });
|
||||||
|
|
||||||
|
final Widget content;
|
||||||
|
final List<SnackBarAction> actions;
|
||||||
|
|
||||||
|
bool get hasContent => false;
|
||||||
|
bool get ephemeral => true;
|
||||||
|
bool get modal => false;
|
||||||
|
Duration get transitionDuration => _kSlideInDuration;
|
||||||
|
|
||||||
|
Widget build(NavigatorState navigator, PerformanceView nextRoutePerformance) => null;
|
||||||
|
}
|
||||||
|
|
||||||
|
void showSnackBar({ NavigatorState navigator, GlobalKey<PlaceholderState> placeholderKey, Widget content, List<SnackBarAction> actions }) {
|
||||||
|
Route route = new _SnackBarRoute();
|
||||||
|
SnackBar snackBar = new SnackBar(
|
||||||
|
content: content,
|
||||||
|
actions: actions,
|
||||||
|
performance: route.performance
|
||||||
|
);
|
||||||
|
placeholderKey.currentState.child = snackBar;
|
||||||
|
navigator.push(route);
|
||||||
|
}
|
||||||
|
@ -37,6 +37,7 @@ export 'src/widgets/material_button.dart';
|
|||||||
export 'src/widgets/mimic.dart';
|
export 'src/widgets/mimic.dart';
|
||||||
export 'src/widgets/mixed_viewport.dart';
|
export 'src/widgets/mixed_viewport.dart';
|
||||||
export 'src/widgets/navigator.dart';
|
export 'src/widgets/navigator.dart';
|
||||||
|
export 'src/widgets/placeholder.dart';
|
||||||
export 'src/widgets/popup_menu.dart';
|
export 'src/widgets/popup_menu.dart';
|
||||||
export 'src/widgets/popup_menu_item.dart';
|
export 'src/widgets/popup_menu_item.dart';
|
||||||
export 'src/widgets/progress_indicator.dart';
|
export 'src/widgets/progress_indicator.dart';
|
||||||
|
Loading…
x
Reference in New Issue
Block a user