mirror of
https://github.com/flutter/flutter.git
synced 2026-02-20 02:29:02 +08:00
Add flutter_lints to samples (#179091)
I recommend reviewing each commit individually. The following were suppressed instead of migrated to minimize the time the tree is closed: 1. The [`Radio` -> `RadioGroup` migration](https://docs.flutter.dev/release/breaking-changes/radio-api-redesign). Tracked by: https://github.com/flutter/flutter/issues/179088. Part of: https://github.com/flutter/flutter/issues/178827 ## Pre-launch Checklist - [x] I read the [Contributor Guide] and followed the process outlined there for submitting PRs. - [x] I read the [Tree Hygiene] wiki page, which explains my responsibilities. - [x] I read and followed the [Flutter Style Guide], including [Features we expect every widget to implement]. - [x] I signed the [CLA]. - [x] I listed at least one issue that this PR fixes in the description above. - [x] I updated/added relevant documentation (doc comments with `///`). - [x] I added new tests to check the change I am making, or this PR is [test-exempt]. - [x] I followed the [breaking change policy] and added [Data Driven Fixes] where supported. - [x] All existing and new tests are passing. If you need help, consider asking for advice on the #hackers-new channel on [Discord]. **Note**: The Flutter team is currently trialing the use of [Gemini Code Assist for GitHub](https://developers.google.com/gemini-code-assist/docs/review-github-code). Comments from the `gemini-code-assist` bot should not be taken as authoritative feedback from the Flutter team. If you find its comments useful you can update your code accordingly, but if you are unsure or disagree with the feedback, please feel free to wait for a Flutter team member's review for guidance on which automated comments should be addressed. <!-- Links --> [Contributor Guide]: https://github.com/flutter/flutter/blob/main/docs/contributing/Tree-hygiene.md#overview [Tree Hygiene]: https://github.com/flutter/flutter/blob/main/docs/contributing/Tree-hygiene.md [test-exempt]: https://github.com/flutter/flutter/blob/main/docs/contributing/Tree-hygiene.md#tests [Flutter Style Guide]: https://github.com/flutter/flutter/blob/main/docs/contributing/Style-guide-for-Flutter-repo.md [Features we expect every widget to implement]: https://github.com/flutter/flutter/blob/main/docs/contributing/Style-guide-for-Flutter-repo.md#features-we-expect-every-widget-to-implement [CLA]: https://cla.developers.google.com/ [flutter/tests]: https://github.com/flutter/tests [breaking change policy]: https://github.com/flutter/flutter/blob/main/docs/contributing/Tree-hygiene.md#handling-breaking-changes [Discord]: https://github.com/flutter/flutter/blob/main/docs/contributing/Chat.md [Data Driven Fixes]: https://github.com/flutter/flutter/blob/main/docs/contributing/Data-driven-Fixes.md
This commit is contained in:
parent
7b98d50631
commit
d248a651b6
@ -5519,10 +5519,10 @@ base class FragmentShader extends Shader {
|
||||
/// shader.setFloat(2, 83); // uMagnitude y
|
||||
///
|
||||
/// // Convert color to premultiplied opacity.
|
||||
/// shader.setFloat(3, color.red / 255 * color.opacity); // uColor r
|
||||
/// shader.setFloat(4, color.green / 255 * color.opacity); // uColor g
|
||||
/// shader.setFloat(5, color.blue / 255 * color.opacity); // uColor b
|
||||
/// shader.setFloat(6, color.opacity); // uColor a
|
||||
/// shader.setFloat(3, color.r * color.a); // uColor r
|
||||
/// shader.setFloat(4, color.g * color.a); // uColor g
|
||||
/// shader.setFloat(5, color.b * color.a); // uColor b
|
||||
/// shader.setFloat(6, color.a); // uColor a
|
||||
///
|
||||
/// // initialize sampler uniform.
|
||||
/// shader.setImageSampler(0, image);
|
||||
|
||||
@ -1,11 +1,8 @@
|
||||
# This file is also used by dev/bots/analyze_snippet_code.dart to analyze code snippets (`{@tool snippet}` sections).
|
||||
|
||||
# include: ../../analysis_options.yaml #TODO(Piinks): Replace with flutter_lints - separate change.
|
||||
|
||||
analyzer:
|
||||
errors:
|
||||
# We have some clean up to do here. Landing examples/api update separately.
|
||||
deprecated_member_use: ignore
|
||||
# The following line activates a set of recommended lints for Flutter apps,
|
||||
# packages, and plugins designed to encourage good coding practices.
|
||||
include: package:flutter_lints/flutter.yaml
|
||||
|
||||
linter:
|
||||
rules:
|
||||
|
||||
@ -23,13 +23,15 @@ class _PlaceholderDigit extends StatelessWidget {
|
||||
context,
|
||||
).textTheme.displayLarge!.copyWith(fontWeight: FontWeight.w500);
|
||||
|
||||
final Iterable<Widget> placeholderDigits = <int>[0, 1, 2, 3, 4, 5, 6, 7, 8, 9].map<Widget>((
|
||||
int n,
|
||||
) {
|
||||
return Text('$n', style: textStyle);
|
||||
});
|
||||
final Iterable<Widget> placeholderDigits =
|
||||
<int>[0, 1, 2, 3, 4, 5, 6, 7, 8, 9].map<Widget>((int n) {
|
||||
return Text('$n', style: textStyle);
|
||||
});
|
||||
|
||||
return Opacity(opacity: 0, child: Stack(children: placeholderDigits.toList()));
|
||||
return Opacity(
|
||||
opacity: 0,
|
||||
child: Stack(children: placeholderDigits.toList()),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@ -46,14 +48,15 @@ class AnimatedDigit extends StatefulWidget {
|
||||
State<AnimatedDigit> createState() => _AnimatedDigitState();
|
||||
}
|
||||
|
||||
class _AnimatedDigitState extends State<AnimatedDigit> with SingleTickerProviderStateMixin {
|
||||
class _AnimatedDigitState extends State<AnimatedDigit>
|
||||
with SingleTickerProviderStateMixin {
|
||||
static const Duration defaultDuration = Duration(milliseconds: 300);
|
||||
|
||||
late final AnimationController controller;
|
||||
late int incomingValue;
|
||||
late int outgoingValue;
|
||||
List<int> pendingValues =
|
||||
<int>[]; // widget.value updates that occurred while the animation is underway
|
||||
// widget.value updates that occurred while the animation is underway.
|
||||
List<int> pendingValues = <int>[];
|
||||
Duration duration = defaultDuration;
|
||||
|
||||
@override
|
||||
@ -109,7 +112,8 @@ class _AnimatedDigitState extends State<AnimatedDigit> with SingleTickerProvider
|
||||
// will show the pending values.
|
||||
pendingValues.add(widget.value);
|
||||
final double percentRemaining = 1 - controller.value;
|
||||
duration = defaultDuration * (1 / (percentRemaining + pendingValues.length));
|
||||
duration =
|
||||
defaultDuration * (1 / (percentRemaining + pendingValues.length));
|
||||
controller.animateTo(1.0, duration: duration * percentRemaining);
|
||||
} else {
|
||||
animateValueUpdate(incomingValue, widget.value);
|
||||
@ -134,7 +138,11 @@ class _AnimatedDigitState extends State<AnimatedDigit> with SingleTickerProvider
|
||||
end: const Offset(0, -1), // Out of view above the top.
|
||||
),
|
||||
),
|
||||
child: Text(key: ValueKey<int>(outgoingValue), '$outgoingValue', style: textStyle),
|
||||
child: Text(
|
||||
key: ValueKey<int>(outgoingValue),
|
||||
'$outgoingValue',
|
||||
style: textStyle,
|
||||
),
|
||||
),
|
||||
SlideTransition(
|
||||
position: controller.drive(
|
||||
@ -143,7 +151,11 @@ class _AnimatedDigitState extends State<AnimatedDigit> with SingleTickerProvider
|
||||
end: Offset.zero,
|
||||
),
|
||||
),
|
||||
child: Text(key: ValueKey<int>(incomingValue), '$incomingValue', style: textStyle),
|
||||
child: Text(
|
||||
key: ValueKey<int>(incomingValue),
|
||||
'$incomingValue',
|
||||
style: textStyle,
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
|
||||
@ -54,7 +54,8 @@ class FollowCurve2D extends StatefulWidget {
|
||||
State<FollowCurve2D> createState() => _FollowCurve2DState();
|
||||
}
|
||||
|
||||
class _FollowCurve2DState extends State<FollowCurve2D> with TickerProviderStateMixin {
|
||||
class _FollowCurve2DState extends State<FollowCurve2D>
|
||||
with TickerProviderStateMixin {
|
||||
// The animation controller for this animation.
|
||||
late AnimationController controller;
|
||||
// The animation that will be used to apply the widget's animation curve.
|
||||
@ -81,8 +82,12 @@ class _FollowCurve2DState extends State<FollowCurve2D> with TickerProviderStateM
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
// Scale the path values to match the -1.0 to 1.0 domain of the Alignment widget.
|
||||
final Offset position = widget.path.transform(animation.value) * 2.0 - const Offset(1.0, 1.0);
|
||||
return Align(alignment: Alignment(position.dx, position.dy), child: widget.child);
|
||||
final Offset position =
|
||||
widget.path.transform(animation.value) * 2.0 - const Offset(1.0, 1.0);
|
||||
return Align(
|
||||
alignment: Alignment(position.dx, position.dy),
|
||||
child: widget.child,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -26,7 +26,9 @@ class CupertinoIndicatorExample extends StatelessWidget {
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return const CupertinoPageScaffold(
|
||||
navigationBar: CupertinoNavigationBar(middle: Text('CupertinoActivityIndicator Sample')),
|
||||
navigationBar: CupertinoNavigationBar(
|
||||
middle: Text('CupertinoActivityIndicator Sample'),
|
||||
),
|
||||
child: Center(
|
||||
child: Column(
|
||||
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
|
||||
@ -44,7 +46,10 @@ class CupertinoIndicatorExample extends StatelessWidget {
|
||||
mainAxisAlignment: MainAxisAlignment.center,
|
||||
children: <Widget>[
|
||||
// Cupertino activity indicator with custom radius and color.
|
||||
CupertinoActivityIndicator(radius: 20.0, color: CupertinoColors.activeBlue),
|
||||
CupertinoActivityIndicator(
|
||||
radius: 20.0,
|
||||
color: CupertinoColors.activeBlue,
|
||||
),
|
||||
SizedBox(height: 10),
|
||||
Text(
|
||||
'radius: 20.0\ncolor: CupertinoColors.activeBlue',
|
||||
@ -59,7 +64,10 @@ class CupertinoIndicatorExample extends StatelessWidget {
|
||||
// animation.
|
||||
CupertinoActivityIndicator(radius: 20.0, animating: false),
|
||||
SizedBox(height: 10),
|
||||
Text('radius: 20.0\nanimating: false', textAlign: TextAlign.center),
|
||||
Text(
|
||||
'radius: 20.0\nanimating: false',
|
||||
textAlign: TextAlign.center,
|
||||
),
|
||||
],
|
||||
),
|
||||
],
|
||||
|
||||
@ -61,7 +61,10 @@ class CupertinoIndicatorExample extends StatelessWidget {
|
||||
Column(
|
||||
mainAxisAlignment: MainAxisAlignment.center,
|
||||
children: <Widget>[
|
||||
CupertinoLinearActivityIndicator(progress: 0.6, color: CupertinoColors.activeGreen),
|
||||
CupertinoLinearActivityIndicator(
|
||||
progress: 0.6,
|
||||
color: CupertinoColors.activeGreen,
|
||||
),
|
||||
SizedBox(height: 10),
|
||||
Text('Color: green', textAlign: TextAlign.center),
|
||||
],
|
||||
|
||||
@ -28,13 +28,22 @@ class CupertinoTabBarExample extends StatelessWidget {
|
||||
return CupertinoTabScaffold(
|
||||
tabBar: CupertinoTabBar(
|
||||
items: const <BottomNavigationBarItem>[
|
||||
BottomNavigationBarItem(icon: Icon(CupertinoIcons.star_fill), label: 'Favorites'),
|
||||
BottomNavigationBarItem(icon: Icon(CupertinoIcons.clock_solid), label: 'Recents'),
|
||||
BottomNavigationBarItem(
|
||||
icon: Icon(CupertinoIcons.star_fill),
|
||||
label: 'Favorites',
|
||||
),
|
||||
BottomNavigationBarItem(
|
||||
icon: Icon(CupertinoIcons.clock_solid),
|
||||
label: 'Recents',
|
||||
),
|
||||
BottomNavigationBarItem(
|
||||
icon: Icon(CupertinoIcons.person_alt_circle_fill),
|
||||
label: 'Contacts',
|
||||
),
|
||||
BottomNavigationBarItem(icon: Icon(CupertinoIcons.circle_grid_3x3_fill), label: 'Keypad'),
|
||||
BottomNavigationBarItem(
|
||||
icon: Icon(CupertinoIcons.circle_grid_3x3_fill),
|
||||
label: 'Keypad',
|
||||
),
|
||||
],
|
||||
),
|
||||
tabBuilder: (BuildContext context, int index) {
|
||||
|
||||
@ -26,18 +26,26 @@ class CupertinoButtonExample extends StatelessWidget {
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return CupertinoPageScaffold(
|
||||
navigationBar: const CupertinoNavigationBar(middle: Text('CupertinoButton Sample')),
|
||||
navigationBar: const CupertinoNavigationBar(
|
||||
middle: Text('CupertinoButton Sample'),
|
||||
),
|
||||
child: Center(
|
||||
child: Column(
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
children: <Widget>[
|
||||
const CupertinoButton(onPressed: null, child: Text('Disabled')),
|
||||
const SizedBox(height: 30),
|
||||
const CupertinoButton.filled(onPressed: null, child: Text('Disabled')),
|
||||
const CupertinoButton.filled(
|
||||
onPressed: null,
|
||||
child: Text('Disabled'),
|
||||
),
|
||||
const SizedBox(height: 30),
|
||||
CupertinoButton(onPressed: () {}, child: const Text('Enabled')),
|
||||
const SizedBox(height: 30),
|
||||
CupertinoButton.filled(onPressed: () {}, child: const Text('Enabled')),
|
||||
CupertinoButton.filled(
|
||||
onPressed: () {},
|
||||
child: const Text('Enabled'),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
|
||||
@ -16,7 +16,9 @@ class CupertinoCheckboxApp extends StatelessWidget {
|
||||
return const CupertinoApp(
|
||||
theme: CupertinoThemeData(brightness: Brightness.light),
|
||||
home: CupertinoPageScaffold(
|
||||
navigationBar: CupertinoNavigationBar(middle: Text('CupertinoCheckbox Example')),
|
||||
navigationBar: CupertinoNavigationBar(
|
||||
middle: Text('CupertinoCheckbox Example'),
|
||||
),
|
||||
child: SafeArea(child: CupertinoCheckboxExample()),
|
||||
),
|
||||
);
|
||||
@ -27,7 +29,8 @@ class CupertinoCheckboxExample extends StatefulWidget {
|
||||
const CupertinoCheckboxExample({super.key});
|
||||
|
||||
@override
|
||||
State<CupertinoCheckboxExample> createState() => _CupertinoCheckboxExampleState();
|
||||
State<CupertinoCheckboxExample> createState() =>
|
||||
_CupertinoCheckboxExampleState();
|
||||
}
|
||||
|
||||
class _CupertinoCheckboxExampleState extends State<CupertinoCheckboxExample> {
|
||||
|
||||
@ -26,7 +26,9 @@ class ContextMenuExample extends StatelessWidget {
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return CupertinoPageScaffold(
|
||||
navigationBar: const CupertinoNavigationBar(middle: Text('CupertinoContextMenu Sample')),
|
||||
navigationBar: const CupertinoNavigationBar(
|
||||
middle: Text('CupertinoContextMenu Sample'),
|
||||
),
|
||||
child: Center(
|
||||
child: SizedBox(
|
||||
width: 100,
|
||||
|
||||
@ -37,7 +37,9 @@ class ContextMenuExample extends StatelessWidget {
|
||||
const ContextMenuExample({super.key});
|
||||
|
||||
// Or just do this inline in the builder below?
|
||||
static Animation<Decoration> _boxDecorationAnimation(Animation<double> animation) {
|
||||
static Animation<Decoration> _boxDecorationAnimation(
|
||||
Animation<double> animation,
|
||||
) {
|
||||
return _tween.animate(
|
||||
CurvedAnimation(
|
||||
parent: animation,
|
||||
@ -49,7 +51,9 @@ class ContextMenuExample extends StatelessWidget {
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return CupertinoPageScaffold(
|
||||
navigationBar: const CupertinoNavigationBar(middle: Text('CupertinoContextMenu Sample')),
|
||||
navigationBar: const CupertinoNavigationBar(
|
||||
middle: Text('CupertinoContextMenu Sample'),
|
||||
),
|
||||
child: Center(
|
||||
child: SizedBox(
|
||||
width: 100,
|
||||
@ -88,12 +92,12 @@ class ContextMenuExample extends StatelessWidget {
|
||||
),
|
||||
],
|
||||
builder: (BuildContext context, Animation<double> animation) {
|
||||
final Animation<Decoration> boxDecorationAnimation = _boxDecorationAnimation(
|
||||
animation,
|
||||
);
|
||||
final Animation<Decoration> boxDecorationAnimation =
|
||||
_boxDecorationAnimation(animation);
|
||||
|
||||
return Container(
|
||||
decoration: animation.value < CupertinoContextMenu.animationOpensAt
|
||||
decoration:
|
||||
animation.value < CupertinoContextMenu.animationOpensAt
|
||||
? boxDecorationAnimation.value
|
||||
: null,
|
||||
child: Container(
|
||||
|
||||
@ -42,7 +42,9 @@ class _DatePickerExampleState extends State<DatePickerExample> {
|
||||
padding: const EdgeInsets.only(top: 6.0),
|
||||
// The Bottom margin is provided to align the popup above the system
|
||||
// navigation bar.
|
||||
margin: EdgeInsets.only(bottom: MediaQuery.of(context).viewInsets.bottom),
|
||||
margin: EdgeInsets.only(
|
||||
bottom: MediaQuery.of(context).viewInsets.bottom,
|
||||
),
|
||||
// Provide a background color for the popup.
|
||||
color: CupertinoColors.systemBackground.resolveFrom(context),
|
||||
// Use a SafeArea widget to avoid system overlaps.
|
||||
@ -54,9 +56,14 @@ class _DatePickerExampleState extends State<DatePickerExample> {
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return CupertinoPageScaffold(
|
||||
navigationBar: const CupertinoNavigationBar(middle: Text('CupertinoDatePicker Sample')),
|
||||
navigationBar: const CupertinoNavigationBar(
|
||||
middle: Text('CupertinoDatePicker Sample'),
|
||||
),
|
||||
child: DefaultTextStyle(
|
||||
style: TextStyle(color: CupertinoColors.label.resolveFrom(context), fontSize: 22.0),
|
||||
style: TextStyle(
|
||||
color: CupertinoColors.label.resolveFrom(context),
|
||||
fontSize: 22.0,
|
||||
),
|
||||
child: Center(
|
||||
child: Column(
|
||||
mainAxisAlignment: MainAxisAlignment.center,
|
||||
@ -165,7 +172,10 @@ class _DatePickerItem extends StatelessWidget {
|
||||
),
|
||||
child: Padding(
|
||||
padding: const EdgeInsets.symmetric(horizontal: 16.0),
|
||||
child: Row(mainAxisAlignment: MainAxisAlignment.spaceBetween, children: children),
|
||||
child: Row(
|
||||
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||
children: children,
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
@ -40,7 +40,9 @@ class _TimerPickerExampleState extends State<TimerPickerExample> {
|
||||
padding: const EdgeInsets.only(top: 6.0),
|
||||
// The bottom margin is provided to align the popup above the system
|
||||
// navigation bar.
|
||||
margin: EdgeInsets.only(bottom: MediaQuery.of(context).viewInsets.bottom),
|
||||
margin: EdgeInsets.only(
|
||||
bottom: MediaQuery.of(context).viewInsets.bottom,
|
||||
),
|
||||
// Provide a background color for the popup.
|
||||
color: CupertinoColors.systemBackground.resolveFrom(context),
|
||||
// Use a SafeArea widget to avoid system overlaps.
|
||||
@ -52,9 +54,14 @@ class _TimerPickerExampleState extends State<TimerPickerExample> {
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return CupertinoPageScaffold(
|
||||
navigationBar: const CupertinoNavigationBar(middle: Text('CupertinoTimerPicker Sample')),
|
||||
navigationBar: const CupertinoNavigationBar(
|
||||
middle: Text('CupertinoTimerPicker Sample'),
|
||||
),
|
||||
child: DefaultTextStyle(
|
||||
style: TextStyle(color: CupertinoColors.label.resolveFrom(context), fontSize: 22.0),
|
||||
style: TextStyle(
|
||||
color: CupertinoColors.label.resolveFrom(context),
|
||||
fontSize: 22.0,
|
||||
),
|
||||
child: Center(
|
||||
child: Column(
|
||||
mainAxisAlignment: MainAxisAlignment.center,
|
||||
@ -78,7 +85,10 @@ class _TimerPickerExampleState extends State<TimerPickerExample> {
|
||||
// In this example, the timer's value is formatted manually.
|
||||
// You can use the intl package to format the value based on
|
||||
// the user's locale settings.
|
||||
child: Text('$duration', style: const TextStyle(fontSize: 22.0)),
|
||||
child: Text(
|
||||
'$duration',
|
||||
style: const TextStyle(fontSize: 22.0),
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
@ -107,7 +117,10 @@ class _TimerPickerItem extends StatelessWidget {
|
||||
),
|
||||
child: Padding(
|
||||
padding: const EdgeInsets.symmetric(horizontal: 16.0),
|
||||
child: Row(mainAxisAlignment: MainAxisAlignment.spaceBetween, children: children),
|
||||
child: Row(
|
||||
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||
children: children,
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
@ -64,7 +64,9 @@ class ActionSheetExample extends StatelessWidget {
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return CupertinoPageScaffold(
|
||||
navigationBar: const CupertinoNavigationBar(middle: Text('CupertinoActionSheet Sample')),
|
||||
navigationBar: const CupertinoNavigationBar(
|
||||
middle: Text('CupertinoActionSheet Sample'),
|
||||
),
|
||||
child: Center(
|
||||
child: CupertinoButton(
|
||||
onPressed: () => _showActionSheet(context),
|
||||
|
||||
@ -57,7 +57,9 @@ class AlertDialogExample extends StatelessWidget {
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return CupertinoPageScaffold(
|
||||
navigationBar: const CupertinoNavigationBar(middle: Text('CupertinoAlertDialog Sample')),
|
||||
navigationBar: const CupertinoNavigationBar(
|
||||
middle: Text('CupertinoAlertDialog Sample'),
|
||||
),
|
||||
child: Center(
|
||||
child: CupertinoButton(
|
||||
onPressed: () => _showAlertDialog(context),
|
||||
|
||||
@ -42,7 +42,8 @@ class _PopupSurfaceExampleState extends State<PopupSurfaceExample> {
|
||||
const SizedBox(width: 16.0),
|
||||
CupertinoSwitch(
|
||||
value: _shouldPaintSurface,
|
||||
onChanged: (bool value) => setState(() => _shouldPaintSurface = value),
|
||||
onChanged: (bool value) =>
|
||||
setState(() => _shouldPaintSurface = value),
|
||||
),
|
||||
],
|
||||
),
|
||||
@ -73,7 +74,9 @@ class _PopupSurfaceExampleState extends State<PopupSurfaceExample> {
|
||||
decoration: _shouldPaintSurface
|
||||
? null
|
||||
: BoxDecoration(
|
||||
color: CupertinoTheme.of(context).scaffoldBackgroundColor,
|
||||
color: CupertinoTheme.of(
|
||||
context,
|
||||
).scaffoldBackgroundColor,
|
||||
borderRadius: BorderRadius.circular(8.0),
|
||||
),
|
||||
child: const Text('This is a popup surface.'),
|
||||
@ -87,7 +90,10 @@ class _PopupSurfaceExampleState extends State<PopupSurfaceExample> {
|
||||
? null
|
||||
: CupertinoTheme.of(context).scaffoldBackgroundColor,
|
||||
onPressed: () => Navigator.pop(context),
|
||||
child: const Text('Close', style: TextStyle(color: CupertinoColors.systemBlue)),
|
||||
child: const Text(
|
||||
'Close',
|
||||
style: TextStyle(color: CupertinoColors.systemBlue),
|
||||
),
|
||||
),
|
||||
),
|
||||
],
|
||||
|
||||
@ -16,7 +16,9 @@ class CupertinoExpansionTileApp extends StatelessWidget {
|
||||
Widget build(BuildContext context) {
|
||||
return const CupertinoApp(
|
||||
home: CupertinoPageScaffold(
|
||||
navigationBar: CupertinoNavigationBar(middle: Text('Cupertino Expansion Tile')),
|
||||
navigationBar: CupertinoNavigationBar(
|
||||
middle: Text('Cupertino Expansion Tile'),
|
||||
),
|
||||
backgroundColor: CupertinoColors.systemGroupedBackground,
|
||||
child: SafeArea(child: ExpansionTileExamples()),
|
||||
),
|
||||
@ -46,7 +48,11 @@ class ExpansionTileExamples extends StatelessWidget {
|
||||
}
|
||||
|
||||
class TransitionTileSection extends StatefulWidget {
|
||||
const TransitionTileSection({super.key, required this.title, required this.transitionMode});
|
||||
const TransitionTileSection({
|
||||
super.key,
|
||||
required this.title,
|
||||
required this.transitionMode,
|
||||
});
|
||||
|
||||
final String title;
|
||||
final ExpansionTileTransitionMode transitionMode;
|
||||
@ -90,17 +96,26 @@ class _TransitionTileSectionState extends State<TransitionTileSection> {
|
||||
CupertinoListTile(
|
||||
leading: Icon(CupertinoIcons.person),
|
||||
backgroundColor: CupertinoColors.white,
|
||||
title: Text('Profile', style: TextStyle(color: CupertinoColors.black)),
|
||||
title: Text(
|
||||
'Profile',
|
||||
style: TextStyle(color: CupertinoColors.black),
|
||||
),
|
||||
),
|
||||
CupertinoListTile(
|
||||
leading: Icon(CupertinoIcons.mail),
|
||||
backgroundColor: CupertinoColors.white,
|
||||
title: Text('Messages', style: TextStyle(color: CupertinoColors.black)),
|
||||
title: Text(
|
||||
'Messages',
|
||||
style: TextStyle(color: CupertinoColors.black),
|
||||
),
|
||||
),
|
||||
CupertinoListTile(
|
||||
leading: Icon(CupertinoIcons.settings),
|
||||
backgroundColor: CupertinoColors.white,
|
||||
title: Text('Settings', style: TextStyle(color: CupertinoColors.black)),
|
||||
title: Text(
|
||||
'Settings',
|
||||
style: TextStyle(color: CupertinoColors.black),
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
|
||||
@ -24,7 +24,8 @@ class CupertinoFormRowExample extends StatefulWidget {
|
||||
const CupertinoFormRowExample({super.key});
|
||||
|
||||
@override
|
||||
State<CupertinoFormRowExample> createState() => _CupertinoFormRowExampleState();
|
||||
State<CupertinoFormRowExample> createState() =>
|
||||
_CupertinoFormRowExampleState();
|
||||
}
|
||||
|
||||
class _CupertinoFormRowExampleState extends State<CupertinoFormRowExample> {
|
||||
@ -33,7 +34,9 @@ class _CupertinoFormRowExampleState extends State<CupertinoFormRowExample> {
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return CupertinoPageScaffold(
|
||||
navigationBar: const CupertinoNavigationBar(middle: Text('CupertinoFormSection Sample')),
|
||||
navigationBar: const CupertinoNavigationBar(
|
||||
middle: Text('CupertinoFormSection Sample'),
|
||||
),
|
||||
// Add safe area widget to place the CupertinoFormSection below the navigation bar.
|
||||
child: SafeArea(
|
||||
child: CupertinoFormSection(
|
||||
@ -85,7 +88,11 @@ class _CupertinoFormRowExampleState extends State<CupertinoFormRowExample> {
|
||||
),
|
||||
child: Row(
|
||||
mainAxisAlignment: MainAxisAlignment.end,
|
||||
children: <Widget>[Text('On'), SizedBox(width: 5), Icon(CupertinoIcons.forward)],
|
||||
children: <Widget>[
|
||||
Text('On'),
|
||||
SizedBox(width: 5),
|
||||
Icon(CupertinoIcons.forward),
|
||||
],
|
||||
),
|
||||
),
|
||||
const CupertinoFormRow(
|
||||
@ -104,7 +111,12 @@ class _CupertinoFormRowExampleState extends State<CupertinoFormRowExample> {
|
||||
}
|
||||
|
||||
class PrefixWidget extends StatelessWidget {
|
||||
const PrefixWidget({super.key, required this.icon, required this.title, required this.color});
|
||||
const PrefixWidget({
|
||||
super.key,
|
||||
required this.icon,
|
||||
required this.title,
|
||||
required this.color,
|
||||
});
|
||||
|
||||
final IconData icon;
|
||||
final String title;
|
||||
@ -116,7 +128,10 @@ class PrefixWidget extends StatelessWidget {
|
||||
children: <Widget>[
|
||||
Container(
|
||||
padding: const EdgeInsets.all(4.0),
|
||||
decoration: BoxDecoration(color: color, borderRadius: BorderRadius.circular(4.0)),
|
||||
decoration: BoxDecoration(
|
||||
color: color,
|
||||
borderRadius: BorderRadius.circular(4.0),
|
||||
),
|
||||
child: Icon(icon, color: CupertinoColors.white),
|
||||
),
|
||||
const SizedBox(width: 15),
|
||||
|
||||
@ -24,11 +24,16 @@ class CupertinoListTileExample extends StatelessWidget {
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return CupertinoPageScaffold(
|
||||
navigationBar: const CupertinoNavigationBar(middle: Text('CupertinoListTile Sample')),
|
||||
navigationBar: const CupertinoNavigationBar(
|
||||
middle: Text('CupertinoListTile Sample'),
|
||||
),
|
||||
child: ListView(
|
||||
children: const <Widget>[
|
||||
CupertinoListTile(title: Text('One-line CupertinoListTile')),
|
||||
CupertinoListTile(leading: FlutterLogo(), title: Text('One-line with leading widget')),
|
||||
CupertinoListTile(
|
||||
leading: FlutterLogo(),
|
||||
title: Text('One-line with leading widget'),
|
||||
),
|
||||
CupertinoListTile(
|
||||
title: Text('One-line with trailing widget'),
|
||||
trailing: Icon(Icons.more_vert),
|
||||
|
||||
@ -49,7 +49,8 @@ class _NavBarExampleState extends State<NavBarExample> {
|
||||
}
|
||||
}
|
||||
|
||||
class _NavigationBarSearchField extends StatelessWidget implements PreferredSizeWidget {
|
||||
class _NavigationBarSearchField extends StatelessWidget
|
||||
implements PreferredSizeWidget {
|
||||
const _NavigationBarSearchField();
|
||||
|
||||
static const double padding = 8.0;
|
||||
@ -59,10 +60,14 @@ class _NavigationBarSearchField extends StatelessWidget implements PreferredSize
|
||||
Widget build(BuildContext context) {
|
||||
return const Padding(
|
||||
padding: EdgeInsets.symmetric(horizontal: padding, vertical: padding),
|
||||
child: SizedBox(height: searchFieldHeight, child: CupertinoSearchTextField()),
|
||||
child: SizedBox(
|
||||
height: searchFieldHeight,
|
||||
child: CupertinoSearchTextField(),
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
@override
|
||||
Size get preferredSize => const Size.fromHeight(searchFieldHeight + padding * 2);
|
||||
Size get preferredSize =>
|
||||
const Size.fromHeight(searchFieldHeight + padding * 2);
|
||||
}
|
||||
|
||||
@ -33,14 +33,21 @@ class _NavBarExampleState extends State<NavBarExample> {
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return CupertinoPageScaffold(
|
||||
navigationBar: const CupertinoNavigationBar.large(largeTitle: Text('Large Sample')),
|
||||
navigationBar: const CupertinoNavigationBar.large(
|
||||
largeTitle: Text('Large Sample'),
|
||||
),
|
||||
child: SafeArea(
|
||||
child: Center(
|
||||
child: Column(
|
||||
children: <Widget>[
|
||||
const Spacer(),
|
||||
const Text('You have pushed the button this many times:'),
|
||||
Text('$_count', style: CupertinoTheme.of(context).textTheme.navLargeTitleTextStyle),
|
||||
Text(
|
||||
'$_count',
|
||||
style: CupertinoTheme.of(
|
||||
context,
|
||||
).textTheme.navLargeTitleTextStyle,
|
||||
),
|
||||
const Spacer(),
|
||||
Padding(
|
||||
padding: const EdgeInsets.all(15.0),
|
||||
|
||||
@ -98,7 +98,10 @@ class NextPage extends StatelessWidget {
|
||||
Text('Drag me up', textAlign: TextAlign.center),
|
||||
// When the "leading" parameter is omitted on a route that has a previous page,
|
||||
// the back button is automatically added to the leading position.
|
||||
Text('Tap on the leading button to navigate back', textAlign: TextAlign.center),
|
||||
Text(
|
||||
'Tap on the leading button to navigate back',
|
||||
textAlign: TextAlign.center,
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
|
||||
@ -59,7 +59,9 @@ class SliverNavBarExample extends StatelessWidget {
|
||||
context,
|
||||
CupertinoPageRoute<Widget>(
|
||||
builder: (BuildContext context) {
|
||||
return const NextPage(bottomMode: NavigationBarBottomMode.always);
|
||||
return const NextPage(
|
||||
bottomMode: NavigationBarBottomMode.always,
|
||||
);
|
||||
},
|
||||
),
|
||||
);
|
||||
@ -77,7 +79,10 @@ class SliverNavBarExample extends StatelessWidget {
|
||||
}
|
||||
|
||||
class NextPage extends StatefulWidget {
|
||||
const NextPage({super.key, this.bottomMode = NavigationBarBottomMode.automatic});
|
||||
const NextPage({
|
||||
super.key,
|
||||
this.bottomMode = NavigationBarBottomMode.automatic,
|
||||
});
|
||||
|
||||
final NavigationBarBottomMode bottomMode;
|
||||
|
||||
@ -132,7 +137,9 @@ class _NextPageState extends State<NextPage> {
|
||||
child: searchIsActive
|
||||
? ColoredBox(
|
||||
color: CupertinoColors.extraLightBackgroundGray,
|
||||
child: Center(child: Text(text, textAlign: TextAlign.center)),
|
||||
child: Center(
|
||||
child: Text(text, textAlign: TextAlign.center),
|
||||
),
|
||||
)
|
||||
: const Padding(
|
||||
padding: EdgeInsets.symmetric(horizontal: 16.0),
|
||||
|
||||
@ -38,7 +38,10 @@ class SliverNavBarExample extends StatelessWidget {
|
||||
largeTitle: Text('Contacts'),
|
||||
bottom: PreferredSize(
|
||||
preferredSize: Size.fromHeight(100),
|
||||
child: ColoredBox(color: Color(0xff191970), child: Text('Bottom Widget')),
|
||||
child: ColoredBox(
|
||||
color: Color(0xff191970),
|
||||
child: Text('Bottom Widget'),
|
||||
),
|
||||
),
|
||||
trailing: Icon(CupertinoIcons.add_circled),
|
||||
),
|
||||
@ -102,7 +105,10 @@ class NextPage extends StatelessWidget {
|
||||
Text('Drag me up', textAlign: TextAlign.center),
|
||||
// When the "leading" parameter is omitted on a route that has a previous page,
|
||||
// the back button is automatically added to the leading position.
|
||||
Text('Tap on the leading button to navigate back', textAlign: TextAlign.center),
|
||||
Text(
|
||||
'Tap on the leading button to navigate back',
|
||||
textAlign: TextAlign.center,
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
|
||||
@ -35,7 +35,9 @@ class _PageScaffoldExampleState extends State<PageScaffoldExample> {
|
||||
return CupertinoPageScaffold(
|
||||
// Uncomment to change the background color
|
||||
// backgroundColor: CupertinoColors.systemPink,
|
||||
navigationBar: const CupertinoNavigationBar(middle: Text('CupertinoPageScaffold Sample')),
|
||||
navigationBar: const CupertinoNavigationBar(
|
||||
middle: Text('CupertinoPageScaffold Sample'),
|
||||
),
|
||||
child: Center(
|
||||
child: Column(
|
||||
mainAxisAlignment: MainAxisAlignment.center,
|
||||
|
||||
@ -48,7 +48,9 @@ class _CupertinoPickerExampleState extends State<CupertinoPickerExample> {
|
||||
height: 216,
|
||||
padding: const EdgeInsets.only(top: 6.0),
|
||||
// The Bottom margin is provided to align the popup above the system navigation bar.
|
||||
margin: EdgeInsets.only(bottom: MediaQuery.of(context).viewInsets.bottom),
|
||||
margin: EdgeInsets.only(
|
||||
bottom: MediaQuery.of(context).viewInsets.bottom,
|
||||
),
|
||||
// Provide a background color for the popup.
|
||||
color: CupertinoColors.systemBackground.resolveFrom(context),
|
||||
// Use a SafeArea widget to avoid system overlaps.
|
||||
@ -60,9 +62,14 @@ class _CupertinoPickerExampleState extends State<CupertinoPickerExample> {
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return CupertinoPageScaffold(
|
||||
navigationBar: const CupertinoNavigationBar(middle: Text('CupertinoPicker Sample')),
|
||||
navigationBar: const CupertinoNavigationBar(
|
||||
middle: Text('CupertinoPicker Sample'),
|
||||
),
|
||||
child: DefaultTextStyle(
|
||||
style: TextStyle(color: CupertinoColors.label.resolveFrom(context), fontSize: 22.0),
|
||||
style: TextStyle(
|
||||
color: CupertinoColors.label.resolveFrom(context),
|
||||
fontSize: 22.0,
|
||||
),
|
||||
child: Center(
|
||||
child: Row(
|
||||
mainAxisAlignment: MainAxisAlignment.center,
|
||||
@ -78,20 +85,26 @@ class _CupertinoPickerExampleState extends State<CupertinoPickerExample> {
|
||||
useMagnifier: true,
|
||||
itemExtent: _kItemExtent,
|
||||
// This sets the initial item.
|
||||
scrollController: FixedExtentScrollController(initialItem: _selectedFruit),
|
||||
scrollController: FixedExtentScrollController(
|
||||
initialItem: _selectedFruit,
|
||||
),
|
||||
// This is called when selected item is changed.
|
||||
onSelectedItemChanged: (int selectedItem) {
|
||||
setState(() {
|
||||
_selectedFruit = selectedItem;
|
||||
});
|
||||
},
|
||||
children: List<Widget>.generate(_fruitNames.length, (int index) {
|
||||
return Center(child: Text(_fruitNames[index]));
|
||||
}),
|
||||
children: [
|
||||
for (final String fruitName in _fruitNames)
|
||||
Center(child: Text(fruitName)),
|
||||
],
|
||||
),
|
||||
),
|
||||
// This displays the selected fruit name.
|
||||
child: Text(_fruitNames[_selectedFruit], style: const TextStyle(fontSize: 22.0)),
|
||||
child: Text(
|
||||
_fruitNames[_selectedFruit],
|
||||
style: const TextStyle(fontSize: 22.0),
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
|
||||
@ -16,7 +16,9 @@ class CupertinoRadioApp extends StatelessWidget {
|
||||
return const CupertinoApp(
|
||||
theme: CupertinoThemeData(brightness: Brightness.light),
|
||||
home: CupertinoPageScaffold(
|
||||
navigationBar: CupertinoNavigationBar(middle: Text('CupertinoRadio Example')),
|
||||
navigationBar: CupertinoNavigationBar(
|
||||
middle: Text('CupertinoRadio Example'),
|
||||
),
|
||||
child: SafeArea(child: CupertinoRadioExample()),
|
||||
),
|
||||
);
|
||||
@ -48,11 +50,15 @@ class _CupertinoRadioExampleState extends State<CupertinoRadioExample> {
|
||||
children: const <Widget>[
|
||||
CupertinoListTile(
|
||||
title: Text('Lafayette'),
|
||||
leading: CupertinoRadio<SingingCharacter>(value: SingingCharacter.lafayette),
|
||||
leading: CupertinoRadio<SingingCharacter>(
|
||||
value: SingingCharacter.lafayette,
|
||||
),
|
||||
),
|
||||
CupertinoListTile(
|
||||
title: Text('Thomas Jefferson'),
|
||||
leading: CupertinoRadio<SingingCharacter>(value: SingingCharacter.jefferson),
|
||||
leading: CupertinoRadio<SingingCharacter>(
|
||||
value: SingingCharacter.jefferson,
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
|
||||
@ -15,7 +15,9 @@ class CupertinoRadioApp extends StatelessWidget {
|
||||
Widget build(BuildContext context) {
|
||||
return const CupertinoApp(
|
||||
home: CupertinoPageScaffold(
|
||||
navigationBar: CupertinoNavigationBar(middle: Text('CupertinoRadio Toggleable Example')),
|
||||
navigationBar: CupertinoNavigationBar(
|
||||
middle: Text('CupertinoRadio Toggleable Example'),
|
||||
),
|
||||
child: SafeArea(child: CupertinoRadioExample()),
|
||||
),
|
||||
);
|
||||
|
||||
@ -46,14 +46,19 @@ class _RefreshControlExampleState extends State<RefreshControlExample> {
|
||||
middle: Text('CupertinoSliverRefreshControl Sample'),
|
||||
),
|
||||
child: CustomScrollView(
|
||||
physics: const BouncingScrollPhysics(parent: AlwaysScrollableScrollPhysics()),
|
||||
physics: const BouncingScrollPhysics(
|
||||
parent: AlwaysScrollableScrollPhysics(),
|
||||
),
|
||||
slivers: <Widget>[
|
||||
const CupertinoSliverNavigationBar(largeTitle: Text('Scroll down')),
|
||||
CupertinoSliverRefreshControl(
|
||||
onRefresh: () async {
|
||||
await Future<void>.delayed(const Duration(milliseconds: 1000));
|
||||
setState(() {
|
||||
items.insert(0, Container(color: colors[items.length % 3], height: 100.0));
|
||||
items.insert(
|
||||
0,
|
||||
Container(color: colors[items.length % 3], height: 100.0),
|
||||
);
|
||||
});
|
||||
},
|
||||
),
|
||||
|
||||
@ -40,7 +40,10 @@ class CupertinoDialogExample extends StatelessWidget {
|
||||
}
|
||||
|
||||
@pragma('vm:entry-point')
|
||||
static Route<Object?> _dialogBuilder(BuildContext context, Object? arguments) {
|
||||
static Route<Object?> _dialogBuilder(
|
||||
BuildContext context,
|
||||
Object? arguments,
|
||||
) {
|
||||
return CupertinoDialogRoute<void>(
|
||||
context: context,
|
||||
builder: (BuildContext context) {
|
||||
|
||||
@ -26,7 +26,9 @@ class ScrollbarExample extends StatelessWidget {
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return CupertinoPageScaffold(
|
||||
navigationBar: const CupertinoNavigationBar(middle: Text('CupertinoScrollbar Sample')),
|
||||
navigationBar: const CupertinoNavigationBar(
|
||||
middle: Text('CupertinoScrollbar Sample'),
|
||||
),
|
||||
child: CupertinoScrollbar(
|
||||
thickness: 6.0,
|
||||
thicknessWhileDragging: 10.0,
|
||||
@ -36,7 +38,10 @@ class ScrollbarExample extends StatelessWidget {
|
||||
itemCount: 120,
|
||||
itemBuilder: (BuildContext context, int index) {
|
||||
return Center(
|
||||
child: Padding(padding: const EdgeInsets.all(8.0), child: Text('Item $index')),
|
||||
child: Padding(
|
||||
padding: const EdgeInsets.all(8.0),
|
||||
child: Text('Item $index'),
|
||||
),
|
||||
);
|
||||
},
|
||||
),
|
||||
|
||||
@ -33,7 +33,9 @@ class _ScrollbarExampleState extends State<ScrollbarExample> {
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return CupertinoPageScaffold(
|
||||
navigationBar: const CupertinoNavigationBar(middle: Text('CupertinoScrollbar Sample')),
|
||||
navigationBar: const CupertinoNavigationBar(
|
||||
middle: Text('CupertinoScrollbar Sample'),
|
||||
),
|
||||
child: CupertinoScrollbar(
|
||||
thickness: 6.0,
|
||||
thicknessWhileDragging: 10.0,
|
||||
@ -46,7 +48,10 @@ class _ScrollbarExampleState extends State<ScrollbarExample> {
|
||||
itemCount: 120,
|
||||
itemBuilder: (BuildContext context, int index) {
|
||||
return Center(
|
||||
child: Padding(padding: const EdgeInsets.all(8.0), child: Text('Item $index')),
|
||||
child: Padding(
|
||||
padding: const EdgeInsets.all(8.0),
|
||||
child: Text('Item $index'),
|
||||
),
|
||||
);
|
||||
},
|
||||
),
|
||||
|
||||
@ -45,11 +45,16 @@ class _SearchTextFieldExampleState extends State<SearchTextFieldExample> {
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return CupertinoPageScaffold(
|
||||
navigationBar: const CupertinoNavigationBar(middle: Text('CupertinoSearchTextField Sample')),
|
||||
navigationBar: const CupertinoNavigationBar(
|
||||
middle: Text('CupertinoSearchTextField Sample'),
|
||||
),
|
||||
child: Center(
|
||||
child: Padding(
|
||||
padding: const EdgeInsets.all(16.0),
|
||||
child: CupertinoSearchTextField(controller: textController, placeholder: 'Search'),
|
||||
child: CupertinoSearchTextField(
|
||||
controller: textController,
|
||||
placeholder: 'Search',
|
||||
),
|
||||
),
|
||||
),
|
||||
);
|
||||
|
||||
@ -33,7 +33,9 @@ class _SearchTextFieldExampleState extends State<SearchTextFieldExample> {
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return CupertinoPageScaffold(
|
||||
navigationBar: const CupertinoNavigationBar(middle: Text('CupertinoSearchTextField Sample')),
|
||||
navigationBar: const CupertinoNavigationBar(
|
||||
middle: Text('CupertinoSearchTextField Sample'),
|
||||
),
|
||||
child: Center(
|
||||
child: Column(
|
||||
mainAxisAlignment: MainAxisAlignment.center,
|
||||
|
||||
@ -32,7 +32,8 @@ class SegmentedControlExample extends StatefulWidget {
|
||||
const SegmentedControlExample({super.key});
|
||||
|
||||
@override
|
||||
State<SegmentedControlExample> createState() => _SegmentedControlExampleState();
|
||||
State<SegmentedControlExample> createState() =>
|
||||
_SegmentedControlExampleState();
|
||||
}
|
||||
|
||||
class _SegmentedControlExampleState extends State<SegmentedControlExample> {
|
||||
@ -88,7 +89,10 @@ class _SegmentedControlExampleState extends State<SegmentedControlExample> {
|
||||
Row(
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
children: <Widget>[
|
||||
const Text('Disable one segment', style: TextStyle(color: CupertinoColors.white)),
|
||||
const Text(
|
||||
'Disable one segment',
|
||||
style: TextStyle(color: CupertinoColors.white),
|
||||
),
|
||||
CupertinoSwitch(
|
||||
value: _toggleOne,
|
||||
onChanged: (bool value) {
|
||||
@ -109,7 +113,10 @@ class _SegmentedControlExampleState extends State<SegmentedControlExample> {
|
||||
Row(
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
children: <Widget>[
|
||||
const Text('Toggle all segments', style: TextStyle(color: CupertinoColors.white)),
|
||||
const Text(
|
||||
'Toggle all segments',
|
||||
style: TextStyle(color: CupertinoColors.white),
|
||||
),
|
||||
CupertinoSwitch(
|
||||
value: _toggleAll,
|
||||
onChanged: (bool value) {
|
||||
@ -119,7 +126,11 @@ class _SegmentedControlExampleState extends State<SegmentedControlExample> {
|
||||
_toggleOne = false;
|
||||
_disabledChildren = <Sky>{};
|
||||
} else {
|
||||
_disabledChildren = <Sky>{Sky.midnight, Sky.viridian, Sky.cerulean};
|
||||
_disabledChildren = <Sky>{
|
||||
Sky.midnight,
|
||||
Sky.viridian,
|
||||
Sky.cerulean,
|
||||
};
|
||||
}
|
||||
});
|
||||
},
|
||||
|
||||
@ -32,7 +32,8 @@ class SegmentedControlExample extends StatefulWidget {
|
||||
const SegmentedControlExample({super.key});
|
||||
|
||||
@override
|
||||
State<SegmentedControlExample> createState() => _SegmentedControlExampleState();
|
||||
State<SegmentedControlExample> createState() =>
|
||||
_SegmentedControlExampleState();
|
||||
}
|
||||
|
||||
class _SegmentedControlExampleState extends State<SegmentedControlExample> {
|
||||
@ -62,15 +63,24 @@ class _SegmentedControlExampleState extends State<SegmentedControlExample> {
|
||||
children: const <Sky, Widget>{
|
||||
Sky.midnight: Padding(
|
||||
padding: EdgeInsets.symmetric(horizontal: 20),
|
||||
child: Text('Midnight', style: TextStyle(color: CupertinoColors.white)),
|
||||
child: Text(
|
||||
'Midnight',
|
||||
style: TextStyle(color: CupertinoColors.white),
|
||||
),
|
||||
),
|
||||
Sky.viridian: Padding(
|
||||
padding: EdgeInsets.symmetric(horizontal: 20),
|
||||
child: Text('Viridian', style: TextStyle(color: CupertinoColors.white)),
|
||||
child: Text(
|
||||
'Viridian',
|
||||
style: TextStyle(color: CupertinoColors.white),
|
||||
),
|
||||
),
|
||||
Sky.cerulean: Padding(
|
||||
padding: EdgeInsets.symmetric(horizontal: 20),
|
||||
child: Text('Cerulean', style: TextStyle(color: CupertinoColors.white)),
|
||||
child: Text(
|
||||
'Cerulean',
|
||||
style: TextStyle(color: CupertinoColors.white),
|
||||
),
|
||||
),
|
||||
},
|
||||
),
|
||||
@ -87,7 +97,10 @@ class _SegmentedControlExampleState extends State<SegmentedControlExample> {
|
||||
Row(
|
||||
mainAxisAlignment: MainAxisAlignment.center,
|
||||
children: <Widget>[
|
||||
const Text('Momentary mode: ', style: TextStyle(color: CupertinoColors.white)),
|
||||
const Text(
|
||||
'Momentary mode: ',
|
||||
style: TextStyle(color: CupertinoColors.white),
|
||||
),
|
||||
CupertinoSwitch(
|
||||
value: _isMomentary,
|
||||
onChanged: (bool value) {
|
||||
|
||||
@ -38,7 +38,7 @@ class HomePage extends StatelessWidget {
|
||||
showCupertinoSheet<void>(
|
||||
context: context,
|
||||
useNestedNavigation: true,
|
||||
pageBuilder: (BuildContext context) => const _SheetScaffold(),
|
||||
builder: (BuildContext context) => const _SheetScaffold(),
|
||||
);
|
||||
},
|
||||
child: const Text('Open Bottom Sheet'),
|
||||
@ -55,7 +55,9 @@ class _SheetScaffold extends StatelessWidget {
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return const CupertinoPageScaffold(child: _SheetBody(title: 'CupertinoSheetRoute'));
|
||||
return const CupertinoPageScaffold(
|
||||
child: _SheetBody(title: 'CupertinoSheetRoute'),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@ -86,7 +88,9 @@ class _SheetBody extends StatelessWidget {
|
||||
CupertinoButton.filled(
|
||||
onPressed: () {
|
||||
Navigator.of(context).push(
|
||||
CupertinoPageRoute<void>(builder: (BuildContext context) => const _SheetNextPage()),
|
||||
CupertinoPageRoute<void>(
|
||||
builder: (BuildContext context) => const _SheetNextPage(),
|
||||
),
|
||||
);
|
||||
},
|
||||
child: const Text('Push Nested Page'),
|
||||
@ -96,7 +100,7 @@ class _SheetBody extends StatelessWidget {
|
||||
showCupertinoSheet<void>(
|
||||
context: context,
|
||||
useNestedNavigation: true,
|
||||
pageBuilder: (BuildContext context) => const _SheetScaffold(),
|
||||
builder: (BuildContext context) => const _SheetScaffold(),
|
||||
);
|
||||
},
|
||||
child: const Text('Push Another Sheet'),
|
||||
|
||||
@ -31,7 +31,8 @@ class RestorableSheet extends StatefulWidget {
|
||||
}
|
||||
|
||||
@pragma('vm:entry-point')
|
||||
class _RestorableSheetState extends State<RestorableSheet> with RestorationMixin {
|
||||
class _RestorableSheetState extends State<RestorableSheet>
|
||||
with RestorationMixin {
|
||||
final RestorableInt _counter = RestorableInt(0);
|
||||
late RestorableRouteFuture<int?> _restorableSheetRouteFuture;
|
||||
|
||||
@ -41,7 +42,10 @@ class _RestorableSheetState extends State<RestorableSheet> with RestorationMixin
|
||||
_restorableSheetRouteFuture = RestorableRouteFuture<int?>(
|
||||
onComplete: _changeCounter,
|
||||
onPresent: (NavigatorState navigator, Object? arguments) {
|
||||
return navigator.restorablePush(_counterSheetBuilder, arguments: _counter.value);
|
||||
return navigator.restorablePush(
|
||||
_counterSheetBuilder,
|
||||
arguments: _counter.value,
|
||||
);
|
||||
},
|
||||
);
|
||||
}
|
||||
@ -62,7 +66,10 @@ class _RestorableSheetState extends State<RestorableSheet> with RestorationMixin
|
||||
}
|
||||
|
||||
@pragma('vm:entry-point')
|
||||
static Route<void> _counterSheetBuilder(BuildContext context, Object? arguments) {
|
||||
static Route<void> _counterSheetBuilder(
|
||||
BuildContext context,
|
||||
Object? arguments,
|
||||
) {
|
||||
return CupertinoSheetRoute<int?>(
|
||||
builder: (BuildContext context) {
|
||||
return Navigator(
|
||||
@ -132,7 +139,8 @@ class CounterSheetScaffold extends StatefulWidget {
|
||||
State<CounterSheetScaffold> createState() => _CounterSheetScaffoldState();
|
||||
}
|
||||
|
||||
class _CounterSheetScaffoldState extends State<CounterSheetScaffold> with RestorationMixin {
|
||||
class _CounterSheetScaffoldState extends State<CounterSheetScaffold>
|
||||
with RestorationMixin {
|
||||
late RestorableInt _counter;
|
||||
late RestorableRouteFuture<int?> _multiplicationRouteFuture;
|
||||
|
||||
@ -143,13 +151,19 @@ class _CounterSheetScaffoldState extends State<CounterSheetScaffold> with Restor
|
||||
_multiplicationRouteFuture = RestorableRouteFuture<int?>(
|
||||
onComplete: _changeCounter,
|
||||
onPresent: (NavigatorState navigator, Object? arguments) {
|
||||
return navigator.restorablePush(_multiplicationRouteBuilder, arguments: _counter.value);
|
||||
return navigator.restorablePush(
|
||||
_multiplicationRouteBuilder,
|
||||
arguments: _counter.value,
|
||||
);
|
||||
},
|
||||
);
|
||||
}
|
||||
|
||||
@pragma('vm:entry-point')
|
||||
static Route<void> _multiplicationRouteBuilder(BuildContext context, Object? arguments) {
|
||||
static Route<void> _multiplicationRouteBuilder(
|
||||
BuildContext context,
|
||||
Object? arguments,
|
||||
) {
|
||||
return CupertinoPageRoute<int?>(
|
||||
settings: const RouteSettings(name: '/multiplication'),
|
||||
builder: (BuildContext context) {
|
||||
@ -215,7 +229,10 @@ class _CounterSheetScaffoldState extends State<CounterSheetScaffold> with Restor
|
||||
child: const Text('Go to Multiplication Page'),
|
||||
),
|
||||
CupertinoButton(
|
||||
onPressed: () => Navigator.of(context, rootNavigator: true).pop(_counter.value),
|
||||
onPressed: () => Navigator.of(
|
||||
context,
|
||||
rootNavigator: true,
|
||||
).pop(_counter.value),
|
||||
child: const Text('Pop Sheet'),
|
||||
),
|
||||
],
|
||||
@ -234,7 +251,8 @@ class MultiplicationPage extends StatefulWidget {
|
||||
State<MultiplicationPage> createState() => _MultiplicationPageState();
|
||||
}
|
||||
|
||||
class _MultiplicationPageState extends State<MultiplicationPage> with RestorationMixin {
|
||||
class _MultiplicationPageState extends State<MultiplicationPage>
|
||||
with RestorationMixin {
|
||||
late final RestorableInt _counter = RestorableInt(widget.counter);
|
||||
|
||||
@override
|
||||
|
||||
@ -34,7 +34,9 @@ class _CupertinoSliderExampleState extends State<CupertinoSliderExample> {
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return CupertinoPageScaffold(
|
||||
navigationBar: const CupertinoNavigationBar(middle: Text('CupertinoSlider Sample')),
|
||||
navigationBar: const CupertinoNavigationBar(
|
||||
middle: Text('CupertinoSlider Sample'),
|
||||
),
|
||||
child: Center(
|
||||
child: Column(
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
@ -72,7 +74,9 @@ class _CupertinoSliderExampleState extends State<CupertinoSliderExample> {
|
||||
),
|
||||
Text(
|
||||
_sliderStatus ?? '',
|
||||
style: CupertinoTheme.of(context).textTheme.textStyle.copyWith(fontSize: 12),
|
||||
style: CupertinoTheme.of(
|
||||
context,
|
||||
).textTheme.textStyle.copyWith(fontSize: 12),
|
||||
),
|
||||
],
|
||||
),
|
||||
|
||||
@ -33,7 +33,9 @@ class _CupertinoSwitchExampleState extends State<CupertinoSwitchExample> {
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return CupertinoPageScaffold(
|
||||
navigationBar: const CupertinoNavigationBar(middle: Text('CupertinoSwitch Sample')),
|
||||
navigationBar: const CupertinoNavigationBar(
|
||||
middle: Text('CupertinoSwitch Sample'),
|
||||
),
|
||||
child: Center(
|
||||
child: CupertinoSwitch(
|
||||
// This bool value toggles the switch.
|
||||
|
||||
@ -42,8 +42,14 @@ class _TabControllerExampleState extends State<TabControllerExample> {
|
||||
controller: controller,
|
||||
tabBar: CupertinoTabBar(
|
||||
items: const <BottomNavigationBarItem>[
|
||||
BottomNavigationBarItem(icon: Icon(CupertinoIcons.square_grid_2x2_fill), label: 'Browse'),
|
||||
BottomNavigationBarItem(icon: Icon(CupertinoIcons.star_circle_fill), label: 'Starred'),
|
||||
BottomNavigationBarItem(
|
||||
icon: Icon(CupertinoIcons.square_grid_2x2_fill),
|
||||
label: 'Browse',
|
||||
),
|
||||
BottomNavigationBarItem(
|
||||
icon: Icon(CupertinoIcons.star_circle_fill),
|
||||
label: 'Starred',
|
||||
),
|
||||
],
|
||||
),
|
||||
tabBuilder: (BuildContext context, int index) {
|
||||
|
||||
@ -33,15 +33,23 @@ class _TabScaffoldExampleState extends State<TabScaffoldExample> {
|
||||
return CupertinoTabScaffold(
|
||||
tabBar: CupertinoTabBar(
|
||||
items: const <BottomNavigationBarItem>[
|
||||
BottomNavigationBarItem(icon: Icon(CupertinoIcons.home), label: 'Home'),
|
||||
BottomNavigationBarItem(icon: Icon(CupertinoIcons.search_circle_fill), label: 'Explore'),
|
||||
BottomNavigationBarItem(
|
||||
icon: Icon(CupertinoIcons.home),
|
||||
label: 'Home',
|
||||
),
|
||||
BottomNavigationBarItem(
|
||||
icon: Icon(CupertinoIcons.search_circle_fill),
|
||||
label: 'Explore',
|
||||
),
|
||||
],
|
||||
),
|
||||
tabBuilder: (BuildContext context, int index) {
|
||||
return CupertinoTabView(
|
||||
builder: (BuildContext context) {
|
||||
return CupertinoPageScaffold(
|
||||
navigationBar: CupertinoNavigationBar(middle: Text('Page 1 of tab $index')),
|
||||
navigationBar: CupertinoNavigationBar(
|
||||
middle: Text('Page 1 of tab $index'),
|
||||
),
|
||||
child: Center(
|
||||
child: CupertinoButton(
|
||||
child: const Text('Next page'),
|
||||
|
||||
@ -24,7 +24,8 @@ class CupertinoTextFieldExample extends StatefulWidget {
|
||||
const CupertinoTextFieldExample({super.key});
|
||||
|
||||
@override
|
||||
State<CupertinoTextFieldExample> createState() => _CupertinoTextFieldExampleState();
|
||||
State<CupertinoTextFieldExample> createState() =>
|
||||
_CupertinoTextFieldExampleState();
|
||||
}
|
||||
|
||||
class _CupertinoTextFieldExampleState extends State<CupertinoTextFieldExample> {
|
||||
@ -45,7 +46,9 @@ class _CupertinoTextFieldExampleState extends State<CupertinoTextFieldExample> {
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return CupertinoPageScaffold(
|
||||
navigationBar: const CupertinoNavigationBar(middle: Text('CupertinoTextField Sample')),
|
||||
navigationBar: const CupertinoNavigationBar(
|
||||
middle: Text('CupertinoTextField Sample'),
|
||||
),
|
||||
child: Center(child: CupertinoTextField(controller: _textController)),
|
||||
);
|
||||
}
|
||||
|
||||
@ -26,7 +26,9 @@ class FromSectionExample extends StatelessWidget {
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return CupertinoPageScaffold(
|
||||
navigationBar: const CupertinoNavigationBar(middle: Text('CupertinoFormSection Sample')),
|
||||
navigationBar: const CupertinoNavigationBar(
|
||||
middle: Text('CupertinoFormSection Sample'),
|
||||
),
|
||||
// Add safe area widget to place the CupertinoFormSection below the navigation bar.
|
||||
child: SafeArea(
|
||||
child: Form(
|
||||
|
||||
@ -71,7 +71,10 @@ class _ColorChangerState extends State<ColorChanger> {
|
||||
},
|
||||
child: Stack(
|
||||
fit: StackFit.expand,
|
||||
children: <Widget>[const AbsorbPointer(), if (widget.child != null) widget.child!],
|
||||
children: <Widget>[
|
||||
const AbsorbPointer(),
|
||||
if (widget.child != null) widget.child!,
|
||||
],
|
||||
),
|
||||
),
|
||||
);
|
||||
@ -82,10 +85,12 @@ class PointerSignalResolverExample extends StatefulWidget {
|
||||
const PointerSignalResolverExample({super.key});
|
||||
|
||||
@override
|
||||
State<PointerSignalResolverExample> createState() => _PointerSignalResolverExampleState();
|
||||
State<PointerSignalResolverExample> createState() =>
|
||||
_PointerSignalResolverExampleState();
|
||||
}
|
||||
|
||||
class _PointerSignalResolverExampleState extends State<PointerSignalResolverExample> {
|
||||
class _PointerSignalResolverExampleState
|
||||
extends State<PointerSignalResolverExample> {
|
||||
bool useResolver = false;
|
||||
|
||||
@override
|
||||
|
||||
@ -64,8 +64,10 @@ class _TapAndDragToZoomWidgetState extends State<TapAndDragToZoomWidget> {
|
||||
}
|
||||
|
||||
void _zoomLogic(Offset currentDragPosition) {
|
||||
final double dx = (_previousDragPosition!.dx - currentDragPosition.dx).abs();
|
||||
final double dy = (_previousDragPosition!.dy - currentDragPosition.dy).abs();
|
||||
final double dx = (_previousDragPosition!.dx - currentDragPosition.dx)
|
||||
.abs();
|
||||
final double dy = (_previousDragPosition!.dy - currentDragPosition.dy)
|
||||
.abs();
|
||||
|
||||
if (dx > dy) {
|
||||
// Ignore horizontal drags.
|
||||
|
||||
@ -15,8 +15,13 @@ class _CustomEndDrawerIcon extends StatelessWidget {
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
final MaterialLocalizations localization = MaterialLocalizations.of(context);
|
||||
return Icon(Icons.more_horiz, semanticLabel: localization.openAppDrawerTooltip);
|
||||
final MaterialLocalizations localization = MaterialLocalizations.of(
|
||||
context,
|
||||
);
|
||||
return Icon(
|
||||
Icons.more_horiz,
|
||||
semanticLabel: localization.openAppDrawerTooltip,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@ -25,8 +30,13 @@ class _CustomDrawerIcon extends StatelessWidget {
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
final MaterialLocalizations localization = MaterialLocalizations.of(context);
|
||||
return Icon(Icons.segment, semanticLabel: localization.openAppDrawerTooltip);
|
||||
final MaterialLocalizations localization = MaterialLocalizations.of(
|
||||
context,
|
||||
);
|
||||
return Icon(
|
||||
Icons.segment,
|
||||
semanticLabel: localization.openAppDrawerTooltip,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@ -66,7 +76,9 @@ class MyHomePage extends StatelessWidget {
|
||||
appBar: AppBar(title: Text(title)),
|
||||
drawer: Drawer(
|
||||
child: Column(
|
||||
children: <Widget>[TextButton(child: const Text('Drawer Item'), onPressed: () {})],
|
||||
children: <Widget>[
|
||||
TextButton(child: const Text('Drawer Item'), onPressed: () {}),
|
||||
],
|
||||
),
|
||||
),
|
||||
body: const Center(child: NextPageButton()),
|
||||
|
||||
@ -37,9 +37,10 @@ class _AnimatedIconExampleState extends State<AnimatedIconExample>
|
||||
@override
|
||||
void initState() {
|
||||
super.initState();
|
||||
controller = AnimationController(vsync: this, duration: const Duration(seconds: 2))
|
||||
..forward()
|
||||
..repeat(reverse: true);
|
||||
controller =
|
||||
AnimationController(vsync: this, duration: const Duration(seconds: 2))
|
||||
..forward()
|
||||
..repeat(reverse: true);
|
||||
animation = Tween<double>(begin: 0.0, end: 1.0).animate(controller);
|
||||
}
|
||||
|
||||
|
||||
@ -54,9 +54,10 @@ class _AnimatedIconExampleState extends State<AnimatedIconExample>
|
||||
@override
|
||||
void initState() {
|
||||
super.initState();
|
||||
controller = AnimationController(vsync: this, duration: const Duration(seconds: 2))
|
||||
..forward()
|
||||
..repeat(reverse: true);
|
||||
controller =
|
||||
AnimationController(vsync: this, duration: const Duration(seconds: 2))
|
||||
..forward()
|
||||
..repeat(reverse: true);
|
||||
animation = Tween<double>(begin: 0.0, end: 1.0).animate(controller);
|
||||
}
|
||||
|
||||
@ -70,8 +71,12 @@ class _AnimatedIconExampleState extends State<AnimatedIconExample>
|
||||
Widget build(BuildContext context) {
|
||||
return Scaffold(
|
||||
body: GridView(
|
||||
gridDelegate: const SliverGridDelegateWithFixedCrossAxisCount(crossAxisCount: 4),
|
||||
children: iconsList.entries.map((MapEntry<String, AnimatedIconData> entry) {
|
||||
gridDelegate: const SliverGridDelegateWithFixedCrossAxisCount(
|
||||
crossAxisCount: 4,
|
||||
),
|
||||
children: iconsList.entries.map((
|
||||
MapEntry<String, AnimatedIconData> entry,
|
||||
) {
|
||||
return Card(
|
||||
child: Center(
|
||||
child: Column(
|
||||
|
||||
@ -12,11 +12,12 @@ void main() {
|
||||
|
||||
enum AnimationStyles { defaultStyle, custom, none }
|
||||
|
||||
const List<(AnimationStyles, String)> animationStyleSegments = <(AnimationStyles, String)>[
|
||||
(AnimationStyles.defaultStyle, 'Default'),
|
||||
(AnimationStyles.custom, 'Custom'),
|
||||
(AnimationStyles.none, 'None'),
|
||||
];
|
||||
const List<(AnimationStyles, String)> animationStyleSegments =
|
||||
<(AnimationStyles, String)>[
|
||||
(AnimationStyles.defaultStyle, 'Default'),
|
||||
(AnimationStyles.custom, 'Custom'),
|
||||
(AnimationStyles.none, 'None'),
|
||||
];
|
||||
|
||||
class MaterialAppExample extends StatefulWidget {
|
||||
const MaterialAppExample({super.key});
|
||||
@ -26,7 +27,9 @@ class MaterialAppExample extends StatefulWidget {
|
||||
}
|
||||
|
||||
class _MaterialAppExampleState extends State<MaterialAppExample> {
|
||||
Set<AnimationStyles> _animationStyleSelection = <AnimationStyles>{AnimationStyles.defaultStyle};
|
||||
Set<AnimationStyles> _animationStyleSelection = <AnimationStyles>{
|
||||
AnimationStyles.defaultStyle,
|
||||
};
|
||||
AnimationStyle? _animationStyle;
|
||||
bool isDarkTheme = false;
|
||||
|
||||
@ -36,7 +39,10 @@ class _MaterialAppExampleState extends State<MaterialAppExample> {
|
||||
themeAnimationStyle: _animationStyle,
|
||||
themeMode: isDarkTheme ? ThemeMode.dark : ThemeMode.light,
|
||||
theme: ThemeData(colorSchemeSeed: Colors.green),
|
||||
darkTheme: ThemeData(colorSchemeSeed: Colors.green, brightness: Brightness.dark),
|
||||
darkTheme: ThemeData(
|
||||
colorSchemeSeed: Colors.green,
|
||||
brightness: Brightness.dark,
|
||||
),
|
||||
home: Scaffold(
|
||||
body: Center(
|
||||
child: Column(
|
||||
@ -60,11 +66,16 @@ class _MaterialAppExampleState extends State<MaterialAppExample> {
|
||||
}
|
||||
});
|
||||
},
|
||||
segments: animationStyleSegments.map<ButtonSegment<AnimationStyles>>((
|
||||
(AnimationStyles, String) shirt,
|
||||
) {
|
||||
return ButtonSegment<AnimationStyles>(value: shirt.$1, label: Text(shirt.$2));
|
||||
}).toList(),
|
||||
segments: animationStyleSegments
|
||||
.map<ButtonSegment<AnimationStyles>>((
|
||||
(AnimationStyles, String) shirt,
|
||||
) {
|
||||
return ButtonSegment<AnimationStyles>(
|
||||
value: shirt.$1,
|
||||
label: Text(shirt.$2),
|
||||
);
|
||||
})
|
||||
.toList(),
|
||||
),
|
||||
const SizedBox(height: 10),
|
||||
OutlinedButton.icon(
|
||||
@ -73,7 +84,9 @@ class _MaterialAppExampleState extends State<MaterialAppExample> {
|
||||
isDarkTheme = !isDarkTheme;
|
||||
});
|
||||
},
|
||||
icon: Icon(isDarkTheme ? Icons.wb_sunny : Icons.nightlight_round),
|
||||
icon: Icon(
|
||||
isDarkTheme ? Icons.wb_sunny : Icons.nightlight_round,
|
||||
),
|
||||
label: const Text('Switch Theme Mode'),
|
||||
),
|
||||
],
|
||||
|
||||
@ -30,9 +30,9 @@ class AppBarExample extends StatelessWidget {
|
||||
icon: const Icon(Icons.add_alert),
|
||||
tooltip: 'Show Snackbar',
|
||||
onPressed: () {
|
||||
ScaffoldMessenger.of(
|
||||
context,
|
||||
).showSnackBar(const SnackBar(content: Text('This is a snackbar')));
|
||||
ScaffoldMessenger.of(context).showSnackBar(
|
||||
const SnackBar(content: Text('This is a snackbar')),
|
||||
);
|
||||
},
|
||||
),
|
||||
IconButton(
|
||||
@ -46,7 +46,10 @@ class AppBarExample extends StatelessWidget {
|
||||
return Scaffold(
|
||||
appBar: AppBar(title: const Text('Next page')),
|
||||
body: const Center(
|
||||
child: Text('This is the next page', style: TextStyle(fontSize: 24)),
|
||||
child: Text(
|
||||
'This is the next page',
|
||||
style: TextStyle(fontSize: 24),
|
||||
),
|
||||
),
|
||||
);
|
||||
},
|
||||
@ -56,7 +59,9 @@ class AppBarExample extends StatelessWidget {
|
||||
),
|
||||
],
|
||||
),
|
||||
body: const Center(child: Text('This is the home page', style: TextStyle(fontSize: 24))),
|
||||
body: const Center(
|
||||
child: Text('This is the home page', style: TextStyle(fontSize: 24)),
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@ -36,8 +36,8 @@ class _AppBarExampleState extends State<AppBarExample> {
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
final ColorScheme colorScheme = Theme.of(context).colorScheme;
|
||||
final Color oddItemColor = colorScheme.primary.withOpacity(0.05);
|
||||
final Color evenItemColor = colorScheme.primary.withOpacity(0.15);
|
||||
final Color oddItemColor = colorScheme.primary.withValues(alpha: 0.05);
|
||||
final Color evenItemColor = colorScheme.primary.withValues(alpha: 0.15);
|
||||
|
||||
return Scaffold(
|
||||
appBar: AppBar(
|
||||
@ -89,7 +89,9 @@ class _AppBarExampleState extends State<AppBarExample> {
|
||||
shadowColor = !shadowColor;
|
||||
});
|
||||
},
|
||||
icon: Icon(shadowColor ? Icons.visibility_off : Icons.visibility),
|
||||
icon: Icon(
|
||||
shadowColor ? Icons.visibility_off : Icons.visibility,
|
||||
),
|
||||
label: const Text('shadow color'),
|
||||
),
|
||||
const SizedBox(width: 5),
|
||||
@ -106,7 +108,9 @@ class _AppBarExampleState extends State<AppBarExample> {
|
||||
});
|
||||
}
|
||||
},
|
||||
child: Text('scrolledUnderElevation: ${scrolledUnderElevation ?? 'default'}'),
|
||||
child: Text(
|
||||
'scrolledUnderElevation: ${scrolledUnderElevation ?? 'default'}',
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
|
||||
@ -28,8 +28,16 @@ class AppBarExample extends StatelessWidget {
|
||||
return Scaffold(
|
||||
appBar: AppBar(
|
||||
actions: <Widget>[
|
||||
TextButton(style: style, onPressed: () {}, child: const Text('Action 1')),
|
||||
TextButton(style: style, onPressed: () {}, child: const Text('Action 2')),
|
||||
TextButton(
|
||||
style: style,
|
||||
onPressed: () {},
|
||||
child: const Text('Action 1'),
|
||||
),
|
||||
TextButton(
|
||||
style: style,
|
||||
onPressed: () {},
|
||||
child: const Text('Action 2'),
|
||||
),
|
||||
],
|
||||
),
|
||||
);
|
||||
|
||||
@ -28,8 +28,8 @@ class AppBarExample extends StatelessWidget {
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
final ColorScheme colorScheme = Theme.of(context).colorScheme;
|
||||
final Color oddItemColor = colorScheme.primary.withOpacity(0.05);
|
||||
final Color evenItemColor = colorScheme.primary.withOpacity(0.15);
|
||||
final Color oddItemColor = colorScheme.primary.withValues(alpha: 0.05);
|
||||
final Color evenItemColor = colorScheme.primary.withValues(alpha: 0.15);
|
||||
const int tabsCount = 3;
|
||||
|
||||
return DefaultTabController(
|
||||
|
||||
@ -35,15 +35,23 @@ class AppBarExample extends StatelessWidget {
|
||||
padding: const EdgeInsets.symmetric(horizontal: 16.0),
|
||||
child: TextField(
|
||||
decoration: InputDecoration(
|
||||
border: OutlineInputBorder(borderSide: BorderSide(color: colorScheme.primary)),
|
||||
border: OutlineInputBorder(
|
||||
borderSide: BorderSide(color: colorScheme.primary),
|
||||
),
|
||||
enabledBorder: OutlineInputBorder(
|
||||
borderSide: BorderSide(color: colorScheme.onPrimaryContainer),
|
||||
),
|
||||
filled: true,
|
||||
hintText: 'Enter a search term',
|
||||
fillColor: colorScheme.surface,
|
||||
prefixIcon: Icon(Icons.search_rounded, color: colorScheme.primary),
|
||||
suffixIcon: Icon(Icons.tune_rounded, color: colorScheme.primary),
|
||||
prefixIcon: Icon(
|
||||
Icons.search_rounded,
|
||||
color: colorScheme.primary,
|
||||
),
|
||||
suffixIcon: Icon(
|
||||
Icons.tune_rounded,
|
||||
color: colorScheme.primary,
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
@ -74,7 +82,12 @@ class CustomAppBarShape extends OutlinedBorder {
|
||||
|
||||
final Offset controlPoint = Offset(size.width * 0.4, size.height);
|
||||
final Offset endPoint = Offset(size.width, size.height / 2);
|
||||
path.quadraticBezierTo(controlPoint.dx, controlPoint.dy, endPoint.dx, endPoint.dy);
|
||||
path.quadraticBezierTo(
|
||||
controlPoint.dx,
|
||||
controlPoint.dy,
|
||||
endPoint.dx,
|
||||
endPoint.dy,
|
||||
);
|
||||
|
||||
path.lineTo(size.width, 0.0);
|
||||
path.close();
|
||||
@ -97,7 +110,10 @@ class CustomAppBarShape extends OutlinedBorder {
|
||||
if (rect.isEmpty) {
|
||||
return;
|
||||
}
|
||||
canvas.drawPath(getOuterPath(rect, textDirection: textDirection), side.toPaint());
|
||||
canvas.drawPath(
|
||||
getOuterPath(rect, textDirection: textDirection),
|
||||
side.toPaint(),
|
||||
);
|
||||
}
|
||||
|
||||
@override
|
||||
|
||||
@ -49,7 +49,9 @@ class _SliverAppBarExampleState extends State<SliverAppBarExample> {
|
||||
const SliverToBoxAdapter(
|
||||
child: SizedBox(
|
||||
height: 20,
|
||||
child: Center(child: Text('Scroll to see the SliverAppBar in effect.')),
|
||||
child: Center(
|
||||
child: Text('Scroll to see the SliverAppBar in effect.'),
|
||||
),
|
||||
),
|
||||
),
|
||||
SliverList.builder(
|
||||
@ -58,7 +60,9 @@ class _SliverAppBarExampleState extends State<SliverAppBarExample> {
|
||||
return Container(
|
||||
color: index.isOdd ? Colors.white : Colors.black12,
|
||||
height: 100.0,
|
||||
child: Center(child: Text('$index', textScaler: const TextScaler.linear(5))),
|
||||
child: Center(
|
||||
child: Text('$index', textScaler: const TextScaler.linear(5)),
|
||||
),
|
||||
);
|
||||
},
|
||||
),
|
||||
|
||||
@ -21,9 +21,14 @@ class AppBarMediumApp extends StatelessWidget {
|
||||
child: CustomScrollView(
|
||||
slivers: <Widget>[
|
||||
SliverAppBar.medium(
|
||||
leading: IconButton(icon: const Icon(Icons.menu), onPressed: () {}),
|
||||
leading: IconButton(
|
||||
icon: const Icon(Icons.menu),
|
||||
onPressed: () {},
|
||||
),
|
||||
title: const Text('Medium App Bar'),
|
||||
actions: <Widget>[IconButton(icon: const Icon(Icons.more_vert), onPressed: () {})],
|
||||
actions: <Widget>[
|
||||
IconButton(icon: const Icon(Icons.more_vert), onPressed: () {}),
|
||||
],
|
||||
),
|
||||
// Just some content big enough to have something to scroll.
|
||||
SliverToBoxAdapter(
|
||||
|
||||
@ -21,9 +21,14 @@ class AppBarLargeApp extends StatelessWidget {
|
||||
child: CustomScrollView(
|
||||
slivers: <Widget>[
|
||||
SliverAppBar.large(
|
||||
leading: IconButton(icon: const Icon(Icons.menu), onPressed: () {}),
|
||||
leading: IconButton(
|
||||
icon: const Icon(Icons.menu),
|
||||
onPressed: () {},
|
||||
),
|
||||
title: const Text('Large App Bar'),
|
||||
actions: <Widget>[IconButton(icon: const Icon(Icons.more_vert), onPressed: () {})],
|
||||
actions: <Widget>[
|
||||
IconButton(icon: const Icon(Icons.more_vert), onPressed: () {}),
|
||||
],
|
||||
),
|
||||
// Just some content big enough to have something to scroll.
|
||||
SliverToBoxAdapter(
|
||||
|
||||
@ -14,7 +14,8 @@ class StretchableSliverAppBar extends StatefulWidget {
|
||||
const StretchableSliverAppBar({super.key});
|
||||
|
||||
@override
|
||||
State<StretchableSliverAppBar> createState() => _StretchableSliverAppBarState();
|
||||
State<StretchableSliverAppBar> createState() =>
|
||||
_StretchableSliverAppBarState();
|
||||
}
|
||||
|
||||
class _StretchableSliverAppBarState extends State<StretchableSliverAppBar> {
|
||||
@ -49,7 +50,12 @@ class _StretchableSliverAppBarState extends State<StretchableSliverAppBar> {
|
||||
return Container(
|
||||
color: index.isOdd ? Colors.white : Colors.black12,
|
||||
height: 100.0,
|
||||
child: Center(child: Text('$index', textScaler: const TextScaler.linear(5.0))),
|
||||
child: Center(
|
||||
child: Text(
|
||||
'$index',
|
||||
textScaler: const TextScaler.linear(5.0),
|
||||
),
|
||||
),
|
||||
);
|
||||
},
|
||||
),
|
||||
|
||||
@ -35,7 +35,11 @@ class AutocompleteExampleApp extends StatelessWidget {
|
||||
class AutocompleteBasicExample extends StatelessWidget {
|
||||
const AutocompleteBasicExample({super.key});
|
||||
|
||||
static const List<String> _kOptions = <String>['aardvark', 'bobcat', 'chameleon'];
|
||||
static const List<String> _kOptions = <String>[
|
||||
'aardvark',
|
||||
'bobcat',
|
||||
'chameleon',
|
||||
];
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
|
||||
@ -76,7 +76,9 @@ class AutocompleteBasicUserExample extends StatelessWidget {
|
||||
return const Iterable<User>.empty();
|
||||
}
|
||||
return _userOptions.where((User option) {
|
||||
return option.toString().contains(textEditingValue.text.toLowerCase());
|
||||
return option.toString().contains(
|
||||
textEditingValue.text.toLowerCase(),
|
||||
);
|
||||
});
|
||||
},
|
||||
onSelected: (User selection) {
|
||||
|
||||
@ -55,7 +55,9 @@ class _AsyncAutocompleteState extends State<_AsyncAutocomplete> {
|
||||
return Autocomplete<String>(
|
||||
optionsBuilder: (TextEditingValue textEditingValue) async {
|
||||
_searchingWithQuery = textEditingValue.text;
|
||||
final Iterable<String> options = await _FakeAPI.search(_searchingWithQuery!);
|
||||
final Iterable<String> options = await _FakeAPI.search(
|
||||
_searchingWithQuery!,
|
||||
);
|
||||
|
||||
// If another search happened after this one, throw away these options.
|
||||
// Use the previous options instead and wait for the newer request to
|
||||
@ -76,7 +78,11 @@ class _AsyncAutocompleteState extends State<_AsyncAutocomplete> {
|
||||
|
||||
// Mimics a remote API.
|
||||
class _FakeAPI {
|
||||
static const List<String> _kOptions = <String>['aardvark', 'bobcat', 'chameleon'];
|
||||
static const List<String> _kOptions = <String>[
|
||||
'aardvark',
|
||||
'bobcat',
|
||||
'chameleon',
|
||||
];
|
||||
|
||||
// Searches the options, but injects a fake "network" delay.
|
||||
static Future<Iterable<String>> search(String query) async {
|
||||
|
||||
@ -21,7 +21,9 @@ class AutocompleteExampleApp extends StatelessWidget {
|
||||
Widget build(BuildContext context) {
|
||||
return MaterialApp(
|
||||
home: Scaffold(
|
||||
appBar: AppBar(title: const Text('Autocomplete - async and debouncing')),
|
||||
appBar: AppBar(
|
||||
title: const Text('Autocomplete - async and debouncing'),
|
||||
),
|
||||
body: Center(
|
||||
child: Column(
|
||||
mainAxisAlignment: MainAxisAlignment.center,
|
||||
@ -82,7 +84,9 @@ class _AsyncAutocompleteState extends State<_AsyncAutocomplete> {
|
||||
Widget build(BuildContext context) {
|
||||
return Autocomplete<String>(
|
||||
optionsBuilder: (TextEditingValue textEditingValue) async {
|
||||
final Iterable<String>? options = await _debouncedSearch(textEditingValue.text);
|
||||
final Iterable<String>? options = await _debouncedSearch(
|
||||
textEditingValue.text,
|
||||
);
|
||||
if (options == null) {
|
||||
return _lastOptions;
|
||||
}
|
||||
@ -98,7 +102,11 @@ class _AsyncAutocompleteState extends State<_AsyncAutocomplete> {
|
||||
|
||||
// Mimics a remote API.
|
||||
class _FakeAPI {
|
||||
static const List<String> _kOptions = <String>['aardvark', 'bobcat', 'chameleon'];
|
||||
static const List<String> _kOptions = <String>[
|
||||
'aardvark',
|
||||
'bobcat',
|
||||
'chameleon',
|
||||
];
|
||||
|
||||
// Searches the options, but injects a fake "network" delay.
|
||||
static Future<Iterable<String>> search(String query) async {
|
||||
|
||||
@ -22,7 +22,11 @@ class AutocompleteExampleApp extends StatelessWidget {
|
||||
Widget build(BuildContext context) {
|
||||
return MaterialApp(
|
||||
home: Scaffold(
|
||||
appBar: AppBar(title: const Text('Autocomplete - async, debouncing, and network errors')),
|
||||
appBar: AppBar(
|
||||
title: const Text(
|
||||
'Autocomplete - async, debouncing, and network errors',
|
||||
),
|
||||
),
|
||||
body: Center(
|
||||
child: Column(
|
||||
mainAxisAlignment: MainAxisAlignment.center,
|
||||
@ -124,7 +128,9 @@ class _AsyncAutocompleteState extends State<_AsyncAutocomplete> {
|
||||
) {
|
||||
return TextFormField(
|
||||
decoration: InputDecoration(
|
||||
errorText: _networkError ? 'Network error, please try again.' : null,
|
||||
errorText: _networkError
|
||||
? 'Network error, please try again.'
|
||||
: null,
|
||||
),
|
||||
controller: controller,
|
||||
focusNode: focusNode,
|
||||
@ -137,7 +143,9 @@ class _AsyncAutocompleteState extends State<_AsyncAutocomplete> {
|
||||
setState(() {
|
||||
_networkError = false;
|
||||
});
|
||||
final Iterable<String>? options = await _debouncedSearch(textEditingValue.text);
|
||||
final Iterable<String>? options = await _debouncedSearch(
|
||||
textEditingValue.text,
|
||||
);
|
||||
if (options == null) {
|
||||
return _lastOptions;
|
||||
}
|
||||
@ -155,10 +163,17 @@ class _AsyncAutocompleteState extends State<_AsyncAutocomplete> {
|
||||
|
||||
// Mimics a remote API.
|
||||
class _FakeAPI {
|
||||
static const List<String> _kOptions = <String>['aardvark', 'bobcat', 'chameleon'];
|
||||
static const List<String> _kOptions = <String>[
|
||||
'aardvark',
|
||||
'bobcat',
|
||||
'chameleon',
|
||||
];
|
||||
|
||||
// Searches the options, but injects a fake "network" delay.
|
||||
static Future<Iterable<String>> search(String query, bool networkEnabled) async {
|
||||
static Future<Iterable<String>> search(
|
||||
String query,
|
||||
bool networkEnabled,
|
||||
) async {
|
||||
await Future<void>.delayed(fakeAPIDuration); // Fake 1 second delay.
|
||||
if (!networkEnabled) {
|
||||
throw const _NetworkException();
|
||||
|
||||
@ -41,7 +41,10 @@ class BadgeExample extends StatelessWidget {
|
||||
),
|
||||
const SizedBox(height: 20),
|
||||
IconButton(
|
||||
icon: Badge.count(count: 9999, child: const Icon(Icons.notifications)),
|
||||
icon: Badge.count(
|
||||
count: 9999,
|
||||
child: const Icon(Icons.notifications),
|
||||
),
|
||||
onPressed: () {},
|
||||
),
|
||||
],
|
||||
|
||||
@ -33,7 +33,9 @@ class MaterialBannerExample extends StatelessWidget {
|
||||
content: Text('Hello, I am a Material Banner'),
|
||||
leading: Icon(Icons.agriculture_outlined),
|
||||
backgroundColor: Colors.green,
|
||||
actions: <Widget>[TextButton(onPressed: null, child: Text('DISMISS'))],
|
||||
actions: <Widget>[
|
||||
TextButton(onPressed: null, child: Text('DISMISS')),
|
||||
],
|
||||
),
|
||||
),
|
||||
),
|
||||
|
||||
@ -20,7 +20,8 @@ class BottomAppBarDemo extends StatefulWidget {
|
||||
class _BottomAppBarDemoState extends State<BottomAppBarDemo> {
|
||||
bool _showFab = true;
|
||||
bool _showNotch = true;
|
||||
FloatingActionButtonLocation _fabLocation = FloatingActionButtonLocation.endDocked;
|
||||
FloatingActionButtonLocation _fabLocation =
|
||||
FloatingActionButtonLocation.endDocked;
|
||||
|
||||
void _onShowNotchChanged(bool value) {
|
||||
setState(() {
|
||||
@ -44,10 +45,14 @@ class _BottomAppBarDemoState extends State<BottomAppBarDemo> {
|
||||
Widget build(BuildContext context) {
|
||||
return MaterialApp(
|
||||
home: Scaffold(
|
||||
appBar: AppBar(automaticallyImplyLeading: false, title: const Text('Bottom App Bar Demo')),
|
||||
appBar: AppBar(
|
||||
automaticallyImplyLeading: false,
|
||||
title: const Text('Bottom App Bar Demo'),
|
||||
),
|
||||
body: RadioGroup<FloatingActionButtonLocation>(
|
||||
groupValue: _fabLocation,
|
||||
onChanged: (FloatingActionButtonLocation? value) => _onFabLocationChanged(value),
|
||||
onChanged: (FloatingActionButtonLocation? value) =>
|
||||
_onFabLocationChanged(value),
|
||||
child: ListView(
|
||||
padding: const EdgeInsets.only(bottom: 88),
|
||||
children: <Widget>[
|
||||
@ -110,10 +115,11 @@ class _DemoBottomAppBar extends StatelessWidget {
|
||||
final FloatingActionButtonLocation fabLocation;
|
||||
final NotchedShape? shape;
|
||||
|
||||
static final List<FloatingActionButtonLocation> centerLocations = <FloatingActionButtonLocation>[
|
||||
FloatingActionButtonLocation.centerDocked,
|
||||
FloatingActionButtonLocation.centerFloat,
|
||||
];
|
||||
static final List<FloatingActionButtonLocation> centerLocations =
|
||||
<FloatingActionButtonLocation>[
|
||||
FloatingActionButtonLocation.centerDocked,
|
||||
FloatingActionButtonLocation.centerFloat,
|
||||
];
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
@ -130,8 +136,16 @@ class _DemoBottomAppBar extends StatelessWidget {
|
||||
onPressed: () {},
|
||||
),
|
||||
if (centerLocations.contains(fabLocation)) const Spacer(),
|
||||
IconButton(tooltip: 'Search', icon: const Icon(Icons.search), onPressed: () {}),
|
||||
IconButton(tooltip: 'Favorite', icon: const Icon(Icons.favorite), onPressed: () {}),
|
||||
IconButton(
|
||||
tooltip: 'Search',
|
||||
icon: const Icon(Icons.search),
|
||||
onPressed: () {},
|
||||
),
|
||||
IconButton(
|
||||
tooltip: 'Favorite',
|
||||
icon: const Icon(Icons.favorite),
|
||||
onPressed: () {},
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
|
||||
@ -78,7 +78,10 @@ class _BottomAppBarDemoState extends State<BottomAppBarDemo> {
|
||||
|
||||
void _addNewItem() {
|
||||
setState(() {
|
||||
items.insert(0, Container(color: colors[items.length % 5], height: 150.0));
|
||||
items.insert(
|
||||
0,
|
||||
Container(color: colors[items.length % 5], height: 150.0),
|
||||
);
|
||||
});
|
||||
}
|
||||
|
||||
@ -114,7 +117,10 @@ class _BottomAppBarDemoState extends State<BottomAppBarDemo> {
|
||||
onChanged: _onElevatedChanged,
|
||||
),
|
||||
Expanded(
|
||||
child: ListView(controller: _controller, children: items.toList()),
|
||||
child: ListView(
|
||||
controller: _controller,
|
||||
children: items.toList(),
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
@ -127,7 +133,10 @@ class _BottomAppBarDemoState extends State<BottomAppBarDemo> {
|
||||
)
|
||||
: null,
|
||||
floatingActionButtonLocation: _fabLocation,
|
||||
bottomNavigationBar: _DemoBottomAppBar(isElevated: _isElevated, isVisible: _isVisible),
|
||||
bottomNavigationBar: _DemoBottomAppBar(
|
||||
isElevated: _isElevated,
|
||||
isVisible: _isVisible,
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
@ -162,8 +171,16 @@ class _DemoBottomAppBar extends StatelessWidget {
|
||||
ScaffoldMessenger.of(context).showSnackBar(snackBar);
|
||||
},
|
||||
),
|
||||
IconButton(tooltip: 'Search', icon: const Icon(Icons.search), onPressed: () {}),
|
||||
IconButton(tooltip: 'Favorite', icon: const Icon(Icons.favorite), onPressed: () {}),
|
||||
IconButton(
|
||||
tooltip: 'Search',
|
||||
icon: const Icon(Icons.search),
|
||||
onPressed: () {},
|
||||
),
|
||||
IconButton(
|
||||
tooltip: 'Favorite',
|
||||
icon: const Icon(Icons.favorite),
|
||||
onPressed: () {},
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
|
||||
@ -21,12 +21,17 @@ class BottomNavigationBarExample extends StatefulWidget {
|
||||
const BottomNavigationBarExample({super.key});
|
||||
|
||||
@override
|
||||
State<BottomNavigationBarExample> createState() => _BottomNavigationBarExampleState();
|
||||
State<BottomNavigationBarExample> createState() =>
|
||||
_BottomNavigationBarExampleState();
|
||||
}
|
||||
|
||||
class _BottomNavigationBarExampleState extends State<BottomNavigationBarExample> {
|
||||
class _BottomNavigationBarExampleState
|
||||
extends State<BottomNavigationBarExample> {
|
||||
int _selectedIndex = 0;
|
||||
static const TextStyle optionStyle = TextStyle(fontSize: 30, fontWeight: FontWeight.bold);
|
||||
static const TextStyle optionStyle = TextStyle(
|
||||
fontSize: 30,
|
||||
fontWeight: FontWeight.bold,
|
||||
);
|
||||
static const List<Widget> _widgetOptions = <Widget>[
|
||||
Text('Index 0: Home', style: optionStyle),
|
||||
Text('Index 1: Business', style: optionStyle),
|
||||
@ -47,7 +52,10 @@ class _BottomNavigationBarExampleState extends State<BottomNavigationBarExample>
|
||||
bottomNavigationBar: BottomNavigationBar(
|
||||
items: const <BottomNavigationBarItem>[
|
||||
BottomNavigationBarItem(icon: Icon(Icons.home), label: 'Home'),
|
||||
BottomNavigationBarItem(icon: Icon(Icons.business), label: 'Business'),
|
||||
BottomNavigationBarItem(
|
||||
icon: Icon(Icons.business),
|
||||
label: 'Business',
|
||||
),
|
||||
BottomNavigationBarItem(icon: Icon(Icons.school), label: 'School'),
|
||||
],
|
||||
currentIndex: _selectedIndex,
|
||||
|
||||
@ -21,12 +21,17 @@ class BottomNavigationBarExample extends StatefulWidget {
|
||||
const BottomNavigationBarExample({super.key});
|
||||
|
||||
@override
|
||||
State<BottomNavigationBarExample> createState() => _BottomNavigationBarExampleState();
|
||||
State<BottomNavigationBarExample> createState() =>
|
||||
_BottomNavigationBarExampleState();
|
||||
}
|
||||
|
||||
class _BottomNavigationBarExampleState extends State<BottomNavigationBarExample> {
|
||||
class _BottomNavigationBarExampleState
|
||||
extends State<BottomNavigationBarExample> {
|
||||
int _selectedIndex = 0;
|
||||
static const TextStyle optionStyle = TextStyle(fontSize: 30, fontWeight: FontWeight.bold);
|
||||
static const TextStyle optionStyle = TextStyle(
|
||||
fontSize: 30,
|
||||
fontWeight: FontWeight.bold,
|
||||
);
|
||||
static const List<Widget> _widgetOptions = <Widget>[
|
||||
Text('Index 0: Home', style: optionStyle),
|
||||
Text('Index 1: Business', style: optionStyle),
|
||||
|
||||
@ -21,10 +21,12 @@ class BottomNavigationBarExample extends StatefulWidget {
|
||||
const BottomNavigationBarExample({super.key});
|
||||
|
||||
@override
|
||||
State<BottomNavigationBarExample> createState() => _BottomNavigationBarExampleState();
|
||||
State<BottomNavigationBarExample> createState() =>
|
||||
_BottomNavigationBarExampleState();
|
||||
}
|
||||
|
||||
class _BottomNavigationBarExampleState extends State<BottomNavigationBarExample> {
|
||||
class _BottomNavigationBarExampleState
|
||||
extends State<BottomNavigationBarExample> {
|
||||
int _selectedIndex = 0;
|
||||
final ScrollController _homeController = ScrollController();
|
||||
|
||||
@ -34,7 +36,8 @@ class _BottomNavigationBarExampleState extends State<BottomNavigationBarExample>
|
||||
itemBuilder: (BuildContext context, int index) {
|
||||
return Center(child: Text('Item $index'));
|
||||
},
|
||||
separatorBuilder: (BuildContext context, int index) => const Divider(thickness: 1),
|
||||
separatorBuilder: (BuildContext context, int index) =>
|
||||
const Divider(thickness: 1),
|
||||
itemCount: 50,
|
||||
);
|
||||
}
|
||||
@ -47,7 +50,10 @@ class _BottomNavigationBarExampleState extends State<BottomNavigationBarExample>
|
||||
bottomNavigationBar: BottomNavigationBar(
|
||||
items: const <BottomNavigationBarItem>[
|
||||
BottomNavigationBarItem(icon: Icon(Icons.home), label: 'Home'),
|
||||
BottomNavigationBarItem(icon: Icon(Icons.open_in_new_rounded), label: 'Open Dialog'),
|
||||
BottomNavigationBarItem(
|
||||
icon: Icon(Icons.open_in_new_rounded),
|
||||
label: 'Open Dialog',
|
||||
),
|
||||
],
|
||||
currentIndex: _selectedIndex,
|
||||
selectedItemColor: Colors.amber[800],
|
||||
|
||||
@ -24,11 +24,12 @@ class BottomSheetExampleApp extends StatelessWidget {
|
||||
|
||||
enum AnimationStyles { defaultStyle, custom, none }
|
||||
|
||||
const List<(AnimationStyles, String)> animationStyleSegments = <(AnimationStyles, String)>[
|
||||
(AnimationStyles.defaultStyle, 'Default'),
|
||||
(AnimationStyles.custom, 'Custom'),
|
||||
(AnimationStyles.none, 'None'),
|
||||
];
|
||||
const List<(AnimationStyles, String)> animationStyleSegments =
|
||||
<(AnimationStyles, String)>[
|
||||
(AnimationStyles.defaultStyle, 'Default'),
|
||||
(AnimationStyles.custom, 'Custom'),
|
||||
(AnimationStyles.none, 'None'),
|
||||
];
|
||||
|
||||
class BottomSheetExample extends StatefulWidget {
|
||||
const BottomSheetExample({super.key});
|
||||
@ -38,7 +39,9 @@ class BottomSheetExample extends StatefulWidget {
|
||||
}
|
||||
|
||||
class _BottomSheetExampleState extends State<BottomSheetExample> {
|
||||
Set<AnimationStyles> _animationStyleSelection = <AnimationStyles>{AnimationStyles.defaultStyle};
|
||||
Set<AnimationStyles> _animationStyleSelection = <AnimationStyles>{
|
||||
AnimationStyles.defaultStyle,
|
||||
};
|
||||
AnimationStyle? _animationStyle;
|
||||
|
||||
@override
|
||||
@ -62,11 +65,16 @@ class _BottomSheetExampleState extends State<BottomSheetExample> {
|
||||
_animationStyleSelection = styles;
|
||||
});
|
||||
},
|
||||
segments: animationStyleSegments.map<ButtonSegment<AnimationStyles>>((
|
||||
(AnimationStyles, String) shirt,
|
||||
) {
|
||||
return ButtonSegment<AnimationStyles>(value: shirt.$1, label: Text(shirt.$2));
|
||||
}).toList(),
|
||||
segments: animationStyleSegments
|
||||
.map<ButtonSegment<AnimationStyles>>((
|
||||
(AnimationStyles, String) shirt,
|
||||
) {
|
||||
return ButtonSegment<AnimationStyles>(
|
||||
value: shirt.$1,
|
||||
label: Text(shirt.$2),
|
||||
);
|
||||
})
|
||||
.toList(),
|
||||
),
|
||||
const SizedBox(height: 10),
|
||||
ElevatedButton(
|
||||
|
||||
@ -24,21 +24,25 @@ class ModalBottomSheetApp extends StatelessWidget {
|
||||
|
||||
enum AnimationStyles { defaultStyle, custom, none }
|
||||
|
||||
const List<(AnimationStyles, String)> animationStyleSegments = <(AnimationStyles, String)>[
|
||||
(AnimationStyles.defaultStyle, 'Default'),
|
||||
(AnimationStyles.custom, 'Custom'),
|
||||
(AnimationStyles.none, 'None'),
|
||||
];
|
||||
const List<(AnimationStyles, String)> animationStyleSegments =
|
||||
<(AnimationStyles, String)>[
|
||||
(AnimationStyles.defaultStyle, 'Default'),
|
||||
(AnimationStyles.custom, 'Custom'),
|
||||
(AnimationStyles.none, 'None'),
|
||||
];
|
||||
|
||||
class ModalBottomSheetExample extends StatefulWidget {
|
||||
const ModalBottomSheetExample({super.key});
|
||||
|
||||
@override
|
||||
State<ModalBottomSheetExample> createState() => _ModalBottomSheetExampleState();
|
||||
State<ModalBottomSheetExample> createState() =>
|
||||
_ModalBottomSheetExampleState();
|
||||
}
|
||||
|
||||
class _ModalBottomSheetExampleState extends State<ModalBottomSheetExample> {
|
||||
Set<AnimationStyles> _animationStyleSelection = <AnimationStyles>{AnimationStyles.defaultStyle};
|
||||
Set<AnimationStyles> _animationStyleSelection = <AnimationStyles>{
|
||||
AnimationStyles.defaultStyle,
|
||||
};
|
||||
AnimationStyle? _animationStyle;
|
||||
|
||||
@override
|
||||
@ -62,11 +66,16 @@ class _ModalBottomSheetExampleState extends State<ModalBottomSheetExample> {
|
||||
_animationStyleSelection = styles;
|
||||
});
|
||||
},
|
||||
segments: animationStyleSegments.map<ButtonSegment<AnimationStyles>>((
|
||||
(AnimationStyles, String) shirt,
|
||||
) {
|
||||
return ButtonSegment<AnimationStyles>(value: shirt.$1, label: Text(shirt.$2));
|
||||
}).toList(),
|
||||
segments: animationStyleSegments
|
||||
.map<ButtonSegment<AnimationStyles>>((
|
||||
(AnimationStyles, String) shirt,
|
||||
) {
|
||||
return ButtonSegment<AnimationStyles>(
|
||||
value: shirt.$1,
|
||||
label: Text(shirt.$2),
|
||||
);
|
||||
})
|
||||
.toList(),
|
||||
),
|
||||
const SizedBox(height: 10),
|
||||
ElevatedButton(
|
||||
|
||||
@ -57,7 +57,10 @@ class ButtonTypesGroup extends StatelessWidget {
|
||||
children: <Widget>[
|
||||
ElevatedButton(onPressed: onPressed, child: const Text('Elevated')),
|
||||
FilledButton(onPressed: onPressed, child: const Text('Filled')),
|
||||
FilledButton.tonal(onPressed: onPressed, child: const Text('Filled Tonal')),
|
||||
FilledButton.tonal(
|
||||
onPressed: onPressed,
|
||||
child: const Text('Filled Tonal'),
|
||||
),
|
||||
OutlinedButton(onPressed: onPressed, child: const Text('Outlined')),
|
||||
TextButton(onPressed: onPressed, child: const Text('Text')),
|
||||
],
|
||||
|
||||
@ -4,6 +4,7 @@
|
||||
|
||||
import 'package:flutter/material.dart';
|
||||
|
||||
// ignore: deprecated_member_use
|
||||
/// Flutter code sample for using [ButtonStyleButton.iconAlignment] parameter.
|
||||
|
||||
void main() {
|
||||
@ -15,7 +16,9 @@ class ButtonStyleButtonIconAlignmentApp extends StatelessWidget {
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return const MaterialApp(home: Scaffold(body: ButtonStyleButtonIconAlignmentExample()));
|
||||
return const MaterialApp(
|
||||
home: Scaffold(body: ButtonStyleButtonIconAlignmentExample()),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@ -100,7 +103,9 @@ class _ButtonStyleButtonIconAlignmentExampleState
|
||||
});
|
||||
},
|
||||
selected: <IconAlignment>{_iconAlignment},
|
||||
segments: IconAlignment.values.map((IconAlignment iconAlignment) {
|
||||
segments: IconAlignment.values.map((
|
||||
IconAlignment iconAlignment,
|
||||
) {
|
||||
return ButtonSegment<IconAlignment>(
|
||||
value: iconAlignment,
|
||||
label: Text(iconAlignment.name),
|
||||
|
||||
@ -39,7 +39,11 @@ class CardExample extends StatelessWidget {
|
||||
onTap: () {
|
||||
debugPrint('Card tapped.');
|
||||
},
|
||||
child: const SizedBox(width: 300, height: 100, child: Text('A card that can be tapped')),
|
||||
child: const SizedBox(
|
||||
width: 300,
|
||||
height: 100,
|
||||
child: Text('A card that can be tapped'),
|
||||
),
|
||||
),
|
||||
),
|
||||
);
|
||||
|
||||
@ -39,6 +39,10 @@ class _SampleCard extends StatelessWidget {
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return SizedBox(width: 300, height: 100, child: Center(child: Text(cardName)));
|
||||
return SizedBox(
|
||||
width: 300,
|
||||
height: 100,
|
||||
child: Center(child: Text(cardName)),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@ -77,7 +77,8 @@ class _CarouselExampleState extends State<CarouselExample> {
|
||||
consumeMaxWeight: false,
|
||||
children: List<Widget>.generate(20, (int index) {
|
||||
return ColoredBox(
|
||||
color: Colors.primaries[index % Colors.primaries.length].withOpacity(0.8),
|
||||
color: Colors.primaries[index % Colors.primaries.length]
|
||||
.withValues(alpha: 0.8),
|
||||
child: const SizedBox.expand(),
|
||||
);
|
||||
}),
|
||||
@ -163,14 +164,18 @@ class HeroLayoutCard extends StatelessWidget {
|
||||
imageInfo.title,
|
||||
overflow: TextOverflow.clip,
|
||||
softWrap: false,
|
||||
style: Theme.of(context).textTheme.headlineLarge?.copyWith(color: Colors.white),
|
||||
style: Theme.of(
|
||||
context,
|
||||
).textTheme.headlineLarge?.copyWith(color: Colors.white),
|
||||
),
|
||||
const SizedBox(height: 10),
|
||||
Text(
|
||||
imageInfo.subtitle,
|
||||
overflow: TextOverflow.clip,
|
||||
softWrap: false,
|
||||
style: Theme.of(context).textTheme.bodyMedium?.copyWith(color: Colors.white),
|
||||
style: Theme.of(
|
||||
context,
|
||||
).textTheme.bodyMedium?.copyWith(color: Colors.white),
|
||||
),
|
||||
],
|
||||
),
|
||||
@ -181,7 +186,11 @@ class HeroLayoutCard extends StatelessWidget {
|
||||
}
|
||||
|
||||
class UncontainedLayoutCard extends StatelessWidget {
|
||||
const UncontainedLayoutCard({super.key, required this.index, required this.label});
|
||||
const UncontainedLayoutCard({
|
||||
super.key,
|
||||
required this.index,
|
||||
required this.label,
|
||||
});
|
||||
|
||||
final int index;
|
||||
final String label;
|
||||
@ -189,7 +198,9 @@ class UncontainedLayoutCard extends StatelessWidget {
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return ColoredBox(
|
||||
color: Colors.primaries[index % Colors.primaries.length].withOpacity(0.5),
|
||||
color: Colors.primaries[index % Colors.primaries.length].withValues(
|
||||
alpha: 0.5,
|
||||
),
|
||||
child: Center(
|
||||
child: Text(
|
||||
label,
|
||||
@ -208,8 +219,18 @@ enum CardInfo {
|
||||
climate('Climate', Icons.thermostat, Color(0xffA44D2A), Color(0xffFAEDE7)),
|
||||
wifi('Wifi', Icons.wifi, Color(0xff417345), Color(0xffE5F4E0)),
|
||||
media('Media', Icons.library_music, Color(0xff2556C8), Color(0xffECEFFD)),
|
||||
security('Security', Icons.crisis_alert, Color(0xff794C01), Color(0xffFAEEDF)),
|
||||
safety('Safety', Icons.medical_services, Color(0xff2251C5), Color(0xffECEFFD)),
|
||||
security(
|
||||
'Security',
|
||||
Icons.crisis_alert,
|
||||
Color(0xff794C01),
|
||||
Color(0xffFAEEDF),
|
||||
),
|
||||
safety(
|
||||
'Safety',
|
||||
Icons.medical_services,
|
||||
Color(0xff2251C5),
|
||||
Color(0xffECEFFD),
|
||||
),
|
||||
more('', Icons.add, Color(0xff201D1C), Color(0xffE3DFD8));
|
||||
|
||||
const CardInfo(this.label, this.icon, this.color, this.backgroundColor);
|
||||
@ -220,16 +241,36 @@ enum CardInfo {
|
||||
}
|
||||
|
||||
enum ImageInfo {
|
||||
image0('The Flow', 'Sponsored | Season 1 Now Streaming', 'content_based_color_scheme_1.png'),
|
||||
image0(
|
||||
'The Flow',
|
||||
'Sponsored | Season 1 Now Streaming',
|
||||
'content_based_color_scheme_1.png',
|
||||
),
|
||||
image1(
|
||||
'Through the Pane',
|
||||
'Sponsored | Season 1 Now Streaming',
|
||||
'content_based_color_scheme_2.png',
|
||||
),
|
||||
image2('Iridescence', 'Sponsored | Season 1 Now Streaming', 'content_based_color_scheme_3.png'),
|
||||
image3('Sea Change', 'Sponsored | Season 1 Now Streaming', 'content_based_color_scheme_4.png'),
|
||||
image4('Blue Symphony', 'Sponsored | Season 1 Now Streaming', 'content_based_color_scheme_5.png'),
|
||||
image5('When It Rains', 'Sponsored | Season 1 Now Streaming', 'content_based_color_scheme_6.png');
|
||||
image2(
|
||||
'Iridescence',
|
||||
'Sponsored | Season 1 Now Streaming',
|
||||
'content_based_color_scheme_3.png',
|
||||
),
|
||||
image3(
|
||||
'Sea Change',
|
||||
'Sponsored | Season 1 Now Streaming',
|
||||
'content_based_color_scheme_4.png',
|
||||
),
|
||||
image4(
|
||||
'Blue Symphony',
|
||||
'Sponsored | Season 1 Now Streaming',
|
||||
'content_based_color_scheme_5.png',
|
||||
),
|
||||
image5(
|
||||
'When It Rains',
|
||||
'Sponsored | Season 1 Now Streaming',
|
||||
'content_based_color_scheme_6.png',
|
||||
);
|
||||
|
||||
const ImageInfo(this.title, this.subtitle, this.url);
|
||||
final String title;
|
||||
|
||||
@ -58,7 +58,12 @@ class _CheckboxExampleState extends State<CheckboxExample> {
|
||||
});
|
||||
},
|
||||
),
|
||||
Checkbox(isError: true, tristate: true, value: isChecked, onChanged: null),
|
||||
Checkbox(
|
||||
isError: true,
|
||||
tristate: true,
|
||||
value: isChecked,
|
||||
onChanged: null,
|
||||
),
|
||||
],
|
||||
);
|
||||
}
|
||||
|
||||
@ -22,7 +22,8 @@ class CheckboxListTileExample extends StatefulWidget {
|
||||
const CheckboxListTileExample({super.key});
|
||||
|
||||
@override
|
||||
State<CheckboxListTileExample> createState() => _CheckboxListTileExampleState();
|
||||
State<CheckboxListTileExample> createState() =>
|
||||
_CheckboxListTileExampleState();
|
||||
}
|
||||
|
||||
class _CheckboxListTileExampleState extends State<CheckboxListTileExample> {
|
||||
|
||||
@ -21,7 +21,8 @@ class CheckboxListTileExample extends StatefulWidget {
|
||||
const CheckboxListTileExample({super.key});
|
||||
|
||||
@override
|
||||
State<CheckboxListTileExample> createState() => _CheckboxListTileExampleState();
|
||||
State<CheckboxListTileExample> createState() =>
|
||||
_CheckboxListTileExampleState();
|
||||
}
|
||||
|
||||
class _CheckboxListTileExampleState extends State<CheckboxListTileExample> {
|
||||
|
||||
@ -32,7 +32,11 @@ class AvatarBoxConstraintsExample extends StatelessWidget {
|
||||
avatar: Icon(Icons.star),
|
||||
label: SizedBox(
|
||||
width: 150,
|
||||
child: Text('One line text.', maxLines: 3, overflow: TextOverflow.ellipsis),
|
||||
child: Text(
|
||||
'One line text.',
|
||||
maxLines: 3,
|
||||
overflow: TextOverflow.ellipsis,
|
||||
),
|
||||
),
|
||||
),
|
||||
SizedBox(height: 10),
|
||||
|
||||
@ -23,7 +23,8 @@ class ChipAnimationStyleExample extends StatefulWidget {
|
||||
const ChipAnimationStyleExample({super.key});
|
||||
|
||||
@override
|
||||
State<ChipAnimationStyleExample> createState() => _ChipAnimationStyleExampleState();
|
||||
State<ChipAnimationStyleExample> createState() =>
|
||||
_ChipAnimationStyleExampleState();
|
||||
}
|
||||
|
||||
class _ChipAnimationStyleExampleState extends State<ChipAnimationStyleExample> {
|
||||
@ -120,7 +121,9 @@ class _ChipAnimationStyleExampleState extends State<ChipAnimationStyleExample> {
|
||||
showCheckmark = !showCheckmark;
|
||||
});
|
||||
},
|
||||
child: Text(showCheckmark ? 'Hide checkmark' : 'Show checkmark'),
|
||||
child: Text(
|
||||
showCheckmark ? 'Hide checkmark' : 'Show checkmark',
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
@ -145,7 +148,9 @@ class _ChipAnimationStyleExampleState extends State<ChipAnimationStyleExample> {
|
||||
showDeleteIcon = !showDeleteIcon;
|
||||
});
|
||||
},
|
||||
child: Text(showDeleteIcon ? 'Hide delete icon' : 'Show delete icon'),
|
||||
child: Text(
|
||||
showDeleteIcon ? 'Hide delete icon' : 'Show delete icon',
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
|
||||
@ -32,7 +32,11 @@ class DeleteIconBoxConstraintsExample extends StatelessWidget {
|
||||
onDeleted: () {},
|
||||
label: const SizedBox(
|
||||
width: 150,
|
||||
child: Text('One line text.', maxLines: 3, overflow: TextOverflow.ellipsis),
|
||||
child: Text(
|
||||
'One line text.',
|
||||
maxLines: 3,
|
||||
overflow: TextOverflow.ellipsis,
|
||||
),
|
||||
),
|
||||
),
|
||||
const SizedBox(height: 10),
|
||||
|
||||
@ -15,7 +15,9 @@ class OnDeletedExampleApp extends StatelessWidget {
|
||||
Widget build(BuildContext context) {
|
||||
return MaterialApp(
|
||||
home: Scaffold(
|
||||
appBar: AppBar(title: const Text('DeletableChipAttributes.onDeleted Sample')),
|
||||
appBar: AppBar(
|
||||
title: const Text('DeletableChipAttributes.onDeleted Sample'),
|
||||
),
|
||||
body: const Center(child: OnDeletedExample()),
|
||||
),
|
||||
);
|
||||
|
||||
@ -21,7 +21,8 @@ class _ColorSchemeExampleState extends State<ColorSchemeExample> {
|
||||
Color selectedColor = ColorSeed.baseColor.color;
|
||||
Brightness selectedBrightness = Brightness.light;
|
||||
double selectedContrast = 0.0;
|
||||
static const List<DynamicSchemeVariant> schemeVariants = DynamicSchemeVariant.values;
|
||||
static const List<DynamicSchemeVariant> schemeVariants =
|
||||
DynamicSchemeVariant.values;
|
||||
|
||||
void updateTheme(Brightness brightness, Color color, double contrastLevel) {
|
||||
setState(() {
|
||||
@ -63,7 +64,9 @@ class _ColorSchemeExampleState extends State<ColorSchemeExample> {
|
||||
SingleChildScrollView(
|
||||
scrollDirection: Axis.horizontal,
|
||||
child: Row(
|
||||
children: List<Widget>.generate(schemeVariants.length, (int index) {
|
||||
children: List<Widget>.generate(schemeVariants.length, (
|
||||
int index,
|
||||
) {
|
||||
return ColorSchemeVariantColumn(
|
||||
selectedColor: selectedColor,
|
||||
brightness: selectedBrightness,
|
||||
@ -122,7 +125,12 @@ class _SettingsState extends State<Settings> {
|
||||
padding: const EdgeInsets.all(20.0),
|
||||
child: ListView(
|
||||
children: <Widget>[
|
||||
Center(child: Text('Settings', style: Theme.of(context).textTheme.titleLarge)),
|
||||
Center(
|
||||
child: Text(
|
||||
'Settings',
|
||||
style: Theme.of(context).textTheme.titleLarge,
|
||||
),
|
||||
),
|
||||
Row(
|
||||
children: <Widget>[
|
||||
const Text('Brightness: '),
|
||||
@ -130,9 +138,15 @@ class _SettingsState extends State<Settings> {
|
||||
value: selectedBrightness == Brightness.light,
|
||||
onChanged: (bool value) {
|
||||
setState(() {
|
||||
selectedBrightness = value ? Brightness.light : Brightness.dark;
|
||||
selectedBrightness = value
|
||||
? Brightness.light
|
||||
: Brightness.dark;
|
||||
});
|
||||
widget.updateTheme(selectedBrightness, selectedColor, selectedContrast);
|
||||
widget.updateTheme(
|
||||
selectedBrightness,
|
||||
selectedColor,
|
||||
selectedContrast,
|
||||
);
|
||||
},
|
||||
),
|
||||
],
|
||||
@ -141,7 +155,9 @@ class _SettingsState extends State<Settings> {
|
||||
crossAxisAlignment: WrapCrossAlignment.center,
|
||||
children: <Widget>[
|
||||
const Text('Seed color: '),
|
||||
...List<Widget>.generate(ColorSeed.values.length, (int index) {
|
||||
...List<Widget>.generate(ColorSeed.values.length, (
|
||||
int index,
|
||||
) {
|
||||
final Color itemColor = ColorSeed.values[index].color;
|
||||
return IconButton(
|
||||
icon: selectedColor == ColorSeed.values[index].color
|
||||
@ -151,7 +167,11 @@ class _SettingsState extends State<Settings> {
|
||||
setState(() {
|
||||
selectedColor = itemColor;
|
||||
});
|
||||
widget.updateTheme(selectedBrightness, selectedColor, selectedContrast);
|
||||
widget.updateTheme(
|
||||
selectedBrightness,
|
||||
selectedColor,
|
||||
selectedContrast,
|
||||
);
|
||||
},
|
||||
);
|
||||
}),
|
||||
@ -170,7 +190,11 @@ class _SettingsState extends State<Settings> {
|
||||
setState(() {
|
||||
selectedContrast = value;
|
||||
});
|
||||
widget.updateTheme(selectedBrightness, selectedColor, selectedContrast);
|
||||
widget.updateTheme(
|
||||
selectedBrightness,
|
||||
selectedColor,
|
||||
selectedContrast,
|
||||
);
|
||||
},
|
||||
),
|
||||
),
|
||||
@ -258,8 +282,16 @@ class ColorSchemeView extends StatelessWidget {
|
||||
divider,
|
||||
ColorGroup(
|
||||
children: <ColorChip>[
|
||||
ColorChip('primaryFixed', colorScheme.primaryFixed, colorScheme.onPrimaryFixed),
|
||||
ColorChip('onPrimaryFixed', colorScheme.onPrimaryFixed, colorScheme.primaryFixed),
|
||||
ColorChip(
|
||||
'primaryFixed',
|
||||
colorScheme.primaryFixed,
|
||||
colorScheme.onPrimaryFixed,
|
||||
),
|
||||
ColorChip(
|
||||
'onPrimaryFixed',
|
||||
colorScheme.onPrimaryFixed,
|
||||
colorScheme.primaryFixed,
|
||||
),
|
||||
ColorChip(
|
||||
'primaryFixedDim',
|
||||
colorScheme.primaryFixedDim,
|
||||
@ -275,8 +307,16 @@ class ColorSchemeView extends StatelessWidget {
|
||||
divider,
|
||||
ColorGroup(
|
||||
children: <ColorChip>[
|
||||
ColorChip('secondary', colorScheme.secondary, colorScheme.onSecondary),
|
||||
ColorChip('onSecondary', colorScheme.onSecondary, colorScheme.secondary),
|
||||
ColorChip(
|
||||
'secondary',
|
||||
colorScheme.secondary,
|
||||
colorScheme.onSecondary,
|
||||
),
|
||||
ColorChip(
|
||||
'onSecondary',
|
||||
colorScheme.onSecondary,
|
||||
colorScheme.secondary,
|
||||
),
|
||||
ColorChip(
|
||||
'secondaryContainer',
|
||||
colorScheme.secondaryContainer,
|
||||
@ -292,8 +332,16 @@ class ColorSchemeView extends StatelessWidget {
|
||||
divider,
|
||||
ColorGroup(
|
||||
children: <ColorChip>[
|
||||
ColorChip('secondaryFixed', colorScheme.secondaryFixed, colorScheme.onSecondaryFixed),
|
||||
ColorChip('onSecondaryFixed', colorScheme.onSecondaryFixed, colorScheme.secondaryFixed),
|
||||
ColorChip(
|
||||
'secondaryFixed',
|
||||
colorScheme.secondaryFixed,
|
||||
colorScheme.onSecondaryFixed,
|
||||
),
|
||||
ColorChip(
|
||||
'onSecondaryFixed',
|
||||
colorScheme.onSecondaryFixed,
|
||||
colorScheme.secondaryFixed,
|
||||
),
|
||||
ColorChip(
|
||||
'secondaryFixedDim',
|
||||
colorScheme.secondaryFixedDim,
|
||||
@ -310,7 +358,11 @@ class ColorSchemeView extends StatelessWidget {
|
||||
ColorGroup(
|
||||
children: <ColorChip>[
|
||||
ColorChip('tertiary', colorScheme.tertiary, colorScheme.onTertiary),
|
||||
ColorChip('onTertiary', colorScheme.onTertiary, colorScheme.tertiary),
|
||||
ColorChip(
|
||||
'onTertiary',
|
||||
colorScheme.onTertiary,
|
||||
colorScheme.tertiary,
|
||||
),
|
||||
ColorChip(
|
||||
'tertiaryContainer',
|
||||
colorScheme.tertiaryContainer,
|
||||
@ -326,8 +378,16 @@ class ColorSchemeView extends StatelessWidget {
|
||||
divider,
|
||||
ColorGroup(
|
||||
children: <ColorChip>[
|
||||
ColorChip('tertiaryFixed', colorScheme.tertiaryFixed, colorScheme.onTertiaryFixed),
|
||||
ColorChip('onTertiaryFixed', colorScheme.onTertiaryFixed, colorScheme.tertiaryFixed),
|
||||
ColorChip(
|
||||
'tertiaryFixed',
|
||||
colorScheme.tertiaryFixed,
|
||||
colorScheme.onTertiaryFixed,
|
||||
),
|
||||
ColorChip(
|
||||
'onTertiaryFixed',
|
||||
colorScheme.onTertiaryFixed,
|
||||
colorScheme.tertiaryFixed,
|
||||
),
|
||||
ColorChip(
|
||||
'tertiaryFixedDim',
|
||||
colorScheme.tertiaryFixedDim,
|
||||
@ -345,16 +405,32 @@ class ColorSchemeView extends StatelessWidget {
|
||||
children: <ColorChip>[
|
||||
ColorChip('error', colorScheme.error, colorScheme.onError),
|
||||
ColorChip('onError', colorScheme.onError, colorScheme.error),
|
||||
ColorChip('errorContainer', colorScheme.errorContainer, colorScheme.onErrorContainer),
|
||||
ColorChip('onErrorContainer', colorScheme.onErrorContainer, colorScheme.errorContainer),
|
||||
ColorChip(
|
||||
'errorContainer',
|
||||
colorScheme.errorContainer,
|
||||
colorScheme.onErrorContainer,
|
||||
),
|
||||
ColorChip(
|
||||
'onErrorContainer',
|
||||
colorScheme.onErrorContainer,
|
||||
colorScheme.errorContainer,
|
||||
),
|
||||
],
|
||||
),
|
||||
divider,
|
||||
ColorGroup(
|
||||
children: <ColorChip>[
|
||||
ColorChip('surfaceDim', colorScheme.surfaceDim, colorScheme.onSurface),
|
||||
ColorChip(
|
||||
'surfaceDim',
|
||||
colorScheme.surfaceDim,
|
||||
colorScheme.onSurface,
|
||||
),
|
||||
ColorChip('surface', colorScheme.surface, colorScheme.onSurface),
|
||||
ColorChip('surfaceBright', colorScheme.surfaceBright, colorScheme.onSurface),
|
||||
ColorChip(
|
||||
'surfaceBright',
|
||||
colorScheme.surfaceBright,
|
||||
colorScheme.onSurface,
|
||||
),
|
||||
ColorChip(
|
||||
'surfaceContainerLowest',
|
||||
colorScheme.surfaceContainerLowest,
|
||||
@ -365,7 +441,11 @@ class ColorSchemeView extends StatelessWidget {
|
||||
colorScheme.surfaceContainerLow,
|
||||
colorScheme.onSurface,
|
||||
),
|
||||
ColorChip('surfaceContainer', colorScheme.surfaceContainer, colorScheme.onSurface),
|
||||
ColorChip(
|
||||
'surfaceContainer',
|
||||
colorScheme.surfaceContainer,
|
||||
colorScheme.onSurface,
|
||||
),
|
||||
ColorChip(
|
||||
'surfaceContainerHigh',
|
||||
colorScheme.surfaceContainerHigh,
|
||||
@ -389,9 +469,21 @@ class ColorSchemeView extends StatelessWidget {
|
||||
children: <ColorChip>[
|
||||
ColorChip('outline', colorScheme.outline, null),
|
||||
ColorChip('shadow', colorScheme.shadow, null),
|
||||
ColorChip('inverseSurface', colorScheme.inverseSurface, colorScheme.onInverseSurface),
|
||||
ColorChip('onInverseSurface', colorScheme.onInverseSurface, colorScheme.inverseSurface),
|
||||
ColorChip('inversePrimary', colorScheme.inversePrimary, colorScheme.primary),
|
||||
ColorChip(
|
||||
'inverseSurface',
|
||||
colorScheme.inverseSurface,
|
||||
colorScheme.onInverseSurface,
|
||||
),
|
||||
ColorChip(
|
||||
'onInverseSurface',
|
||||
colorScheme.onInverseSurface,
|
||||
colorScheme.inverseSurface,
|
||||
),
|
||||
ColorChip(
|
||||
'inversePrimary',
|
||||
colorScheme.inversePrimary,
|
||||
colorScheme.primary,
|
||||
),
|
||||
],
|
||||
),
|
||||
],
|
||||
|
||||
@ -35,7 +35,10 @@ class DynamicColorExample extends StatefulWidget {
|
||||
),
|
||||
];
|
||||
|
||||
final Future<ColorScheme> Function(ImageProvider<Object> provider, Brightness brightness)?
|
||||
final Future<ColorScheme> Function(
|
||||
ImageProvider<Object> provider,
|
||||
Brightness brightness,
|
||||
)?
|
||||
loadColorScheme;
|
||||
|
||||
@override
|
||||
@ -83,7 +86,10 @@ class _DynamicColorExampleState extends State<DynamicColorExample> {
|
||||
padding: const EdgeInsets.symmetric(vertical: 15),
|
||||
child: Text(
|
||||
brightness,
|
||||
style: TextStyle(fontWeight: FontWeight.bold, color: colorScheme.onSecondaryContainer),
|
||||
style: TextStyle(
|
||||
fontWeight: FontWeight.bold,
|
||||
color: colorScheme.onSecondaryContainer,
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
@ -107,7 +113,7 @@ class _DynamicColorExampleState extends State<DynamicColorExample> {
|
||||
actions: <Widget>[
|
||||
const Icon(Icons.light_mode),
|
||||
Switch(
|
||||
activeColor: colorScheme.primary,
|
||||
activeThumbColor: colorScheme.primary,
|
||||
activeTrackColor: colorScheme.surface,
|
||||
inactiveTrackColor: colorScheme.onSecondary,
|
||||
value: isLight,
|
||||
@ -128,59 +134,82 @@ class _DynamicColorExampleState extends State<DynamicColorExample> {
|
||||
child: Column(
|
||||
children: <Widget>[
|
||||
divider,
|
||||
_imagesRow(context, DynamicColorExample.images, colorScheme),
|
||||
_imagesRow(
|
||||
context,
|
||||
DynamicColorExample.images,
|
||||
colorScheme,
|
||||
),
|
||||
divider,
|
||||
Expanded(
|
||||
child: ColoredBox(
|
||||
color: colorScheme.surface,
|
||||
child: LayoutBuilder(
|
||||
builder: (BuildContext context, BoxConstraints constraints) {
|
||||
if (constraints.maxWidth < narrowScreenWidthThreshold) {
|
||||
return SingleChildScrollView(
|
||||
child: Column(
|
||||
children: <Widget>[
|
||||
divider,
|
||||
schemeLabel('Light ColorScheme', colorScheme),
|
||||
schemeView(lightTheme),
|
||||
divider,
|
||||
divider,
|
||||
schemeLabel('Dark ColorScheme', colorScheme),
|
||||
schemeView(darkTheme),
|
||||
],
|
||||
),
|
||||
);
|
||||
} else {
|
||||
return SingleChildScrollView(
|
||||
child: Padding(
|
||||
padding: const EdgeInsets.only(top: 5),
|
||||
child: Column(
|
||||
children: <Widget>[
|
||||
Row(
|
||||
builder:
|
||||
(
|
||||
BuildContext context,
|
||||
BoxConstraints constraints,
|
||||
) {
|
||||
if (constraints.maxWidth <
|
||||
narrowScreenWidthThreshold) {
|
||||
return SingleChildScrollView(
|
||||
child: Column(
|
||||
children: <Widget>[
|
||||
divider,
|
||||
schemeLabel(
|
||||
'Light ColorScheme',
|
||||
colorScheme,
|
||||
),
|
||||
schemeView(lightTheme),
|
||||
divider,
|
||||
divider,
|
||||
schemeLabel(
|
||||
'Dark ColorScheme',
|
||||
colorScheme,
|
||||
),
|
||||
schemeView(darkTheme),
|
||||
],
|
||||
),
|
||||
);
|
||||
} else {
|
||||
return SingleChildScrollView(
|
||||
child: Padding(
|
||||
padding: const EdgeInsets.only(
|
||||
top: 5,
|
||||
),
|
||||
child: Column(
|
||||
children: <Widget>[
|
||||
Expanded(
|
||||
child: Column(
|
||||
children: <Widget>[
|
||||
schemeLabel('Light ColorScheme', colorScheme),
|
||||
schemeView(lightTheme),
|
||||
],
|
||||
),
|
||||
),
|
||||
Expanded(
|
||||
child: Column(
|
||||
children: <Widget>[
|
||||
schemeLabel('Dark ColorScheme', colorScheme),
|
||||
schemeView(darkTheme),
|
||||
],
|
||||
),
|
||||
Row(
|
||||
children: <Widget>[
|
||||
Expanded(
|
||||
child: Column(
|
||||
children: <Widget>[
|
||||
schemeLabel(
|
||||
'Light ColorScheme',
|
||||
colorScheme,
|
||||
),
|
||||
schemeView(lightTheme),
|
||||
],
|
||||
),
|
||||
),
|
||||
Expanded(
|
||||
child: Column(
|
||||
children: <Widget>[
|
||||
schemeLabel(
|
||||
'Dark ColorScheme',
|
||||
colorScheme,
|
||||
),
|
||||
schemeView(darkTheme),
|
||||
],
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
],
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
},
|
||||
),
|
||||
);
|
||||
}
|
||||
},
|
||||
),
|
||||
),
|
||||
),
|
||||
@ -217,7 +246,11 @@ class _DynamicColorExampleState extends State<DynamicColorExample> {
|
||||
|
||||
// For small screens, have two rows of image selection. For wide screens,
|
||||
// fit them onto one row.
|
||||
Widget _imagesRow(BuildContext context, List<ImageProvider> images, ColorScheme colorScheme) {
|
||||
Widget _imagesRow(
|
||||
BuildContext context,
|
||||
List<ImageProvider> images,
|
||||
ColorScheme colorScheme,
|
||||
) {
|
||||
final double windowHeight = MediaQuery.of(context).size.height;
|
||||
final double windowWidth = MediaQuery.of(context).size.width;
|
||||
return Padding(
|
||||
@ -229,8 +262,16 @@ class _DynamicColorExampleState extends State<DynamicColorExample> {
|
||||
} else {
|
||||
return Column(
|
||||
children: <Widget>[
|
||||
_adaptiveLayoutImagesRow(images.sublist(0, 3), colorScheme, windowWidth),
|
||||
_adaptiveLayoutImagesRow(images.sublist(3), colorScheme, windowWidth),
|
||||
_adaptiveLayoutImagesRow(
|
||||
images.sublist(0, 3),
|
||||
colorScheme,
|
||||
windowWidth,
|
||||
),
|
||||
_adaptiveLayoutImagesRow(
|
||||
images.sublist(3),
|
||||
colorScheme,
|
||||
windowWidth,
|
||||
),
|
||||
],
|
||||
);
|
||||
}
|
||||
@ -253,7 +294,8 @@ class _DynamicColorExampleState extends State<DynamicColorExample> {
|
||||
child: GestureDetector(
|
||||
onTap: () => _updateImage(image),
|
||||
child: Card(
|
||||
color: DynamicColorExample.images.indexOf(image) == selectedImage
|
||||
color:
|
||||
DynamicColorExample.images.indexOf(image) == selectedImage
|
||||
? colorScheme.primaryContainer
|
||||
: colorScheme.surface,
|
||||
child: Padding(
|
||||
@ -286,7 +328,11 @@ class ColorSchemeView extends StatelessWidget {
|
||||
children: <Widget>[
|
||||
ColorGroup(
|
||||
children: <ColorChip>[
|
||||
ColorChip(label: 'primary', color: colorScheme.primary, onColor: colorScheme.onPrimary),
|
||||
ColorChip(
|
||||
label: 'primary',
|
||||
color: colorScheme.primary,
|
||||
onColor: colorScheme.onPrimary,
|
||||
),
|
||||
ColorChip(
|
||||
label: 'onPrimary',
|
||||
color: colorScheme.onPrimary,
|
||||
@ -357,8 +403,16 @@ class ColorSchemeView extends StatelessWidget {
|
||||
divider,
|
||||
ColorGroup(
|
||||
children: <ColorChip>[
|
||||
ColorChip(label: 'error', color: colorScheme.error, onColor: colorScheme.onError),
|
||||
ColorChip(label: 'onError', color: colorScheme.onError, onColor: colorScheme.error),
|
||||
ColorChip(
|
||||
label: 'error',
|
||||
color: colorScheme.error,
|
||||
onColor: colorScheme.onError,
|
||||
),
|
||||
ColorChip(
|
||||
label: 'onError',
|
||||
color: colorScheme.onError,
|
||||
onColor: colorScheme.error,
|
||||
),
|
||||
ColorChip(
|
||||
label: 'errorContainer',
|
||||
color: colorScheme.errorContainer,
|
||||
@ -374,7 +428,11 @@ class ColorSchemeView extends StatelessWidget {
|
||||
divider,
|
||||
ColorGroup(
|
||||
children: <ColorChip>[
|
||||
ColorChip(label: 'surface', color: colorScheme.surface, onColor: colorScheme.onSurface),
|
||||
ColorChip(
|
||||
label: 'surface',
|
||||
color: colorScheme.surface,
|
||||
onColor: colorScheme.onSurface,
|
||||
),
|
||||
ColorChip(
|
||||
label: 'onSurface',
|
||||
color: colorScheme.onSurface,
|
||||
@ -431,7 +489,12 @@ class ColorGroup extends StatelessWidget {
|
||||
}
|
||||
|
||||
class ColorChip extends StatelessWidget {
|
||||
const ColorChip({super.key, required this.color, required this.label, this.onColor});
|
||||
const ColorChip({
|
||||
super.key,
|
||||
required this.color,
|
||||
required this.label,
|
||||
this.onColor,
|
||||
});
|
||||
|
||||
final Color color;
|
||||
final Color? onColor;
|
||||
|
||||
@ -12,21 +12,25 @@ import 'package:flutter/services.dart';
|
||||
void main() => runApp(const ContextMenuControllerExampleApp());
|
||||
|
||||
/// A builder that includes an Offset to draw the context menu at.
|
||||
typedef ContextMenuBuilder = Widget Function(BuildContext context, Offset offset);
|
||||
typedef ContextMenuBuilder =
|
||||
Widget Function(BuildContext context, Offset offset);
|
||||
|
||||
class ContextMenuControllerExampleApp extends StatefulWidget {
|
||||
const ContextMenuControllerExampleApp({super.key});
|
||||
|
||||
@override
|
||||
State<ContextMenuControllerExampleApp> createState() => _ContextMenuControllerExampleAppState();
|
||||
State<ContextMenuControllerExampleApp> createState() =>
|
||||
_ContextMenuControllerExampleAppState();
|
||||
}
|
||||
|
||||
class _ContextMenuControllerExampleAppState extends State<ContextMenuControllerExampleApp> {
|
||||
class _ContextMenuControllerExampleAppState
|
||||
extends State<ContextMenuControllerExampleApp> {
|
||||
void _showDialog(BuildContext context) {
|
||||
Navigator.of(context).push(
|
||||
DialogRoute<void>(
|
||||
context: context,
|
||||
builder: (BuildContext context) => const AlertDialog(title: Text('You clicked print!')),
|
||||
builder: (BuildContext context) =>
|
||||
const AlertDialog(title: Text('You clicked print!')),
|
||||
),
|
||||
);
|
||||
}
|
||||
@ -93,7 +97,10 @@ class _ContextMenuControllerExampleAppState extends State<ContextMenuControllerE
|
||||
/// By default, shows the menu on right clicks and long presses.
|
||||
class _ContextMenuRegion extends StatefulWidget {
|
||||
/// Creates an instance of [_ContextMenuRegion].
|
||||
const _ContextMenuRegion({required this.child, required this.contextMenuBuilder});
|
||||
const _ContextMenuRegion({
|
||||
required this.child,
|
||||
required this.contextMenuBuilder,
|
||||
});
|
||||
|
||||
/// Builds the context menu.
|
||||
final ContextMenuBuilder contextMenuBuilder;
|
||||
|
||||
@ -23,7 +23,8 @@ class EditableTextToolbarBuilderExampleApp extends StatefulWidget {
|
||||
class _EditableTextToolbarBuilderExampleAppState
|
||||
extends State<EditableTextToolbarBuilderExampleApp> {
|
||||
final TextEditingController _controller = TextEditingController(
|
||||
text: 'Right click (desktop) or long press (mobile) to see the menu with custom buttons.',
|
||||
text:
|
||||
'Right click (desktop) or long press (mobile) to see the menu with custom buttons.',
|
||||
);
|
||||
|
||||
@override
|
||||
@ -55,31 +56,38 @@ class _EditableTextToolbarBuilderExampleAppState
|
||||
const SizedBox(height: 20.0),
|
||||
TextField(
|
||||
controller: _controller,
|
||||
contextMenuBuilder: (BuildContext context, EditableTextState editableTextState) {
|
||||
return AdaptiveTextSelectionToolbar(
|
||||
anchors: editableTextState.contextMenuAnchors,
|
||||
// Build the default buttons, but make them look custom.
|
||||
// In a real project you may want to build different
|
||||
// buttons depending on the platform.
|
||||
children: editableTextState.contextMenuButtonItems.map((
|
||||
ContextMenuButtonItem buttonItem,
|
||||
contextMenuBuilder:
|
||||
(
|
||||
BuildContext context,
|
||||
EditableTextState editableTextState,
|
||||
) {
|
||||
return CupertinoButton(
|
||||
color: const Color(0xffaaaa00),
|
||||
disabledColor: const Color(0xffaaaaff),
|
||||
onPressed: buttonItem.onPressed,
|
||||
padding: const EdgeInsets.all(10.0),
|
||||
pressedOpacity: 0.7,
|
||||
child: SizedBox(
|
||||
width: 200.0,
|
||||
child: Text(
|
||||
CupertinoTextSelectionToolbarButton.getButtonLabel(context, buttonItem),
|
||||
),
|
||||
),
|
||||
return AdaptiveTextSelectionToolbar(
|
||||
anchors: editableTextState.contextMenuAnchors,
|
||||
// Build the default buttons, but make them look custom.
|
||||
// In a real project you may want to build different
|
||||
// buttons depending on the platform.
|
||||
children: editableTextState.contextMenuButtonItems.map((
|
||||
ContextMenuButtonItem buttonItem,
|
||||
) {
|
||||
return CupertinoButton(
|
||||
color: const Color(0xffaaaa00),
|
||||
disabledColor: const Color(0xffaaaaff),
|
||||
onPressed: buttonItem.onPressed,
|
||||
padding: const EdgeInsets.all(10.0),
|
||||
pressedOpacity: 0.7,
|
||||
child: SizedBox(
|
||||
width: 200.0,
|
||||
child: Text(
|
||||
CupertinoTextSelectionToolbarButton.getButtonLabel(
|
||||
context,
|
||||
buttonItem,
|
||||
),
|
||||
),
|
||||
),
|
||||
);
|
||||
}).toList(),
|
||||
);
|
||||
}).toList(),
|
||||
);
|
||||
},
|
||||
},
|
||||
),
|
||||
],
|
||||
),
|
||||
|
||||
@ -65,30 +65,36 @@ class _EditableTextToolbarBuilderExampleAppState
|
||||
Container(height: 20.0),
|
||||
TextField(
|
||||
controller: _controller,
|
||||
contextMenuBuilder: (BuildContext context, EditableTextState editableTextState) {
|
||||
final List<ContextMenuButtonItem> buttonItems =
|
||||
editableTextState.contextMenuButtonItems;
|
||||
// Here we add an "Email" button to the default TextField
|
||||
// context menu for the current platform, but only if an email
|
||||
// address is currently selected.
|
||||
final TextEditingValue value = _controller.value;
|
||||
if (_isValidEmail(value.selection.textInside(value.text))) {
|
||||
buttonItems.insert(
|
||||
0,
|
||||
ContextMenuButtonItem(
|
||||
label: 'Send email',
|
||||
onPressed: () {
|
||||
ContextMenuController.removeAny();
|
||||
_showDialog(context);
|
||||
},
|
||||
),
|
||||
);
|
||||
}
|
||||
return AdaptiveTextSelectionToolbar.buttonItems(
|
||||
anchors: editableTextState.contextMenuAnchors,
|
||||
buttonItems: buttonItems,
|
||||
);
|
||||
},
|
||||
contextMenuBuilder:
|
||||
(
|
||||
BuildContext context,
|
||||
EditableTextState editableTextState,
|
||||
) {
|
||||
final List<ContextMenuButtonItem> buttonItems =
|
||||
editableTextState.contextMenuButtonItems;
|
||||
// Here we add an "Email" button to the default TextField
|
||||
// context menu for the current platform, but only if an email
|
||||
// address is currently selected.
|
||||
final TextEditingValue value = _controller.value;
|
||||
if (_isValidEmail(
|
||||
value.selection.textInside(value.text),
|
||||
)) {
|
||||
buttonItems.insert(
|
||||
0,
|
||||
ContextMenuButtonItem(
|
||||
label: 'Send email',
|
||||
onPressed: () {
|
||||
ContextMenuController.removeAny();
|
||||
_showDialog(context);
|
||||
},
|
||||
),
|
||||
);
|
||||
}
|
||||
return AdaptiveTextSelectionToolbar.buttonItems(
|
||||
anchors: editableTextState.contextMenuAnchors,
|
||||
buttonItems: buttonItems,
|
||||
);
|
||||
},
|
||||
),
|
||||
],
|
||||
),
|
||||
|
||||
@ -22,7 +22,8 @@ class EditableTextToolbarBuilderExampleApp extends StatefulWidget {
|
||||
class _EditableTextToolbarBuilderExampleAppState
|
||||
extends State<EditableTextToolbarBuilderExampleApp> {
|
||||
final TextEditingController _controller = TextEditingController(
|
||||
text: 'Right click (desktop) or long press (mobile) to see the menu with a custom toolbar.',
|
||||
text:
|
||||
'Right click (desktop) or long press (mobile) to see the menu with a custom toolbar.',
|
||||
);
|
||||
|
||||
@override
|
||||
@ -47,46 +48,59 @@ class _EditableTextToolbarBuilderExampleAppState
|
||||
Widget build(BuildContext context) {
|
||||
return MaterialApp(
|
||||
home: Scaffold(
|
||||
appBar: AppBar(title: const Text('Custom toolbar, default-looking buttons')),
|
||||
appBar: AppBar(
|
||||
title: const Text('Custom toolbar, default-looking buttons'),
|
||||
),
|
||||
body: Center(
|
||||
child: Column(
|
||||
children: <Widget>[
|
||||
const SizedBox(height: 20.0),
|
||||
TextField(
|
||||
controller: _controller,
|
||||
contextMenuBuilder: (BuildContext context, EditableTextState editableTextState) {
|
||||
return _MyTextSelectionToolbar(
|
||||
anchor: editableTextState.contextMenuAnchors.primaryAnchor,
|
||||
// getAdaptiveButtons creates the default button widgets for
|
||||
// the current platform.
|
||||
children: AdaptiveTextSelectionToolbar.getAdaptiveButtons(
|
||||
context,
|
||||
// These buttons just close the menu when clicked.
|
||||
<ContextMenuButtonItem>[
|
||||
ContextMenuButtonItem(
|
||||
label: 'One',
|
||||
onPressed: () => ContextMenuController.removeAny(),
|
||||
),
|
||||
ContextMenuButtonItem(
|
||||
label: 'Two',
|
||||
onPressed: () => ContextMenuController.removeAny(),
|
||||
),
|
||||
ContextMenuButtonItem(
|
||||
label: 'Three',
|
||||
onPressed: () => ContextMenuController.removeAny(),
|
||||
),
|
||||
ContextMenuButtonItem(
|
||||
label: 'Four',
|
||||
onPressed: () => ContextMenuController.removeAny(),
|
||||
),
|
||||
ContextMenuButtonItem(
|
||||
label: 'Five',
|
||||
onPressed: () => ContextMenuController.removeAny(),
|
||||
),
|
||||
],
|
||||
).toList(),
|
||||
);
|
||||
},
|
||||
contextMenuBuilder:
|
||||
(
|
||||
BuildContext context,
|
||||
EditableTextState editableTextState,
|
||||
) {
|
||||
return _MyTextSelectionToolbar(
|
||||
anchor:
|
||||
editableTextState.contextMenuAnchors.primaryAnchor,
|
||||
// getAdaptiveButtons creates the default button widgets for
|
||||
// the current platform.
|
||||
children:
|
||||
AdaptiveTextSelectionToolbar.getAdaptiveButtons(
|
||||
context,
|
||||
// These buttons just close the menu when clicked.
|
||||
<ContextMenuButtonItem>[
|
||||
ContextMenuButtonItem(
|
||||
label: 'One',
|
||||
onPressed: () =>
|
||||
ContextMenuController.removeAny(),
|
||||
),
|
||||
ContextMenuButtonItem(
|
||||
label: 'Two',
|
||||
onPressed: () =>
|
||||
ContextMenuController.removeAny(),
|
||||
),
|
||||
ContextMenuButtonItem(
|
||||
label: 'Three',
|
||||
onPressed: () =>
|
||||
ContextMenuController.removeAny(),
|
||||
),
|
||||
ContextMenuButtonItem(
|
||||
label: 'Four',
|
||||
onPressed: () =>
|
||||
ContextMenuController.removeAny(),
|
||||
),
|
||||
ContextMenuButtonItem(
|
||||
label: 'Five',
|
||||
onPressed: () =>
|
||||
ContextMenuController.removeAny(),
|
||||
),
|
||||
],
|
||||
).toList(),
|
||||
);
|
||||
},
|
||||
),
|
||||
],
|
||||
),
|
||||
@ -115,7 +129,7 @@ class _MyTextSelectionToolbar extends StatelessWidget {
|
||||
child: Container(
|
||||
width: 200.0,
|
||||
height: 200.0,
|
||||
color: Colors.cyanAccent.withOpacity(0.5),
|
||||
color: Colors.cyanAccent.withValues(alpha: 0.5),
|
||||
child: GridView.count(
|
||||
padding: const EdgeInsets.all(12.0),
|
||||
crossAxisCount: 2,
|
||||
|
||||
@ -28,7 +28,8 @@ class _SelectableRegionToolbarBuilderExampleAppState
|
||||
Navigator.of(context).push(
|
||||
DialogRoute<void>(
|
||||
context: context,
|
||||
builder: (BuildContext context) => const AlertDialog(title: Text('You clicked print!')),
|
||||
builder: (BuildContext context) =>
|
||||
const AlertDialog(title: Text('You clicked print!')),
|
||||
),
|
||||
);
|
||||
}
|
||||
@ -61,7 +62,10 @@ class _SelectableRegionToolbarBuilderExampleAppState
|
||||
width: 200.0,
|
||||
child: SelectionArea(
|
||||
contextMenuBuilder:
|
||||
(BuildContext context, SelectableRegionState selectableRegionState) {
|
||||
(
|
||||
BuildContext context,
|
||||
SelectableRegionState selectableRegionState,
|
||||
) {
|
||||
return AdaptiveTextSelectionToolbar.buttonItems(
|
||||
anchors: selectableRegionState.contextMenuAnchors,
|
||||
buttonItems: <ContextMenuButtonItem>[
|
||||
@ -76,7 +80,9 @@ class _SelectableRegionToolbarBuilderExampleAppState
|
||||
],
|
||||
);
|
||||
},
|
||||
child: ListView(children: const <Widget>[SizedBox(height: 20.0), Text(text)]),
|
||||
child: ListView(
|
||||
children: const <Widget>[SizedBox(height: 20.0), Text(text)],
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
|
||||
@ -41,10 +41,14 @@ class _DataTableExampleState extends State<DataTableExample> {
|
||||
rows: List<DataRow>.generate(
|
||||
numItems,
|
||||
(int index) => DataRow(
|
||||
color: WidgetStateProperty.resolveWith<Color?>((Set<WidgetState> states) {
|
||||
color: WidgetStateProperty.resolveWith<Color?>((
|
||||
Set<WidgetState> states,
|
||||
) {
|
||||
// All rows will have the same selected color.
|
||||
if (states.contains(WidgetState.selected)) {
|
||||
return Theme.of(context).colorScheme.primary.withValues(alpha: 0.08);
|
||||
return Theme.of(
|
||||
context,
|
||||
).colorScheme.primary.withValues(alpha: 0.08);
|
||||
}
|
||||
// Even rows will have a grey color.
|
||||
if (index.isEven) {
|
||||
|
||||
@ -24,7 +24,8 @@ class CalendarDatePickerExample extends StatefulWidget {
|
||||
const CalendarDatePickerExample({super.key});
|
||||
|
||||
@override
|
||||
State<CalendarDatePickerExample> createState() => _CalendarDatePickerExampleState();
|
||||
State<CalendarDatePickerExample> createState() =>
|
||||
_CalendarDatePickerExampleState();
|
||||
}
|
||||
|
||||
class _CalendarDatePickerExampleState extends State<CalendarDatePickerExample> {
|
||||
@ -90,7 +91,8 @@ class CustomCalendarDelegate extends CalendarDelegate<DateTime> {
|
||||
DateTime dateOnly(DateTime date) => DateUtils.dateOnly(date);
|
||||
|
||||
@override
|
||||
int monthDelta(DateTime startDate, DateTime endDate) => DateUtils.monthDelta(startDate, endDate);
|
||||
int monthDelta(DateTime startDate, DateTime endDate) =>
|
||||
DateUtils.monthDelta(startDate, endDate);
|
||||
|
||||
@override
|
||||
DateTime addMonthsToMonthDate(DateTime monthDate, int monthsToAdd) {
|
||||
@ -98,7 +100,8 @@ class CustomCalendarDelegate extends CalendarDelegate<DateTime> {
|
||||
}
|
||||
|
||||
@override
|
||||
DateTime addDaysToDate(DateTime date, int days) => DateUtils.addDaysToDate(date, days);
|
||||
DateTime addDaysToDate(DateTime date, int days) =>
|
||||
DateUtils.addDaysToDate(date, days);
|
||||
|
||||
@override
|
||||
DateTime getMonth(int year, int month) => DateTime(year, month);
|
||||
@ -117,7 +120,10 @@ class CustomCalendarDelegate extends CalendarDelegate<DateTime> {
|
||||
}
|
||||
|
||||
@override
|
||||
String formatShortMonthDay(DateTime date, MaterialLocalizations localizations) {
|
||||
String formatShortMonthDay(
|
||||
DateTime date,
|
||||
MaterialLocalizations localizations,
|
||||
) {
|
||||
return localizations.formatShortMonthDay(date);
|
||||
}
|
||||
|
||||
@ -137,7 +143,10 @@ class CustomCalendarDelegate extends CalendarDelegate<DateTime> {
|
||||
}
|
||||
|
||||
@override
|
||||
DateTime? parseCompactDate(String? inputString, MaterialLocalizations localizations) {
|
||||
DateTime? parseCompactDate(
|
||||
String? inputString,
|
||||
MaterialLocalizations localizations,
|
||||
) {
|
||||
return localizations.parseCompactDate(inputString);
|
||||
}
|
||||
|
||||
|
||||
@ -16,13 +16,19 @@ class DatePickerApp extends StatelessWidget {
|
||||
return MaterialApp(
|
||||
theme: ThemeData(
|
||||
datePickerTheme: DatePickerThemeData(
|
||||
todayBackgroundColor: const WidgetStatePropertyAll<Color>(Colors.amber),
|
||||
todayForegroundColor: const WidgetStatePropertyAll<Color>(Colors.black),
|
||||
todayBackgroundColor: const WidgetStatePropertyAll<Color>(
|
||||
Colors.amber,
|
||||
),
|
||||
todayForegroundColor: const WidgetStatePropertyAll<Color>(
|
||||
Colors.black,
|
||||
),
|
||||
todayBorder: const BorderSide(width: 2),
|
||||
dayShape: WidgetStatePropertyAll<OutlinedBorder>(
|
||||
RoundedRectangleBorder(borderRadius: BorderRadius.circular(8.0)),
|
||||
),
|
||||
shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(16.0)),
|
||||
shape: RoundedRectangleBorder(
|
||||
borderRadius: BorderRadius.circular(16.0),
|
||||
),
|
||||
),
|
||||
),
|
||||
home: const DatePickerExample(),
|
||||
|
||||
@ -30,13 +30,16 @@ class DatePickerExample extends StatefulWidget {
|
||||
}
|
||||
|
||||
/// RestorationProperty objects can be used because of RestorationMixin.
|
||||
class _DatePickerExampleState extends State<DatePickerExample> with RestorationMixin {
|
||||
class _DatePickerExampleState extends State<DatePickerExample>
|
||||
with RestorationMixin {
|
||||
// In this example, the restoration ID for the mixin is passed in through
|
||||
// the [StatefulWidget]'s constructor.
|
||||
@override
|
||||
String? get restorationId => widget.restorationId;
|
||||
|
||||
final RestorableDateTime _selectedDate = RestorableDateTime(DateTime(2021, 7, 25));
|
||||
final RestorableDateTime _selectedDate = RestorableDateTime(
|
||||
DateTime(2021, 7, 25),
|
||||
);
|
||||
late final RestorableRouteFuture<DateTime?> _restorableDatePickerRouteFuture =
|
||||
RestorableRouteFuture<DateTime?>(
|
||||
onComplete: _selectDate,
|
||||
@ -49,7 +52,10 @@ class _DatePickerExampleState extends State<DatePickerExample> with RestorationM
|
||||
);
|
||||
|
||||
@pragma('vm:entry-point')
|
||||
static Route<DateTime> _datePickerRoute(BuildContext context, Object? arguments) {
|
||||
static Route<DateTime> _datePickerRoute(
|
||||
BuildContext context,
|
||||
Object? arguments,
|
||||
) {
|
||||
return DialogRoute<DateTime>(
|
||||
context: context,
|
||||
builder: (BuildContext context) {
|
||||
@ -67,7 +73,10 @@ class _DatePickerExampleState extends State<DatePickerExample> with RestorationM
|
||||
@override
|
||||
void restoreState(RestorationBucket? oldBucket, bool initialRestore) {
|
||||
registerForRestoration(_selectedDate, 'selected_date');
|
||||
registerForRestoration(_restorableDatePickerRouteFuture, 'date_picker_route_future');
|
||||
registerForRestoration(
|
||||
_restorableDatePickerRouteFuture,
|
||||
'date_picker_route_future',
|
||||
);
|
||||
}
|
||||
|
||||
void _selectDate(DateTime? newSelectedDate) {
|
||||
|
||||
@ -56,7 +56,10 @@ class _DatePickerExampleState extends State<DatePickerExample> {
|
||||
? '${selectedDate!.day}/${selectedDate!.month}/${selectedDate!.year}'
|
||||
: 'No date selected',
|
||||
),
|
||||
OutlinedButton(onPressed: _selectDate, child: const Text('Select Date')),
|
||||
OutlinedButton(
|
||||
onPressed: _selectDate,
|
||||
child: const Text('Select Date'),
|
||||
),
|
||||
],
|
||||
);
|
||||
}
|
||||
|
||||
@ -30,27 +30,30 @@ class DatePickerExample extends StatefulWidget {
|
||||
}
|
||||
|
||||
/// RestorationProperty objects can be used because of RestorationMixin.
|
||||
class _DatePickerExampleState extends State<DatePickerExample> with RestorationMixin {
|
||||
class _DatePickerExampleState extends State<DatePickerExample>
|
||||
with RestorationMixin {
|
||||
// In this example, the restoration ID for the mixin is passed in through
|
||||
// the [StatefulWidget]'s constructor.
|
||||
@override
|
||||
String? get restorationId => widget.restorationId;
|
||||
|
||||
final RestorableDateTimeN _startDate = RestorableDateTimeN(DateTime(2021));
|
||||
final RestorableDateTimeN _endDate = RestorableDateTimeN(DateTime(2021, 1, 5));
|
||||
late final RestorableRouteFuture<DateTimeRange?> _restorableDateRangePickerRouteFuture =
|
||||
RestorableRouteFuture<DateTimeRange?>(
|
||||
onComplete: _selectDateRange,
|
||||
onPresent: (NavigatorState navigator, Object? arguments) {
|
||||
return navigator.restorablePush(
|
||||
_dateRangePickerRoute,
|
||||
arguments: <String, dynamic>{
|
||||
'initialStartDate': _startDate.value?.millisecondsSinceEpoch,
|
||||
'initialEndDate': _endDate.value?.millisecondsSinceEpoch,
|
||||
},
|
||||
);
|
||||
final RestorableDateTimeN _endDate = RestorableDateTimeN(
|
||||
DateTime(2021, 1, 5),
|
||||
);
|
||||
late final RestorableRouteFuture<DateTimeRange?>
|
||||
_restorableDateRangePickerRouteFuture = RestorableRouteFuture<DateTimeRange?>(
|
||||
onComplete: _selectDateRange,
|
||||
onPresent: (NavigatorState navigator, Object? arguments) {
|
||||
return navigator.restorablePush(
|
||||
_dateRangePickerRoute,
|
||||
arguments: <String, dynamic>{
|
||||
'initialStartDate': _startDate.value?.millisecondsSinceEpoch,
|
||||
'initialEndDate': _endDate.value?.millisecondsSinceEpoch,
|
||||
},
|
||||
);
|
||||
},
|
||||
);
|
||||
|
||||
void _selectDateRange(DateTimeRange? newSelectedDate) {
|
||||
if (newSelectedDate != null) {
|
||||
@ -65,17 +68,25 @@ class _DatePickerExampleState extends State<DatePickerExample> with RestorationM
|
||||
void restoreState(RestorationBucket? oldBucket, bool initialRestore) {
|
||||
registerForRestoration(_startDate, 'start_date');
|
||||
registerForRestoration(_endDate, 'end_date');
|
||||
registerForRestoration(_restorableDateRangePickerRouteFuture, 'date_picker_route_future');
|
||||
registerForRestoration(
|
||||
_restorableDateRangePickerRouteFuture,
|
||||
'date_picker_route_future',
|
||||
);
|
||||
}
|
||||
|
||||
@pragma('vm:entry-point')
|
||||
static Route<DateTimeRange?> _dateRangePickerRoute(BuildContext context, Object? arguments) {
|
||||
static Route<DateTimeRange?> _dateRangePickerRoute(
|
||||
BuildContext context,
|
||||
Object? arguments,
|
||||
) {
|
||||
return DialogRoute<DateTimeRange?>(
|
||||
context: context,
|
||||
builder: (BuildContext context) {
|
||||
return DateRangePickerDialog(
|
||||
restorationId: 'date_picker_dialog',
|
||||
initialDateRange: _initialDateTimeRange(arguments! as Map<dynamic, dynamic>),
|
||||
initialDateRange: _initialDateTimeRange(
|
||||
arguments! as Map<dynamic, dynamic>,
|
||||
),
|
||||
firstDate: DateTime(2021),
|
||||
currentDate: DateTime(2021, 1, 25),
|
||||
lastDate: DateTime(2022),
|
||||
@ -85,10 +96,15 @@ class _DatePickerExampleState extends State<DatePickerExample> with RestorationM
|
||||
}
|
||||
|
||||
static DateTimeRange? _initialDateTimeRange(Map<dynamic, dynamic> arguments) {
|
||||
if (arguments['initialStartDate'] != null && arguments['initialEndDate'] != null) {
|
||||
if (arguments['initialStartDate'] != null &&
|
||||
arguments['initialEndDate'] != null) {
|
||||
return DateTimeRange(
|
||||
start: DateTime.fromMillisecondsSinceEpoch(arguments['initialStartDate'] as int),
|
||||
end: DateTime.fromMillisecondsSinceEpoch(arguments['initialEndDate'] as int),
|
||||
start: DateTime.fromMillisecondsSinceEpoch(
|
||||
arguments['initialStartDate'] as int,
|
||||
),
|
||||
end: DateTime.fromMillisecondsSinceEpoch(
|
||||
arguments['initialEndDate'] as int,
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
@ -38,7 +38,10 @@ class DialogExample extends StatelessWidget {
|
||||
onPressed: () => Navigator.pop(context, 'Cancel'),
|
||||
child: const Text('Cancel'),
|
||||
),
|
||||
TextButton(onPressed: () => Navigator.pop(context, 'OK'), child: const Text('OK')),
|
||||
TextButton(
|
||||
onPressed: () => Navigator.pop(context, 'OK'),
|
||||
child: const Text('OK'),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
|
||||
@ -39,7 +39,10 @@ class DialogExample extends StatelessWidget {
|
||||
onPressed: () => Navigator.pop(context, 'Cancel'),
|
||||
child: const Text('Cancel'),
|
||||
),
|
||||
TextButton(onPressed: () => Navigator.pop(context, 'OK'), child: const Text('OK')),
|
||||
TextButton(
|
||||
onPressed: () => Navigator.pop(context, 'OK'),
|
||||
child: const Text('OK'),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Loading…
x
Reference in New Issue
Block a user