├── .gitignore
├── .vscode
└── launch.json
├── CHANGELOG.md
├── LICENSE
├── example
├── .gitignore
├── .metadata
├── README.md
├── android
│ ├── app
│ │ ├── build.gradle
│ │ └── src
│ │ │ ├── debug
│ │ │ └── AndroidManifest.xml
│ │ │ ├── main
│ │ │ ├── AndroidManifest.xml
│ │ │ ├── kotlin
│ │ │ │ └── com
│ │ │ │ │ └── example
│ │ │ │ │ └── flutter_cupertino_settings_example
│ │ │ │ │ └── MainActivity.kt
│ │ │ └── res
│ │ │ │ ├── drawable
│ │ │ │ └── launch_background.xml
│ │ │ │ ├── mipmap-hdpi
│ │ │ │ └── ic_launcher.png
│ │ │ │ ├── mipmap-mdpi
│ │ │ │ └── ic_launcher.png
│ │ │ │ ├── mipmap-xhdpi
│ │ │ │ └── ic_launcher.png
│ │ │ │ ├── mipmap-xxhdpi
│ │ │ │ └── ic_launcher.png
│ │ │ │ ├── mipmap-xxxhdpi
│ │ │ │ └── ic_launcher.png
│ │ │ │ └── values
│ │ │ │ └── styles.xml
│ │ │ └── profile
│ │ │ └── AndroidManifest.xml
│ ├── build.gradle
│ ├── gradle.properties
│ ├── gradle
│ │ └── wrapper
│ │ │ └── gradle-wrapper.properties
│ └── settings.gradle
├── lib
│ └── main.dart
├── pubspec.yaml
└── test
│ └── widget_test.dart
├── flutter_cupertino_settings.iml
├── lib
├── flutter_cupertino_settings.dart
└── widgets
│ ├── button.dart
│ ├── control.dart
│ ├── description.dart
│ ├── header.dart
│ ├── link.dart
│ ├── secret.dart
│ ├── selection.dart
│ ├── spacer.dart
│ └── widget.dart
├── pubspec.yaml
├── readme.md
└── screenshots
└── scr1.png
/.gitignore:
--------------------------------------------------------------------------------
1 | .DS_Store
2 | .atom/
3 | .idea
4 | .packages
5 | .pub/
6 | .dart_tool
7 | .vscode
8 | packages
9 | ios/
10 | pubspec.lock
--------------------------------------------------------------------------------
/.vscode/launch.json:
--------------------------------------------------------------------------------
1 | {
2 | // Use IntelliSense to learn about possible attributes.
3 | // Hover to view descriptions of existing attributes.
4 | // For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387
5 | "version": "0.2.0",
6 | "configurations": [
7 | {
8 | "name": "Flutter",
9 | "type": "dart",
10 | "request": "launch",
11 | "program": "example/lib/main.dart"
12 | }
13 |
14 | ]
15 | }
--------------------------------------------------------------------------------
/CHANGELOG.md:
--------------------------------------------------------------------------------
1 | ## [0.5.0]
2 | * NULL safety
3 | * Allow a scroll controller to be specified
4 | * Support subtitle for selection lists
5 |
6 | ## [0.4.0]
7 | * Allow to use library in web #26
8 | * Update cupertino_icons to 1.0.0 #24
9 | * Remove state from CSSelection widget #22
10 |
11 | ## [0.3.0] - iOS 13 Support
12 |
13 | * added support for the different types of CSLink based on UITableViewCell
14 | * use CupertinoDynamicColors to match the official DynamicColors added with iOS13
15 | * use CupertinoColors and CupertinoIcons instead of Material one
16 | * added HapticFeedback to CSSelection
17 | * updated example
18 | * bump Flutter Version to 1.12.13-hotfix.5
19 |
20 | ## [0.2.0] - Smaller changes and fixes
21 |
22 | ## [0.1.0] - Dark Mode Support
23 |
24 | * Dark Mode Support
25 | * Support for different font sizes
26 | * Added Example App
27 | * Added Optional Shrink Wrap
28 | * Includes SafeArea Wrapper
29 |
30 | ## [0.0.9] - Dart 2.1.0 Support
31 |
32 | * Dart 2.1.0 Support Added
33 |
34 | ## [0.0.1] - TODO: Add release date.
35 |
36 | * TODO: Describe initial release.
37 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | Copyright (c) 2018 Matthias Rupp
2 | Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
3 |
4 | The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
5 |
6 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
--------------------------------------------------------------------------------
/example/.gitignore:
--------------------------------------------------------------------------------
1 | # Miscellaneous
2 | *.class
3 | *.log
4 | *.pyc
5 | *.swp
6 | .DS_Store
7 | .atom/
8 | .buildlog/
9 | .history
10 | .svn/
11 |
12 | # IntelliJ related
13 | *.iml
14 | *.ipr
15 | *.iws
16 | .idea/
17 |
18 | # Visual Studio Code related
19 | .vscode/
20 |
21 | # Flutter/Dart/Pub related
22 | **/doc/api/
23 | .dart_tool/
24 | .flutter-plugins
25 | .packages
26 | .pub-cache/
27 | .pub/
28 | /build/
29 |
30 | # Android related
31 | **/android/**/gradle-wrapper.jar
32 | **/android/.gradle
33 | **/android/captures/
34 | **/android/gradlew
35 | **/android/gradlew.bat
36 | **/android/local.properties
37 | **/android/**/GeneratedPluginRegistrant.java
38 |
39 | # iOS/XCode related
40 | **/ios/**/*.mode1v3
41 | **/ios/**/*.mode2v3
42 | **/ios/**/*.moved-aside
43 | **/ios/**/*.pbxuser
44 | **/ios/**/*.perspectivev3
45 | **/ios/**/*sync/
46 | **/ios/**/.sconsign.dblite
47 | **/ios/**/.tags*
48 | **/ios/**/.vagrant/
49 | **/ios/**/DerivedData/
50 | **/ios/**/Icon?
51 | **/ios/**/Pods/
52 | **/ios/**/.symlinks/
53 | **/ios/**/profile
54 | **/ios/**/xcuserdata
55 | **/ios/.generated/
56 | **/ios/Flutter/App.framework
57 | **/ios/Flutter/Flutter.framework
58 | **/ios/Flutter/Generated.xcconfig
59 | **/ios/Flutter/app.flx
60 | **/ios/Flutter/app.zip
61 | **/ios/Flutter/flutter_assets/
62 | **/ios/ServiceDefinitions.json
63 | **/ios/Runner/GeneratedPluginRegistrant.*
64 |
65 | # Exceptions to above rules.
66 | !**/ios/**/default.mode1v3
67 | !**/ios/**/default.mode2v3
68 | !**/ios/**/default.pbxuser
69 | !**/ios/**/default.perspectivev3
70 | !/packages/flutter_tools/test/data/dart_dependencies_test/**/.packages
71 |
--------------------------------------------------------------------------------
/example/.metadata:
--------------------------------------------------------------------------------
1 | # This file tracks properties of this Flutter project.
2 | # Used by Flutter tool to assess capabilities and perform upgrades etc.
3 | #
4 | # This file should be version controlled and should not be manually edited.
5 |
6 | version:
7 | revision: 035e0765cc575c3b455689c2402cce073d564fce
8 | channel: master
9 |
10 | project_type: app
11 |
--------------------------------------------------------------------------------
/example/README.md:
--------------------------------------------------------------------------------
1 | # flutter_cupertino_settings_example
2 |
3 | Demonstrates how to use the flutter_cupertino_settings plugin.
4 |
5 | ## Getting Started
6 |
7 | This project is a starting point for a Flutter application.
8 |
9 | A few resources to get you started if this is your first Flutter project:
10 |
11 | - [Lab: Write your first Flutter app](https://flutter.io/docs/get-started/codelab)
12 | - [Cookbook: Useful Flutter samples](https://flutter.io/docs/cookbook)
13 |
14 | For help getting started with Flutter, view our
15 | [online documentation](https://flutter.io/docs), which offers tutorials,
16 | samples, guidance on mobile development, and a full API reference.
17 |
--------------------------------------------------------------------------------
/example/android/app/build.gradle:
--------------------------------------------------------------------------------
1 | def localProperties = new Properties()
2 | def localPropertiesFile = rootProject.file('local.properties')
3 | if (localPropertiesFile.exists()) {
4 | localPropertiesFile.withReader('UTF-8') { reader ->
5 | localProperties.load(reader)
6 | }
7 | }
8 |
9 | def flutterRoot = localProperties.getProperty('flutter.sdk')
10 | if (flutterRoot == null) {
11 | throw new GradleException("Flutter SDK not found. Define location with flutter.sdk in the local.properties file.")
12 | }
13 |
14 | def flutterVersionCode = localProperties.getProperty('flutter.versionCode')
15 | if (flutterVersionCode == null) {
16 | flutterVersionCode = '1'
17 | }
18 |
19 | def flutterVersionName = localProperties.getProperty('flutter.versionName')
20 | if (flutterVersionName == null) {
21 | flutterVersionName = '1.0'
22 | }
23 |
24 | apply plugin: 'com.android.application'
25 | apply plugin: 'kotlin-android'
26 | apply from: "$flutterRoot/packages/flutter_tools/gradle/flutter.gradle"
27 |
28 | android {
29 | compileSdkVersion 28
30 |
31 | sourceSets {
32 | main.java.srcDirs += 'src/main/kotlin'
33 | }
34 |
35 | lintOptions {
36 | disable 'InvalidPackage'
37 | }
38 |
39 | defaultConfig {
40 | // TODO: Specify your own unique Application ID (https://developer.android.com/studio/build/application-id.html).
41 | applicationId "com.example.flutter_cupertino_settings_example"
42 | minSdkVersion 16
43 | targetSdkVersion 28
44 | versionCode flutterVersionCode.toInteger()
45 | versionName flutterVersionName
46 | testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
47 | }
48 |
49 | buildTypes {
50 | release {
51 | // TODO: Add your own signing config for the release build.
52 | // Signing with the debug keys for now, so `flutter run --release` works.
53 | signingConfig signingConfigs.debug
54 | }
55 | }
56 | }
57 |
58 | flutter {
59 | source '../..'
60 | }
61 |
62 | dependencies {
63 | implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version"
64 | testImplementation 'junit:junit:4.12'
65 | androidTestImplementation 'com.android.support.test:runner:1.0.2'
66 | androidTestImplementation 'com.android.support.test.espresso:espresso-core:3.0.2'
67 | }
68 |
--------------------------------------------------------------------------------
/example/android/app/src/debug/AndroidManifest.xml:
--------------------------------------------------------------------------------
1 |
3 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/example/android/app/src/main/AndroidManifest.xml:
--------------------------------------------------------------------------------
1 |
3 |
4 |
9 |
13 |
20 |
24 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
--------------------------------------------------------------------------------
/example/android/app/src/main/kotlin/com/example/flutter_cupertino_settings_example/MainActivity.kt:
--------------------------------------------------------------------------------
1 | package com.example.flutter_cupertino_settings_example
2 |
3 | import android.os.Bundle
4 |
5 | import io.flutter.app.FlutterActivity
6 | import io.flutter.plugins.GeneratedPluginRegistrant
7 |
8 | class MainActivity: FlutterActivity() {
9 | override fun onCreate(savedInstanceState: Bundle?) {
10 | super.onCreate(savedInstanceState)
11 | GeneratedPluginRegistrant.registerWith(this)
12 | }
13 | }
14 |
--------------------------------------------------------------------------------
/example/android/app/src/main/res/drawable/launch_background.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
12 |
13 |
--------------------------------------------------------------------------------
/example/android/app/src/main/res/mipmap-hdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/matthinc/flutter_cupertino_settings/5edb0476d73ecfbc1857d6f9f9eddaf507344f5e/example/android/app/src/main/res/mipmap-hdpi/ic_launcher.png
--------------------------------------------------------------------------------
/example/android/app/src/main/res/mipmap-mdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/matthinc/flutter_cupertino_settings/5edb0476d73ecfbc1857d6f9f9eddaf507344f5e/example/android/app/src/main/res/mipmap-mdpi/ic_launcher.png
--------------------------------------------------------------------------------
/example/android/app/src/main/res/mipmap-xhdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/matthinc/flutter_cupertino_settings/5edb0476d73ecfbc1857d6f9f9eddaf507344f5e/example/android/app/src/main/res/mipmap-xhdpi/ic_launcher.png
--------------------------------------------------------------------------------
/example/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/matthinc/flutter_cupertino_settings/5edb0476d73ecfbc1857d6f9f9eddaf507344f5e/example/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png
--------------------------------------------------------------------------------
/example/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/matthinc/flutter_cupertino_settings/5edb0476d73ecfbc1857d6f9f9eddaf507344f5e/example/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png
--------------------------------------------------------------------------------
/example/android/app/src/main/res/values/styles.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
8 |
9 |
--------------------------------------------------------------------------------
/example/android/app/src/profile/AndroidManifest.xml:
--------------------------------------------------------------------------------
1 |
3 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/example/android/build.gradle:
--------------------------------------------------------------------------------
1 | buildscript {
2 | ext.kotlin_version = '1.2.71'
3 | repositories {
4 | google()
5 | jcenter()
6 | }
7 |
8 | dependencies {
9 | classpath 'com.android.tools.build:gradle:3.2.1'
10 | classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
11 | }
12 | }
13 |
14 | allprojects {
15 | repositories {
16 | google()
17 | jcenter()
18 | }
19 | }
20 |
21 | rootProject.buildDir = '../build'
22 | subprojects {
23 | project.buildDir = "${rootProject.buildDir}/${project.name}"
24 | }
25 | subprojects {
26 | project.evaluationDependsOn(':app')
27 | }
28 |
29 | task clean(type: Delete) {
30 | delete rootProject.buildDir
31 | }
32 |
--------------------------------------------------------------------------------
/example/android/gradle.properties:
--------------------------------------------------------------------------------
1 | org.gradle.jvmargs=-Xmx1536M
2 | android.enableR8=true
3 |
--------------------------------------------------------------------------------
/example/android/gradle/wrapper/gradle-wrapper.properties:
--------------------------------------------------------------------------------
1 | #Fri Jun 23 08:50:38 CEST 2017
2 | distributionBase=GRADLE_USER_HOME
3 | distributionPath=wrapper/dists
4 | zipStoreBase=GRADLE_USER_HOME
5 | zipStorePath=wrapper/dists
6 | distributionUrl=https\://services.gradle.org/distributions/gradle-4.10.2-all.zip
7 |
--------------------------------------------------------------------------------
/example/android/settings.gradle:
--------------------------------------------------------------------------------
1 | include ':app'
2 |
3 | def flutterProjectRoot = rootProject.projectDir.parentFile.toPath()
4 |
5 | def plugins = new Properties()
6 | def pluginsFile = new File(flutterProjectRoot.toFile(), '.flutter-plugins')
7 | if (pluginsFile.exists()) {
8 | pluginsFile.withReader('UTF-8') { reader -> plugins.load(reader) }
9 | }
10 |
11 | plugins.each { name, path ->
12 | def pluginDirectory = flutterProjectRoot.resolve(path).resolve('android').toFile()
13 | include ":$name"
14 | project(":$name").projectDir = pluginDirectory
15 | }
16 |
--------------------------------------------------------------------------------
/example/lib/main.dart:
--------------------------------------------------------------------------------
1 | import 'package:flutter/cupertino.dart';
2 |
3 | import 'package:font_awesome_flutter/font_awesome_flutter.dart';
4 | import 'package:flutter_cupertino_settings/flutter_cupertino_settings.dart';
5 |
6 | void main() => runApp(MyApp());
7 |
8 | class MyApp extends StatelessWidget {
9 | @override
10 | Widget build(BuildContext context) {
11 | return CupertinoApp(
12 | theme: const CupertinoThemeData(
13 | brightness: Brightness.light,
14 | ),
15 | home: HomeScreen(),
16 | );
17 | }
18 | }
19 |
20 | class HomeScreen extends StatefulWidget {
21 | @override
22 | _HomeScreenState createState() => _HomeScreenState();
23 | }
24 |
25 | class _HomeScreenState extends State {
26 | double _slider = 0.5;
27 | bool _switch = false;
28 | int _index = 0;
29 |
30 | @override
31 | Widget build(BuildContext context) {
32 | return CupertinoPageScaffold(
33 | navigationBar: const CupertinoNavigationBar(
34 | middle: Text('Cupertino Settings'),
35 | ),
36 | child: CupertinoSettings(
37 | items: [
38 | const CSHeader('Brightness'),
39 | CSWidget(
40 | CupertinoSlider(
41 | value: _slider,
42 | onChanged: (double value) => setState(() => _slider = value),
43 | ),
44 | style: CSWidgetStyle(
45 | icon: Icon(FontAwesomeIcons.sun),
46 | ),
47 | addPaddingToBorder: true,
48 | ),
49 | CSControl(
50 | nameWidget: Text('Auto brightness'),
51 | contentWidget: CupertinoSwitch(
52 | value: _switch,
53 | onChanged: (bool value) => setState(() => _switch = value),
54 | ),
55 | style: CSWidgetStyle(
56 | icon: Icon(FontAwesomeIcons.sun),
57 | ),
58 | addPaddingToBorder: false,
59 | ),
60 | const CSHeader('Selection'),
61 | CSSelection(
62 | items: const >[
63 | CSSelectionItem(text: 'Day mode', value: 0),
64 | CSSelectionItem(text: 'Night mode', value: 1, subtitle: 'Subtitle'),
65 | ],
66 | onSelected: (value) => setState(() => _index = value),
67 | currentSelection: _index,
68 | ),
69 | const CSDescription(
70 | 'Using Night mode extends battery life on devices with OLED display',
71 | ),
72 | const CSHeader(""),
73 | CSControl(
74 | nameWidget: Text('Loading...'),
75 | contentWidget: const CupertinoActivityIndicator(),
76 | ),
77 | CSButton(CSButtonType.DEFAULT, "Licenses", () {
78 | print("It works!");
79 | }),
80 | const CSHeader(""),
81 | CSSecret("Your Password", "Hello World"),
82 | CSButton(CSButtonType.DESTRUCTIVE, "Delete all data", () {}),
83 | ],
84 | ),
85 | );
86 | }
87 | }
88 |
--------------------------------------------------------------------------------
/example/pubspec.yaml:
--------------------------------------------------------------------------------
1 | name: flutter_cupertino_settings_example
2 | description: Demonstrates how to use the flutter_cupertino_settings plugin.
3 | publish_to: 'none'
4 |
5 | environment:
6 | sdk: ">=2.12.0 <3.0.0"
7 |
8 | dependencies:
9 | flutter:
10 | sdk: flutter
11 |
12 | # The following adds the Cupertino Icons font to your application.
13 | # Use with the CupertinoIcons class for iOS style icons.
14 | cupertino_icons: ^1.0.0
15 | # cupertino_icons:
16 | # git:
17 | # url: https://github.com/flutter/cupertino_icons.git
18 | font_awesome_flutter: ^9.0.0
19 |
20 | dev_dependencies:
21 | flutter_test:
22 | sdk: flutter
23 |
24 | flutter_cupertino_settings:
25 | path: ../
26 |
27 | # For information on the generic Dart part of this file, see the
28 | # following page: https://www.dartlang.org/tools/pub/pubspec
29 |
30 | # The following section is specific to Flutter.
31 | flutter:
32 |
33 | # The following line ensures that the Material Icons font is
34 | # included with your application, so that you can use the icons in
35 | # the material Icons class.
36 | uses-material-design: true
37 |
38 | # To add assets to your application, add an assets section, like this:
39 | # assets:
40 | # - images/a_dot_burr.jpeg
41 | # - images/a_dot_ham.jpeg
42 |
43 | # An image asset can refer to one or more resolution-specific "variants", see
44 | # https://flutter.io/assets-and-images/#resolution-aware.
45 |
46 | # For details regarding adding assets from package dependencies, see
47 | # https://flutter.io/assets-and-images/#from-packages
48 |
49 | # To add custom fonts to your application, add a fonts section here,
50 | # in this "flutter" section. Each entry in this list should have a
51 | # "family" key with the font family name, and a "fonts" key with a
52 | # list giving the asset and other descriptors for the font. For
53 | # example:
54 | # fonts:
55 | # - family: Schyler
56 | # fonts:
57 | # - asset: fonts/Schyler-Regular.ttf
58 | # - asset: fonts/Schyler-Italic.ttf
59 | # style: italic
60 | # - family: Trajan Pro
61 | # fonts:
62 | # - asset: fonts/TrajanPro.ttf
63 | # - asset: fonts/TrajanPro_Bold.ttf
64 | # weight: 700
65 | #
66 | # For details regarding fonts from package dependencies,
67 | # see https://flutter.io/custom-fonts/#from-packages
68 |
--------------------------------------------------------------------------------
/example/test/widget_test.dart:
--------------------------------------------------------------------------------
1 | // This is a basic Flutter widget test.
2 | //
3 | // To perform an interaction with a widget in your test, use the WidgetTester
4 | // utility that Flutter provides. For example, you can send tap and scroll
5 | // gestures. You can also use WidgetTester to find child widgets in the widget
6 | // tree, read text, and verify that the values of widget properties are correct.
7 |
8 | import 'package:flutter/material.dart';
9 | import 'package:flutter_test/flutter_test.dart';
10 |
11 | import 'package:flutter_cupertino_settings_example/main.dart';
12 |
13 | void main() {
14 | testWidgets('Verify Platform version', (WidgetTester tester) async {
15 | // Build our app and trigger a frame.
16 | await tester.pumpWidget(MyApp());
17 |
18 | // Verify that platform version is retrieved.
19 | expect(
20 | find.byWidgetPredicate(
21 | (Widget widget) => widget is Text &&
22 | widget.data.startsWith('Running on:'),
23 | ),
24 | findsOneWidget,
25 | );
26 | });
27 | }
28 |
--------------------------------------------------------------------------------
/flutter_cupertino_settings.iml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
--------------------------------------------------------------------------------
/lib/flutter_cupertino_settings.dart:
--------------------------------------------------------------------------------
1 | library flutter_cupertino_settings;
2 |
3 | import 'dart:io';
4 |
5 | import 'package:flutter/foundation.dart';
6 | import 'package:flutter/material.dart' show Theme;
7 | import 'package:flutter/cupertino.dart';
8 | import 'package:flutter/rendering.dart';
9 | import 'package:flutter/services.dart';
10 |
11 | part 'widgets/button.dart';
12 | part 'widgets/control.dart';
13 | part 'widgets/description.dart';
14 | part 'widgets/header.dart';
15 | part 'widgets/link.dart';
16 | part 'widgets/secret.dart';
17 | part 'widgets/selection.dart';
18 | part 'widgets/spacer.dart';
19 | part 'widgets/widget.dart';
20 |
21 | const double CS_ITEM_HEIGHT = 50.0;
22 | const EdgeInsets CS_ITEM_PADDING =
23 | EdgeInsets.symmetric(horizontal: 10, vertical: 1);
24 | const double CS_TITLE_FONT_SIZE = 16.0;
25 | const double CS_SUBTITLE_FONT_SIZE = 11.0;
26 | const double CS_HEADER_FONT_SIZE = 14.0;
27 | const double CS_DESCRIPTION_FONT_SIZE = 13.0;
28 | const double CS_ITEM_NAME_SIZE = 15.0;
29 | const EdgeInsets CS_ICON_PADDING = EdgeInsets.only(
30 | right: 10.0,
31 | left: 4.0,
32 | );
33 | const CSWidgetStyle CS_DEFAULT_STYLE = CSWidgetStyle();
34 | const double CS_CHECK_SIZE = 20.0;
35 | const double CS_CHEVRON_SIZE = 17.0;
36 |
37 | /// Event for [CSSelection]
38 | typedef void SelectionCallback(int selected);
39 |
40 | TextStyle basicTextStyle(BuildContext context) =>
41 | (kIsWeb
42 | ? Theme.of(context).textTheme.subtitle2
43 | : Platform.isIOS
44 | ? CupertinoTheme.of(context).textTheme.textStyle
45 | : Theme.of(context).textTheme.subtitle2) ??
46 | TextStyle();
47 |
48 | class CupertinoSettings extends StatelessWidget {
49 | final List items;
50 | final bool shrinkWrap;
51 | final ScrollController? scrollController;
52 |
53 | const CupertinoSettings({
54 | required this.items,
55 | this.scrollController,
56 | this.shrinkWrap = false,
57 | });
58 |
59 | @override
60 | Widget build(BuildContext context) {
61 | return Container(
62 | color: CupertinoColors.systemGroupedBackground.resolveFrom(context),
63 | child: SafeArea(
64 | bottom: false,
65 | child: shrinkWrap
66 | ? ListView.builder(
67 | shrinkWrap: shrinkWrap,
68 | itemCount: items.length,
69 | controller: scrollController,
70 | itemBuilder: (BuildContext context, int index) => items[index],
71 | )
72 | : Column(
73 | children: [
74 | Expanded(
75 | child: ListView.builder(
76 | shrinkWrap: shrinkWrap,
77 | itemCount: items.length,
78 | controller: scrollController,
79 | itemBuilder: (BuildContext context, int index) =>
80 | items[index],
81 | ),
82 | ),
83 | ],
84 | ),
85 | ),
86 | );
87 | }
88 | }
89 |
--------------------------------------------------------------------------------
/lib/widgets/button.dart:
--------------------------------------------------------------------------------
1 | part of flutter_cupertino_settings;
2 |
3 | /// A button-cell inside [CupertinoSettings]
4 | /// 3 different types are available (they only affect the design):
5 | /// [CSButtonType.DESTRUCTIVE] Red and centered
6 | /// [CSButtonType.DEFAULT] Blue and left aligned
7 | /// [CSButtonType.DEFAULT_CENTER] Blue and centered
8 | /// Provides the correct paddings and text properties
9 | ///
10 | /// It is quite complex:
11 | ///
12 | /// -- Widget
13 | /// |- Flex
14 | /// |- Expand
15 | /// |- CupertinoButton
16 | /// |- Container (<--- For text-alignment)
17 | /// |- Text
18 | ///
19 | /// This "hack" is mandatory to archive that...
20 | /// 1) The button can be aligned
21 | /// 2) The entire row is touch-sensitive
22 | class CSButton extends CSWidget {
23 | final CSButtonType buttonType;
24 | final String text;
25 | final VoidCallback pressed;
26 | final double fontSize;
27 |
28 | CSButton(
29 | this.buttonType,
30 | this.text,
31 | this.pressed, {
32 | CSWidgetStyle style = CS_DEFAULT_STYLE,
33 | this.fontSize = CS_TITLE_FONT_SIZE,
34 | }) : super(
35 | Flex(
36 | direction: Axis.horizontal,
37 | children: [
38 | Expanded(
39 | child: CupertinoButton(
40 | padding: EdgeInsets.zero,
41 | onPressed: pressed,
42 | child: Container(
43 | alignment: buttonType.alignment,
44 | child: Text(
45 | text,
46 | style: TextStyle(
47 | color: buttonType.color,
48 | fontSize: fontSize,
49 | ),
50 | ),
51 | ),
52 | ),
53 | ),
54 | ],
55 | ),
56 | style: style,
57 | );
58 | }
59 |
60 | /// Defines different types for [CSButton]
61 | /// Specifies color and alignment
62 | class CSButtonType {
63 | static const CSButtonType DESTRUCTIVE = CSButtonType(
64 | CupertinoColors.destructiveRed,
65 | AlignmentDirectional.center,
66 | );
67 | static const CSButtonType DEFAULT = CSButtonType(
68 | CupertinoColors.systemBlue,
69 | AlignmentDirectional.centerStart,
70 | );
71 | static const CSButtonType DEFAULT_CENTER = CSButtonType(
72 | CupertinoColors.systemBlue,
73 | AlignmentDirectional.center,
74 | );
75 |
76 | final Color color;
77 | final AlignmentGeometry alignment;
78 |
79 | const CSButtonType(this.color, this.alignment);
80 | }
81 |
--------------------------------------------------------------------------------
/lib/widgets/control.dart:
--------------------------------------------------------------------------------
1 | part of flutter_cupertino_settings;
2 |
3 | /// A title [name] in combination with any widget [contentWidget]
4 | /// extends [CSWidget]
5 | /// Provides the correct paddings and text properties
6 | class CSControl extends CSWidget {
7 | final Widget? nameWidget;
8 | final Widget? contentWidget;
9 | final double fontSize;
10 |
11 | CSControl({
12 | this.nameWidget,
13 | this.contentWidget,
14 | CSWidgetStyle style = CS_DEFAULT_STYLE,
15 | this.fontSize = CS_TITLE_FONT_SIZE,
16 | bool addPaddingToBorder = true,
17 | }) : super(
18 | _ControlWidget(
19 | fontSize: fontSize,
20 | contentWidget: contentWidget,
21 | nameWidget: nameWidget,
22 | ),
23 | style: style,
24 | addPaddingToBorder: addPaddingToBorder,
25 | );
26 | }
27 |
28 | class _ControlWidget extends StatelessWidget {
29 | final Widget? nameWidget;
30 | final Widget? contentWidget;
31 | final double? fontSize;
32 |
33 | const _ControlWidget({
34 | Key? key,
35 | this.fontSize,
36 | this.contentWidget,
37 | this.nameWidget,
38 | }) : super(key: key);
39 |
40 | @override
41 | Widget build(BuildContext context) {
42 | return DefaultTextStyle(
43 | style: basicTextStyle(context).copyWith(
44 | color: CupertinoColors.label.resolveFrom(context),
45 | fontSize: fontSize,
46 | ),
47 | child: Row(
48 | mainAxisAlignment: MainAxisAlignment.spaceBetween,
49 | children: [
50 | if (nameWidget != null) nameWidget!,
51 | if (contentWidget != null) contentWidget!,
52 | ],
53 | ),
54 | );
55 | }
56 | }
57 |
--------------------------------------------------------------------------------
/lib/widgets/description.dart:
--------------------------------------------------------------------------------
1 | part of flutter_cupertino_settings;
2 |
3 | class CSDescription extends StatelessWidget {
4 | final String description;
5 |
6 | const CSDescription(this.description);
7 |
8 | @override
9 | Widget build(BuildContext context) {
10 | return Container(
11 | padding: const EdgeInsets.fromLTRB(10, 7.5, 5, 5),
12 | color: CupertinoColors.systemGroupedBackground.resolveFrom(context),
13 | child: Text(
14 | description,
15 | style: basicTextStyle(context).copyWith(
16 | color: CupertinoColors.secondaryLabel.resolveFrom(context),
17 | fontSize: CS_DESCRIPTION_FONT_SIZE,
18 | height: 1.1,
19 | ),
20 | ),
21 | );
22 | }
23 | }
24 |
--------------------------------------------------------------------------------
/lib/widgets/header.dart:
--------------------------------------------------------------------------------
1 | part of flutter_cupertino_settings;
2 |
3 | /// This widgets is used as a grouping separator.
4 | /// The [title] attribute is optional.
5 | class CSHeader extends StatelessWidget {
6 | final String title;
7 |
8 | const CSHeader(this.title);
9 |
10 | @override
11 | Widget build(BuildContext context) {
12 | return Container(
13 | padding: const EdgeInsets.only(left: 10.0, top: 30.0, bottom: 5.0),
14 | decoration: BoxDecoration(
15 | color: CupertinoColors.systemGroupedBackground.resolveFrom(context),
16 | border: Border(
17 | bottom: BorderSide(
18 | color: CupertinoColors.opaqueSeparator.resolveFrom(context),
19 | ),
20 | ),
21 | ),
22 | child: Text(
23 | title.toUpperCase(),
24 | style: basicTextStyle(context).copyWith(
25 | color: CupertinoColors.secondaryLabel.resolveFrom(context),
26 | fontSize: CS_HEADER_FONT_SIZE,
27 | ),
28 | ),
29 | );
30 | }
31 | }
32 |
--------------------------------------------------------------------------------
/lib/widgets/link.dart:
--------------------------------------------------------------------------------
1 | part of flutter_cupertino_settings;
2 |
3 | /// Provides a button for navigation
4 | class CSLink extends StatelessWidget {
5 | final String title;
6 | final String? subtitle;
7 | final String? detail;
8 | final VoidCallback? onPressed;
9 | final double titleFontSize;
10 | final double subTitleFontSize;
11 | final CSWidgetStyle style;
12 | final bool addPaddingToBorder;
13 | final bool showTopBorder;
14 | final Widget? trailing;
15 | final CellType cellType;
16 |
17 | const CSLink({
18 | required this.title,
19 | this.onPressed,
20 | this.subtitle,
21 | this.detail,
22 | this.style = CS_DEFAULT_STYLE,
23 | this.titleFontSize = CS_TITLE_FONT_SIZE,
24 | this.subTitleFontSize = CS_SUBTITLE_FONT_SIZE,
25 | this.addPaddingToBorder = true,
26 | this.showTopBorder = false,
27 | this.trailing,
28 | this.cellType = CellType.defaultStyle,
29 | });
30 |
31 | @override
32 | Widget build(BuildContext context) {
33 | final showSubtitle = (cellType == CellType.subtitleDetailStyle ||
34 | cellType == CellType.subtitleStyle) &&
35 | subtitle != null &&
36 | subtitle!.isNotEmpty;
37 | final showDetail = (cellType == CellType.subtitleDetailStyle ||
38 | cellType == CellType.detailRightStyle) &&
39 | detail != null &&
40 | detail!.isNotEmpty;
41 |
42 | return CSWidget(
43 | CupertinoButton(
44 | padding: EdgeInsets.zero,
45 | onPressed: onPressed,
46 | child: Row(
47 | mainAxisAlignment: MainAxisAlignment.spaceBetween,
48 | crossAxisAlignment: CrossAxisAlignment.center,
49 | children: [
50 | Expanded(
51 | child: Column(
52 | crossAxisAlignment: CrossAxisAlignment.start,
53 | mainAxisAlignment: MainAxisAlignment.center,
54 | mainAxisSize: MainAxisSize.min,
55 | children: [
56 | Text(
57 | title,
58 | style: basicTextStyle(context).copyWith(
59 | color: CupertinoColors.label.resolveFrom(context),
60 | fontSize: titleFontSize,
61 | ),
62 | maxLines: 2,
63 | overflow: TextOverflow.ellipsis,
64 | ),
65 | if (showSubtitle) const SizedBox(height: 2),
66 | if (showSubtitle)
67 | Text(
68 | subtitle!,
69 | style: basicTextStyle(context).copyWith(
70 | color:
71 | CupertinoColors.secondaryLabel.resolveFrom(context),
72 | fontSize: subTitleFontSize,
73 | fontWeight: FontWeight.w400,
74 | ),
75 | maxLines: 1,
76 | overflow: TextOverflow.clip,
77 | ),
78 | ],
79 | ),
80 | ),
81 | if (showDetail) ...[
82 | Text(
83 | detail!,
84 | style: basicTextStyle(context).copyWith(
85 | color: CupertinoColors.secondaryLabel.resolveFrom(context),
86 | fontSize: titleFontSize,
87 | ),
88 | maxLines: 1,
89 | overflow: TextOverflow.clip,
90 | ),
91 | const SizedBox(width: 4),
92 | ],
93 | Padding(
94 | padding: const EdgeInsets.only(left: 1.0, right: 2.0),
95 | child: trailing ??
96 | Icon(
97 | CupertinoIcons.right_chevron,
98 | color: CupertinoColors.secondaryLabel
99 | .resolveFrom(context)
100 | .withOpacity(0.4),
101 | size: CS_CHEVRON_SIZE,
102 | ),
103 | ),
104 | ],
105 | ),
106 | ),
107 | style: style,
108 | addPaddingToBorder: addPaddingToBorder,
109 | showTopBorder: showTopBorder,
110 | );
111 | }
112 | }
113 |
114 | enum CellType {
115 | /// Default Style with optional widget on left side and left-aligned title
116 | defaultStyle,
117 |
118 | /// Left-aligned title and left-aligned subtitle below
119 | subtitleStyle,
120 |
121 | /// Left-aligned title, left-aligned subtitle below and right-aligned detail
122 | subtitleDetailStyle,
123 |
124 | /// Left-aligned title and right-aligned detail
125 | detailRightStyle,
126 |
127 | /// right-aligned title and left-aligned detail
128 | detailLeftStyle,
129 | }
130 |
--------------------------------------------------------------------------------
/lib/widgets/secret.dart:
--------------------------------------------------------------------------------
1 | part of flutter_cupertino_settings;
2 |
3 | /// Provides a button for navigation
4 | class CSSecret extends StatefulWidget {
5 | final String text;
6 | final String secret;
7 | final double fontSize;
8 | final CSWidgetStyle style;
9 | final bool addPaddingToBorder;
10 | final String obscuringCharacter;
11 |
12 | CSSecret(
13 | this.text,
14 | this.secret, {
15 | this.style = CS_DEFAULT_STYLE,
16 | this.fontSize = CS_TITLE_FONT_SIZE,
17 | this.addPaddingToBorder = true,
18 | this.obscuringCharacter = '•',
19 | });
20 |
21 | @override
22 | _CSSecretState createState() => _CSSecretState();
23 | }
24 |
25 | class _CSSecretState extends State {
26 | bool _show = false;
27 |
28 | @override
29 | Widget build(BuildContext context) {
30 | return CSWidget(
31 | DefaultTextStyle(
32 | style: basicTextStyle(context).copyWith(
33 | color: CupertinoColors.label.resolveFrom(context),
34 | fontSize: widget.fontSize,
35 | ),
36 | child: Row(
37 | mainAxisAlignment: MainAxisAlignment.spaceBetween,
38 | children: [
39 | Text(widget.text),
40 | Row(
41 | children: [
42 | Text(
43 | _show ? widget.secret : widget.obscuringCharacter * widget.secret.length,
44 | ),
45 | CupertinoButton(
46 | child: Icon(
47 | CupertinoIcons.eye_solid,
48 | size: CS_CHECK_SIZE,
49 | ),
50 | onPressed: () => setState(() => _show = !_show),
51 | ),
52 | ],
53 | ),
54 | ],
55 | ),
56 | ),
57 | style: widget.style,
58 | addPaddingToBorder: widget.addPaddingToBorder,
59 | );
60 | }
61 | }
62 |
--------------------------------------------------------------------------------
/lib/widgets/selection.dart:
--------------------------------------------------------------------------------
1 | part of flutter_cupertino_settings;
2 |
3 | /// A selection view
4 | /// Allows to select between multiple items
5 | /// Every item is represented by a String
6 | ///
7 | /// If an item is selected, onSelected is called with its index
8 | ///
9 | /// eg:
10 | /// items = ["hello","world","flutter"]
11 | /// select "world"
12 | ///
13 | /// onSelected(1)
14 |
15 | class CSSelection extends StatelessWidget {
16 | final List> items;
17 | final void Function(T selected) onSelected;
18 | final T? currentSelection;
19 | final double fontSize;
20 |
21 | const CSSelection({
22 | required this.items,
23 | required this.onSelected,
24 | this.currentSelection,
25 | this.fontSize = CS_TITLE_FONT_SIZE,
26 | });
27 |
28 | @override
29 | Widget build(BuildContext context) {
30 | return Column(
31 | children: items.map((item) => createItem(context, item)).toList(),
32 | );
33 | }
34 |
35 | Widget createItem(BuildContext context, CSSelectionItem item) {
36 | final text = Text(item.text,
37 | style: TextStyle(
38 | color: CupertinoColors.label.resolveFrom(context),
39 | fontSize: fontSize,
40 | ));
41 | final textWidget = item.subtitle == null
42 | ? text
43 | : Column(crossAxisAlignment: CrossAxisAlignment.start, children: [
44 | text,
45 | SizedBox(height: 2),
46 | Text(item.subtitle!,
47 | style: basicTextStyle(context).copyWith(
48 | color: CupertinoColors.secondaryLabel.resolveFrom(context),
49 | fontSize: CS_HEADER_FONT_SIZE))
50 | ]);
51 | return CSWidget(
52 | CupertinoButton(
53 | onPressed: () {
54 | HapticFeedback.selectionClick();
55 | onSelected(item.value);
56 | },
57 | pressedOpacity: 1.0,
58 | padding: const EdgeInsets.fromLTRB(4, 8, 2, 8),
59 | child: Row(
60 | crossAxisAlignment: CrossAxisAlignment.center,
61 | children: [
62 | Expanded(child: textWidget),
63 | Padding(
64 | padding: const EdgeInsets.only(right: 5.0),
65 | child: Icon(
66 | CupertinoIcons.check_mark,
67 | color: item.value == currentSelection
68 | ? CupertinoColors.activeBlue
69 | : const Color(0x00000000),
70 | size: CS_CHECK_SIZE,
71 | ),
72 | ),
73 | ],
74 | ),
75 | ),
76 | addPaddingToBorder: items.last != item,
77 | showTopBorder: item.showTopBorder,
78 | );
79 | }
80 | }
81 |
82 | class CSSelectionItem {
83 | final T value;
84 | final String text;
85 | final String? subtitle;
86 | final bool showTopBorder;
87 |
88 | const CSSelectionItem({
89 | required this.value,
90 | required this.text,
91 | this.subtitle,
92 | this.showTopBorder = false,
93 | });
94 | }
95 |
--------------------------------------------------------------------------------
/lib/widgets/spacer.dart:
--------------------------------------------------------------------------------
1 | part of flutter_cupertino_settings;
2 |
3 | class CSSpacer extends StatelessWidget {
4 | final bool showBorder;
5 |
6 | const CSSpacer({
7 | Key? key,
8 | this.showBorder = true,
9 | }) : super(key: key);
10 |
11 | @override
12 | Widget build(BuildContext context) {
13 | return Container(
14 | padding: const EdgeInsets.only(left: 10.0, top: 20.0, bottom: 5.0),
15 | decoration: BoxDecoration(
16 | color: CupertinoColors.systemGroupedBackground.resolveFrom(context),
17 | border: Border(
18 | bottom: showBorder
19 | ? BorderSide(
20 | color: CupertinoColors.opaqueSeparator.resolveFrom(context),
21 | )
22 | : BorderSide.none,
23 | ),
24 | ),
25 | );
26 | }
27 | }
28 |
--------------------------------------------------------------------------------
/lib/widgets/widget.dart:
--------------------------------------------------------------------------------
1 | part of flutter_cupertino_settings;
2 |
3 | /// Used to display a widget of any kind in [CupertinoSettings]
4 | /// It provices the correct height, color and border to create the intended look
5 | /// The optional [alignment] attribute allows to specify the aligment inside the container
6 | /// The optional [style] attribute allows to specify a style (e.g. an Icon)
7 | class CSWidget extends StatelessWidget {
8 | final Widget widget;
9 | final AlignmentGeometry? alignment;
10 | final double height;
11 | final CSWidgetStyle style;
12 | final bool addPaddingToBorder;
13 | final bool showTopBorder;
14 |
15 | const CSWidget(
16 | this.widget, {
17 | this.alignment,
18 | this.height = CS_ITEM_HEIGHT,
19 | this.style = CS_DEFAULT_STYLE,
20 | this.addPaddingToBorder = false,
21 | this.showTopBorder = false,
22 | });
23 |
24 | @override
25 | Widget build(BuildContext context) {
26 | Widget child;
27 | EdgeInsets padding;
28 |
29 | //style.icon
30 | if (style.icon != null) {
31 | padding = CS_ICON_PADDING;
32 | child = Row(
33 | children: [
34 | Container(
35 | padding: CS_ICON_PADDING,
36 | child: style.icon,
37 | ),
38 | Expanded(child: widget)
39 | ],
40 | );
41 | } else {
42 | child = widget;
43 | padding = CS_ITEM_PADDING;
44 | }
45 |
46 | return Container(
47 | alignment: alignment,
48 | decoration: BoxDecoration(
49 | color: CupertinoColors.secondarySystemGroupedBackground
50 | .resolveFrom(context),
51 | border: Border(
52 | top: showTopBorder
53 | ? BorderSide(
54 | color: CupertinoColors.opaqueSeparator.resolveFrom(context),
55 | )
56 | : BorderSide.none,
57 | ),
58 | ),
59 | constraints: const BoxConstraints(minHeight: 42),
60 | // height: height,
61 | padding: EdgeInsets.only(
62 | left: addPaddingToBorder ? padding.left : 0,
63 | ),
64 | child: Container(
65 | padding: padding.copyWith(
66 | left: addPaddingToBorder ? 2 : padding.left + 2,
67 | ),
68 | decoration: BoxDecoration(
69 | border: Border(
70 | bottom: BorderSide(
71 | color: CupertinoColors.opaqueSeparator.resolveFrom(context),
72 | ),
73 | ),
74 | ),
75 | child: child,
76 | ),
77 | );
78 | }
79 | }
80 |
81 | /// Defines style attributes that can be applied to every [CSWidget]
82 | class CSWidgetStyle {
83 | final Icon? icon;
84 |
85 | const CSWidgetStyle({this.icon});
86 | }
87 |
88 | enum ItemType { single, list, listLast }
89 |
--------------------------------------------------------------------------------
/pubspec.yaml:
--------------------------------------------------------------------------------
1 | name: flutter_cupertino_settings
2 | description: Flutter widget to create an iOS settings-table (static TableView).
3 | version: 0.5.0
4 | homepage: https://github.com/matthinc/flutter_cupertino_settings
5 |
6 | environment:
7 | sdk: ">=2.12.0 <3.0.0"
8 |
9 | dependencies:
10 | flutter:
11 | sdk: flutter
12 | cupertino_icons: ^1.0.0
13 |
--------------------------------------------------------------------------------
/readme.md:
--------------------------------------------------------------------------------
1 | # flutter_cupertino_settings
2 |
3 | [](https://pub.dartlang.org/packages/flutter_cupertino_settings) 
4 |
5 | A Flutter widget to create an iOS settings-table (static TableView).
6 |
7 | ```dart
8 |
9 | import 'package:flutter_cupertino_settings/flutter_cupertino_settings.dart';
10 |
11 | CSWidgetStyle brightnessStyle = const CSWidgetStyle(
12 | icon: const Icon(Icons.brightness_medium, color: Colors.black54)
13 | );
14 |
15 | CupertinoSettings(
16 | items: [
17 | const CSHeader('Brightness'),
18 | CSWidget(CupertinoSlider(value: 0.5), style: brightnessStyle),
19 | CSControl(
20 | nameWidget: Text('Auto brightness'),
21 | contentWidget: CupertinoSwitch(value: true),
22 | style: brightnessStyle,
23 | ),
24 | CSHeader('Selection'),
25 | CSSelection(
26 | items: const >[
27 | CSSelectionItem(text: 'Day mode', value: 0),
28 | CSSelectionItem(text: 'Night mode', value: 1),
29 | ],
30 | onSelected: (index) {print(index);},
31 | currentSelection: 0,
32 | ),
33 | CSDescription('Using Night mode extends battery life on devices with OLED display',),
34 | const CSHeader(''),
35 | CSControl(
36 | nameWidget: Text('Loading...'),
37 | contentWidget: CupertinoActivityIndicator(),
38 | ),
39 | CSButton(CSButtonType.DEFAULT, "Licenses", (){ print("It works!"); }),
40 | const CSHeader(''),
41 | CSButton(CSButtonType.DESTRUCTIVE, "Delete all data", (){})
42 | ]
43 | );
44 | ```
45 |
46 | 
47 |
48 | ### Contributors
49 | - Dark theme & example by [AppleEducate](https://github.com/appleeducate)
50 | - CSSecret by [SimonIT](https://github.com/SimonIT)
51 | - iOS 13 support by [Tim Bierbaum](https://github.com/bierbaumtim)
52 |
--------------------------------------------------------------------------------
/screenshots/scr1.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/matthinc/flutter_cupertino_settings/5edb0476d73ecfbc1857d6f9f9eddaf507344f5e/screenshots/scr1.png
--------------------------------------------------------------------------------