| // Copyright 2014 The Flutter 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:flutter/material.dart'; |
| |
| class FortnightlyDemo extends StatelessWidget { |
| const FortnightlyDemo({super.key}); |
| |
| static const String routeName = '/fortnightly'; |
| |
| @override |
| Widget build(BuildContext context) { |
| return MaterialApp( |
| title: 'Fortnightly Demo', |
| theme: _fortnightlyTheme, |
| home: Scaffold( |
| body: Stack( |
| children: <Widget>[ |
| const FruitPage(), |
| SafeArea( |
| child: ShortAppBar( |
| onBackPressed: () { |
| Navigator.pop(context); |
| }, |
| ), |
| ), |
| ], |
| ), |
| ), |
| ); |
| } |
| } |
| |
| class ShortAppBar extends StatelessWidget { |
| const ShortAppBar({ super.key, this.onBackPressed }); |
| |
| final VoidCallback? onBackPressed; |
| |
| @override |
| Widget build(BuildContext context) { |
| return SizedBox( |
| width: 96, |
| height: 50, |
| child: Material( |
| color: Theme.of(context).colorScheme.surface, |
| elevation: 4, |
| shape: const BeveledRectangleBorder( |
| borderRadius: BorderRadius.only(bottomRight: Radius.circular(22)), |
| ), |
| child: Row( |
| children: <Widget>[ |
| IconButton( |
| icon: const Icon(Icons.arrow_back), |
| tooltip: 'Back', |
| onPressed: onBackPressed, |
| ), |
| const SizedBox(width: 12), |
| Image.asset( |
| 'logos/fortnightly/fortnightly_logo.png', |
| package: 'flutter_gallery_assets', |
| ), |
| ], |
| ), |
| ), |
| ); |
| } |
| } |
| |
| class FruitPage extends StatelessWidget { |
| const FruitPage({super.key}); |
| |
| static final String paragraph1 = ''' |
| Have you ever held a quince? It's strange; |
| covered in a fuzz somewhere between peach skin and a spider web. And it's |
| hard as soft lumber. You'd be forgiven for thinking it's veneered Larch-wood. |
| But inhale the aroma and you'll instantly know you have something wonderful. |
| Its scent can fill a room for days. And all this before you've even cooked it. |
| '''.replaceAll('\n', ' '); |
| |
| static final String paragraph2 = ''' |
| Pomegranates on the other hand have become |
| almost ubiquitous. You can find its juice in any bodega, Walmart, and even some |
| gas stations. But at what cost? The pomegranate juice craze of the aughts made |
| "megafarmers" Lynda and Stewart Resnick billions. Unfortunately, it takes a lot |
| of water to make that much pomegranate juice. Water the Resnicks get from their |
| majority stake in the Kern Water Bank. How did one family come to hold control |
| over water meant for the whole central valley of California? The story will shock you. |
| '''.replaceAll('\n', ' '); |
| |
| @override |
| Widget build(BuildContext context) { |
| final TextTheme textTheme = Theme.of(context).primaryTextTheme; |
| |
| return SingleChildScrollView( |
| child: SafeArea( |
| top: false, |
| child: ColoredBox( |
| color: Theme.of(context).colorScheme.surface, |
| child: Column( |
| children: <Widget>[ |
| Container( |
| constraints: const BoxConstraints.expand(height: 248), |
| child: Image.asset( |
| 'food/fruits.png', |
| package: 'flutter_gallery_assets', |
| fit: BoxFit.fitWidth, |
| ), |
| ), |
| const SizedBox(height: 17), |
| Padding( |
| padding: const EdgeInsets.symmetric(horizontal: 8), |
| child: Column( |
| crossAxisAlignment: CrossAxisAlignment.start, |
| children: <Widget>[ |
| Row( |
| children: <Widget>[ |
| Text( |
| 'US', |
| style: textTheme.labelSmall, |
| ), |
| Text( |
| ' ¬ ', |
| // TODO(larche): Replace textTheme.headline2.color with a ColorScheme value when known. |
| style: textTheme.labelSmall!.apply(color: textTheme.displayMedium!.color), |
| ), |
| Text( |
| 'CULTURE', |
| style: textTheme.labelSmall, |
| ), |
| ], |
| ), |
| const SizedBox(height: 10), |
| Text( |
| 'Quince for Wisdom, Persimmon for Luck, Pomegranate for Love', |
| style: textTheme.headlineMedium, |
| ), |
| const SizedBox(height: 10), |
| Text( |
| 'How these crazy fruits sweetened our hearts, relationships, ' |
| 'and puffed pastries', |
| style: textTheme.bodyMedium, |
| ), |
| Padding( |
| padding: const EdgeInsets.symmetric(vertical: 16), |
| child: Row( |
| children: <Widget>[ |
| const CircleAvatar( |
| backgroundImage: ExactAssetImage( |
| 'people/square/trevor.png', |
| package: 'flutter_gallery_assets', |
| ), |
| radius: 20, |
| ), |
| const SizedBox(width: 12), |
| Text( |
| 'by', |
| style: textTheme.displayMedium, |
| ), |
| const SizedBox(width: 4), |
| const Text( |
| 'Connor Eghan', |
| style: TextStyle( |
| fontFamily: 'Merriweather', |
| fontSize: 18, |
| fontWeight: FontWeight.w500, |
| color: Colors.black, |
| ), |
| ), |
| ], |
| ), |
| ), |
| Text( |
| '$paragraph1\n\n$paragraph2', |
| style: textTheme.bodyLarge, |
| ), |
| ], |
| ), |
| ), |
| ], |
| ), |
| ), |
| ), |
| ); |
| } |
| } |
| |
| final ThemeData _fortnightlyTheme = _buildFortnightlyTheme(); |
| |
| ThemeData _buildFortnightlyTheme() { |
| final ThemeData base = ThemeData.light(); |
| return base.copyWith( |
| primaryTextTheme: _buildTextTheme(base.primaryTextTheme), |
| scaffoldBackgroundColor: Colors.white, |
| ); |
| } |
| |
| TextTheme _buildTextTheme(TextTheme base) { |
| TextTheme theme = base.apply(bodyColor: Colors.black); |
| theme = theme.apply(displayColor: Colors.black); |
| |
| theme = theme.copyWith( |
| headlineMedium: base.headlineMedium!.copyWith( |
| fontFamily: 'Merriweather', |
| fontStyle: FontStyle.italic, |
| fontSize: 28, |
| fontWeight: FontWeight.w800, |
| color: Colors.black, |
| height: .88, |
| ), |
| displayMedium: base.displayMedium!.copyWith( |
| fontFamily: 'LibreFranklin', |
| fontSize: 18, |
| fontWeight: FontWeight.w500, |
| color: Colors.black.withAlpha(153), |
| ), |
| headlineSmall: base.headlineSmall!.copyWith(fontWeight: FontWeight.w500), |
| bodyMedium: base.bodyMedium!.copyWith( |
| fontFamily: 'Merriweather', |
| fontSize: 14, |
| fontWeight: FontWeight.w300, |
| color: const Color(0xFF666666), |
| height: 1.11, |
| ), |
| bodyLarge: base.bodyLarge!.copyWith( |
| fontFamily: 'Merriweather', |
| fontSize: 16, |
| fontWeight: FontWeight.w300, |
| color: const Color(0xFF666666), |
| height: 1.4, |
| letterSpacing: .25, |
| ), |
| labelSmall: const TextStyle( |
| fontFamily: 'LibreFranklin', |
| fontSize: 10, |
| fontWeight: FontWeight.w700, |
| color: Colors.black, |
| ), |
| ); |
| |
| return theme; |
| } |