-
Notifications
You must be signed in to change notification settings - Fork 173
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Add PlatformSliverAppBar class with example #427
Merged
aqwert
merged 2 commits into
stryder-dev:master
from
bookshiyi:#425-PlatformSliverAppBar
Jan 31, 2024
Merged
Changes from all commits
Commits
Show all changes
2 commits
Select commit
Hold shift + click to select a range
File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,39 @@ | ||
import 'package:flutter/material.dart'; | ||
import 'package:flutter_platform_widgets/flutter_platform_widgets.dart'; | ||
|
||
class PlatformSliverAppBarPage extends StatefulWidget { | ||
const PlatformSliverAppBarPage({super.key}); | ||
|
||
@override | ||
State<PlatformSliverAppBarPage> createState() => | ||
_PlatformSliverAppBarPageState(); | ||
} | ||
|
||
class _PlatformSliverAppBarPageState extends State<PlatformSliverAppBarPage> { | ||
@override | ||
Widget build(BuildContext context) { | ||
return PlatformScaffold( | ||
body: CustomScrollView( | ||
slivers: <Widget>[ | ||
PlatformSliverAppBar( | ||
title: Text('Sliver App Bar'), | ||
), | ||
SliverList( | ||
delegate: SliverChildBuilderDelegate( | ||
(BuildContext context, int index) { | ||
return Container( | ||
color: index.isOdd ? Colors.white : Colors.black12, | ||
height: 100.0, | ||
child: Center( | ||
child: PlatformText('$index', textScaleFactor: 5), | ||
), | ||
); | ||
}, | ||
childCount: 20, | ||
), | ||
), | ||
], | ||
), | ||
); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,297 @@ | ||
/* | ||
* flutter_platform_widgets | ||
* Copyright (c) 2018 Lance Johnstone. All rights reserved. | ||
* See LICENSE for distribution and usage details. | ||
*/ | ||
|
||
import 'package:flutter/cupertino.dart' | ||
show CupertinoSliverNavigationBar, Brightness; | ||
import 'package:flutter/material.dart' | ||
show SliverAppBar, kToolbarHeight; //MaterialStateProperty, ; | ||
import 'package:flutter/widgets.dart'; | ||
import 'package:flutter/foundation.dart' show AsyncCallback; | ||
import 'package:flutter/services.dart' show SystemUiOverlayStyle; | ||
import 'platform.dart'; | ||
import 'widget_base.dart'; | ||
|
||
abstract class _BaseData { | ||
_BaseData({ | ||
//Common | ||
this.widgetKey, | ||
this.leading, | ||
this.automaticallyImplyLeading, | ||
this.backgroundColor, | ||
this.stretch, | ||
this.title, | ||
}); | ||
|
||
final Key? widgetKey; | ||
final Widget? leading; | ||
final bool? automaticallyImplyLeading; | ||
final Color? backgroundColor; | ||
final bool? stretch; | ||
final Widget? title; | ||
} | ||
|
||
class MaterialSliverAppBarData extends _BaseData { | ||
MaterialSliverAppBarData({ | ||
// Common | ||
super.widgetKey, | ||
super.leading, | ||
super.automaticallyImplyLeading, | ||
super.backgroundColor, | ||
super.stretch, | ||
super.title, | ||
|
||
//Material | ||
this.actions, | ||
this.flexibleSpace, | ||
this.bottom, | ||
this.elevation, | ||
this.scrolledUnderElevation, | ||
this.shadowColor, | ||
this.surfaceTintColor, | ||
this.forceElevated = false, | ||
this.foregroundColor, | ||
this.iconTheme, | ||
this.actionsIconTheme, | ||
this.primary = true, | ||
this.centerTitle, | ||
this.excludeHeaderSemantics = false, | ||
this.titleSpacing, | ||
this.collapsedHeight, | ||
this.expandedHeight, | ||
this.floating = false, | ||
this.pinned = false, | ||
this.snap = false, | ||
this.stretchTriggerOffset = 100.0, | ||
this.onStretchTrigger, | ||
this.shape, | ||
this.toolbarHeight = kToolbarHeight, | ||
this.leadingWidth, | ||
this.toolbarTextStyle, | ||
this.titleTextStyle, | ||
this.systemOverlayStyle, | ||
this.forceMaterialTransparency = false, | ||
this.clipBehavior, | ||
}) : assert(floating || !snap, | ||
'The "snap" argument only makes sense for floating app bars.'), | ||
assert(stretchTriggerOffset > 0.0), | ||
assert(collapsedHeight == null || collapsedHeight >= toolbarHeight, | ||
'The "collapsedHeight" argument has to be larger than or equal to [toolbarHeight].'); | ||
|
||
// final Widget? title; | ||
final List<Widget>? actions; | ||
final Widget? flexibleSpace; | ||
final PreferredSizeWidget? bottom; | ||
final double? elevation; | ||
final double? scrolledUnderElevation; | ||
final Color? shadowColor; | ||
final Color? surfaceTintColor; | ||
final bool forceElevated; | ||
final Color? foregroundColor; | ||
final IconThemeData? iconTheme; | ||
final IconThemeData? actionsIconTheme; | ||
final bool primary; | ||
final bool? centerTitle; | ||
final bool excludeHeaderSemantics; | ||
final double? titleSpacing; | ||
final double? collapsedHeight; | ||
final double? expandedHeight; | ||
final bool floating; | ||
final bool pinned; | ||
final ShapeBorder? shape; | ||
final bool snap; | ||
final double stretchTriggerOffset; | ||
final AsyncCallback? onStretchTrigger; | ||
final double toolbarHeight; | ||
final double? leadingWidth; | ||
final TextStyle? toolbarTextStyle; | ||
final TextStyle? titleTextStyle; | ||
final SystemUiOverlayStyle? systemOverlayStyle; | ||
final bool forceMaterialTransparency; | ||
final Clip? clipBehavior; | ||
} | ||
|
||
class CupertinoSliverAppBarData extends _BaseData { | ||
CupertinoSliverAppBarData({ | ||
//Common | ||
super.widgetKey, | ||
super.leading, | ||
super.automaticallyImplyLeading, | ||
super.backgroundColor, | ||
super.stretch, | ||
super.title, | ||
|
||
//Cupertino | ||
// this.largeTitle, | ||
this.automaticallyImplyTitle = true, | ||
this.alwaysShowMiddle = true, | ||
this.previousPageTitle, | ||
this.middle, | ||
this.trailing, | ||
this.border = _kDefaultNavBarBorder, | ||
this.brightness, | ||
this.padding, | ||
this.transitionBetweenRoutes = true, | ||
this.heroTag = _defaultHeroTag, | ||
}) : assert( | ||
automaticallyImplyTitle == true || title != null, | ||
'No title has been provided but automaticallyImplyTitle is also ' | ||
'false. Either provide a title or set automaticallyImplyTitle to ' | ||
'true.', | ||
); | ||
|
||
// final Widget? largeTitle; | ||
final bool automaticallyImplyTitle; | ||
final bool alwaysShowMiddle; | ||
final String? previousPageTitle; | ||
final Widget? middle; | ||
final Widget? trailing; | ||
final Brightness? brightness; | ||
final EdgeInsetsDirectional? padding; | ||
final Border? border; | ||
final bool transitionBetweenRoutes; | ||
final Object heroTag; | ||
} | ||
|
||
class PlatformSliverAppBar | ||
extends PlatformWidgetBase<CupertinoSliverNavigationBar, SliverAppBar> { | ||
//Common | ||
final Key? widgetKey; | ||
|
||
final Widget? leading; | ||
final bool? automaticallyImplyLeading; | ||
final Color? backgroundColor; | ||
final bool? stretch; | ||
final Widget? title; | ||
|
||
//Platform | ||
final PlatformBuilder<MaterialSliverAppBarData>? material; | ||
final PlatformBuilder<CupertinoSliverAppBarData>? cupertino; | ||
|
||
PlatformSliverAppBar({ | ||
//Common | ||
super.key, | ||
this.widgetKey, | ||
this.leading, | ||
this.automaticallyImplyLeading, | ||
this.backgroundColor, | ||
this.stretch, | ||
this.title, | ||
//Platform | ||
this.material, | ||
this.cupertino, | ||
}); | ||
|
||
@override | ||
SliverAppBar createMaterialWidget(BuildContext context) { | ||
final data = material?.call(context, platform(context)); | ||
return SliverAppBar( | ||
//Common | ||
key: data?.widgetKey ?? widgetKey, | ||
leading: data?.leading ?? leading, | ||
automaticallyImplyLeading: | ||
data?.automaticallyImplyLeading ?? automaticallyImplyLeading ?? true, | ||
backgroundColor: data?.backgroundColor ?? backgroundColor, | ||
stretch: data?.stretch ?? stretch ?? false, | ||
title: data?.title ?? title, | ||
|
||
//Material only | ||
actions: data?.actions, | ||
flexibleSpace: data?.flexibleSpace, | ||
bottom: data?.bottom, | ||
elevation: data?.elevation, | ||
shadowColor: data?.shadowColor, | ||
forceElevated: data?.forceElevated ?? false, | ||
foregroundColor: data?.foregroundColor, | ||
iconTheme: data?.iconTheme, | ||
actionsIconTheme: data?.actionsIconTheme, | ||
primary: data?.primary ?? true, | ||
centerTitle: data?.centerTitle, | ||
excludeHeaderSemantics: data?.excludeHeaderSemantics ?? false, | ||
titleSpacing: data?.titleSpacing, | ||
collapsedHeight: data?.collapsedHeight, | ||
expandedHeight: data?.expandedHeight, | ||
floating: data?.floating ?? false, | ||
pinned: data?.pinned ?? false, | ||
snap: data?.snap ?? false, | ||
stretchTriggerOffset: data?.stretchTriggerOffset ?? 100.0, | ||
onStretchTrigger: data?.onStretchTrigger, | ||
shape: data?.shape, | ||
toolbarHeight: data?.toolbarHeight ?? kToolbarHeight, | ||
leadingWidth: data?.leadingWidth, | ||
toolbarTextStyle: data?.toolbarTextStyle, | ||
titleTextStyle: data?.titleTextStyle, | ||
systemOverlayStyle: data?.systemOverlayStyle, | ||
forceMaterialTransparency: data?.forceMaterialTransparency ?? false, | ||
clipBehavior: data?.clipBehavior, | ||
); | ||
} | ||
|
||
@override | ||
CupertinoSliverNavigationBar createCupertinoWidget(BuildContext context) { | ||
final data = cupertino?.call(context, platform(context)); | ||
|
||
return CupertinoSliverNavigationBar( | ||
//Common | ||
key: data?.widgetKey ?? widgetKey, | ||
leading: data?.leading ?? leading, | ||
automaticallyImplyLeading: | ||
data?.automaticallyImplyLeading ?? automaticallyImplyLeading ?? true, | ||
backgroundColor: data?.backgroundColor ?? backgroundColor, | ||
stretch: data?.stretch ?? stretch ?? false, | ||
largeTitle: data?.title ?? title, | ||
|
||
//Cupertino only | ||
automaticallyImplyTitle: data?.automaticallyImplyTitle ?? true, | ||
alwaysShowMiddle: data?.alwaysShowMiddle ?? true, | ||
previousPageTitle: data?.previousPageTitle, | ||
middle: data?.middle, | ||
trailing: data?.trailing, | ||
border: data?.border ?? _kDefaultNavBarBorder, | ||
brightness: data?.brightness, | ||
padding: data?.padding, | ||
transitionBetweenRoutes: data?.transitionBetweenRoutes ?? true, | ||
heroTag: data?.heroTag ?? _defaultHeroTag, | ||
); | ||
} | ||
} | ||
|
||
//! Copied from file: /opt/homebrew/Caskroom/flutter/3.10.0/flutter/packages/flutter/lib/src/cupertino/nav_bar.dart | ||
const Color _kDefaultNavBarBorderColor = Color(0x4D000000); | ||
|
||
const Border _kDefaultNavBarBorder = Border( | ||
bottom: BorderSide( | ||
color: _kDefaultNavBarBorderColor, | ||
width: 0.0, // 0.0 means one physical pixel | ||
), | ||
); | ||
|
||
const _HeroTag _defaultHeroTag = _HeroTag(null); | ||
|
||
@immutable | ||
class _HeroTag { | ||
const _HeroTag(this.navigator); | ||
|
||
final NavigatorState? navigator; | ||
|
||
// Let the Hero tag be described in tree dumps. | ||
@override | ||
String toString() => | ||
'Default Hero tag for Cupertino navigation bars with navigator $navigator'; | ||
|
||
@override | ||
bool operator ==(Object other) { | ||
if (identical(this, other)) { | ||
return true; | ||
} | ||
if (other.runtimeType != runtimeType) { | ||
return false; | ||
} | ||
return other is _HeroTag && other.navigator == navigator; | ||
} | ||
|
||
@override | ||
int get hashCode => identityHashCode(navigator); | ||
} | ||
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Regarding these local variables, I didn't find a better solution, so I had to copy and paste them here intact.