mirror of
https://github.com/flutter/samples.git
synced 2025-11-08 13:58:47 +00:00
Update VeggieSeasons Settings screen to use CupertinoList (#2426)
## Pre-launch Checklist - [x] I read the [Flutter Style Guide] _recently_, and have followed its advice. - [x] I signed the [CLA]. - [x] I read the [Contributors Guide]. - [x] I updated/added relevant documentation (doc comments with `///`). - [x] All existing and new tests are passing. If you need help, consider asking for advice on the #hackers-devrel channel on [Discord]. <!-- Links --> [Flutter Style Guide]: https://github.com/flutter/flutter/blob/master/docs/contributing/Style-guide-for-Flutter-repo.md [CLA]: https://cla.developers.google.com/ [Discord]: https://github.com/flutter/flutter/blob/master/docs/contributing/Chat.md [Contributors Guide]: https://github.com/flutter/samples/blob/main/CONTRIBUTING.md
This commit is contained in:
@@ -8,8 +8,6 @@ import 'package:provider/provider.dart';
|
|||||||
import '../data/preferences.dart';
|
import '../data/preferences.dart';
|
||||||
import '../data/veggie.dart';
|
import '../data/veggie.dart';
|
||||||
import '../styles.dart';
|
import '../styles.dart';
|
||||||
import '../widgets/settings_group.dart';
|
|
||||||
import '../widgets/settings_item.dart';
|
|
||||||
|
|
||||||
class VeggieCategorySettingsScreen extends StatelessWidget {
|
class VeggieCategorySettingsScreen extends StatelessWidget {
|
||||||
const VeggieCategorySettingsScreen({super.key, this.restorationId});
|
const VeggieCategorySettingsScreen({super.key, this.restorationId});
|
||||||
@@ -40,7 +38,7 @@ class VeggieCategorySettingsScreen extends StatelessWidget {
|
|||||||
child: FutureBuilder<Set<VeggieCategory>>(
|
child: FutureBuilder<Set<VeggieCategory>>(
|
||||||
future: currentPrefs,
|
future: currentPrefs,
|
||||||
builder: (context, snapshot) {
|
builder: (context, snapshot) {
|
||||||
final items = <SettingsItem>[];
|
final tiles = <CupertinoListTile>[];
|
||||||
|
|
||||||
for (final category in VeggieCategory.values) {
|
for (final category in VeggieCategory.values) {
|
||||||
CupertinoSwitch toggle;
|
CupertinoSwitch toggle;
|
||||||
@@ -66,17 +64,20 @@ class VeggieCategorySettingsScreen extends StatelessWidget {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
items.add(SettingsItem(
|
tiles.add(
|
||||||
label: veggieCategoryNames[category]!,
|
CupertinoListTile.notched(
|
||||||
content: toggle,
|
title: Text(veggieCategoryNames[category]!),
|
||||||
));
|
trailing: toggle,
|
||||||
|
),
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
return ListView(
|
return ListView(
|
||||||
restorationId: 'list',
|
restorationId: 'list',
|
||||||
children: [
|
children: [
|
||||||
SettingsGroup(
|
CupertinoListSection.insetGrouped(
|
||||||
items: items,
|
hasLeading: false,
|
||||||
|
children: tiles,
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
);
|
);
|
||||||
@@ -121,33 +122,39 @@ class CalorieSettingsScreen extends StatelessWidget {
|
|||||||
FutureBuilder<int>(
|
FutureBuilder<int>(
|
||||||
future: model.desiredCalories,
|
future: model.desiredCalories,
|
||||||
builder: (context, snapshot) {
|
builder: (context, snapshot) {
|
||||||
final steps = <SettingsItem>[];
|
final tiles = <CupertinoListTile>[];
|
||||||
|
|
||||||
for (var cals = max; cals < min; cals += step) {
|
for (var cals = max; cals < min; cals += step) {
|
||||||
steps.add(
|
tiles.add(
|
||||||
SettingsItem(
|
CupertinoListTile.notched(
|
||||||
label: cals.toString(),
|
title: Text('$cals calories'),
|
||||||
icon: SettingsIcon(
|
trailing: SettingsIcon(
|
||||||
icon: Styles.checkIcon,
|
icon: CupertinoIcons.check_mark,
|
||||||
foregroundColor:
|
foregroundColor:
|
||||||
snapshot.hasData && snapshot.data == cals
|
snapshot.hasData && snapshot.data == cals
|
||||||
? CupertinoColors.activeBlue
|
? CupertinoColors.activeBlue
|
||||||
: Styles.transparentColor,
|
: Styles.transparentColor,
|
||||||
backgroundColor: Styles.transparentColor,
|
backgroundColor: Styles.transparentColor,
|
||||||
),
|
),
|
||||||
onPress: snapshot.hasData
|
onTap: snapshot.hasData
|
||||||
? () => model.setDesiredCalories(cals)
|
? () => model.setDesiredCalories(cals)
|
||||||
: null,
|
: null,
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
return SettingsGroup(
|
return CupertinoListSection.insetGrouped(
|
||||||
items: steps,
|
header: Text(
|
||||||
header: const SettingsGroupHeader('Available calorie levels'),
|
'Available calorie levels'.toUpperCase(),
|
||||||
footer:
|
style: Styles.settingsGroupHeaderText(
|
||||||
const SettingsGroupFooter('These are used for serving '
|
CupertinoTheme.of(context)),
|
||||||
'calculations'),
|
),
|
||||||
|
footer: Text(
|
||||||
|
'These are used for serving calculations',
|
||||||
|
style: Styles.settingsGroupFooterText(
|
||||||
|
CupertinoTheme.of(context)),
|
||||||
|
),
|
||||||
|
children: tiles,
|
||||||
);
|
);
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
@@ -168,59 +175,50 @@ class SettingsScreen extends StatefulWidget {
|
|||||||
}
|
}
|
||||||
|
|
||||||
class _SettingsScreenState extends State<SettingsScreen> {
|
class _SettingsScreenState extends State<SettingsScreen> {
|
||||||
SettingsItem _buildCaloriesItem(BuildContext context, Preferences prefs) {
|
CupertinoListTile _buildCaloriesTile(
|
||||||
return SettingsItem(
|
BuildContext context, Preferences prefs) {
|
||||||
label: 'Calorie Target',
|
return CupertinoListTile.notched(
|
||||||
icon: const SettingsIcon(
|
leading: const SettingsIcon(
|
||||||
backgroundColor: Styles.iconBlue,
|
backgroundColor: CupertinoColors.systemBlue,
|
||||||
icon: Styles.calorieIcon,
|
icon: Styles.calorieIcon,
|
||||||
),
|
),
|
||||||
content: FutureBuilder<int>(
|
title: const Text('Calorie Target'),
|
||||||
|
additionalInfo: FutureBuilder<int>(
|
||||||
future: prefs.desiredCalories,
|
future: prefs.desiredCalories,
|
||||||
builder: (context, snapshot) {
|
builder: (context, snapshot) {
|
||||||
return Row(
|
return Text(
|
||||||
children: [
|
snapshot.data?.toString() ?? '',
|
||||||
Text(
|
style: CupertinoTheme.of(context).textTheme.textStyle,
|
||||||
snapshot.data?.toString() ?? '',
|
|
||||||
style: CupertinoTheme.of(context).textTheme.textStyle,
|
|
||||||
),
|
|
||||||
const SizedBox(width: 8),
|
|
||||||
const SettingsNavigationIndicator(),
|
|
||||||
],
|
|
||||||
);
|
);
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
onPress: () {
|
trailing: const CupertinoListTileChevron(),
|
||||||
context.go('/settings/calories');
|
onTap: () => context.go('/settings/calories'),
|
||||||
},
|
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
SettingsItem _buildCategoriesItem(BuildContext context, Preferences prefs) {
|
CupertinoListTile _buildCategoriesTile(
|
||||||
return SettingsItem(
|
BuildContext context, Preferences prefs) {
|
||||||
label: 'Preferred Categories',
|
return CupertinoListTile.notched(
|
||||||
subtitle: 'What types of veggies you prefer!',
|
leading: const SettingsIcon(
|
||||||
icon: const SettingsIcon(
|
backgroundColor: CupertinoColors.systemOrange,
|
||||||
backgroundColor: Styles.iconGold,
|
|
||||||
icon: Styles.preferenceIcon,
|
icon: Styles.preferenceIcon,
|
||||||
),
|
),
|
||||||
content: const SettingsNavigationIndicator(),
|
title: const Text('Preferred Categories'),
|
||||||
onPress: () {
|
trailing: const CupertinoListTileChevron(),
|
||||||
context.go('/settings/categories');
|
onTap: () => context.go('/settings/categories'),
|
||||||
},
|
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
SettingsItem _buildRestoreDefaultsItem(
|
CupertinoListTile _buildRestoreDefaultsTile(
|
||||||
BuildContext context, Preferences prefs) {
|
BuildContext context, Preferences prefs) {
|
||||||
return SettingsItem(
|
return CupertinoListTile.notched(
|
||||||
label: 'Restore Defaults',
|
leading: const SettingsIcon(
|
||||||
icon: const SettingsIcon(
|
|
||||||
backgroundColor: CupertinoColors.systemRed,
|
backgroundColor: CupertinoColors.systemRed,
|
||||||
icon: Styles.resetIcon,
|
icon: Styles.resetIcon,
|
||||||
),
|
),
|
||||||
content: const SettingsNavigationIndicator(),
|
title: const Text('Restore Defaults'),
|
||||||
onPress: () {
|
onTap: () {
|
||||||
showCupertinoDialog<void>(
|
showCupertinoDialog<void>(
|
||||||
context: context,
|
context: context,
|
||||||
builder: (context) => CupertinoAlertDialog(
|
builder: (context) => CupertinoAlertDialog(
|
||||||
@@ -254,36 +252,61 @@ class _SettingsScreenState extends State<SettingsScreen> {
|
|||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
final prefs = Provider.of<Preferences>(context);
|
final prefs = Provider.of<Preferences>(context);
|
||||||
|
|
||||||
return RestorationScope(
|
return CupertinoPageScaffold(
|
||||||
restorationId: widget.restorationId,
|
backgroundColor:
|
||||||
child: CupertinoPageScaffold(
|
Styles.scaffoldBackground(CupertinoTheme.brightnessOf(context)),
|
||||||
child: Container(
|
child: CustomScrollView(
|
||||||
color:
|
slivers: <Widget>[
|
||||||
Styles.scaffoldBackground(CupertinoTheme.brightnessOf(context)),
|
const CupertinoSliverNavigationBar(
|
||||||
child: CustomScrollView(
|
largeTitle: Text('Settings'),
|
||||||
restorationId: 'list',
|
|
||||||
slivers: [
|
|
||||||
const CupertinoSliverNavigationBar(
|
|
||||||
largeTitle: Text('Settings'),
|
|
||||||
),
|
|
||||||
SliverSafeArea(
|
|
||||||
top: false,
|
|
||||||
sliver: SliverList(
|
|
||||||
delegate: SliverChildListDelegate(
|
|
||||||
[
|
|
||||||
SettingsGroup(
|
|
||||||
items: [
|
|
||||||
_buildCaloriesItem(context, prefs),
|
|
||||||
_buildCategoriesItem(context, prefs),
|
|
||||||
_buildRestoreDefaultsItem(context, prefs),
|
|
||||||
],
|
|
||||||
),
|
|
||||||
],
|
|
||||||
),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
],
|
|
||||||
),
|
),
|
||||||
|
SliverList(
|
||||||
|
delegate: SliverChildListDelegate(
|
||||||
|
[
|
||||||
|
CupertinoListSection.insetGrouped(
|
||||||
|
children: [
|
||||||
|
_buildCaloriesTile(context, prefs),
|
||||||
|
_buildCategoriesTile(context, prefs),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
CupertinoListSection.insetGrouped(
|
||||||
|
children: [
|
||||||
|
_buildRestoreDefaultsTile(context, prefs),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class SettingsIcon extends StatelessWidget {
|
||||||
|
const SettingsIcon({
|
||||||
|
required this.icon,
|
||||||
|
this.foregroundColor = CupertinoColors.white,
|
||||||
|
this.backgroundColor = CupertinoColors.black,
|
||||||
|
super.key,
|
||||||
|
});
|
||||||
|
|
||||||
|
final Color backgroundColor;
|
||||||
|
final Color foregroundColor;
|
||||||
|
final IconData icon;
|
||||||
|
|
||||||
|
@override
|
||||||
|
Widget build(BuildContext context) {
|
||||||
|
return Container(
|
||||||
|
decoration: BoxDecoration(
|
||||||
|
borderRadius: BorderRadius.circular(5),
|
||||||
|
color: backgroundColor,
|
||||||
|
),
|
||||||
|
child: Center(
|
||||||
|
child: Icon(
|
||||||
|
icon,
|
||||||
|
color: foregroundColor,
|
||||||
|
size: 20,
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
|
|||||||
@@ -107,7 +107,7 @@ abstract class Styles {
|
|||||||
|
|
||||||
static TextStyle settingsGroupFooterText(CupertinoThemeData themeData) =>
|
static TextStyle settingsGroupFooterText(CupertinoThemeData themeData) =>
|
||||||
themeData.textTheme.textStyle.copyWith(
|
themeData.textTheme.textStyle.copyWith(
|
||||||
color: Styles.settingsGroupSubtitle,
|
color: const Color(0xff777777),
|
||||||
fontSize: 13,
|
fontSize: 13,
|
||||||
letterSpacing: -0.08,
|
letterSpacing: -0.08,
|
||||||
);
|
);
|
||||||
@@ -116,7 +116,7 @@ abstract class Styles {
|
|||||||
|
|
||||||
static Color? scaffoldBackground(Brightness brightness) =>
|
static Color? scaffoldBackground(Brightness brightness) =>
|
||||||
brightness == Brightness.light
|
brightness == Brightness.light
|
||||||
? CupertinoColors.lightBackgroundGray
|
? CupertinoColors.extraLightBackgroundGray
|
||||||
: null;
|
: null;
|
||||||
|
|
||||||
static const frostedBackground = Color(0xccf8f8f8);
|
static const frostedBackground = Color(0xccf8f8f8);
|
||||||
@@ -203,12 +203,6 @@ abstract class Styles {
|
|||||||
|
|
||||||
static const Color settingsBackground = Color(0xffefeff4);
|
static const Color settingsBackground = Color(0xffefeff4);
|
||||||
|
|
||||||
static const Color settingsGroupSubtitle = Color(0xff777777);
|
|
||||||
|
|
||||||
static const Color iconBlue = Color(0xff0000ff);
|
|
||||||
|
|
||||||
static const Color iconGold = Color(0xffdba800);
|
|
||||||
|
|
||||||
static const preferenceIcon = IconData(
|
static const preferenceIcon = IconData(
|
||||||
0xf443,
|
0xf443,
|
||||||
fontFamily: CupertinoIcons.iconFont,
|
fontFamily: CupertinoIcons.iconFont,
|
||||||
@@ -227,12 +221,6 @@ abstract class Styles {
|
|||||||
fontPackage: CupertinoIcons.iconFontPackage,
|
fontPackage: CupertinoIcons.iconFontPackage,
|
||||||
);
|
);
|
||||||
|
|
||||||
static const checkIcon = IconData(
|
|
||||||
0xf383,
|
|
||||||
fontFamily: CupertinoIcons.iconFont,
|
|
||||||
fontPackage: CupertinoIcons.iconFontPackage,
|
|
||||||
);
|
|
||||||
|
|
||||||
static const servingInfoBorderColor = Color(0xffb0b0b0);
|
static const servingInfoBorderColor = Color(0xffb0b0b0);
|
||||||
|
|
||||||
static const ColorFilter desaturatedColorFilter =
|
static const ColorFilter desaturatedColorFilter =
|
||||||
|
|||||||
@@ -1,111 +0,0 @@
|
|||||||
// Copyright 2018 The Flutter team. All rights reserved.
|
|
||||||
// Use of this source code is governed by a BSD-style license that can be
|
|
||||||
// found in the LICENSE file.
|
|
||||||
|
|
||||||
import 'package:flutter/cupertino.dart';
|
|
||||||
import '../styles.dart';
|
|
||||||
|
|
||||||
import 'settings_item.dart';
|
|
||||||
|
|
||||||
// The widgets in this file present a group of Cupertino-style settings items to
|
|
||||||
// the user. In the future, the Cupertino package in the Flutter SDK will
|
|
||||||
// include dedicated widgets for this purpose, but for now they're done here.
|
|
||||||
//
|
|
||||||
// See https://github.com/flutter/flutter/projects/29 for more info.
|
|
||||||
|
|
||||||
class SettingsGroupHeader extends StatelessWidget {
|
|
||||||
const SettingsGroupHeader(this.title, {super.key});
|
|
||||||
|
|
||||||
final String title;
|
|
||||||
|
|
||||||
@override
|
|
||||||
Widget build(BuildContext context) {
|
|
||||||
return Padding(
|
|
||||||
padding: const EdgeInsets.only(
|
|
||||||
left: 15,
|
|
||||||
right: 15,
|
|
||||||
bottom: 6,
|
|
||||||
),
|
|
||||||
child: Text(
|
|
||||||
title.toUpperCase(),
|
|
||||||
style: Styles.settingsGroupHeaderText(CupertinoTheme.of(context)),
|
|
||||||
),
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
class SettingsGroupFooter extends StatelessWidget {
|
|
||||||
const SettingsGroupFooter(this.title, {super.key});
|
|
||||||
|
|
||||||
final String title;
|
|
||||||
|
|
||||||
@override
|
|
||||||
Widget build(BuildContext context) {
|
|
||||||
return Padding(
|
|
||||||
padding: const EdgeInsets.only(
|
|
||||||
left: 15,
|
|
||||||
right: 15,
|
|
||||||
top: 7.5,
|
|
||||||
),
|
|
||||||
child: Text(title,
|
|
||||||
style: Styles.settingsGroupFooterText(CupertinoTheme.of(context))),
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
class SettingsGroup extends StatelessWidget {
|
|
||||||
SettingsGroup({
|
|
||||||
required this.items,
|
|
||||||
this.header,
|
|
||||||
this.footer,
|
|
||||||
super.key,
|
|
||||||
}) : assert(items.isNotEmpty);
|
|
||||||
|
|
||||||
final List<SettingsItem> items;
|
|
||||||
final Widget? header;
|
|
||||||
final Widget? footer;
|
|
||||||
@override
|
|
||||||
Widget build(BuildContext context) {
|
|
||||||
var brightness = CupertinoTheme.brightnessOf(context);
|
|
||||||
final dividedItems = <Widget>[items[0]];
|
|
||||||
for (var i = 1; i < items.length; i++) {
|
|
||||||
dividedItems.add(Container(
|
|
||||||
color: Styles.settingsLineation(brightness),
|
|
||||||
height: 0.3,
|
|
||||||
));
|
|
||||||
dividedItems.add(items[i]);
|
|
||||||
}
|
|
||||||
|
|
||||||
return Padding(
|
|
||||||
padding: EdgeInsets.only(
|
|
||||||
top: header == null ? 35 : 22,
|
|
||||||
),
|
|
||||||
child: Column(
|
|
||||||
crossAxisAlignment: CrossAxisAlignment.start,
|
|
||||||
children: [
|
|
||||||
if (header != null) header!,
|
|
||||||
Container(
|
|
||||||
decoration: BoxDecoration(
|
|
||||||
color: CupertinoColors.white,
|
|
||||||
border: Border(
|
|
||||||
top: BorderSide(
|
|
||||||
color: Styles.settingsLineation(brightness),
|
|
||||||
width: 0,
|
|
||||||
),
|
|
||||||
bottom: BorderSide(
|
|
||||||
color: Styles.settingsLineation(brightness),
|
|
||||||
width: 0,
|
|
||||||
),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
child: Column(
|
|
||||||
crossAxisAlignment: CrossAxisAlignment.stretch,
|
|
||||||
children: dividedItems,
|
|
||||||
),
|
|
||||||
),
|
|
||||||
if (footer != null) footer!,
|
|
||||||
],
|
|
||||||
),
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,161 +0,0 @@
|
|||||||
// Copyright 2018 The Flutter team. All rights reserved.
|
|
||||||
// Use of this source code is governed by a BSD-style license that can be
|
|
||||||
// found in the LICENSE file.
|
|
||||||
|
|
||||||
import 'dart:async';
|
|
||||||
|
|
||||||
import 'package:flutter/cupertino.dart';
|
|
||||||
import '../styles.dart';
|
|
||||||
|
|
||||||
// The widgets in this file present a Cupertino-style settings item to the user.
|
|
||||||
// In the future, the Cupertino package in the Flutter SDK will include
|
|
||||||
// dedicated widgets for this purpose, but for now they're done here.
|
|
||||||
//
|
|
||||||
// See https://github.com/flutter/flutter/projects/29 for more info.
|
|
||||||
|
|
||||||
typedef SettingsItemCallback = FutureOr<void> Function();
|
|
||||||
|
|
||||||
class SettingsNavigationIndicator extends StatelessWidget {
|
|
||||||
const SettingsNavigationIndicator({super.key});
|
|
||||||
|
|
||||||
@override
|
|
||||||
Widget build(BuildContext context) {
|
|
||||||
return const Icon(
|
|
||||||
CupertinoIcons.forward,
|
|
||||||
color: Styles.settingsMediumGray,
|
|
||||||
size: 21,
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
class SettingsIcon extends StatelessWidget {
|
|
||||||
const SettingsIcon({
|
|
||||||
required this.icon,
|
|
||||||
this.foregroundColor = CupertinoColors.white,
|
|
||||||
this.backgroundColor = CupertinoColors.black,
|
|
||||||
super.key,
|
|
||||||
});
|
|
||||||
|
|
||||||
final Color backgroundColor;
|
|
||||||
final Color foregroundColor;
|
|
||||||
final IconData icon;
|
|
||||||
|
|
||||||
@override
|
|
||||||
Widget build(BuildContext context) {
|
|
||||||
return Container(
|
|
||||||
decoration: BoxDecoration(
|
|
||||||
borderRadius: BorderRadius.circular(5),
|
|
||||||
color: backgroundColor,
|
|
||||||
),
|
|
||||||
child: Center(
|
|
||||||
child: Icon(
|
|
||||||
icon,
|
|
||||||
color: foregroundColor,
|
|
||||||
size: 20,
|
|
||||||
),
|
|
||||||
),
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
class SettingsItem extends StatefulWidget {
|
|
||||||
const SettingsItem({
|
|
||||||
required this.label,
|
|
||||||
this.icon,
|
|
||||||
this.content,
|
|
||||||
this.subtitle,
|
|
||||||
this.onPress,
|
|
||||||
super.key,
|
|
||||||
});
|
|
||||||
|
|
||||||
final String label;
|
|
||||||
final Widget? icon;
|
|
||||||
final Widget? content;
|
|
||||||
final String? subtitle;
|
|
||||||
final SettingsItemCallback? onPress;
|
|
||||||
|
|
||||||
@override
|
|
||||||
State<SettingsItem> createState() => _SettingsItemState();
|
|
||||||
}
|
|
||||||
|
|
||||||
class _SettingsItemState extends State<SettingsItem> {
|
|
||||||
bool pressed = false;
|
|
||||||
|
|
||||||
@override
|
|
||||||
Widget build(BuildContext context) {
|
|
||||||
var themeData = CupertinoTheme.of(context);
|
|
||||||
var brightness = CupertinoTheme.brightnessOf(context);
|
|
||||||
return AnimatedContainer(
|
|
||||||
duration: const Duration(milliseconds: 200),
|
|
||||||
color: Styles.settingsItemColor(brightness),
|
|
||||||
child: GestureDetector(
|
|
||||||
behavior: HitTestBehavior.opaque,
|
|
||||||
onTap: () async {
|
|
||||||
if (widget.onPress != null) {
|
|
||||||
setState(() {
|
|
||||||
pressed = true;
|
|
||||||
});
|
|
||||||
await widget.onPress!();
|
|
||||||
Future.delayed(
|
|
||||||
const Duration(milliseconds: 150),
|
|
||||||
() {
|
|
||||||
setState(() {
|
|
||||||
pressed = false;
|
|
||||||
});
|
|
||||||
},
|
|
||||||
);
|
|
||||||
}
|
|
||||||
},
|
|
||||||
child: SizedBox(
|
|
||||||
height: widget.subtitle == null ? 44 : 57,
|
|
||||||
child: Row(
|
|
||||||
children: [
|
|
||||||
if (widget.icon != null)
|
|
||||||
Padding(
|
|
||||||
padding: const EdgeInsets.only(
|
|
||||||
left: 15,
|
|
||||||
bottom: 2,
|
|
||||||
),
|
|
||||||
child: SizedBox(
|
|
||||||
height: 29,
|
|
||||||
width: 29,
|
|
||||||
child: widget.icon,
|
|
||||||
),
|
|
||||||
),
|
|
||||||
Expanded(
|
|
||||||
child: Padding(
|
|
||||||
padding: const EdgeInsets.only(
|
|
||||||
left: 15,
|
|
||||||
),
|
|
||||||
child: widget.subtitle != null
|
|
||||||
? Column(
|
|
||||||
crossAxisAlignment: CrossAxisAlignment.start,
|
|
||||||
children: [
|
|
||||||
const SizedBox(height: 8.5),
|
|
||||||
Text(widget.label,
|
|
||||||
style: themeData.textTheme.textStyle),
|
|
||||||
const SizedBox(height: 4),
|
|
||||||
Text(
|
|
||||||
widget.subtitle!,
|
|
||||||
style: Styles.settingsItemSubtitleText(themeData),
|
|
||||||
),
|
|
||||||
],
|
|
||||||
)
|
|
||||||
: Padding(
|
|
||||||
padding: const EdgeInsets.only(top: 1.5),
|
|
||||||
child: Text(widget.label,
|
|
||||||
style: themeData.textTheme.textStyle),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
Padding(
|
|
||||||
padding: const EdgeInsets.only(right: 11),
|
|
||||||
child: widget.content ?? Container(),
|
|
||||||
),
|
|
||||||
],
|
|
||||||
),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
Reference in New Issue
Block a user