Skip to content

Instantly share code, notes, and snippets.

@hectorAguero
Last active September 25, 2023 16:02
Show Gist options
  • Save hectorAguero/fc079d392975045afab647dc349fdc29 to your computer and use it in GitHub Desktop.
Save hectorAguero/fc079d392975045afab647dc349fdc29 to your computer and use it in GitHub Desktop.
Flutter Cupertino
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