Skip to content

Instantly share code, notes, and snippets.

@long1eu
Created August 9, 2018 10:03
Show Gist options
  • Save long1eu/0cac0f67eeb3115941cb0366929cc946 to your computer and use it in GitHub Desktop.
Save long1eu/0cac0f67eeb3115941cb0366929cc946 to your computer and use it in GitHub Desktop.
import 'dart:async';
import 'package:flutter/material.dart';
void main() => runApp(new MyApp());
class MyApp extends StatefulWidget {
static MyAppState of(BuildContext context) => (context.inheritFromWidgetOfExactType(AppState) as AppState).data;
@override
MyAppState createState() => new MyAppState();
}
class MyAppState extends State<MyApp> {
final GlobalKey<NavigatorState> key = GlobalKey<NavigatorState>();
bool isLocked = true;
NavigatorState get navigator => key.currentState;
void pushRoute(FakeRoute route) {
navigator.pushReplacement(PageRouteBuilder<void>(
pageBuilder: (BuildContext _, Animation __, Animation ___) => appRoutes[route](),
));
}
void setIsLocked(bool isLocked) {
if (this.isLocked != isLocked) {
setState(() => this.isLocked = isLocked);
}
}
@override
Widget build(BuildContext context) {
return AppState(
data: this,
isLocked: isLocked,
child: new MaterialApp(
navigatorKey: key,
title: 'Flutter Demo',
theme: new ThemeData(
primarySwatch: Colors.blue,
),
home: const SplashScreen(),
),
);
}
}
class AppState extends InheritedWidget {
const AppState({this.data, this.isLocked, Widget child}) : super(child: child);
final MyAppState data;
final bool isLocked;
@override
bool updateShouldNotify(InheritedWidget oldWidget) => (oldWidget as AppState).isLocked != isLocked;
}
class SplashScreen extends StatefulWidget {
const SplashScreen();
@override
SplashScreenState createState() => new SplashScreenState();
}
class SplashScreenState extends State<SplashScreen> {
@override
void initState() {
super.initState();
Future.delayed(const Duration(seconds: 3), () {
MyApp.of(context).pushRoute(FakeRoute.public);
});
}
@override
Widget build(BuildContext context) {
return Scaffold(
body: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.spaceAround,
children: <Widget>[
FlutterLogo(size: 240.0),
CircularProgressIndicator(strokeWidth: 1.0),
],
),
),
);
}
}
Map<FakeRoute, Widget Function()> appRoutes = <FakeRoute, Widget Function()>{
PublicNavigator.route: () => const PublicNavigator(),
PrivateNavigator.route: () => const PrivateNavigator(),
};
Route<dynamic> onGenerateRoute(RouteSettings settings, Map<String, WidgetBuilder> routes) {
final String name = settings.name;
final WidgetBuilder builder = routes[name];
return MaterialPageRoute<dynamic>(
builder: builder,
settings: settings,
);
}
enum FakeRoute { public, private }
class PublicRoutes {
static const String public1 = '/';
static const String public2 = '/2';
}
class PublicNavigator extends StatelessWidget {
static const FakeRoute route = FakeRoute.public;
const PublicNavigator();
@override
Widget build(BuildContext context) {
final Map<String, WidgetBuilder> routes = <String, WidgetBuilder>{
PublicRoutes.public1: (BuildContext context) => const PublicPage(i: 1),
PublicRoutes.public2: (BuildContext context) => const PublicPage(i: 2),
};
return Navigator(
key: key,
initialRoute: PublicRoutes.public1,
onGenerateRoute: (RouteSettings settings) => onGenerateRoute(settings, routes),
);
}
}
class PublicPage extends StatelessWidget {
const PublicPage({Key key, @required this.i}) : super(key: key);
final int i;
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(title: Text('Public page $i')),
body: Center(
child: new Text(
'Public page $i',
style: Theme.of(context).textTheme.body1,
),
),
floatingActionButton: RaisedButton.icon(
color: Theme.of(context).primaryColor,
icon: Icon(
Icons.navigate_next,
color: Colors.white,
),
label: Text(
i == 1 ? '2' : 'Private',
style: const TextStyle(
color: Colors.white,
),
),
onPressed: i == 1
? () => Navigator.of(context).pushNamed(PublicRoutes.public2)
: () => MyApp.of(context).pushRoute(FakeRoute.private),
),
);
}
}
class PrivateRoutes {
static const String private1 = '/';
static const String private2 = '/2';
static const String locked = '/locked';
}
class PrivateNavigator extends StatelessWidget {
static const FakeRoute route = FakeRoute.private;
const PrivateNavigator();
@override
Widget build(BuildContext context) {
final Map<String, WidgetBuilder> routes = <String, WidgetBuilder>{
PrivateRoutes.private1: (BuildContext context) => const PrivatePage(i: 1),
PrivateRoutes.private2: (BuildContext context) => const PrivatePage(i: 2),
PrivateRoutes.locked: (BuildContext context) => const LockPage(),
};
return Stack(
children: <Widget>[
Navigator(
key: key,
initialRoute: PrivateRoutes.private1,
onGenerateRoute: (RouteSettings settings) => onGenerateRoute(settings, routes),
),
MyApp.of(context).isLocked ? const LockPage() : Container(),
],
);
}
}
class PrivatePage extends StatelessWidget {
const PrivatePage({Key key, @required this.i}) : super(key: key);
final int i;
@override
Widget build(BuildContext context) {
return Theme(
data: Theme.of(context).copyWith(
primaryColor: Colors.red,
accentColor: Colors.grey,
),
child: Builder(
builder: (BuildContext context) {
return Scaffold(
appBar: AppBar(title: Text('Private page $i')),
body: Center(
child: new Text(
'Private page $i',
style: Theme.of(context).textTheme.body1,
),
),
floatingActionButton: Container(
height: 120.0,
child: i == 1
? Column(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: <Widget>[
FloatingActionButton(
child: Icon(Icons.lock),
onPressed: () {
MyApp.of(context).setIsLocked(true);
},
),
RaisedButton.icon(
color: Colors.grey,
icon: Icon(
Icons.navigate_next,
color: Colors.white,
),
label: Text(
'2',
style: const TextStyle(
color: Colors.white,
),
),
onPressed: () => Navigator.of(context).pushNamed(PrivateRoutes.private2),
),
],
)
: FloatingActionButton(
child: Icon(Icons.lock),
onPressed: () {
MyApp.of(context).setIsLocked(true);
},
),
),
);
},
),
);
}
}
class LockPage extends StatelessWidget {
const LockPage();
@override
Widget build(BuildContext context) {
return Theme(
data: Theme.of(context).copyWith(
primaryColor: Colors.purple,
accentColor: Colors.deepPurple,
),
child: Builder(
builder: (BuildContext context) {
return Scaffold(
backgroundColor: Theme.of(context).primaryColor,
body: Padding(
padding: const EdgeInsets.all(16.0),
child: Column(
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
children: <Widget>[
Text('Enter 5 characters to unlock, if you can, the keyboard won\'t open.'),
TextField(
decoration: InputDecoration(
hintText: 'password',
),
onChanged: (String text) {
if (text.length >= 5) {
MyApp.of(context).setIsLocked(false);
}
},
),
Text('Or you can cheat by taping the FloatingActionButton.'),
],
),
),
floatingActionButton: FloatingActionButton(
child: Icon(Icons.lock_open),
onPressed: () => MyApp.of(context).setIsLocked(false),
),
);
},
),
);
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment