Last active
September 25, 2023 16:02
-
-
Save hectorAguero/fc079d392975045afab647dc349fdc29 to your computer and use it in GitHub Desktop.
Flutter Cupertino
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import 'package:flutter/cupertino.dart'; | |
import 'package:flutter/material.dart'; | |
import 'package:intl/intl.dart'; | |
void main() => runApp(const MyApp()); | |
TextTheme cupertinoTextTheme = TextTheme( | |
headlineMedium: const CupertinoThemeData() | |
.textTheme | |
.navLargeTitleTextStyle | |
// fixes a small bug with spacing | |
.copyWith(letterSpacing: -1.5), | |
titleLarge: const CupertinoThemeData().textTheme.navTitleTextStyle, | |
); | |
class MyApp extends StatelessWidget { | |
const MyApp({super.key}); | |
@override | |
Widget build(BuildContext context) { | |
return MaterialApp( | |
debugShowCheckedModeBanner: false, | |
builder: (context, child) => CupertinoTheme( | |
data: CupertinoThemeData( | |
brightness: MediaQuery.platformBrightnessOf(context), | |
primaryColor: CupertinoColors.systemBlue, | |
barBackgroundColor: CupertinoDynamicColor.resolve( | |
CupertinoColors.systemGroupedBackground, | |
context, | |
), | |
scaffoldBackgroundColor: CupertinoDynamicColor.resolve( | |
CupertinoColors.systemGroupedBackground, | |
context, | |
), | |
textTheme: CupertinoTextThemeData( | |
navLargeTitleTextStyle: const CupertinoThemeData() | |
.textTheme | |
.navLargeTitleTextStyle | |
// fixes a small bug with spacing | |
.copyWith(letterSpacing: -1.5), | |
), | |
), | |
child: child!, | |
), | |
theme: ThemeData.light().copyWith( | |
scaffoldBackgroundColor: CupertinoDynamicColor.resolve( | |
CupertinoColors.systemGroupedBackground, | |
context, | |
), | |
textTheme: cupertinoTextTheme, | |
), | |
darkTheme: ThemeData.dark().copyWith( | |
scaffoldBackgroundColor: CupertinoDynamicColor.resolve( | |
CupertinoColors.systemGroupedBackground, | |
context, | |
), | |
textTheme: cupertinoTextTheme, | |
), | |
home: const HomePage(), | |
); | |
} | |
} | |
class HomePage extends StatelessWidget { | |
const HomePage({super.key}); | |
@override | |
Widget build(BuildContext context) { | |
final chooseSwitch = ValueNotifier<bool>(false); | |
final dateNotifier = ValueNotifier<DateTime>(DateTime.now()); | |
final awesomeCounter = ValueNotifier<int>(0); | |
return Scaffold( | |
body: CustomScrollView( | |
slivers: [ | |
const CupertinoSliverNavigationBar( | |
largeTitle: Text('Swift UI Config Demo'), | |
stretch: true, | |
border: Border(), | |
), | |
SliverToBoxAdapter( | |
child: CupertinoListSection.insetGrouped( | |
additionalDividerMargin: 8, | |
header: const Padding( | |
padding: EdgeInsets.only(left: 20), | |
child: Text( | |
'FIRST SECTION', | |
style: TextStyle( | |
fontSize: 13, | |
color: CupertinoColors.systemGrey2, | |
), | |
), | |
), | |
children: <CupertinoListTile>[ | |
CupertinoListTile( | |
title: const Text('On or off: you choose'), | |
trailing: ValueListenableBuilder( | |
valueListenable: chooseSwitch, | |
builder: (context, value, child) { | |
return CupertinoSwitch( | |
value: value, | |
onChanged: (value) { | |
chooseSwitch.value = value; | |
}, | |
); | |
}, | |
), | |
), | |
CupertinoListTile( | |
title: ValueListenableBuilder( | |
valueListenable: awesomeCounter, | |
builder: (context, value, child) { | |
return Text('Awesomeness: $value'); | |
}, | |
), | |
trailing: ValueListenableBuilder( | |
valueListenable: awesomeCounter, | |
builder: (context, value, child) { | |
return Row( | |
children: [ | |
CupertinoButton( | |
minSize: 30, | |
color: CupertinoColors.systemGrey5, | |
disabledColor: CupertinoColors.systemGrey6, | |
padding: const EdgeInsets.symmetric(horizontal: 12), | |
onPressed: value == 0 | |
? null | |
: () { | |
awesomeCounter.value = (value - 1) | |
.clamp(0, double.infinity) | |
.toInt(); | |
}, | |
borderRadius: | |
const BorderRadius.all(Radius.circular(8)) | |
.copyWith( | |
topRight: Radius.zero, | |
bottomRight: Radius.zero, | |
), | |
child: const Icon( | |
CupertinoIcons.minus, | |
size: 16, | |
color: CupertinoColors.systemGrey, | |
), | |
), | |
const SizedBox( | |
height: 30, | |
child: VerticalDivider( | |
width: 0, | |
color: CupertinoColors.separator, | |
endIndent: 6, | |
indent: 6, | |
), | |
), | |
CupertinoButton( | |
minSize: 30, | |
color: CupertinoColors.systemGrey5, | |
padding: const EdgeInsets.symmetric(horizontal: 12), | |
borderRadius: | |
const BorderRadius.all(Radius.circular(8)) | |
.copyWith( | |
topLeft: Radius.zero, | |
bottomLeft: Radius.zero, | |
), | |
onPressed: () => awesomeCounter.value++, | |
child: const Icon( | |
CupertinoIcons.plus, | |
size: 16, | |
color: CupertinoColors.systemGrey, | |
), | |
), | |
], | |
); | |
}, | |
), | |
), | |
CupertinoListTile( | |
title: const Text('Date'), | |
trailing: ValueListenableBuilder( | |
valueListenable: dateNotifier, | |
builder: (context, value, child) { | |
return Row( | |
children: [ | |
CupertinoButton( | |
minSize: 30, | |
padding: const EdgeInsets.symmetric(horizontal: 12), | |
color: CupertinoColors.systemGrey5, | |
child: Text( | |
DateFormat(DateFormat.YEAR_ABBR_MONTH_DAY) | |
.format(value), | |
style: TextStyle( | |
color: | |
CupertinoColors.label.resolveFrom(context), | |
), | |
), | |
onPressed: () { | |
_showDialog( | |
context: context, | |
child: CupertinoDatePicker( | |
initialDateTime: DateTime.now(), | |
mode: CupertinoDatePickerMode.date, | |
onDateTimeChanged: (DateTime newDate) { | |
dateNotifier.value = newDate; | |
}, | |
), | |
); | |
}, | |
), | |
const SizedBox(width: 4), | |
CupertinoButton( | |
color: CupertinoColors.systemGrey5, | |
minSize: 30, | |
padding: const EdgeInsets.symmetric(horizontal: 12), | |
child: Text( | |
DateFormat(DateFormat.HOUR_MINUTE).format(value), | |
style: TextStyle( | |
color: | |
CupertinoColors.label.resolveFrom(context), | |
), | |
), | |
onPressed: () { | |
_showDialog( | |
context: context, | |
child: CupertinoDatePicker( | |
initialDateTime: DateTime.now(), | |
mode: CupertinoDatePickerMode.time, | |
onDateTimeChanged: (DateTime newDate) { | |
dateNotifier.value = newDate; | |
}, | |
), | |
); | |
}, | |
), | |
], | |
); | |
}, | |
), | |
), | |
], | |
), | |
), | |
const SliverPadding( | |
padding: EdgeInsets.only(left: 40, bottom: 16), | |
sliver: SliverToBoxAdapter( | |
child: Text( | |
'This sections contains some useful settings.', | |
style: TextStyle(color: CupertinoColors.systemGrey), | |
), | |
), | |
), | |
SliverToBoxAdapter( | |
child: CupertinoListSection.insetGrouped( | |
additionalDividerMargin: 8, | |
header: const Padding( | |
padding: EdgeInsets.only(left: 20), | |
child: Text( | |
'SECOND SECTION', | |
style: TextStyle( | |
fontSize: 13, | |
color: CupertinoColors.systemGrey2, | |
), | |
), | |
), | |
children: List.generate( | |
4, | |
(index) => CupertinoListTile( | |
title: const Text('Hello World!'), | |
onTap: () {}, | |
), | |
), | |
), | |
), | |
], | |
), | |
); | |
} | |
} | |
void _showDialog({required BuildContext context, required Widget child}) { | |
showCupertinoModalPopup<void>( | |
context: context, | |
builder: (BuildContext context) => Container( | |
height: 216, | |
padding: const EdgeInsets.only(top: 6), | |
margin: EdgeInsets.only( | |
bottom: MediaQuery.of(context).viewInsets.bottom, | |
), | |
color: CupertinoColors.systemBackground.resolveFrom(context), | |
child: SafeArea( | |
top: false, | |
child: child, | |
), | |
), | |
); | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment