backdrop.dart:
import 'package:flutter/material.dart';
import 'package:meta/meta.dart';
import 'model/product.dart';
class Backdrop extends StatefulWidget {
final Category currentCategory;
final Widget frontLayer;
final Widget backLayer;
final Widget frontTitle;
final Widget backTitle;
const Backdrop({
@required this.currentCategory,
@required this.frontLayer,
@required this.backLayer,
@required this.frontTitle,
@required this.backTitle,
}) : assert(currentCategory != null),
assert(frontLayer != null),
assert(backLayer != null),
assert(frontTitle != null),
assert(backTitle != null);
@override
_BackdropState createState() => _BackdropState();
}
class _BackdropState extends State<Backdrop> with SingleTickerProviderStateMixin {
final GlobalKey _backdropKey = GlobalKey(debugLabel: 'Backdrop');
Widget _buildStack() => Stack(
key: _backdropKey,
children: <Widget>[
widget.backLayer,
widget.frontLayer,
],
);
@override
Widget build(BuildContext context) {
var appbar = AppBar(
brightness: Brightness.light,
elevation: 0.0,
titleSpacing: 0.0,
leading: Icon(Icons.menu),
title: Text('SHRINE'),
actions: [
IconButton(icon: Icon(Icons.search, semanticLabel: 'search'), onPressed: () {}),
IconButton(icon: Icon(Icons.tune, semanticLabel: 'filter'), onPressed: () {})
],
);
return Scaffold(
appBar: appbar,
body: _buildStack(),
);
}
}home.dart:
import 'package:flutter/material.dart';
import 'model/product.dart';
import 'model/products_repository.dart';
import 'supplemental/asymmetric_view.dart';
class HomePage extends StatelessWidget {
@override
Widget build(BuildContext context) {
return AsymmetricView(products: ProductsRepository.loadProducts(Category.all));
}
}app.dart:
import 'package:Shrine/backdrop.dart';
import 'package:Shrine/model/product.dart';
import 'package:flutter/material.dart';
import 'colors.dart';
import 'home.dart';
import 'login.dart';
import 'supplemental/cut_corners_border.dart';
class ShrineApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Shrine',
home: Backdrop(
currentCategory: Category.all,
frontLayer: HomePage(),
backLayer: Container(color: kShrinePink100),
frontTitle: Text('SHRINE'),
backTitle: Text('MENU')),
initialRoute: '/login',
onGenerateRoute: _getRoute,
theme: _kShrineTheme,
);
}
Route<dynamic> _getRoute(RouteSettings settings) {
if (settings.name != '/login') {
return null;
}
return MaterialPageRoute<void>(
settings: settings,
builder: (BuildContext context) => LoginPage(),
fullscreenDialog: true,
);
}
}
final ThemeData _kShrineTheme = _buildShrineTheme();
ThemeData _buildShrineTheme() {
final ThemeData base = ThemeData.light();
return base.copyWith(
accentColor: kShrineBrown900,
primaryColor: kShrinePink100,
buttonColor: kShrinePink100,
scaffoldBackgroundColor: kShrineBackgroundWhite,
cardColor: kShrineBackgroundWhite,
textSelectionColor: kShrinePink100,
errorColor: kShrineErrorRed,
buttonTheme: base.buttonTheme.copyWith(
buttonColor: kShrinePink100,
colorScheme: base.colorScheme.copyWith(secondary: kShrineBrown900),
),
buttonBarTheme: base.buttonBarTheme.copyWith(
buttonTextTheme: ButtonTextTheme.accent,
),
primaryIconTheme: base.iconTheme.copyWith(color: kShrineBrown900),
inputDecorationTheme: InputDecorationTheme(
focusedBorder: CutCornersBorder(
borderSide: BorderSide(width: 2.0, color: kShrineBrown900),
),
border: CutCornersBorder(),
),
textTheme: _buildShrineTextTheme(base.textTheme),
primaryTextTheme: _buildShrineTextTheme(base.primaryTextTheme),
accentTextTheme: _buildShrineTextTheme(base.accentTextTheme),
);
}
TextTheme _buildShrineTextTheme(TextTheme base) {
return base
.copyWith(
headline5: base.headline5.copyWith(fontWeight: FontWeight.w500),
headline6: base.headline6.copyWith(fontSize: 18.0),
caption: base.caption.copyWith(fontWeight: FontWeight.w400, fontSize: 14.0),
bodyText1: base.bodyText1.copyWith(fontWeight: FontWeight.w500, fontSize: 16.0))
.apply(
fontFamily: 'Rubik',
displayColor: kShrineBrown900,
bodyColor: kShrineBrown900,
);
}