diff --git a/platform_design/lib/main.dart b/platform_design/lib/main.dart index 5752cacf5..e58e9d331 100644 --- a/platform_design/lib/main.dart +++ b/platform_design/lib/main.dart @@ -46,7 +46,8 @@ class MyAdaptingApp extends StatelessWidget { // depending on the app and content. class PlatformAdaptingHomePage extends StatefulWidget { @override - _PlatformAdaptingHomePageState createState() => _PlatformAdaptingHomePageState(); + _PlatformAdaptingHomePageState createState() => + _PlatformAdaptingHomePageState(); } class _PlatformAdaptingHomePageState extends State { @@ -80,9 +81,12 @@ class _PlatformAdaptingHomePageState extends State { return CupertinoTabScaffold( tabBar: CupertinoTabBar( items: [ - BottomNavigationBarItem(title: Text(SongsTab.title), icon: SongsTab.iosIcon), - BottomNavigationBarItem(title: Text(NewsTab.title), icon: NewsTab.iosIcon), - BottomNavigationBarItem(title: Text(ProfileTab.title), icon: ProfileTab.iosIcon), + BottomNavigationBarItem( + title: Text(SongsTab.title), icon: SongsTab.iosIcon), + BottomNavigationBarItem( + title: Text(NewsTab.title), icon: NewsTab.iosIcon), + BottomNavigationBarItem( + title: Text(ProfileTab.title), icon: ProfileTab.iosIcon), ], ), tabBuilder: (context, index) { @@ -149,9 +153,8 @@ class _AndroidDrawer extends StatelessWidget { title: Text(NewsTab.title), onTap: () { Navigator.pop(context); - Navigator.push(context, MaterialPageRoute( - builder: (context) => NewsTab() - )); + Navigator.push( + context, MaterialPageRoute(builder: (context) => NewsTab())); }, ), ListTile( @@ -159,9 +162,8 @@ class _AndroidDrawer extends StatelessWidget { title: Text(ProfileTab.title), onTap: () { Navigator.pop(context); - Navigator.push(context, MaterialPageRoute( - builder: (context) => ProfileTab() - )); + Navigator.push(context, + MaterialPageRoute(builder: (context) => ProfileTab())); }, ), // Long drawer contents are often segmented. @@ -174,9 +176,8 @@ class _AndroidDrawer extends StatelessWidget { title: Text(SettingsTab.title), onTap: () { Navigator.pop(context); - Navigator.push(context, MaterialPageRoute( - builder: (context) => SettingsTab() - )); + Navigator.push(context, + MaterialPageRoute(builder: (context) => SettingsTab())); }, ), ], diff --git a/platform_design/lib/news_tab.dart b/platform_design/lib/news_tab.dart index f567de84e..31bc1e269 100644 --- a/platform_design/lib/news_tab.dart +++ b/platform_design/lib/news_tab.dart @@ -26,13 +26,13 @@ class _NewsTabState extends State { void initState() { colors = getRandomColors(_itemsLength); titles = List.generate(_itemsLength, (index) => generateRandomHeadline()); - contents = List.generate(_itemsLength, (index) => lorem(paragraphs: 1, words: 24)); + contents = + List.generate(_itemsLength, (index) => lorem(paragraphs: 1, words: 24)); super.initState(); } Widget _listBuilder(context, index) { - if (index >= _itemsLength) - return null; + if (index >= _itemsLength) return null; return SafeArea( top: false, @@ -81,7 +81,7 @@ class _NewsTabState extends State { ], ), ), - ) + ), ), ); } diff --git a/platform_design/lib/profile_tab.dart b/platform_design/lib/profile_tab.dart index 1b414ad33..fb4e413c9 100644 --- a/platform_design/lib/profile_tab.dart +++ b/platform_design/lib/profile_tab.dart @@ -18,10 +18,13 @@ class ProfileTab extends StatelessWidget { Padding( padding: EdgeInsets.all(8), child: Center( - child: Text('😼', style: TextStyle( - fontSize: 80, - decoration: TextDecoration.none, - )), + child: Text( + '😼', + style: TextStyle( + fontSize: 80, + decoration: TextDecoration.none, + ), + ), ), ), PreferenceCard( @@ -102,7 +105,7 @@ class ProfileTab extends StatelessWidget { } class PreferenceCard extends StatelessWidget { - const PreferenceCard({ this.header, this.content, this.preferenceChoices }); + const PreferenceCard({this.header, this.content, this.preferenceChoices}); final String header; final String content; @@ -157,7 +160,8 @@ class PreferenceCard extends StatelessWidget { } class LogOutButton extends StatelessWidget { - static const _logoutMessage = Text('You may check out any time you like, but you can never leave'); + static const _logoutMessage = + Text('You may check out any time you like, but you can never leave'); // =========================================================================== // Non-shared code below because this tab shows different interfaces. On @@ -183,7 +187,7 @@ class LogOutButton extends StatelessWidget { actions: [ FlatButton( child: const Text('Go back'), - onPressed: () => Navigator.pop(context) , + onPressed: () => Navigator.pop(context), ), FlatButton( child: const Text('Cancel'), @@ -191,7 +195,7 @@ class LogOutButton extends StatelessWidget { ), ], ); - } + }, ); }, ); diff --git a/platform_design/lib/settings_tab.dart b/platform_design/lib/settings_tab.dart index 643e9d727..ff2a3d1ee 100644 --- a/platform_design/lib/settings_tab.dart +++ b/platform_design/lib/settings_tab.dart @@ -13,8 +13,13 @@ class SettingsTab extends StatefulWidget { } class _SettingsTabState extends State { - var switch1 = false; var switch2 = true; var switch3 = true; var switch4 = true; - var switch5 = true; var switch6 = false; var switch7 = true; + var switch1 = false; + var switch2 = true; + var switch3 = true; + var switch4 = true; + var switch5 = true; + var switch6 = false; + var switch7 = true; Widget _buildList() { return ListView( diff --git a/platform_design/lib/song_detail_tab.dart b/platform_design/lib/song_detail_tab.dart index 97c217991..21eadd977 100644 --- a/platform_design/lib/song_detail_tab.dart +++ b/platform_design/lib/song_detail_tab.dart @@ -8,7 +8,7 @@ import 'widgets.dart'; // On Android, this page sits at the top of your app. On iOS, this page is on // top of the songs tab's content but is below the tab bar itself. class SongDetailTab extends StatelessWidget { - const SongDetailTab({ this.id, this.song, this.color }); + const SongDetailTab({this.id, this.song, this.color}); final int id; final String song; @@ -33,7 +33,8 @@ class SongDetailTab extends StatelessWidget { // to build while the hero transition is mid-flight. // // It could either be specified here or in SongsTab. - flightShuttleBuilder: (context, animation, flightDirection, fromHeroContext, toHeroContext) { + flightShuttleBuilder: (context, animation, flightDirection, + fromHeroContext, toHeroContext) { return HeroAnimatingSongCard( song: song, color: color, @@ -51,11 +52,15 @@ class SongDetailTab extends StatelessWidget { itemBuilder: (context, index) { if (index == 0) { return Padding( - padding: const EdgeInsets.only(left: 15, top: 16, bottom: 8), - child: Text('You might also like:', style: TextStyle( - fontSize: 16, - fontWeight: FontWeight.w500, - )), + padding: + const EdgeInsets.only(left: 15, top: 16, bottom: 8), + child: Text( + 'You might also like:', + style: TextStyle( + fontSize: 16, + fontWeight: FontWeight.w500, + ), + ), ); } // Just a bunch of boxes that simulates loading song choices. diff --git a/platform_design/lib/songs_tab.dart b/platform_design/lib/songs_tab.dart index 835cfaec9..413d56705 100644 --- a/platform_design/lib/songs_tab.dart +++ b/platform_design/lib/songs_tab.dart @@ -11,7 +11,7 @@ class SongsTab extends StatefulWidget { static const androidIcon = Icon(Icons.music_note); static const iosIcon = Icon(CupertinoIcons.music_note); - const SongsTab({ Key key, this.androidDrawer }) : super(key: key); + const SongsTab({Key key, this.androidDrawer}) : super(key: key); final Widget androidDrawer; @@ -47,8 +47,7 @@ class _SongsTabState extends State { } Widget _listBuilder(context, index) { - if (index >= _itemsLength) - return null; + if (index >= _itemsLength) return null; // Show a slightly different color palette. Show poppy-ier colors on iOS // due to lighter contrasting bars and tone it down on Android. @@ -65,13 +64,15 @@ class _SongsTabState extends State { song: songNames[index], color: color, heroAnimation: AlwaysStoppedAnimation(0), - onPressed: () => Navigator.of(context).push(MaterialPageRoute( - builder: (context) => SongDetailTab( - id: index, - song: songNames[index], - color: color, - ), - )), + onPressed: () => Navigator.of(context).push( + MaterialPageRoute( + builder: (context) => SongDetailTab( + id: index, + song: songNames[index], + color: color, + ), + ), + ), ), ), ); @@ -138,7 +139,9 @@ class _SongsTabState extends State { CupertinoSliverNavigationBar( trailing: CupertinoButton( padding: EdgeInsets.zero, - child: Icon(CupertinoIcons.shuffle), + // TODO(redbrogdon): Change this back to shuffle once the new icon + // makes it into Flutter's stable channel. + child: Icon(CupertinoIcons.shuffle_thick), onPressed: _togglePlatform, ), ), diff --git a/platform_design/lib/utils.dart b/platform_design/lib/utils.dart index 3413e77db..fa1012ae1 100644 --- a/platform_design/lib/utils.dart +++ b/platform_design/lib/utils.dart @@ -11,8 +11,16 @@ import 'package:flutter/material.dart'; // This file has a number of platform-agnostic non-Widget utility functions. const _myListOfRandomColors = [ - Colors.red, Colors.blue, Colors.teal, Colors.yellow, Colors.amber, - Colors.deepOrange, Colors.green, Colors.indigo, Colors.lime, Colors.pink, + Colors.red, + Colors.blue, + Colors.teal, + Colors.yellow, + Colors.amber, + Colors.deepOrange, + Colors.green, + Colors.indigo, + Colors.lime, + Colors.pink, Colors.orange, ]; @@ -32,8 +40,7 @@ Iterable generateWordPair() sync* { } final suffix = pickRandom(nouns); - if (filterWord(prefix) || filterWord(suffix)) - continue; + if (filterWord(prefix) || filterWord(suffix)) continue; final wordPair = WordPair(prefix, suffix); yield wordPair; diff --git a/platform_design/lib/widgets.dart b/platform_design/lib/widgets.dart index fadca8b20..5fe2a78a0 100644 --- a/platform_design/lib/widgets.dart +++ b/platform_design/lib/widgets.dart @@ -8,9 +8,9 @@ class PlatformWidget extends StatelessWidget { Key key, @required this.androidBuilder, @required this.iosBuilder, - }) : assert(androidBuilder != null), - assert(iosBuilder != null), - super(key: key); + }) : assert(androidBuilder != null), + assert(iosBuilder != null), + super(key: key); final WidgetBuilder androidBuilder; final WidgetBuilder iosBuilder; @@ -50,7 +50,8 @@ class PressableCard extends StatefulWidget { State createState() => new _PressableCardState(); } -class _PressableCardState extends State with SingleTickerProviderStateMixin { +class _PressableCardState extends State + with SingleTickerProviderStateMixin { bool pressed = false; AnimationController controller; Animation elevationAnimation; @@ -61,7 +62,8 @@ class _PressableCardState extends State with SingleTickerProvider vsync: this, duration: const Duration(milliseconds: 40), ); - elevationAnimation = controller.drive(CurveTween(curve: Curves.easeInOutCubic)); + elevationAnimation = + controller.drive(CurveTween(curve: Curves.easeInOutCubic)); super.initState(); } @@ -76,8 +78,14 @@ class _PressableCardState extends State with SingleTickerProvider @override Widget build(context) { return Listener( - onPointerDown: (details) { if (widget.onPressed != null) { controller.forward(); } }, - onPointerUp: (details) { controller.reverse(); }, + onPointerDown: (details) { + if (widget.onPressed != null) { + controller.forward(); + } + }, + onPointerUp: (details) { + controller.reverse(); + }, child: GestureDetector( behavior: HitTestBehavior.opaque, onTap: () { @@ -90,7 +98,8 @@ class _PressableCardState extends State with SingleTickerProvider // hero animation. You likely want to modularize them more in your own // app. child: AnimatedBuilder( - animation: Listenable.merge([elevationAnimation, widget.flattenAnimation]), + animation: + Listenable.merge([elevationAnimation, widget.flattenAnimation]), child: widget.child, builder: (context, child) { return Transform.scale( @@ -98,9 +107,11 @@ class _PressableCardState extends State with SingleTickerProvider // in your own app. scale: 1 - elevationAnimation.value * 0.03, child: Padding( - padding: EdgeInsets.symmetric(vertical: 16, horizontal: 16) * flatten, + padding: EdgeInsets.symmetric(vertical: 16, horizontal: 16) * + flatten, child: PhysicalModel( - elevation: ((1 - elevationAnimation.value) * 10 + 10) * flatten, + elevation: + ((1 - elevationAnimation.value) * 10 + 10) * flatten, borderRadius: BorderRadius.circular(12 * flatten), clipBehavior: Clip.antiAlias, color: widget.color, @@ -123,7 +134,8 @@ class _PressableCardState extends State with SingleTickerProvider /// This is an example of a custom widget that an app developer might create for /// use on both iOS and Android as part of their brand's unique design. class HeroAnimatingSongCard extends StatelessWidget { - HeroAnimatingSongCard({ this.song, this.color, this.heroAnimation, this.onPressed }); + HeroAnimatingSongCard( + {this.song, this.color, this.heroAnimation, this.onPressed}); final String song; final Color color; @@ -154,7 +166,7 @@ class HeroAnimatingSongCard extends StatelessWidget { children: [ // The song title banner slides off in the hero animation. Positioned( - bottom: - 80 * heroAnimation.value, + bottom: -80 * heroAnimation.value, left: 0, right: 0, child: Container( @@ -173,7 +185,8 @@ class HeroAnimatingSongCard extends StatelessWidget { ), // The play button grows in the hero animation. Padding( - padding: EdgeInsets.only(bottom: 45) * (1 - heroAnimation.value), + padding: + EdgeInsets.only(bottom: 45) * (1 - heroAnimation.value), child: Container( height: playButtonSize, width: playButtonSize, @@ -182,7 +195,8 @@ class HeroAnimatingSongCard extends StatelessWidget { color: Colors.black12, ), alignment: Alignment.center, - child: Icon(Icons.play_arrow, size: playButtonSize, color: Colors.black38), + child: Icon(Icons.play_arrow, + size: playButtonSize, color: Colors.black38), ), ), ], @@ -315,17 +329,19 @@ void showChoices(BuildContext context, List choices) { itemExtent: 40, scrollController: FixedExtentScrollController(initialItem: 1), children: List.generate(choices.length, (index) { - return Center(child: Text( - choices[index], - style: TextStyle( - fontSize: 21, + return Center( + child: Text( + choices[index], + style: TextStyle( + fontSize: 21, + ), ), - )); + ); }), onSelectedItemChanged: (value) {}, ), ); - } + }, ); return; default: diff --git a/platform_design/pubspec.lock b/platform_design/pubspec.lock new file mode 100644 index 000000000..150d185a4 --- /dev/null +++ b/platform_design/pubspec.lock @@ -0,0 +1,161 @@ +# Generated by pub +# See https://www.dartlang.org/tools/pub/glossary#lockfile +packages: + async: + dependency: transitive + description: + name: async + url: "https://pub.dartlang.org" + source: hosted + version: "2.1.0" + boolean_selector: + dependency: transitive + description: + name: boolean_selector + url: "https://pub.dartlang.org" + source: hosted + version: "1.0.4" + charcode: + dependency: transitive + description: + name: charcode + url: "https://pub.dartlang.org" + source: hosted + version: "1.1.2" + collection: + dependency: transitive + description: + name: collection + url: "https://pub.dartlang.org" + source: hosted + version: "1.14.11" + cupertino_icons: + dependency: "direct main" + description: + name: cupertino_icons + url: "https://pub.dartlang.org" + source: hosted + version: "0.1.2" + english_words: + dependency: "direct main" + description: + name: english_words + url: "https://pub.dartlang.org" + source: hosted + version: "3.1.5" + flutter: + dependency: "direct main" + description: flutter + source: sdk + version: "0.0.0" + flutter_lorem: + dependency: "direct main" + description: + name: flutter_lorem + url: "https://pub.dartlang.org" + source: hosted + version: "1.1.0" + flutter_test: + dependency: "direct dev" + description: flutter + source: sdk + version: "0.0.0" + matcher: + dependency: transitive + description: + name: matcher + url: "https://pub.dartlang.org" + source: hosted + version: "0.12.5" + meta: + dependency: transitive + description: + name: meta + url: "https://pub.dartlang.org" + source: hosted + version: "1.1.6" + path: + dependency: transitive + description: + name: path + url: "https://pub.dartlang.org" + source: hosted + version: "1.6.2" + pedantic: + dependency: transitive + description: + name: pedantic + url: "https://pub.dartlang.org" + source: hosted + version: "1.5.0" + quiver: + dependency: transitive + description: + name: quiver + url: "https://pub.dartlang.org" + source: hosted + version: "2.0.2" + sky_engine: + dependency: transitive + description: flutter + source: sdk + version: "0.0.99" + source_span: + dependency: transitive + description: + name: source_span + url: "https://pub.dartlang.org" + source: hosted + version: "1.5.5" + stack_trace: + dependency: transitive + description: + name: stack_trace + url: "https://pub.dartlang.org" + source: hosted + version: "1.9.3" + stream_channel: + dependency: transitive + description: + name: stream_channel + url: "https://pub.dartlang.org" + source: hosted + version: "2.0.0" + string_scanner: + dependency: transitive + description: + name: string_scanner + url: "https://pub.dartlang.org" + source: hosted + version: "1.0.4" + term_glyph: + dependency: transitive + description: + name: term_glyph + url: "https://pub.dartlang.org" + source: hosted + version: "1.1.0" + test_api: + dependency: transitive + description: + name: test_api + url: "https://pub.dartlang.org" + source: hosted + version: "0.2.4" + typed_data: + dependency: transitive + description: + name: typed_data + url: "https://pub.dartlang.org" + source: hosted + version: "1.1.6" + vector_math: + dependency: transitive + description: + name: vector_math + url: "https://pub.dartlang.org" + source: hosted + version: "2.0.8" +sdks: + dart: ">=2.2.0 <3.0.0" + flutter: ">=1.5.2"