diff --git a/gallery/gallery/lib/layout/adaptive.dart b/gallery/gallery/lib/layout/adaptive.dart index 473efcc6c..cfbbeb92d 100644 --- a/gallery/gallery/lib/layout/adaptive.dart +++ b/gallery/gallery/lib/layout/adaptive.dart @@ -10,6 +10,7 @@ enum DisplayType { } const _desktopBreakpoint = 700.0; +const _smallDesktopMaxWidth = 1000.0; /// Returns the [DisplayType] for the current screen. This app only supports /// mobile and desktop layouts, and as such we only have one breakpoint. @@ -26,3 +27,10 @@ DisplayType displayTypeOf(BuildContext context) { bool isDisplayDesktop(BuildContext context) { return displayTypeOf(context) == DisplayType.desktop; } + +/// Returns a boolean if we are in a display of [DisplayType.desktop] but less +/// than 1000 width. Used to build adaptive and responsive layouts. +bool isDisplaySmallDesktop(BuildContext context) { + return isDisplayDesktop(context) && + MediaQuery.of(context).size.width < _smallDesktopMaxWidth; +} diff --git a/gallery/gallery/lib/studies/crane/backdrop.dart b/gallery/gallery/lib/studies/crane/backdrop.dart index c26ecf93c..563d45fb1 100644 --- a/gallery/gallery/lib/studies/crane/backdrop.dart +++ b/gallery/gallery/lib/studies/crane/backdrop.dart @@ -15,6 +15,7 @@ import 'package:gallery/layout/adaptive.dart'; import 'package:gallery/studies/crane/border_tab_indicator.dart'; import 'package:gallery/studies/crane/backlayer.dart'; import 'package:gallery/studies/crane/colors.dart'; +import 'package:gallery/studies/crane/header_form.dart'; import 'package:gallery/studies/crane/item_cards.dart'; class _FrontLayer extends StatelessWidget { @@ -32,6 +33,7 @@ class _FrontLayer extends StatelessWidget { @override Widget build(BuildContext context) { final isDesktop = isDisplayDesktop(context); + final isSmallDesktop = isDisplaySmallDesktop(context); return DefaultFocusTraversal( policy: ReadingOrderTraversalPolicy(), @@ -48,7 +50,10 @@ class _FrontLayer extends StatelessWidget { ), child: ListView( padding: isDesktop - ? EdgeInsets.symmetric(horizontal: 120, vertical: 22) + ? EdgeInsets.symmetric( + horizontal: + isSmallDesktop ? appPaddingSmall : appPaddingLarge, + vertical: 22) : EdgeInsets.all(20), children: [ Text(title, style: Theme.of(context).textTheme.subtitle), @@ -152,7 +157,10 @@ class _BackdropState extends State with TickerProviderStateMixin { Container( margin: EdgeInsets.only( top: isDesktop - ? 60 + 20 * textScaleFactor / 2 + ? (isDisplaySmallDesktop(context) + ? textFieldHeight * 2 + : textFieldHeight) + + 20 * textScaleFactor / 2 : 175 + 140 * textScaleFactor / 2, ), child: TabBarView( @@ -213,11 +221,15 @@ class _CraneAppBarState extends State { @override Widget build(BuildContext context) { final isDesktop = isDisplayDesktop(context); + final isSmallDesktop = isDisplaySmallDesktop(context); final textScaleFactor = GalleryOptions.of(context).textScaleFactor(context); return SafeArea( child: Padding( - padding: EdgeInsets.symmetric(horizontal: isDesktop ? 120 : 24), + padding: EdgeInsets.symmetric( + horizontal: + isDesktop && !isSmallDesktop ? appPaddingLarge : appPaddingSmall, + ), child: Row( mainAxisAlignment: MainAxisAlignment.spaceEvenly, crossAxisAlignment: CrossAxisAlignment.center, diff --git a/gallery/gallery/lib/studies/crane/header_form.dart b/gallery/gallery/lib/studies/crane/header_form.dart index 3f7216345..049a9ec30 100644 --- a/gallery/gallery/lib/studies/crane/header_form.dart +++ b/gallery/gallery/lib/studies/crane/header_form.dart @@ -6,6 +6,10 @@ import 'package:flutter/material.dart'; import 'package:gallery/layout/adaptive.dart'; import 'package:gallery/studies/crane/colors.dart'; +const textFieldHeight = 60.0; +const appPaddingLarge = 120.0; +const appPaddingSmall = 24.0; + class HeaderFormField { final IconData iconData; final String title; @@ -22,21 +26,32 @@ class HeaderForm extends StatelessWidget { @override Widget build(BuildContext context) { final isDesktop = isDisplayDesktop(context); - + final isSmallDesktop = isDisplaySmallDesktop(context); return Padding( - padding: EdgeInsets.symmetric(horizontal: isDesktop ? 120 : 24), + padding: EdgeInsets.symmetric( + horizontal: + isDesktop && !isSmallDesktop ? appPaddingLarge : appPaddingSmall, + ), child: isDesktop - ? Row( - children: [ - for (final field in fields) - Flexible( - child: Padding( + ? LayoutBuilder(builder: (context, constraints) { + var crossAxisCount = isSmallDesktop ? 2 : 4; + if (fields.length < crossAxisCount) { + crossAxisCount = fields.length; + } + final itemWidth = constraints.maxWidth / crossAxisCount; + return GridView.count( + crossAxisCount: crossAxisCount, + childAspectRatio: itemWidth / textFieldHeight, + physics: NeverScrollableScrollPhysics(), + children: [ + for (final field in fields) + Padding( padding: const EdgeInsetsDirectional.only(end: 16), child: _HeaderTextField(field: field), - ), - ) - ], - ) + ) + ], + ); + }) : Column( mainAxisSize: MainAxisSize.min, children: [