├── .gitignore ├── .metadata ├── CHANGELOG.md ├── LICENSE ├── README.md ├── analysis_options.yaml ├── example ├── .gitignore ├── .metadata ├── README.md ├── android │ ├── .gitignore │ ├── app │ │ ├── build.gradle │ │ └── src │ │ │ ├── debug │ │ │ └── AndroidManifest.xml │ │ │ ├── main │ │ │ ├── AndroidManifest.xml │ │ │ ├── java │ │ │ │ └── com │ │ │ │ │ └── happyworks │ │ │ │ │ └── flutter_settings_screens_example │ │ │ │ │ └── MainActivity.java │ │ │ └── res │ │ │ │ ├── drawable-v21 │ │ │ │ └── launch_background.xml │ │ │ │ ├── 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-night │ │ │ │ └── styles.xml │ │ │ │ └── values │ │ │ │ └── styles.xml │ │ │ └── profile │ │ │ └── AndroidManifest.xml │ ├── build.gradle │ ├── gradle.properties │ ├── gradle │ │ └── wrapper │ │ │ └── gradle-wrapper.properties │ └── settings.gradle ├── ios │ ├── .gitignore │ ├── Flutter │ │ ├── AppFrameworkInfo.plist │ │ ├── Debug.xcconfig │ │ └── Release.xcconfig │ ├── Podfile │ ├── Runner.xcodeproj │ │ ├── project.pbxproj │ │ ├── project.xcworkspace │ │ │ ├── contents.xcworkspacedata │ │ │ └── xcshareddata │ │ │ │ ├── IDEWorkspaceChecks.plist │ │ │ │ └── WorkspaceSettings.xcsettings │ │ └── xcshareddata │ │ │ └── xcschemes │ │ │ └── Runner.xcscheme │ ├── Runner.xcworkspace │ │ ├── contents.xcworkspacedata │ │ └── xcshareddata │ │ │ ├── IDEWorkspaceChecks.plist │ │ │ └── WorkspaceSettings.xcsettings │ └── Runner │ │ ├── AppDelegate.swift │ │ ├── Assets.xcassets │ │ ├── AppIcon.appiconset │ │ │ ├── Contents.json │ │ │ ├── Icon-App-1024x1024@1x.png │ │ │ ├── Icon-App-20x20@1x.png │ │ │ ├── Icon-App-20x20@2x.png │ │ │ ├── Icon-App-20x20@3x.png │ │ │ ├── Icon-App-29x29@1x.png │ │ │ ├── Icon-App-29x29@2x.png │ │ │ ├── Icon-App-29x29@3x.png │ │ │ ├── Icon-App-40x40@1x.png │ │ │ ├── Icon-App-40x40@2x.png │ │ │ ├── Icon-App-40x40@3x.png │ │ │ ├── Icon-App-60x60@2x.png │ │ │ ├── Icon-App-60x60@3x.png │ │ │ ├── Icon-App-76x76@1x.png │ │ │ ├── Icon-App-76x76@2x.png │ │ │ └── Icon-App-83.5x83.5@2x.png │ │ └── LaunchImage.imageset │ │ │ ├── Contents.json │ │ │ ├── LaunchImage.png │ │ │ ├── LaunchImage@2x.png │ │ │ ├── LaunchImage@3x.png │ │ │ └── README.md │ │ ├── Base.lproj │ │ ├── LaunchScreen.storyboard │ │ └── Main.storyboard │ │ ├── Info.plist │ │ └── Runner-Bridging-Header.h ├── lib │ ├── app_settings_page.dart │ ├── cache_provider.dart │ └── main.dart ├── macos │ ├── .gitignore │ ├── Flutter │ │ ├── Flutter-Debug.xcconfig │ │ ├── Flutter-Release.xcconfig │ │ └── GeneratedPluginRegistrant.swift │ ├── Podfile │ ├── Runner.xcodeproj │ │ ├── project.pbxproj │ │ ├── project.xcworkspace │ │ │ └── xcshareddata │ │ │ │ └── IDEWorkspaceChecks.plist │ │ └── xcshareddata │ │ │ └── xcschemes │ │ │ └── Runner.xcscheme │ ├── Runner.xcworkspace │ │ ├── contents.xcworkspacedata │ │ └── xcshareddata │ │ │ └── IDEWorkspaceChecks.plist │ └── Runner │ │ ├── AppDelegate.swift │ │ ├── Assets.xcassets │ │ └── AppIcon.appiconset │ │ │ ├── Contents.json │ │ │ ├── app_icon_1024.png │ │ │ ├── app_icon_128.png │ │ │ ├── app_icon_16.png │ │ │ ├── app_icon_256.png │ │ │ ├── app_icon_32.png │ │ │ ├── app_icon_512.png │ │ │ └── app_icon_64.png │ │ ├── Base.lproj │ │ └── MainMenu.xib │ │ ├── Configs │ │ ├── AppInfo.xcconfig │ │ ├── Debug.xcconfig │ │ ├── Release.xcconfig │ │ └── Warnings.xcconfig │ │ ├── DebugProfile.entitlements │ │ ├── Info.plist │ │ ├── MainFlutterWindow.swift │ │ └── Release.entitlements ├── pubspec.yaml ├── test │ └── widget_test.dart └── web │ ├── favicon.png │ ├── icons │ ├── Icon-192.png │ ├── Icon-512.png │ ├── Icon-maskable-192.png │ └── Icon-maskable-512.png │ ├── index.html │ └── manifest.json ├── lib ├── flutter_settings_screens.dart └── src │ ├── cache │ ├── cache.dart │ ├── cache_provider.dart │ └── cache_provider_impl.dart │ ├── settings.dart │ ├── utils │ ├── utils.dart │ └── widget_utils.dart │ └── widgets │ ├── base_widgets.dart │ ├── color_picker │ ├── circle_color.dart │ ├── colors.dart │ └── material_color_picker.dart │ └── settings_widgets.dart ├── media ├── example_1.gif ├── example_2.gif ├── example_3.gif ├── example_4.gif └── example_5.gif ├── pubspec.yaml └── test └── flutter_settings_screens_test.dart /.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 | .idea/* 18 | 19 | # The .vscode folder contains launch configuration and tasks you configure in 20 | # VS Code which you may wish to be included in version control, so this line 21 | # is commented out by default. 22 | #.vscode/ 23 | 24 | # Flutter/Dart/Pub related 25 | **/doc/api/ 26 | .dart_tool/ 27 | .flutter-plugins 28 | .packages 29 | .pub-cache/ 30 | .pub/ 31 | /build/ 32 | 33 | # Web related 34 | lib/generated_plugin_registrant.dart 35 | 36 | # Exceptions to above rules. 37 | !/packages/flutter_tools/test/data/dart_dependencies_test/**/.packages 38 | pubspec.lock 39 | example/.flutter-plugins-dependencies 40 | example/pubspec.lock 41 | .flutter-plugins-dependencies 42 | /.fvm/ 43 | -------------------------------------------------------------------------------- /.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: 2c7af1e24e45a79f4eb73d67d98fcecea8bf6146 8 | channel: master 9 | 10 | project_type: plugin 11 | -------------------------------------------------------------------------------- /CHANGELOG.md: -------------------------------------------------------------------------------- 1 | ## 0.3.4 2 | - Finalised release of 0.3.3-null-safety+2 with Null-safety, Material 3 & flutter 3 changes 3 | - Huge thanks to @nyxkn for all fixes & updates for this release 4 | - Huge thanks to @romanbsd for all updates to Flutter 3 changes 5 | 6 | 7 | ## 0.3.3-null-safety+2 8 | - add flag to enable textfield content to be autoselected on focus 9 | - change capitalization of autovalidateMode 10 | - TextInput: expose helperText and inputFormatters 11 | - fix: null-safety warning messages 12 | - fix: valuechangeobserver dispose accidentally clears the whole _notifier map rather than just its own cachekey 13 | - Huge thanks to @nyxkn for all fixes & updates for this release 14 | 15 | ## 0.3.3-null-safety+1 16 | - Fix issue where implementation for setObject in default cache provider always throws exception 17 | - Custom text style in all widgets 18 | - Clear the notifiers map when the widget is disposed 19 | 20 | ## 0.3.3-null-safety 21 | - Breaking Changes: 22 | - Cache Provider interface definition updated to allow asynchronous getter/setter 23 | - Optional Default values are moved to getters instead of setters 24 | - Flutter SDK version upgraded to 2.15.0 & upgraded the plugin dependencies 25 | - Changed all getters & setters definitions to support null values 26 | - Changed Settings implementation according to new changes 27 | - Example app moved Flutter SDK to 2.15.0 28 | - Updated example app implementation 29 | - Updated Code documentation in cache provider interface 30 | 31 | 32 | ## 0.3.2-null-safety 33 | - Provider version updated to 6.0.0, thanks to @Pawelek55 34 | - ExpandedSettingTile were not using the provided expanded status, fixed by @Colton127 35 | - Updated theme changes in the source code & in the example to resolve analyzer warnings 36 | 37 | ## 0.3.1-null-safety 38 | - added functionality to update the specific SettingsUI by updating it's value 39 | by calling setValue with `notify` as `true`. 40 | 41 | Example: 42 | ```dart 43 | await Settings.setValue(cacheKey, newValue, notify: true); 44 | ``` 45 | 46 | - Fix - Unresponsive tapping of the switch tile, fixed by @pascalwils 47 | - Updated ReadMe content to match new updates 48 | - Updated example app code to demo the UI update functionality 49 | - Checkout Auto adjusting Volume slider 50 | 51 | ## 0.3.0-null-safety 52 | - null-safety migration 53 | - bug-fix for slider not respecting step value in decimal points 54 | 55 | ## 0.2.2+1 56 | - complete dependency update to latest 57 | 58 | ## 0.2.2 59 | - remove autovalidate option to comply with new sdk changes 60 | - remove unnecessary use of Generic cache provider interface 61 | `Set getKeys()` -> `Set getKeys()` 62 | - reason for this is that generics may restrict some implementation in some way 63 | - to achieve the same effect as the generics implementation, one can just `cast` the set as they want 64 | - if the whole interface depends on generics only then the previous declaration makes sense. 65 | - update & fix example app code 66 | - plugin code organization & documentation updates 67 | 68 | #### Developer Note: 69 | 1. The sdk upgrade will be done in two stages 70 | - stage 1: only update the dependencies with code changes to comply with the updates 71 | - stage 2: update the flutter/dart sdk version along with the least version of supported dependencies 72 | 2. Few of the next releases may contain some breaking changes in relation to cache provider implementation 73 | 3. A few of the planned updates: 74 | - null safety support for library 75 | - cache provider structuring to support universal implementation, allows using any storage platform to be used 76 | like, shared_preferences, hive, flutter_secure_storage, etc 77 | - massive UI customization in terms of platforms & designs 78 | - conditional changes or changes with confirmation 79 | - settings value change observation 80 | 81 | **If you have any suggestions and/or support to offer please file an issue in the repository & let me know, use `[Suggestion]` or `[FeatureRequest]` tags in issue titles** 82 | 83 | ## 0.2.1+1 84 | * improved overall alignment of settings tiles 85 | * update cache provide code to make asynchronous calls to setter methods 86 | - autoValidated parameter in text input settings is now deprecated and will be removed soon. User `autoValidateMode` parameter instead. 87 | * removed native platform dependency code as this library does not depend on native features. At least not directly. 88 | 89 | ## 0.2.1 90 | * `SimpleSettingsTile` will take any widget as `child` instead of only `SettingsScreen` 91 | - **Breaking**: parameter name changed from `screen` to `child` for consistency 92 | * Added `subtitle` property for most settings tiles to allow a describing how this setting may introduce change in behaviour of the app 93 | * Improved Settings title and subtitle text style for consistency in UI 94 | * `SliderSettings` now have 2 additional callbacks: 95 | - onChangeStart - allows detecting drag start event 96 | - onChangeEnd - allows detecting drag end event 97 | - Using this allows changing the slider value only when user stops sliding 98 | * Updated Example code to reflect latest features 99 | 100 | ## 0.2.0+1 101 | * improved plugin initialization, now supports async method call 102 | * resolved a bug where Radio Settings was not reflecting changes 103 | 104 | ## 0.2.0 105 | * complete re-do of the whole library 106 | * removed rx-dart dependency 107 | * improved the working of the many existing settings widgets 108 | * many of the choice based widgets now support any primitive value as input/output values instead of just strings 109 | * added more customization choices per setting widget 110 | * added a default cache provider which is based on `shared_preferences` library by flutter team 111 | * updated code documentation 112 | 113 | #### Breaking Change: 114 | Your existing use of some settings widgets might show error or not work as due to them being re-designed, like change in name/type of the parameters or the widget itself is renamed. 115 | 116 | This was a major re-design/refactor of the library, so please re-test part of your code which uses this library. 117 | 118 | ## 0.1.0+0.2 119 | * update in license file 120 | 121 | ## 0.1.0+0.1 122 | * 0.1.0 release + update in documentation and sdk version constraints 123 | 124 | ## 0.1.0 125 | * first release 126 | 127 | ## 0.0.1 128 | * initial code release -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2019 Harshvardhan Joshi 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # flutter_settings_screens 2 | 3 | [![pub package](https://img.shields.io/pub/v/flutter_settings_screens.svg)](https://pub.dev/packages/flutter_settings_screens) 4 | [![License: MIT](https://img.shields.io/badge/License-MIT-blue.svg)](https://opensource.org/licenses/MIT) 5 | 6 | This is a simple flutter plugin for easily creating app settings screens. 7 | The unique thing about this library is that it is not dependent upon any specific storage library used to store settings. 8 | 9 | Inspired by the [shared_preferences_settings](https://pub.dev/packages/shared_preferences_settings) plugin. 10 | 11 | **Update: Now with Null-safety & Material3 support** 12 | 13 | ## Features 14 | - A collection of settings widgets to make a settings page in a few seconds and get going. 15 | - **Normal**: 16 | - SimpleSettingsTile 17 | - Switch/Toggle setting 18 | - Checkbox setting 19 | - Drop down setting 20 | - Radio selection Setting 21 | - Slider setting 22 | - Color choice panel 23 | - Text Input Setting 24 | - **Advanced**: 25 | - SettingsScreen: 26 | > A Flutter Widget/Page which can contain all settings widget. 27 | - ExpandableSettingsTile 28 | > A settings widget which can hold a set of widgets in a section which is collapsible 29 | - SettingsContainer 30 | > A Settings widget that helps any flutter widget fit into the settings page 31 | - SettingsGroup 32 | > A Container widget that creates a section with a title to separate settings inside this from other settings 33 | - Settings saved via "CacheProvider" library of your choice 34 | - default version uses SharedPreferences. 35 | - Widgets with conditional visibility of some other settings. 36 | - for example, A set of settings is only visible if a switch or a checkbox is enabled. 37 | 38 | 39 | ## Examples 40 | ![](https://github.com/GAM3RG33K/flutter_settings_screens/blob/master/media/example_1.gif?raw=true "") 41 | ![](https://github.com/GAM3RG33K/flutter_settings_screens/blob/master/media/example_2.gif?raw=true "") 42 | ![](https://github.com/GAM3RG33K/flutter_settings_screens/blob/master/media/example_3.gif?raw=true "") 43 | ![](https://github.com/GAM3RG33K/flutter_settings_screens/blob/master/media/example_4.gif?raw=true "") 44 | ![](https://github.com/GAM3RG33K/flutter_settings_screens/blob/master/media/example_5.gif?raw=true "") 45 | 46 | 47 | ## Initializing the plugin 48 | 49 | Initialize the plugin as following: 50 | ```dart 51 | await Settings.init(cacheProvider: _customCacheProvider); 52 | ``` 53 | 54 | **Note**: 55 | The plugin must be initialized before Navigating to the settings page. 56 | 57 | It is recommended that `Settings.init()` should be called before `runApp()` is called in the main file. However, anywhere before showing the settings page is fine. 58 | 59 | 60 | ### Cache Provider Interface 61 | Cache Provider is an interface by which the plugin accesses the underlying caching storage. 62 | 63 | This plugin includes an implementation of the `CacheProvider` using the `SharedPreferences` library by flutter. If `cacheProvider` parameter is not given explicitly then the default implementation will be used to store the settings. 64 | 65 | However, if you wish to use other means for storing the data, you can implement one by yourself. 66 | 67 | All you have to do is create a class as follows: 68 | ```dart 69 | import 'package:flutter_settings_screens/flutter_settings_screens.dart'; 70 | 71 | class CustomCacheProvider extends CacheProvider { 72 | ///... 73 | ///implement the methods as you want 74 | ///... 75 | } 76 | ``` 77 | 78 | for example, 79 | 80 | ```dart 81 | /// A cache access provider class for shared preferences using shared_preferences library 82 | class SharePreferenceCache extends CacheProvider { 83 | //... 84 | } 85 | ``` 86 | 87 | OR 88 | 89 | ```dart 90 | /// A cache access provider class for shared preferences using Hive library 91 | class HiveCache extends CacheProvider { 92 | //... 93 | } 94 | ``` 95 | 96 | Once you implement the class, use an instance of this class to initialize the Settings class. 97 | 98 | 99 | ## Accessing/Retrieving data 100 | You can use static methods of `Settings` class to access any data from the storage. 101 | 102 | Get value: 103 | ```dart 104 | Settings.getValue(cacheKey, defaultValue); 105 | ``` 106 | Set value(no UI updates): 107 | ```dart 108 | await Settings.setValue(cacheKey, newValue); 109 | ``` 110 | 111 | Set value(with UI updates): 112 | ```dart 113 | await Settings.setValue(cacheKey, newValue, notify: true); 114 | ``` 115 | 116 | T represents any of the following: 117 | - String 118 | - bool 119 | - int 120 | - double 121 | - Object 122 | 123 | For example if you want to access a String value from the storage: 124 | Get value: 125 | ```dart 126 | Settings.getValue(cacheKey, defaultValue); 127 | ``` 128 | Set value: 129 | ```dart 130 | await Settings.setValue(cacheKey, newValue, notify: true); 131 | ``` 132 | 133 | ### Special-Note: 134 | Since, `Color` or `MaterialColor` is a Flutter object, we need to convert it to string version of the color before saving it to cache & convert string version to color while fetching it from the cache. 135 | 136 | For that the plugin exposes `ConversionUtils` class with utility method to do that needed. 137 | 138 | From color to string: 139 | ```dart 140 | String colorString = ConversionUtils.stringFromColor(Colors.blue); 141 | ``` 142 | 143 | From string to color: 144 | ```dart 145 | Color color = ConversionUtils.colorFromString('#0000ff'); 146 | ``` 147 | 148 | 149 | ## Tile widgets 150 | 151 | #### SimpleSettingsTile 152 | 153 | SimpleSettingsTile is a simple settings tile that can open a new screen by tapping the tile. 154 | 155 | Example: 156 | ```dart 157 | SimpleSettingsTile( 158 | title: 'Advanced', 159 | subtitle: 'More, advanced settings.' 160 | screen: SettingsScreen( 161 | title: 'Sub menu', 162 | children: [ 163 | CheckboxSettingsTile( 164 | settingsKey: 'key-of-your-setting', 165 | title: 'This is a simple Checkbox', 166 | ), 167 | ], 168 | ), 169 | ); 170 | ``` 171 | 172 | #### SettingsTileGroup 173 | 174 | SettingsGroup is a widget that contains multiple settings tiles and other widgets together as a group and shows a title/name of that group. 175 | 176 | All the children widget will have small padding from the left and top to provide a sense that they in a separate group from others 177 | 178 | Example: 179 | ```dart 180 | SettingsGroup( 181 | title: 'Group title', 182 | children: [ 183 | CheckboxSettingsTile( 184 | settingKey: 'key-day-light-savings', 185 | title: 'Daylight Time Saving', 186 | enabledLabel: 'Enabled', 187 | disabledLabel: 'Disabled', 188 | leading: Icon(Icons.timelapse), 189 | ), 190 | SwitchSettingsTile( 191 | settingKey: 'key-dark-mode', 192 | title: 'Dark Mode', 193 | enabledLabel: 'Enabled', 194 | disabledLabel: 'Disabled', 195 | leading: Icon(Icons.palette), 196 | ), 197 | ], 198 | ); 199 | ``` 200 | 201 | 202 | #### ExpandableSettingsTile 203 | ExpandableSettingsTile is a wrapper widget that shows the given children when expanded by clicking on the tile. 204 | 205 | Example: 206 | ```dart 207 | ExpandableSettingsTile( 208 | title: 'Quick setting dialog2', 209 | subtitle: 'Expandable Settings', 210 | children: [ 211 | CheckboxSettingsTile( 212 | settingKey: 'key-day-light-savings', 213 | title: 'Daylight Time Saving', 214 | enabledLabel: 'Enabled', 215 | disabledLabel: 'Disabled', 216 | leading: Icon(Icons.timelapse), 217 | ), 218 | SwitchSettingsTile( 219 | settingKey: 'key-dark-mode', 220 | title: 'Dark Mode', 221 | enabledLabel: 'Enabled', 222 | disabledLabel: 'Disabled', 223 | leading: Icon(Icons.palette), 224 | ), 225 | ], 226 | ); 227 | ``` 228 | 229 | #### CheckboxSettingsTile 230 | 231 | CheckboxSettingsTile is a widget that has a Checkbox with given title, subtitle and default value/status of the Checkbox 232 | 233 | This widget supports an additional list of widgets to display when the Checkbox is checked. This optional list of widgets is accessed through `childrenIfEnabled` property of this widget. 234 | 235 | This widget works similar to `SwitchSettingsTile`. 236 | 237 | Example: 238 | ```dart 239 | CheckboxSettingsTile( 240 | leading: Icon(Icons.developer_mode), 241 | settingKey: 'key-check-box-dev-mode', 242 | title: 'Developer Settings', 243 | onChange: (value) { 244 | debugPrint('key-check-box-dev-mode: $value'); 245 | }, 246 | childrenIfEnabled: [ 247 | CheckboxSettingsTile( 248 | leading: Icon(Icons.adb), 249 | settingKey: 'key-is-developer', 250 | title: 'Developer Mode', 251 | onChange: (value) { 252 | debugPrint('key-is-developer: $value'); 253 | }, 254 | ), 255 | SwitchSettingsTile( 256 | leading: Icon(Icons.usb), 257 | settingKey: 'key-is-usb-debugging', 258 | title: 'USB Debugging', 259 | onChange: (value) { 260 | debugPrint('key-is-usb-debugging: $value'); 261 | }, 262 | ), 263 | ], 264 | ); 265 | ``` 266 | 267 | #### SwitchSettingsTile 268 | SwitchSettingsTile is a widget that has a Switch with given title, subtitle and default value/status of the switch 269 | 270 | This widget supports an additional list of widgets to display when the switch is enabled. This optional list of widgets is accessed through `childrenIfEnabled` property of this widget. 271 | 272 | This widget works similar to `CheckboxSettingsTile`. 273 | 274 | Example: 275 | ```dart 276 | SwitchSettingsTile( 277 | leading: Icon(Icons.developer_mode), 278 | settingKey: 'key-switch-dev-mode', 279 | title: 'Developer Settings', 280 | onChange: (value) { 281 | debugPrint('key-switch-dev-mod: $value'); 282 | }, 283 | childrenIfEnabled: [ 284 | CheckboxSettingsTile( 285 | leading: Icon(Icons.adb), 286 | settingKey: 'key-is-developer', 287 | title: 'Developer Mode', 288 | onChange: (value) { 289 | debugPrint('key-is-developer: $value'); 290 | }, 291 | ), 292 | SwitchSettingsTile( 293 | leading: Icon(Icons.usb), 294 | settingKey: 'key-is-usb-debugging', 295 | title: 'USB Debugging', 296 | onChange: (value) { 297 | debugPrint('key-is-usb-debugging: $value'); 298 | }, 299 | ), 300 | SimpleSettingsTile( 301 | title: 'Root Settings', 302 | subtitle: 'These settings is not accessible', 303 | enabled: false, 304 | ) 305 | ], 306 | ); 307 | ``` 308 | 309 | #### RadioSettingsTile 310 | RadioSettingsTile is a widget that has a list of Radio widgets with given title, subtitle and default/group value which determines which Radio will be selected initially. 311 | 312 | This widget supports Any type of values which should be put in the preference. 313 | 314 | However, since any type of value is supported, the input for this widget is a Map to the required values with their string representation. 315 | 316 | For example, if the required value type is a boolean then the values map can be as following: 317 | ```dart 318 | { 319 | true: 'Enabled', 320 | false: 'Disabled' 321 | } 322 | ``` 323 | 324 | So, if the `Enabled` value radio is selected then the value `true` will be stored in the preference 325 | 326 | Complete Example: 327 | ```dart 328 | RadioSettingsTile( 329 | title: 'Preferred Sync Period', 330 | settingKey: 'key-radio-sync-period', 331 | values: { 332 | 0: 'Never', 333 | 1: 'Daily', 334 | 7: 'Weekly', 335 | 15: 'Fortnight', 336 | 30: 'Monthly', 337 | }, 338 | selected: 0, 339 | onChange: (value) { 340 | debugPrint('key-radio-sync-period: $value days'); 341 | }, 342 | ) 343 | ``` 344 | 345 | #### DropDownSettingTile 346 | DropDownSettingsTile is a widget that has a list of DropdownMenuItems with given title, subtitle and default/group value which determines which value will be set to selected initially. 347 | 348 | This widget supports Any type of values which should be put in the preference. 349 | 350 | However, since any type of value is supported, the input for this widget is a Map to the required values with their string representation. 351 | 352 | For example, if the required value type is a boolean then the values map can 353 | be as following: 354 | ```dart 355 | { 356 | true: 'Enabled', 357 | false: 'Disabled' 358 | } 359 | ``` 360 | 361 | So, if the `Enabled` value is selected then the value `true` will be stored in the preference 362 | 363 | Complete Example: 364 | ```dart 365 | DropDownSettingsTile( 366 | title: 'E-Mail View', 367 | settingKey: 'key-dropdown-email-view', 368 | values: { 369 | 2: 'Simple', 370 | 3: 'Adjusted', 371 | 4: 'Normal', 372 | 5: 'Compact', 373 | 6: 'Squizzed', 374 | }, 375 | selected: 2, 376 | onChange: (value) { 377 | debugPrint('key-dropdown-email-view: $value'); 378 | }, 379 | ); 380 | ``` 381 | 382 | #### SliderSettingsTile 383 | SliderSettingsTile is a widget that has a slider given title, subtitle and default value which determines what the slider's position will be set initially. 384 | 385 | This widget supports double and integer types of values which should be put in the preference. 386 | 387 | Example: 388 | ```dart 389 | SliderSettingsTile( 390 | title: 'Volume', 391 | settingKey: 'key-slider-volume', 392 | defaultValue: 20, 393 | min: 0, 394 | max: 100, 395 | step: 1, 396 | leading: Icon(Icons.volume_up), 397 | onChange: (value) { 398 | debugPrint('key-slider-volume: $value'); 399 | }, 400 | ); 401 | ``` 402 | 403 | 404 | ## Modal widgets 405 | 406 | #### RadioModalSettingsTile 407 | RadioModalSettingsTile widget is the dialog version of the `RadioSettingsTile` widget. 408 | 409 | The use of this widget is similar to the RadioSettingsTile, only the displayed widget will be in a different position. 410 | 411 | i.e instead of inside the settings screen, it will be shown in a dialog above the settings screen. 412 | 413 | Example: 414 | ```dart 415 | RadioModalSettingsTile( 416 | title: 'Preferred Sync Period', 417 | settingKey: 'key-radio-sync-period', 418 | values: { 419 | 0: 'Never', 420 | 1: 'Daily', 421 | 7: 'Weekly', 422 | 15: 'Fortnight', 423 | 30: 'Monthly', 424 | }, 425 | selected: 0, 426 | onChange: (value) { 427 | debugPrint('key-radio-sync-period: $value days'); 428 | }, 429 | ); 430 | ``` 431 | 432 | #### SliderModalSettingsTile 433 | SliderModalSettingsTile widget is the dialog version of the SliderSettingsTile widget. 434 | 435 | The use of this widget is similar to the SliderSettingsTile, only the displayed widget will be in a different position. 436 | 437 | i.e instead of inside the settings screen, it will be shown in a dialog above the settings screen. 438 | 439 | Example: 440 | ```dart 441 | SliderSettingsTile( 442 | title: 'Volume', 443 | settingKey: 'key-slider-volume', 444 | defaultValue: 20, 445 | min: 0, 446 | max: 100, 447 | step: 1, 448 | leading: Icon(Icons.volume_up), 449 | onChange: (value) { 450 | debugPrint('key-slider-volume: $value'); 451 | }, 452 | ); 453 | ``` 454 | 455 | 456 | #### TextInputSettingsTile 457 | A Setting widget which allows user a text input in a TextFormField. 458 | 459 | Example: 460 | ```dart 461 | TextInputSettingsTile( 462 | title: 'User Name', 463 | settingKey: 'key-user-name', 464 | initialValue: 'admin', 465 | validator: (String username) { 466 | if (username != null && username.length > 3) { 467 | return null; 468 | } 469 | return "User Name can't be smaller than 4 letters"; 470 | }, 471 | borderColor: Colors.blueAccent, 472 | errorColor: Colors.deepOrangeAccent, 473 | ); 474 | ``` 475 | 476 | OR 477 | 478 | ``` dart 479 | TextInputSettingsTile( 480 | title: 'password', 481 | settingKey: 'key-user-password', 482 | obscureText: true, 483 | validator: (String password) { 484 | if (password != null && password.length > 6) { 485 | return null; 486 | } 487 | return "Password can't be smaller than 7 letters"; 488 | }, 489 | borderColor: Colors.blueAccent, 490 | errorColor: Colors.deepOrangeAccent, 491 | ); 492 | ``` 493 | 494 | #### ColorPickerSettingsTile 495 | ColorPickerSettingsTile is a widget which allows user to select a color from a set of Material color choices. 496 | 497 | Since, `Color` is an in-memory object type, the serialized version of the value of this widget will be a Hex value String of the selected color. 498 | 499 | For example, If selected color is `red` then the stored value will be "#ffff0000", but when retrieved, the value will be an instance of `Color` with properties of red color. 500 | 501 | This conversion string <-> color, makes this easy to check/debug the values from the storage/preference manually. 502 | 503 | The color panel shown in the widget is provided by the `flutter_material_color_picker` library. 504 | 505 | Example: 506 | ```dart 507 | ColorPickerSettingsTile( 508 | settingKey: 'key-color-picker', 509 | title: 'Accent Color', 510 | defaultValue: Colors.blue, 511 | onChange: (value) { 512 | debugPrint('key-color-picker: $value'); 513 | }, 514 | ); 515 | ``` 516 | 517 | ## Utility widgets 518 | 519 | #### SettingsScreen 520 | A simple Screen widget that may contain settings tiles or other widgets. 521 | The following example shows how you can create an empty settings screen with a title: 522 | 523 | ```dart 524 | SettingsScreen( 525 | title: "Application Settings", 526 | children: [], 527 | ); 528 | ``` 529 | 530 | Inside the children parameter, you can define settings tiles and other widgets. In this example we create a screen with a simple CheckboxSettingsTile in it: 531 | 532 | ```dart 533 | SettingsScreen( 534 | title: "Application Settings", 535 | children: 536 | CheckboxSettingsTile( 537 | settingKey: 'key-of-your-setting', 538 | title: 'This is a simple Checkbox', 539 | ), 540 | , 541 | ); 542 | ``` 543 | 544 | #### SettingsContainer 545 | A widget that helps its child or children to fin in the settings screen. It is helpful if you want to place other widgets than settings tiles in the settings screen body. 546 | The following example shows how you can create a container with one Text widget: 547 | ```dart 548 | SettingsContainer( 549 | child: Text('Hello world'), 550 | ); 551 | ``` 552 | In this example, we create a container with multiple Text widgets: 553 | ```dart 554 | SettingsContainer( 555 | children: 556 | Text('First line'), 557 | Text('Second line'), 558 | ], 559 | ); 560 | ``` 561 | 562 | ## Alternate widgets 563 | 564 | #### SimpleRadioSettingsTile 565 | SimpleRadioSettingsTile is a simpler version of the RadioSettingsTile. 566 | Instead of a Value-String map, this widget just takes a list of String values. 567 | 568 | In this widget, the displayed value and the stored value will be the same. 569 | 570 | Example: 571 | ```dart 572 | SimpleRadioSettingsTile( 573 | title: 'Sync Settings', 574 | settingKey: 'key-radio-sync-settings', 575 | values: [ 576 | 'Never', 577 | 'Daily', 578 | 'Weekly', 579 | 'Fortnight', 580 | 'Monthly', 581 | ], 582 | selected: 'Daily', 583 | onChange: (value) { 584 | debugPrint('key-radio-sync-settings: $value'); 585 | }, 586 | ); 587 | ``` 588 | 589 | #### SimpleDropDownSettingsTile 590 | SimpleDropDownSettingsTile is a simpler version of the DropDownSettingsTile. 591 | Instead of a Value-String map, this widget just takes a list of String values. 592 | 593 | In this widget, the displayed value and the stored value will be the same. 594 | 595 | Example: 596 | ```dart 597 | SimpleDropDownSettingsTile( 598 | title: 'Beauty Filter', 599 | settingKey: 'key-dropdown-beauty-filter', 600 | values: [ 601 | 'Simple', 602 | 'Normal', 603 | 'Little Special', 604 | 'Special', 605 | 'Extra Special', 606 | 'Bizarre', 607 | 'Horrific', 608 | ], 609 | selected: 'Special', 610 | onChange: (value) { 611 | debugPrint('key-dropdown-beauty-filter: $value'); 612 | }, 613 | ); 614 | ``` 615 | 616 | ## Contribution/Support 617 | - File an issue on the repository, if something is not working as expected. 618 | - Please follow the issue template used in flutter-sdk's repository, may be we'll integrate that here as well. 619 | - File an issue in the repository, If you have any suggestions and/or feature requests, use `[Suggestion]` or `[FeatureRequest]` tags in issue titles. 620 | - To support you just have to help out fellow developers on of the filed issues in this repository. 621 | - To contribute, just follow the standard open source contributions instructions, maybe we can follow the ones used in the flutter sdk. We'll see how it goes. 622 | 623 | 624 | **All help, issues, support and contributions are most welcome.** 625 | 626 | _If any one is interested in helping me maintain this library then please reach to me via comment on this [issue](https://github.com/GAM3RG33K/flutter_settings_screens/issues/86)._ 627 | -------------------------------------------------------------------------------- /analysis_options.yaml: -------------------------------------------------------------------------------- 1 | # This file configures the analyzer, which statically analyzes Dart code to 2 | # check for errors, warnings, and lints. 3 | # 4 | # The issues identified by the analyzer are surfaced in the UI of Dart-enabled 5 | # IDEs (https://dart.dev/tools#ides-and-editors). The analyzer can also be 6 | # invoked from the command line by running `flutter analyze`. 7 | 8 | # The following line activates a set of recommended lints for Flutter apps, 9 | # packages, and plugins designed to encourage good coding practices. 10 | include: package:flutter_lints/flutter.yaml 11 | 12 | linter: 13 | # The lint rules applied to this project can be customized in the 14 | # section below to disable rules from the `package:flutter_lints/flutter.yaml` 15 | # included above or to enable additional rules. A list of all available lints 16 | # and their documentation is published at https://dart.dev/lints. 17 | # 18 | # Instead of disabling a lint rule for the entire project in the 19 | # section below, it can also be suppressed for a single line of code 20 | # or a specific dart file by using the `// ignore: name_of_lint` and 21 | # `// ignore_for_file: name_of_lint` syntax on the line or in the file 22 | # producing the lint. 23 | rules: 24 | # avoid_print: false # Uncomment to disable the `avoid_print` rule 25 | # prefer_single_quotes: true # Uncomment to enable the `prefer_single_quotes` rule 26 | 27 | # Additional information about this file can be found at 28 | # https://dart.dev/guides/language/analysis-options 29 | -------------------------------------------------------------------------------- /example/.gitignore: -------------------------------------------------------------------------------- 1 | # Miscellaneous 2 | *.class 3 | *.log 4 | *.pyc 5 | *.swp 6 | .DS_Store 7 | .atom/ 8 | .buildlog/ 9 | .history 10 | .svn/ 11 | .fvm/ 12 | 13 | # IntelliJ related 14 | *.iml 15 | *.ipr 16 | *.iws 17 | .idea/ 18 | 19 | # The .vscode folder contains launch configuration and tasks you configure in 20 | # VS Code which you may wish to be included in version control, so this line 21 | # is commented out by default. 22 | #.vscode/ 23 | 24 | # Flutter/Dart/Pub related 25 | **/doc/api/ 26 | .dart_tool/ 27 | .flutter-plugins 28 | .packages 29 | .pub-cache/ 30 | .pub/ 31 | /build/ 32 | pubspec.lock 33 | 34 | # Web related 35 | lib/generated_plugin_registrant.dart 36 | 37 | # Exceptions to above rules. 38 | !/packages/flutter_tools/test/data/dart_dependencies_test/**/.packages 39 | -------------------------------------------------------------------------------- /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: 2c7af1e24e45a79f4eb73d67d98fcecea8bf6146 8 | channel: master 9 | 10 | project_type: app 11 | -------------------------------------------------------------------------------- /example/README.md: -------------------------------------------------------------------------------- 1 | # flutter_settings_screens_example 2 | 3 | Demonstrates how to use the flutter_settings_screens 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.dev/docs/get-started/codelab) 12 | - [Cookbook: Useful Flutter samples](https://flutter.dev/docs/cookbook) 13 | 14 | For help getting started with Flutter, view our 15 | [online documentation](https://flutter.dev/docs), which offers tutorials, 16 | samples, guidance on mobile development, and a full API reference. 17 | -------------------------------------------------------------------------------- /example/android/.gitignore: -------------------------------------------------------------------------------- 1 | gradle-wrapper.jar 2 | /.gradle 3 | /captures/ 4 | /gradlew 5 | /gradlew.bat 6 | /local.properties 7 | GeneratedPluginRegistrant.java 8 | 9 | # Remember to never publicly share your keystore. 10 | # See https://flutter.dev/docs/deployment/android#reference-the-keystore-from-the-app 11 | key.properties 12 | **/*.keystore 13 | **/*.jks 14 | -------------------------------------------------------------------------------- /example/android/app/build.gradle: -------------------------------------------------------------------------------- 1 | 2 | plugins { 3 | id "com.android.application" 4 | id "dev.flutter.flutter-gradle-plugin" 5 | } 6 | 7 | def localProperties = new Properties() 8 | def localPropertiesFile = rootProject.file('local.properties') 9 | if (localPropertiesFile.exists()) { 10 | localPropertiesFile.withReader('UTF-8') { reader -> 11 | localProperties.load(reader) 12 | } 13 | } 14 | 15 | def flutterVersionCode = localProperties.getProperty('flutter.versionCode') 16 | if (flutterVersionCode == null) { 17 | flutterVersionCode = '1' 18 | } 19 | 20 | def flutterVersionName = localProperties.getProperty('flutter.versionName') 21 | if (flutterVersionName == null) { 22 | flutterVersionName = '1.0' 23 | } 24 | 25 | android { 26 | namespace "com.happyworks.flutter_settings_screens_example" 27 | compileSdkVersion flutter.compileSdkVersion 28 | 29 | compileOptions { 30 | sourceCompatibility JavaVersion.VERSION_1_8 31 | targetCompatibility JavaVersion.VERSION_1_8 32 | } 33 | 34 | defaultConfig { 35 | applicationId "com.happyworks.flutter_settings_screens_example" 36 | minSdkVersion flutter.minSdkVersion 37 | targetSdkVersion flutter.targetSdkVersion 38 | versionCode flutterVersionCode.toInteger() 39 | versionName flutterVersionName 40 | } 41 | 42 | buildTypes { 43 | release { 44 | // Signing with the debug keys for now, so `flutter run --release` works. 45 | signingConfig signingConfigs.debug 46 | } 47 | } 48 | } 49 | 50 | flutter { 51 | source '../..' 52 | } 53 | 54 | dependencies { 55 | } 56 | -------------------------------------------------------------------------------- /example/android/app/src/debug/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 3 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /example/android/app/src/main/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 3 | 4 | 8 | 16 | 20 | 23 | 24 | 25 | 26 | 27 | 28 | 30 | 33 | 34 | 35 | -------------------------------------------------------------------------------- /example/android/app/src/main/java/com/happyworks/flutter_settings_screens_example/MainActivity.java: -------------------------------------------------------------------------------- 1 | package com.happyworks.flutter_settings_screens_example; 2 | 3 | import io.flutter.embedding.android.FlutterActivity; 4 | 5 | public class MainActivity extends FlutterActivity { 6 | } 7 | -------------------------------------------------------------------------------- /example/android/app/src/main/res/drawable-v21/launch_background.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 11 | 12 | -------------------------------------------------------------------------------- /example/android/app/src/main/res/drawable/launch_background.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 11 | 12 | -------------------------------------------------------------------------------- /example/android/app/src/main/res/mipmap-hdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/GAM3RG33K/flutter_settings_screens/18f937739d7fb4c7ceb0d8b9877f20f0b5e9e6d8/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/GAM3RG33K/flutter_settings_screens/18f937739d7fb4c7ceb0d8b9877f20f0b5e9e6d8/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/GAM3RG33K/flutter_settings_screens/18f937739d7fb4c7ceb0d8b9877f20f0b5e9e6d8/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/GAM3RG33K/flutter_settings_screens/18f937739d7fb4c7ceb0d8b9877f20f0b5e9e6d8/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/GAM3RG33K/flutter_settings_screens/18f937739d7fb4c7ceb0d8b9877f20f0b5e9e6d8/example/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png -------------------------------------------------------------------------------- /example/android/app/src/main/res/values-night/styles.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 9 | 15 | 18 | 19 | -------------------------------------------------------------------------------- /example/android/app/src/main/res/values/styles.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 9 | 15 | 18 | 19 | -------------------------------------------------------------------------------- /example/android/app/src/profile/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 3 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /example/android/build.gradle: -------------------------------------------------------------------------------- 1 | allprojects { 2 | repositories { 3 | google() 4 | mavenCentral() 5 | } 6 | } 7 | 8 | rootProject.layout.buildDirectory = '../build' 9 | subprojects { 10 | project.layout.buildDirectory = rootProject.layout.buildDirectory.dir(project.name) 11 | } 12 | subprojects { 13 | project.evaluationDependsOn(':app') 14 | } 15 | 16 | tasks.register("clean", Delete) { 17 | delete rootProject.layout.buildDirectory 18 | } 19 | -------------------------------------------------------------------------------- /example/android/gradle.properties: -------------------------------------------------------------------------------- 1 | org.gradle.jvmargs=-Xmx1536M 2 | android.useAndroidX=true 3 | android.enableJetifier=true 4 | -------------------------------------------------------------------------------- /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-8.6-all.zip 7 | -------------------------------------------------------------------------------- /example/android/settings.gradle: -------------------------------------------------------------------------------- 1 | pluginManagement { 2 | def flutterSdkPath = { 3 | def properties = new Properties() 4 | file("local.properties").withInputStream { properties.load(it) } 5 | def flutterSdkPath = properties.getProperty("flutter.sdk") 6 | assert flutterSdkPath != null, "flutter.sdk not set in local.properties" 7 | return flutterSdkPath 8 | }() 9 | 10 | includeBuild("$flutterSdkPath/packages/flutter_tools/gradle") 11 | 12 | repositories { 13 | google() 14 | mavenCentral() 15 | gradlePluginPortal() 16 | } 17 | } 18 | 19 | plugins { 20 | id "dev.flutter.flutter-plugin-loader" version "1.0.0" 21 | id "com.android.application" version '8.4.0' apply false 22 | } 23 | 24 | include ':app' 25 | -------------------------------------------------------------------------------- /example/ios/.gitignore: -------------------------------------------------------------------------------- 1 | **/dgph 2 | *.mode1v3 3 | *.mode2v3 4 | *.moved-aside 5 | *.pbxuser 6 | *.perspectivev3 7 | **/*sync/ 8 | .sconsign.dblite 9 | .tags* 10 | **/.vagrant/ 11 | **/DerivedData/ 12 | Icon? 13 | **/Pods/ 14 | **/.symlinks/ 15 | profile 16 | xcuserdata 17 | **/.generated/ 18 | Flutter/App.framework 19 | Flutter/Flutter.framework 20 | Flutter/Flutter.podspec 21 | Flutter/Generated.xcconfig 22 | Flutter/ephemeral/ 23 | Flutter/app.flx 24 | Flutter/app.zip 25 | Flutter/flutter_assets/ 26 | Flutter/flutter_export_environment.sh 27 | ServiceDefinitions.json 28 | Runner/GeneratedPluginRegistrant.* 29 | 30 | # Exceptions to above rules. 31 | !default.mode1v3 32 | !default.mode2v3 33 | !default.pbxuser 34 | !default.perspectivev3 35 | -------------------------------------------------------------------------------- /example/ios/Flutter/AppFrameworkInfo.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | en 7 | CFBundleExecutable 8 | App 9 | CFBundleIdentifier 10 | io.flutter.flutter.app 11 | CFBundleInfoDictionaryVersion 12 | 6.0 13 | CFBundleName 14 | App 15 | CFBundlePackageType 16 | FMWK 17 | CFBundleShortVersionString 18 | 1.0 19 | CFBundleSignature 20 | ???? 21 | CFBundleVersion 22 | 1.0 23 | MinimumOSVersion 24 | 12.0 25 | 26 | 27 | -------------------------------------------------------------------------------- /example/ios/Flutter/Debug.xcconfig: -------------------------------------------------------------------------------- 1 | #include? "Pods/Target Support Files/Pods-Runner/Pods-Runner.debug.xcconfig" 2 | #include "Generated.xcconfig" 3 | -------------------------------------------------------------------------------- /example/ios/Flutter/Release.xcconfig: -------------------------------------------------------------------------------- 1 | #include? "Pods/Target Support Files/Pods-Runner/Pods-Runner.release.xcconfig" 2 | #include "Generated.xcconfig" 3 | -------------------------------------------------------------------------------- /example/ios/Podfile: -------------------------------------------------------------------------------- 1 | # Uncomment this line to define a global platform for your project 2 | # platform :ios, '12.0' 3 | 4 | # CocoaPods analytics sends network stats synchronously affecting flutter build latency. 5 | ENV['COCOAPODS_DISABLE_STATS'] = 'true' 6 | 7 | project 'Runner', { 8 | 'Debug' => :debug, 9 | 'Profile' => :release, 10 | 'Release' => :release, 11 | } 12 | 13 | def flutter_root 14 | generated_xcode_build_settings_path = File.expand_path(File.join('..', 'Flutter', 'Generated.xcconfig'), __FILE__) 15 | unless File.exist?(generated_xcode_build_settings_path) 16 | raise "#{generated_xcode_build_settings_path} must exist. If you're running pod install manually, make sure flutter pub get is executed first" 17 | end 18 | 19 | File.foreach(generated_xcode_build_settings_path) do |line| 20 | matches = line.match(/FLUTTER_ROOT\=(.*)/) 21 | return matches[1].strip if matches 22 | end 23 | raise "FLUTTER_ROOT not found in #{generated_xcode_build_settings_path}. Try deleting Generated.xcconfig, then run flutter pub get" 24 | end 25 | 26 | require File.expand_path(File.join('packages', 'flutter_tools', 'bin', 'podhelper'), flutter_root) 27 | 28 | flutter_ios_podfile_setup 29 | 30 | target 'Runner' do 31 | use_frameworks! 32 | use_modular_headers! 33 | 34 | flutter_install_all_ios_pods File.dirname(File.realpath(__FILE__)) 35 | end 36 | 37 | post_install do |installer| 38 | installer.pods_project.targets.each do |target| 39 | flutter_additional_ios_build_settings(target) 40 | end 41 | end 42 | -------------------------------------------------------------------------------- /example/ios/Runner.xcodeproj/project.pbxproj: -------------------------------------------------------------------------------- 1 | // !$*UTF8*$! 2 | { 3 | archiveVersion = 1; 4 | classes = { 5 | }; 6 | objectVersion = 54; 7 | objects = { 8 | 9 | /* Begin PBXBuildFile section */ 10 | 1498D2341E8E89220040F4C2 /* GeneratedPluginRegistrant.m in Sources */ = {isa = PBXBuildFile; fileRef = 1498D2331E8E89220040F4C2 /* GeneratedPluginRegistrant.m */; }; 11 | 2D304D1C1AD25E7DB8EB1CA0 /* Pods_Runner.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 56463CB180FDED103A6CB9C3 /* Pods_Runner.framework */; }; 12 | 3B3967161E833CAA004F5970 /* AppFrameworkInfo.plist in Resources */ = {isa = PBXBuildFile; fileRef = 3B3967151E833CAA004F5970 /* AppFrameworkInfo.plist */; }; 13 | 74858FAF1ED2DC5600515810 /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 74858FAE1ED2DC5600515810 /* AppDelegate.swift */; }; 14 | 97C146FC1CF9000F007C117D /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 97C146FA1CF9000F007C117D /* Main.storyboard */; }; 15 | 97C146FE1CF9000F007C117D /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 97C146FD1CF9000F007C117D /* Assets.xcassets */; }; 16 | 97C147011CF9000F007C117D /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 97C146FF1CF9000F007C117D /* LaunchScreen.storyboard */; }; 17 | /* End PBXBuildFile section */ 18 | 19 | /* Begin PBXCopyFilesBuildPhase section */ 20 | 9705A1C41CF9048500538489 /* Embed Frameworks */ = { 21 | isa = PBXCopyFilesBuildPhase; 22 | buildActionMask = 2147483647; 23 | dstPath = ""; 24 | dstSubfolderSpec = 10; 25 | files = ( 26 | ); 27 | name = "Embed Frameworks"; 28 | runOnlyForDeploymentPostprocessing = 0; 29 | }; 30 | /* End PBXCopyFilesBuildPhase section */ 31 | 32 | /* Begin PBXFileReference section */ 33 | 1498D2321E8E86230040F4C2 /* GeneratedPluginRegistrant.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = GeneratedPluginRegistrant.h; sourceTree = ""; }; 34 | 1498D2331E8E89220040F4C2 /* GeneratedPluginRegistrant.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = GeneratedPluginRegistrant.m; sourceTree = ""; }; 35 | 17AD69071B14EF34D761EA0E /* Pods-Runner.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Runner.release.xcconfig"; path = "Target Support Files/Pods-Runner/Pods-Runner.release.xcconfig"; sourceTree = ""; }; 36 | 3B3967151E833CAA004F5970 /* AppFrameworkInfo.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; name = AppFrameworkInfo.plist; path = Flutter/AppFrameworkInfo.plist; sourceTree = ""; }; 37 | 56463CB180FDED103A6CB9C3 /* Pods_Runner.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_Runner.framework; sourceTree = BUILT_PRODUCTS_DIR; }; 38 | 74858FAD1ED2DC5600515810 /* Runner-Bridging-Header.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "Runner-Bridging-Header.h"; sourceTree = ""; }; 39 | 74858FAE1ED2DC5600515810 /* AppDelegate.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = ""; }; 40 | 7AFA3C8E1D35360C0083082E /* Release.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; name = Release.xcconfig; path = Flutter/Release.xcconfig; sourceTree = ""; }; 41 | 9740EEB21CF90195004384FC /* Debug.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; name = Debug.xcconfig; path = Flutter/Debug.xcconfig; sourceTree = ""; }; 42 | 9740EEB31CF90195004384FC /* Generated.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; name = Generated.xcconfig; path = Flutter/Generated.xcconfig; sourceTree = ""; }; 43 | 97C146EE1CF9000F007C117D /* Runner.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = Runner.app; sourceTree = BUILT_PRODUCTS_DIR; }; 44 | 97C146FB1CF9000F007C117D /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/Main.storyboard; sourceTree = ""; }; 45 | 97C146FD1CF9000F007C117D /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = ""; }; 46 | 97C147001CF9000F007C117D /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/LaunchScreen.storyboard; sourceTree = ""; }; 47 | 97C147021CF9000F007C117D /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; 48 | B7FD848EF692798DFEB371FA /* Pods-Runner.profile.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Runner.profile.xcconfig"; path = "Target Support Files/Pods-Runner/Pods-Runner.profile.xcconfig"; sourceTree = ""; }; 49 | D4AD61949C3A50BB5618FC8E /* Pods-Runner.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Runner.debug.xcconfig"; path = "Target Support Files/Pods-Runner/Pods-Runner.debug.xcconfig"; sourceTree = ""; }; 50 | /* End PBXFileReference section */ 51 | 52 | /* Begin PBXFrameworksBuildPhase section */ 53 | 97C146EB1CF9000F007C117D /* Frameworks */ = { 54 | isa = PBXFrameworksBuildPhase; 55 | buildActionMask = 2147483647; 56 | files = ( 57 | 2D304D1C1AD25E7DB8EB1CA0 /* Pods_Runner.framework in Frameworks */, 58 | ); 59 | runOnlyForDeploymentPostprocessing = 0; 60 | }; 61 | /* End PBXFrameworksBuildPhase section */ 62 | 63 | /* Begin PBXGroup section */ 64 | 9740EEB11CF90186004384FC /* Flutter */ = { 65 | isa = PBXGroup; 66 | children = ( 67 | 3B3967151E833CAA004F5970 /* AppFrameworkInfo.plist */, 68 | 9740EEB21CF90195004384FC /* Debug.xcconfig */, 69 | 7AFA3C8E1D35360C0083082E /* Release.xcconfig */, 70 | 9740EEB31CF90195004384FC /* Generated.xcconfig */, 71 | ); 72 | name = Flutter; 73 | sourceTree = ""; 74 | }; 75 | 974384AC923C661FE6D16947 /* Frameworks */ = { 76 | isa = PBXGroup; 77 | children = ( 78 | 56463CB180FDED103A6CB9C3 /* Pods_Runner.framework */, 79 | ); 80 | name = Frameworks; 81 | sourceTree = ""; 82 | }; 83 | 97C146E51CF9000F007C117D = { 84 | isa = PBXGroup; 85 | children = ( 86 | 9740EEB11CF90186004384FC /* Flutter */, 87 | 97C146F01CF9000F007C117D /* Runner */, 88 | 97C146EF1CF9000F007C117D /* Products */, 89 | C03ACAA41C034593E01687FB /* Pods */, 90 | 974384AC923C661FE6D16947 /* Frameworks */, 91 | ); 92 | sourceTree = ""; 93 | }; 94 | 97C146EF1CF9000F007C117D /* Products */ = { 95 | isa = PBXGroup; 96 | children = ( 97 | 97C146EE1CF9000F007C117D /* Runner.app */, 98 | ); 99 | name = Products; 100 | sourceTree = ""; 101 | }; 102 | 97C146F01CF9000F007C117D /* Runner */ = { 103 | isa = PBXGroup; 104 | children = ( 105 | 97C146FA1CF9000F007C117D /* Main.storyboard */, 106 | 97C146FD1CF9000F007C117D /* Assets.xcassets */, 107 | 97C146FF1CF9000F007C117D /* LaunchScreen.storyboard */, 108 | 97C147021CF9000F007C117D /* Info.plist */, 109 | 1498D2321E8E86230040F4C2 /* GeneratedPluginRegistrant.h */, 110 | 1498D2331E8E89220040F4C2 /* GeneratedPluginRegistrant.m */, 111 | 74858FAE1ED2DC5600515810 /* AppDelegate.swift */, 112 | 74858FAD1ED2DC5600515810 /* Runner-Bridging-Header.h */, 113 | ); 114 | path = Runner; 115 | sourceTree = ""; 116 | }; 117 | C03ACAA41C034593E01687FB /* Pods */ = { 118 | isa = PBXGroup; 119 | children = ( 120 | D4AD61949C3A50BB5618FC8E /* Pods-Runner.debug.xcconfig */, 121 | 17AD69071B14EF34D761EA0E /* Pods-Runner.release.xcconfig */, 122 | B7FD848EF692798DFEB371FA /* Pods-Runner.profile.xcconfig */, 123 | ); 124 | name = Pods; 125 | path = Pods; 126 | sourceTree = ""; 127 | }; 128 | /* End PBXGroup section */ 129 | 130 | /* Begin PBXNativeTarget section */ 131 | 97C146ED1CF9000F007C117D /* Runner */ = { 132 | isa = PBXNativeTarget; 133 | buildConfigurationList = 97C147051CF9000F007C117D /* Build configuration list for PBXNativeTarget "Runner" */; 134 | buildPhases = ( 135 | 17F39D70C0DB2A58A43E2364 /* [CP] Check Pods Manifest.lock */, 136 | 9740EEB61CF901F6004384FC /* Run Script */, 137 | 97C146EA1CF9000F007C117D /* Sources */, 138 | 97C146EB1CF9000F007C117D /* Frameworks */, 139 | 97C146EC1CF9000F007C117D /* Resources */, 140 | 9705A1C41CF9048500538489 /* Embed Frameworks */, 141 | 3B06AD1E1E4923F5004D2608 /* Thin Binary */, 142 | E0B88306847A324AD9DFA0C9 /* [CP] Embed Pods Frameworks */, 143 | ); 144 | buildRules = ( 145 | ); 146 | dependencies = ( 147 | ); 148 | name = Runner; 149 | productName = Runner; 150 | productReference = 97C146EE1CF9000F007C117D /* Runner.app */; 151 | productType = "com.apple.product-type.application"; 152 | }; 153 | /* End PBXNativeTarget section */ 154 | 155 | /* Begin PBXProject section */ 156 | 97C146E61CF9000F007C117D /* Project object */ = { 157 | isa = PBXProject; 158 | attributes = { 159 | LastUpgradeCheck = 1510; 160 | ORGANIZATIONNAME = ""; 161 | TargetAttributes = { 162 | 97C146ED1CF9000F007C117D = { 163 | CreatedOnToolsVersion = 7.3.1; 164 | LastSwiftMigration = 1100; 165 | }; 166 | }; 167 | }; 168 | buildConfigurationList = 97C146E91CF9000F007C117D /* Build configuration list for PBXProject "Runner" */; 169 | compatibilityVersion = "Xcode 9.3"; 170 | developmentRegion = en; 171 | hasScannedForEncodings = 0; 172 | knownRegions = ( 173 | en, 174 | Base, 175 | ); 176 | mainGroup = 97C146E51CF9000F007C117D; 177 | productRefGroup = 97C146EF1CF9000F007C117D /* Products */; 178 | projectDirPath = ""; 179 | projectRoot = ""; 180 | targets = ( 181 | 97C146ED1CF9000F007C117D /* Runner */, 182 | ); 183 | }; 184 | /* End PBXProject section */ 185 | 186 | /* Begin PBXResourcesBuildPhase section */ 187 | 97C146EC1CF9000F007C117D /* Resources */ = { 188 | isa = PBXResourcesBuildPhase; 189 | buildActionMask = 2147483647; 190 | files = ( 191 | 97C147011CF9000F007C117D /* LaunchScreen.storyboard in Resources */, 192 | 3B3967161E833CAA004F5970 /* AppFrameworkInfo.plist in Resources */, 193 | 97C146FE1CF9000F007C117D /* Assets.xcassets in Resources */, 194 | 97C146FC1CF9000F007C117D /* Main.storyboard in Resources */, 195 | ); 196 | runOnlyForDeploymentPostprocessing = 0; 197 | }; 198 | /* End PBXResourcesBuildPhase section */ 199 | 200 | /* Begin PBXShellScriptBuildPhase section */ 201 | 17F39D70C0DB2A58A43E2364 /* [CP] Check Pods Manifest.lock */ = { 202 | isa = PBXShellScriptBuildPhase; 203 | buildActionMask = 2147483647; 204 | files = ( 205 | ); 206 | inputFileListPaths = ( 207 | ); 208 | inputPaths = ( 209 | "${PODS_PODFILE_DIR_PATH}/Podfile.lock", 210 | "${PODS_ROOT}/Manifest.lock", 211 | ); 212 | name = "[CP] Check Pods Manifest.lock"; 213 | outputFileListPaths = ( 214 | ); 215 | outputPaths = ( 216 | "$(DERIVED_FILE_DIR)/Pods-Runner-checkManifestLockResult.txt", 217 | ); 218 | runOnlyForDeploymentPostprocessing = 0; 219 | shellPath = /bin/sh; 220 | shellScript = "diff \"${PODS_PODFILE_DIR_PATH}/Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [ $? != 0 ] ; then\n # print error to STDERR\n echo \"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\" >&2\n exit 1\nfi\n# This output is used by Xcode 'outputs' to avoid re-running this script phase.\necho \"SUCCESS\" > \"${SCRIPT_OUTPUT_FILE_0}\"\n"; 221 | showEnvVarsInLog = 0; 222 | }; 223 | 3B06AD1E1E4923F5004D2608 /* Thin Binary */ = { 224 | isa = PBXShellScriptBuildPhase; 225 | alwaysOutOfDate = 1; 226 | buildActionMask = 2147483647; 227 | files = ( 228 | ); 229 | inputPaths = ( 230 | "${TARGET_BUILD_DIR}/${INFOPLIST_PATH}", 231 | ); 232 | name = "Thin Binary"; 233 | outputPaths = ( 234 | ); 235 | runOnlyForDeploymentPostprocessing = 0; 236 | shellPath = /bin/sh; 237 | shellScript = "/bin/sh \"$FLUTTER_ROOT/packages/flutter_tools/bin/xcode_backend.sh\" embed_and_thin"; 238 | }; 239 | 9740EEB61CF901F6004384FC /* Run Script */ = { 240 | isa = PBXShellScriptBuildPhase; 241 | alwaysOutOfDate = 1; 242 | buildActionMask = 2147483647; 243 | files = ( 244 | ); 245 | inputPaths = ( 246 | ); 247 | name = "Run Script"; 248 | outputPaths = ( 249 | ); 250 | runOnlyForDeploymentPostprocessing = 0; 251 | shellPath = /bin/sh; 252 | shellScript = "/bin/sh \"$FLUTTER_ROOT/packages/flutter_tools/bin/xcode_backend.sh\" build"; 253 | }; 254 | E0B88306847A324AD9DFA0C9 /* [CP] Embed Pods Frameworks */ = { 255 | isa = PBXShellScriptBuildPhase; 256 | buildActionMask = 2147483647; 257 | files = ( 258 | ); 259 | inputFileListPaths = ( 260 | "${PODS_ROOT}/Target Support Files/Pods-Runner/Pods-Runner-frameworks-${CONFIGURATION}-input-files.xcfilelist", 261 | ); 262 | name = "[CP] Embed Pods Frameworks"; 263 | outputFileListPaths = ( 264 | "${PODS_ROOT}/Target Support Files/Pods-Runner/Pods-Runner-frameworks-${CONFIGURATION}-output-files.xcfilelist", 265 | ); 266 | runOnlyForDeploymentPostprocessing = 0; 267 | shellPath = /bin/sh; 268 | shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-Runner/Pods-Runner-frameworks.sh\"\n"; 269 | showEnvVarsInLog = 0; 270 | }; 271 | /* End PBXShellScriptBuildPhase section */ 272 | 273 | /* Begin PBXSourcesBuildPhase section */ 274 | 97C146EA1CF9000F007C117D /* Sources */ = { 275 | isa = PBXSourcesBuildPhase; 276 | buildActionMask = 2147483647; 277 | files = ( 278 | 74858FAF1ED2DC5600515810 /* AppDelegate.swift in Sources */, 279 | 1498D2341E8E89220040F4C2 /* GeneratedPluginRegistrant.m in Sources */, 280 | ); 281 | runOnlyForDeploymentPostprocessing = 0; 282 | }; 283 | /* End PBXSourcesBuildPhase section */ 284 | 285 | /* Begin PBXVariantGroup section */ 286 | 97C146FA1CF9000F007C117D /* Main.storyboard */ = { 287 | isa = PBXVariantGroup; 288 | children = ( 289 | 97C146FB1CF9000F007C117D /* Base */, 290 | ); 291 | name = Main.storyboard; 292 | sourceTree = ""; 293 | }; 294 | 97C146FF1CF9000F007C117D /* LaunchScreen.storyboard */ = { 295 | isa = PBXVariantGroup; 296 | children = ( 297 | 97C147001CF9000F007C117D /* Base */, 298 | ); 299 | name = LaunchScreen.storyboard; 300 | sourceTree = ""; 301 | }; 302 | /* End PBXVariantGroup section */ 303 | 304 | /* Begin XCBuildConfiguration section */ 305 | 249021D3217E4FDB00AE95B9 /* Profile */ = { 306 | isa = XCBuildConfiguration; 307 | buildSettings = { 308 | ALWAYS_SEARCH_USER_PATHS = NO; 309 | CLANG_ANALYZER_NONNULL = YES; 310 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; 311 | CLANG_CXX_LIBRARY = "libc++"; 312 | CLANG_ENABLE_MODULES = YES; 313 | CLANG_ENABLE_OBJC_ARC = YES; 314 | CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; 315 | CLANG_WARN_BOOL_CONVERSION = YES; 316 | CLANG_WARN_COMMA = YES; 317 | CLANG_WARN_CONSTANT_CONVERSION = YES; 318 | CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; 319 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 320 | CLANG_WARN_EMPTY_BODY = YES; 321 | CLANG_WARN_ENUM_CONVERSION = YES; 322 | CLANG_WARN_INFINITE_RECURSION = YES; 323 | CLANG_WARN_INT_CONVERSION = YES; 324 | CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; 325 | CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; 326 | CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; 327 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 328 | CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; 329 | CLANG_WARN_STRICT_PROTOTYPES = YES; 330 | CLANG_WARN_SUSPICIOUS_MOVE = YES; 331 | CLANG_WARN_UNREACHABLE_CODE = YES; 332 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 333 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; 334 | COPY_PHASE_STRIP = NO; 335 | DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; 336 | ENABLE_NS_ASSERTIONS = NO; 337 | ENABLE_STRICT_OBJC_MSGSEND = YES; 338 | GCC_C_LANGUAGE_STANDARD = gnu99; 339 | GCC_NO_COMMON_BLOCKS = YES; 340 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 341 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 342 | GCC_WARN_UNDECLARED_SELECTOR = YES; 343 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 344 | GCC_WARN_UNUSED_FUNCTION = YES; 345 | GCC_WARN_UNUSED_VARIABLE = YES; 346 | IPHONEOS_DEPLOYMENT_TARGET = 12.0; 347 | MTL_ENABLE_DEBUG_INFO = NO; 348 | SDKROOT = iphoneos; 349 | SUPPORTED_PLATFORMS = iphoneos; 350 | TARGETED_DEVICE_FAMILY = "1,2"; 351 | VALIDATE_PRODUCT = YES; 352 | }; 353 | name = Profile; 354 | }; 355 | 249021D4217E4FDB00AE95B9 /* Profile */ = { 356 | isa = XCBuildConfiguration; 357 | baseConfigurationReference = 7AFA3C8E1D35360C0083082E /* Release.xcconfig */; 358 | buildSettings = { 359 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; 360 | CLANG_ENABLE_MODULES = YES; 361 | CURRENT_PROJECT_VERSION = "$(FLUTTER_BUILD_NUMBER)"; 362 | ENABLE_BITCODE = NO; 363 | INFOPLIST_FILE = Runner/Info.plist; 364 | LD_RUNPATH_SEARCH_PATHS = ( 365 | "$(inherited)", 366 | "@executable_path/Frameworks", 367 | ); 368 | PRODUCT_BUNDLE_IDENTIFIER = com.example.example; 369 | PRODUCT_NAME = "$(TARGET_NAME)"; 370 | SWIFT_OBJC_BRIDGING_HEADER = "Runner/Runner-Bridging-Header.h"; 371 | SWIFT_VERSION = 5.0; 372 | VERSIONING_SYSTEM = "apple-generic"; 373 | }; 374 | name = Profile; 375 | }; 376 | 97C147031CF9000F007C117D /* Debug */ = { 377 | isa = XCBuildConfiguration; 378 | buildSettings = { 379 | ALWAYS_SEARCH_USER_PATHS = NO; 380 | CLANG_ANALYZER_NONNULL = YES; 381 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; 382 | CLANG_CXX_LIBRARY = "libc++"; 383 | CLANG_ENABLE_MODULES = YES; 384 | CLANG_ENABLE_OBJC_ARC = YES; 385 | CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; 386 | CLANG_WARN_BOOL_CONVERSION = YES; 387 | CLANG_WARN_COMMA = YES; 388 | CLANG_WARN_CONSTANT_CONVERSION = YES; 389 | CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; 390 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 391 | CLANG_WARN_EMPTY_BODY = YES; 392 | CLANG_WARN_ENUM_CONVERSION = YES; 393 | CLANG_WARN_INFINITE_RECURSION = YES; 394 | CLANG_WARN_INT_CONVERSION = YES; 395 | CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; 396 | CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; 397 | CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; 398 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 399 | CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; 400 | CLANG_WARN_STRICT_PROTOTYPES = YES; 401 | CLANG_WARN_SUSPICIOUS_MOVE = YES; 402 | CLANG_WARN_UNREACHABLE_CODE = YES; 403 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 404 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; 405 | COPY_PHASE_STRIP = NO; 406 | DEBUG_INFORMATION_FORMAT = dwarf; 407 | ENABLE_STRICT_OBJC_MSGSEND = YES; 408 | ENABLE_TESTABILITY = YES; 409 | GCC_C_LANGUAGE_STANDARD = gnu99; 410 | GCC_DYNAMIC_NO_PIC = NO; 411 | GCC_NO_COMMON_BLOCKS = YES; 412 | GCC_OPTIMIZATION_LEVEL = 0; 413 | GCC_PREPROCESSOR_DEFINITIONS = ( 414 | "DEBUG=1", 415 | "$(inherited)", 416 | ); 417 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 418 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 419 | GCC_WARN_UNDECLARED_SELECTOR = YES; 420 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 421 | GCC_WARN_UNUSED_FUNCTION = YES; 422 | GCC_WARN_UNUSED_VARIABLE = YES; 423 | IPHONEOS_DEPLOYMENT_TARGET = 12.0; 424 | MTL_ENABLE_DEBUG_INFO = YES; 425 | ONLY_ACTIVE_ARCH = YES; 426 | SDKROOT = iphoneos; 427 | TARGETED_DEVICE_FAMILY = "1,2"; 428 | }; 429 | name = Debug; 430 | }; 431 | 97C147041CF9000F007C117D /* Release */ = { 432 | isa = XCBuildConfiguration; 433 | buildSettings = { 434 | ALWAYS_SEARCH_USER_PATHS = NO; 435 | CLANG_ANALYZER_NONNULL = YES; 436 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; 437 | CLANG_CXX_LIBRARY = "libc++"; 438 | CLANG_ENABLE_MODULES = YES; 439 | CLANG_ENABLE_OBJC_ARC = YES; 440 | CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; 441 | CLANG_WARN_BOOL_CONVERSION = YES; 442 | CLANG_WARN_COMMA = YES; 443 | CLANG_WARN_CONSTANT_CONVERSION = YES; 444 | CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; 445 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 446 | CLANG_WARN_EMPTY_BODY = YES; 447 | CLANG_WARN_ENUM_CONVERSION = YES; 448 | CLANG_WARN_INFINITE_RECURSION = YES; 449 | CLANG_WARN_INT_CONVERSION = YES; 450 | CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; 451 | CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; 452 | CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; 453 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 454 | CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; 455 | CLANG_WARN_STRICT_PROTOTYPES = YES; 456 | CLANG_WARN_SUSPICIOUS_MOVE = YES; 457 | CLANG_WARN_UNREACHABLE_CODE = YES; 458 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 459 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; 460 | COPY_PHASE_STRIP = NO; 461 | DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; 462 | ENABLE_NS_ASSERTIONS = NO; 463 | ENABLE_STRICT_OBJC_MSGSEND = YES; 464 | GCC_C_LANGUAGE_STANDARD = gnu99; 465 | GCC_NO_COMMON_BLOCKS = YES; 466 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 467 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 468 | GCC_WARN_UNDECLARED_SELECTOR = YES; 469 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 470 | GCC_WARN_UNUSED_FUNCTION = YES; 471 | GCC_WARN_UNUSED_VARIABLE = YES; 472 | IPHONEOS_DEPLOYMENT_TARGET = 12.0; 473 | MTL_ENABLE_DEBUG_INFO = NO; 474 | SDKROOT = iphoneos; 475 | SUPPORTED_PLATFORMS = iphoneos; 476 | SWIFT_COMPILATION_MODE = wholemodule; 477 | SWIFT_OPTIMIZATION_LEVEL = "-O"; 478 | TARGETED_DEVICE_FAMILY = "1,2"; 479 | VALIDATE_PRODUCT = YES; 480 | }; 481 | name = Release; 482 | }; 483 | 97C147061CF9000F007C117D /* Debug */ = { 484 | isa = XCBuildConfiguration; 485 | baseConfigurationReference = 9740EEB21CF90195004384FC /* Debug.xcconfig */; 486 | buildSettings = { 487 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; 488 | CLANG_ENABLE_MODULES = YES; 489 | CURRENT_PROJECT_VERSION = "$(FLUTTER_BUILD_NUMBER)"; 490 | ENABLE_BITCODE = NO; 491 | INFOPLIST_FILE = Runner/Info.plist; 492 | LD_RUNPATH_SEARCH_PATHS = ( 493 | "$(inherited)", 494 | "@executable_path/Frameworks", 495 | ); 496 | PRODUCT_BUNDLE_IDENTIFIER = com.example.example; 497 | PRODUCT_NAME = "$(TARGET_NAME)"; 498 | SWIFT_OBJC_BRIDGING_HEADER = "Runner/Runner-Bridging-Header.h"; 499 | SWIFT_OPTIMIZATION_LEVEL = "-Onone"; 500 | SWIFT_VERSION = 5.0; 501 | VERSIONING_SYSTEM = "apple-generic"; 502 | }; 503 | name = Debug; 504 | }; 505 | 97C147071CF9000F007C117D /* Release */ = { 506 | isa = XCBuildConfiguration; 507 | baseConfigurationReference = 7AFA3C8E1D35360C0083082E /* Release.xcconfig */; 508 | buildSettings = { 509 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; 510 | CLANG_ENABLE_MODULES = YES; 511 | CURRENT_PROJECT_VERSION = "$(FLUTTER_BUILD_NUMBER)"; 512 | ENABLE_BITCODE = NO; 513 | INFOPLIST_FILE = Runner/Info.plist; 514 | LD_RUNPATH_SEARCH_PATHS = ( 515 | "$(inherited)", 516 | "@executable_path/Frameworks", 517 | ); 518 | PRODUCT_BUNDLE_IDENTIFIER = com.example.example; 519 | PRODUCT_NAME = "$(TARGET_NAME)"; 520 | SWIFT_OBJC_BRIDGING_HEADER = "Runner/Runner-Bridging-Header.h"; 521 | SWIFT_VERSION = 5.0; 522 | VERSIONING_SYSTEM = "apple-generic"; 523 | }; 524 | name = Release; 525 | }; 526 | /* End XCBuildConfiguration section */ 527 | 528 | /* Begin XCConfigurationList section */ 529 | 97C146E91CF9000F007C117D /* Build configuration list for PBXProject "Runner" */ = { 530 | isa = XCConfigurationList; 531 | buildConfigurations = ( 532 | 97C147031CF9000F007C117D /* Debug */, 533 | 97C147041CF9000F007C117D /* Release */, 534 | 249021D3217E4FDB00AE95B9 /* Profile */, 535 | ); 536 | defaultConfigurationIsVisible = 0; 537 | defaultConfigurationName = Release; 538 | }; 539 | 97C147051CF9000F007C117D /* Build configuration list for PBXNativeTarget "Runner" */ = { 540 | isa = XCConfigurationList; 541 | buildConfigurations = ( 542 | 97C147061CF9000F007C117D /* Debug */, 543 | 97C147071CF9000F007C117D /* Release */, 544 | 249021D4217E4FDB00AE95B9 /* Profile */, 545 | ); 546 | defaultConfigurationIsVisible = 0; 547 | defaultConfigurationName = Release; 548 | }; 549 | /* End XCConfigurationList section */ 550 | }; 551 | rootObject = 97C146E61CF9000F007C117D /* Project object */; 552 | } 553 | -------------------------------------------------------------------------------- /example/ios/Runner.xcodeproj/project.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /example/ios/Runner.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | IDEDidComputeMac32BitWarning 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /example/ios/Runner.xcodeproj/project.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | PreviewsEnabled 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /example/ios/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme: -------------------------------------------------------------------------------- 1 | 2 | 5 | 8 | 9 | 15 | 21 | 22 | 23 | 24 | 25 | 30 | 31 | 37 | 38 | 39 | 40 | 41 | 42 | 52 | 54 | 60 | 61 | 62 | 63 | 69 | 71 | 77 | 78 | 79 | 80 | 82 | 83 | 86 | 87 | 88 | -------------------------------------------------------------------------------- /example/ios/Runner.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 9 | 10 | 11 | -------------------------------------------------------------------------------- /example/ios/Runner.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | IDEDidComputeMac32BitWarning 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /example/ios/Runner.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | PreviewsEnabled 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /example/ios/Runner/AppDelegate.swift: -------------------------------------------------------------------------------- 1 | import UIKit 2 | import Flutter 3 | 4 | @UIApplicationMain 5 | @objc class AppDelegate: FlutterAppDelegate { 6 | override func application( 7 | _ application: UIApplication, 8 | didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]? 9 | ) -> Bool { 10 | GeneratedPluginRegistrant.register(with: self) 11 | return super.application(application, didFinishLaunchingWithOptions: launchOptions) 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images": [ 3 | { 4 | "size": "20x20", 5 | "idiom": "iphone", 6 | "filename": "Icon-App-20x20@2x.png", 7 | "scale": "2x" 8 | }, 9 | { 10 | "size": "20x20", 11 | "idiom": "iphone", 12 | "filename": "Icon-App-20x20@3x.png", 13 | "scale": "3x" 14 | }, 15 | { 16 | "size": "29x29", 17 | "idiom": "iphone", 18 | "filename": "Icon-App-29x29@1x.png", 19 | "scale": "1x" 20 | }, 21 | { 22 | "size": "29x29", 23 | "idiom": "iphone", 24 | "filename": "Icon-App-29x29@2x.png", 25 | "scale": "2x" 26 | }, 27 | { 28 | "size": "29x29", 29 | "idiom": "iphone", 30 | "filename": "Icon-App-29x29@3x.png", 31 | "scale": "3x" 32 | }, 33 | { 34 | "size": "40x40", 35 | "idiom": "iphone", 36 | "filename": "Icon-App-40x40@2x.png", 37 | "scale": "2x" 38 | }, 39 | { 40 | "size": "40x40", 41 | "idiom": "iphone", 42 | "filename": "Icon-App-40x40@3x.png", 43 | "scale": "3x" 44 | }, 45 | { 46 | "size": "60x60", 47 | "idiom": "iphone", 48 | "filename": "Icon-App-60x60@2x.png", 49 | "scale": "2x" 50 | }, 51 | { 52 | "size": "60x60", 53 | "idiom": "iphone", 54 | "filename": "Icon-App-60x60@3x.png", 55 | "scale": "3x" 56 | }, 57 | { 58 | "size": "20x20", 59 | "idiom": "ipad", 60 | "filename": "Icon-App-20x20@1x.png", 61 | "scale": "1x" 62 | }, 63 | { 64 | "size": "20x20", 65 | "idiom": "ipad", 66 | "filename": "Icon-App-20x20@2x.png", 67 | "scale": "2x" 68 | }, 69 | { 70 | "size": "29x29", 71 | "idiom": "ipad", 72 | "filename": "Icon-App-29x29@1x.png", 73 | "scale": "1x" 74 | }, 75 | { 76 | "size": "29x29", 77 | "idiom": "ipad", 78 | "filename": "Icon-App-29x29@2x.png", 79 | "scale": "2x" 80 | }, 81 | { 82 | "size": "40x40", 83 | "idiom": "ipad", 84 | "filename": "Icon-App-40x40@1x.png", 85 | "scale": "1x" 86 | }, 87 | { 88 | "size": "40x40", 89 | "idiom": "ipad", 90 | "filename": "Icon-App-40x40@2x.png", 91 | "scale": "2x" 92 | }, 93 | { 94 | "size": "76x76", 95 | "idiom": "ipad", 96 | "filename": "Icon-App-76x76@1x.png", 97 | "scale": "1x" 98 | }, 99 | { 100 | "size": "76x76", 101 | "idiom": "ipad", 102 | "filename": "Icon-App-76x76@2x.png", 103 | "scale": "2x" 104 | }, 105 | { 106 | "size": "83.5x83.5", 107 | "idiom": "ipad", 108 | "filename": "Icon-App-83.5x83.5@2x.png", 109 | "scale": "2x" 110 | }, 111 | { 112 | "size": "1024x1024", 113 | "idiom": "ios-marketing", 114 | "filename": "Icon-App-1024x1024@1x.png", 115 | "scale": "1x" 116 | } 117 | ], 118 | "info": { 119 | "version": 1, 120 | "author": "xcode" 121 | } 122 | } 123 | -------------------------------------------------------------------------------- /example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-1024x1024@1x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/GAM3RG33K/flutter_settings_screens/18f937739d7fb4c7ceb0d8b9877f20f0b5e9e6d8/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-1024x1024@1x.png -------------------------------------------------------------------------------- /example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@1x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/GAM3RG33K/flutter_settings_screens/18f937739d7fb4c7ceb0d8b9877f20f0b5e9e6d8/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@1x.png -------------------------------------------------------------------------------- /example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/GAM3RG33K/flutter_settings_screens/18f937739d7fb4c7ceb0d8b9877f20f0b5e9e6d8/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@2x.png -------------------------------------------------------------------------------- /example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/GAM3RG33K/flutter_settings_screens/18f937739d7fb4c7ceb0d8b9877f20f0b5e9e6d8/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@3x.png -------------------------------------------------------------------------------- /example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@1x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/GAM3RG33K/flutter_settings_screens/18f937739d7fb4c7ceb0d8b9877f20f0b5e9e6d8/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@1x.png -------------------------------------------------------------------------------- /example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/GAM3RG33K/flutter_settings_screens/18f937739d7fb4c7ceb0d8b9877f20f0b5e9e6d8/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@2x.png -------------------------------------------------------------------------------- /example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/GAM3RG33K/flutter_settings_screens/18f937739d7fb4c7ceb0d8b9877f20f0b5e9e6d8/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@3x.png -------------------------------------------------------------------------------- /example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@1x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/GAM3RG33K/flutter_settings_screens/18f937739d7fb4c7ceb0d8b9877f20f0b5e9e6d8/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@1x.png -------------------------------------------------------------------------------- /example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/GAM3RG33K/flutter_settings_screens/18f937739d7fb4c7ceb0d8b9877f20f0b5e9e6d8/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@2x.png -------------------------------------------------------------------------------- /example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/GAM3RG33K/flutter_settings_screens/18f937739d7fb4c7ceb0d8b9877f20f0b5e9e6d8/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@3x.png -------------------------------------------------------------------------------- /example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/GAM3RG33K/flutter_settings_screens/18f937739d7fb4c7ceb0d8b9877f20f0b5e9e6d8/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@2x.png -------------------------------------------------------------------------------- /example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/GAM3RG33K/flutter_settings_screens/18f937739d7fb4c7ceb0d8b9877f20f0b5e9e6d8/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@3x.png -------------------------------------------------------------------------------- /example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@1x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/GAM3RG33K/flutter_settings_screens/18f937739d7fb4c7ceb0d8b9877f20f0b5e9e6d8/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@1x.png -------------------------------------------------------------------------------- /example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/GAM3RG33K/flutter_settings_screens/18f937739d7fb4c7ceb0d8b9877f20f0b5e9e6d8/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@2x.png -------------------------------------------------------------------------------- /example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-83.5x83.5@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/GAM3RG33K/flutter_settings_screens/18f937739d7fb4c7ceb0d8b9877f20f0b5e9e6d8/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-83.5x83.5@2x.png -------------------------------------------------------------------------------- /example/ios/Runner/Assets.xcassets/LaunchImage.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images": [ 3 | { 4 | "idiom": "universal", 5 | "filename": "LaunchImage.png", 6 | "scale": "1x" 7 | }, 8 | { 9 | "idiom": "universal", 10 | "filename": "LaunchImage@2x.png", 11 | "scale": "2x" 12 | }, 13 | { 14 | "idiom": "universal", 15 | "filename": "LaunchImage@3x.png", 16 | "scale": "3x" 17 | } 18 | ], 19 | "info": { 20 | "version": 1, 21 | "author": "xcode" 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /example/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/GAM3RG33K/flutter_settings_screens/18f937739d7fb4c7ceb0d8b9877f20f0b5e9e6d8/example/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage.png -------------------------------------------------------------------------------- /example/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/GAM3RG33K/flutter_settings_screens/18f937739d7fb4c7ceb0d8b9877f20f0b5e9e6d8/example/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@2x.png -------------------------------------------------------------------------------- /example/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/GAM3RG33K/flutter_settings_screens/18f937739d7fb4c7ceb0d8b9877f20f0b5e9e6d8/example/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@3x.png -------------------------------------------------------------------------------- /example/ios/Runner/Assets.xcassets/LaunchImage.imageset/README.md: -------------------------------------------------------------------------------- 1 | # Launch Screen Assets 2 | 3 | You can customize the launch screen with your own desired assets by replacing the image files in this directory. 4 | 5 | You can also do it by opening your Flutter project's Xcode project with `open ios/Runner.xcworkspace`, selecting `Runner/Assets.xcassets` in the Project Navigator and dropping in the desired images. -------------------------------------------------------------------------------- /example/ios/Runner/Base.lproj/LaunchScreen.storyboard: -------------------------------------------------------------------------------- 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 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | -------------------------------------------------------------------------------- /example/ios/Runner/Base.lproj/Main.storyboard: -------------------------------------------------------------------------------- 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 | 27 | -------------------------------------------------------------------------------- /example/ios/Runner/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | $(DEVELOPMENT_LANGUAGE) 7 | CFBundleDisplayName 8 | Example 9 | CFBundleExecutable 10 | $(EXECUTABLE_NAME) 11 | CFBundleIdentifier 12 | $(PRODUCT_BUNDLE_IDENTIFIER) 13 | CFBundleInfoDictionaryVersion 14 | 6.0 15 | CFBundleName 16 | flutter_settings_screens_example 17 | CFBundlePackageType 18 | APPL 19 | CFBundleShortVersionString 20 | $(FLUTTER_BUILD_NAME) 21 | CFBundleSignature 22 | ???? 23 | CFBundleVersion 24 | $(FLUTTER_BUILD_NUMBER) 25 | LSRequiresIPhoneOS 26 | 27 | UILaunchStoryboardName 28 | LaunchScreen 29 | UIMainStoryboardFile 30 | Main 31 | UISupportedInterfaceOrientations 32 | 33 | UIInterfaceOrientationPortrait 34 | UIInterfaceOrientationLandscapeLeft 35 | UIInterfaceOrientationLandscapeRight 36 | 37 | UISupportedInterfaceOrientations~ipad 38 | 39 | UIInterfaceOrientationPortrait 40 | UIInterfaceOrientationPortraitUpsideDown 41 | UIInterfaceOrientationLandscapeLeft 42 | UIInterfaceOrientationLandscapeRight 43 | 44 | UIViewControllerBasedStatusBarAppearance 45 | 46 | CADisableMinimumFrameDurationOnPhone 47 | 48 | UIApplicationSupportsIndirectInputEvents 49 | 50 | 51 | 52 | -------------------------------------------------------------------------------- /example/ios/Runner/Runner-Bridging-Header.h: -------------------------------------------------------------------------------- 1 | #import "GeneratedPluginRegistrant.h" 2 | -------------------------------------------------------------------------------- /example/lib/app_settings_page.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/material.dart'; 2 | import 'package:flutter_settings_screens/flutter_settings_screens.dart'; 3 | 4 | class AppSettings extends StatefulWidget { 5 | @override 6 | _AppSettingsState createState() => _AppSettingsState(); 7 | } 8 | 9 | class _AppSettingsState extends State { 10 | @override 11 | Widget build(BuildContext context) { 12 | return Container( 13 | child: SettingsScreen( 14 | title: 'Application Settings', 15 | children: [ 16 | SettingsGroup( 17 | title: 'Single Choice Settings', 18 | children: [ 19 | SwitchSettingsTile( 20 | settingKey: 'key-wifi', 21 | title: 'Wi-Fi', 22 | subtitle: 'Wi-Fi allows interacting with the local network ' 23 | 'or internet via connecting to a W-Fi router', 24 | enabledLabel: 'Enabled', 25 | disabledLabel: 'Disabled', 26 | leading: Icon(Icons.wifi), 27 | onChange: (value) { 28 | debugPrint('key-wifi: $value'); 29 | }, 30 | ), 31 | CheckboxSettingsTile( 32 | settingKey: 'key-blue-tooth', 33 | title: 'Bluetooth', 34 | subtitle: 'Bluetooth allows interacting with the ' 35 | 'near by bluetooth enabled devices', 36 | enabledLabel: 'Enabled', 37 | disabledLabel: 'Disabled', 38 | leading: Icon(Icons.bluetooth), 39 | onChange: (value) { 40 | debugPrint('key-blue-tooth: $value'); 41 | }, 42 | ), 43 | SwitchSettingsTile( 44 | leading: Icon(Icons.developer_mode), 45 | settingKey: 'key-switch-dev-mode', 46 | title: 'Developer Settings', 47 | onChange: (value) { 48 | debugPrint('key-switch-dev-mod: $value'); 49 | }, 50 | childrenIfEnabled: [ 51 | CheckboxSettingsTile( 52 | leading: Icon(Icons.adb), 53 | settingKey: 'key-is-developer', 54 | title: 'Developer Mode', 55 | defaultValue: true, 56 | onChange: (value) { 57 | debugPrint('key-is-developer: $value'); 58 | }, 59 | ), 60 | SwitchSettingsTile( 61 | leading: Icon(Icons.usb), 62 | settingKey: 'key-is-usb-debugging', 63 | title: 'USB Debugging', 64 | onChange: (value) { 65 | debugPrint('key-is-usb-debugging: $value'); 66 | }, 67 | ), 68 | SimpleSettingsTile( 69 | title: 'Root Settings', 70 | subtitle: 'These setting is not accessible', 71 | enabled: false, 72 | ), 73 | SimpleSettingsTile( 74 | title: 'Custom Settings', 75 | subtitle: 'Tap to execute custom callback', 76 | onTap: () => debugPrint('Custom action'), 77 | ), 78 | ], 79 | ), 80 | SimpleSettingsTile( 81 | title: 'More Settings', 82 | subtitle: 'General App Settings', 83 | child: SettingsScreen( 84 | title: 'App Settings', 85 | children: [ 86 | CheckboxSettingsTile( 87 | leading: Icon(Icons.adb), 88 | settingKey: 'key-is-developer', 89 | title: 'Developer Mode', 90 | onChange: (bool value) { 91 | debugPrint('Developer Mode ${value ? 'on' : 'off'}'); 92 | }, 93 | ), 94 | SwitchSettingsTile( 95 | leading: Icon(Icons.usb), 96 | settingKey: 'key-is-usb-debugging', 97 | title: 'USB Debugging', 98 | onChange: (value) { 99 | debugPrint('USB Debugging: $value'); 100 | }, 101 | ), 102 | ], 103 | ), 104 | ), 105 | TextInputSettingsTile( 106 | title: 'User Name', 107 | settingKey: 'key-user-name', 108 | initialValue: 'admin', 109 | validator: (String? username) { 110 | if (username != null && username.length > 3) { 111 | return null; 112 | } 113 | return "User Name can't be smaller than 4 letters"; 114 | }, 115 | borderColor: Colors.blueAccent, 116 | errorColor: Colors.deepOrangeAccent, 117 | ), 118 | TextInputSettingsTile( 119 | title: 'password', 120 | settingKey: 'key-user-password', 121 | obscureText: true, 122 | validator: (String? password) { 123 | if (password != null && password.length > 6) { 124 | return null; 125 | } 126 | return "Password can't be smaller than 7 letters"; 127 | }, 128 | borderColor: Colors.blueAccent, 129 | errorColor: Colors.deepOrangeAccent, 130 | ), 131 | ModalSettingsTile( 132 | title: 'Quick setting dialog', 133 | subtitle: 'Settings on a dialog', 134 | children: [ 135 | CheckboxSettingsTile( 136 | settingKey: 'key-day-light-savings', 137 | title: 'Daylight Time Saving', 138 | enabledLabel: 'Enabled', 139 | disabledLabel: 'Disabled', 140 | leading: Icon(Icons.timelapse), 141 | onChange: (value) { 142 | debugPrint('key-day-light-saving: $value'); 143 | }, 144 | ), 145 | SwitchSettingsTile( 146 | settingKey: 'key-dark-mode', 147 | title: 'Dark Mode', 148 | enabledLabel: 'Enabled', 149 | disabledLabel: 'Disabled', 150 | leading: Icon(Icons.palette), 151 | onChange: (value) { 152 | debugPrint('jey-dark-mode: $value'); 153 | }, 154 | ), 155 | ], 156 | ), 157 | ExpandableSettingsTile( 158 | title: 'Quick setting 2', 159 | subtitle: 'Expandable Settings', 160 | expanded: true, 161 | children: [ 162 | CheckboxSettingsTile( 163 | settingKey: 'key-day-light-savings-2', 164 | title: 'Daylight Time Saving', 165 | enabledLabel: 'Enabled', 166 | disabledLabel: 'Disabled', 167 | leading: Icon(Icons.timelapse), 168 | onChange: (value) { 169 | debugPrint('key-day-light-savings-2: $value'); 170 | }, 171 | ), 172 | SwitchSettingsTile( 173 | settingKey: 'key-dark-mode-2', 174 | title: 'Dark Mode', 175 | enabledLabel: 'Enabled', 176 | disabledLabel: 'Disabled', 177 | leading: Icon(Icons.palette), 178 | onChange: (value) { 179 | debugPrint('key-dark-mode-2: $value'); 180 | }, 181 | ), 182 | ], 183 | ), 184 | ], 185 | ), 186 | SettingsGroup( 187 | title: 'Multiple choice settings', 188 | children: [ 189 | RadioSettingsTile( 190 | title: 'Preferred Sync Period', 191 | settingKey: 'key-radio-sync-period', 192 | values: { 193 | 0: 'Never', 194 | 1: 'Daily', 195 | 7: 'Weekly', 196 | 15: 'Fortnight', 197 | 30: 'Monthly', 198 | }, 199 | selected: 0, 200 | onChange: (value) { 201 | debugPrint('key-radio-sync-period: $value'); 202 | }, 203 | ), 204 | DropDownSettingsTile( 205 | title: 'E-Mail View', 206 | settingKey: 'key-dropdown-email-view', 207 | values: { 208 | 2: 'Simple', 209 | 3: 'Adjusted', 210 | 4: 'Normal', 211 | 5: 'Compact', 212 | 6: 'Squizzed', 213 | }, 214 | selected: 2, 215 | onChange: (value) { 216 | debugPrint('key-dropdown-email-view: $value'); 217 | }, 218 | ), 219 | ], 220 | ), 221 | ModalSettingsTile( 222 | title: 'Group Settings', 223 | subtitle: 'Same group settings but in a dialog', 224 | children: [ 225 | SimpleRadioSettingsTile( 226 | title: 'Sync Settings', 227 | settingKey: 'key-radio-sync-settings', 228 | values: [ 229 | 'Never', 230 | 'Daily', 231 | 'Weekly', 232 | 'Fortnight', 233 | 'Monthly', 234 | ], 235 | selected: 'Daily', 236 | onChange: (value) { 237 | debugPrint('key-radio-sync-settings: $value'); 238 | }, 239 | ), 240 | SimpleDropDownSettingsTile( 241 | title: 'Beauty Filter', 242 | settingKey: 'key-dropdown-beauty-filter', 243 | values: [ 244 | 'Simple', 245 | 'Normal', 246 | 'Little Special', 247 | 'Special', 248 | 'Extra Special', 249 | 'Bizarre', 250 | 'Horrific', 251 | ], 252 | selected: 'Special', 253 | onChange: (value) { 254 | debugPrint('key-dropdown-beauty-filter: $value'); 255 | }, 256 | ) 257 | ], 258 | ), 259 | ExpandableSettingsTile( 260 | title: 'Expandable Group Settings', 261 | subtitle: 'Group of settings (expandable)', 262 | children: [ 263 | RadioSettingsTile( 264 | title: 'Beauty Filter', 265 | settingKey: 'key-radio-beauty-filter-expandable', 266 | values: { 267 | 1.0: 'Simple', 268 | 1.5: 'Normal', 269 | 2.0: 'Little Special', 270 | 2.5: 'Special', 271 | 3.0: 'Extra Special', 272 | 3.5: 'Bizarre', 273 | 4.0: 'Horrific', 274 | }, 275 | selected: 2.5, 276 | onChange: (value) { 277 | debugPrint('key-radio-beauty-filter-expandable: $value'); 278 | }, 279 | ), 280 | DropDownSettingsTile( 281 | title: 'Preferred Sync Period', 282 | settingKey: 'key-dropdown-sync-period-2', 283 | values: { 284 | 0: 'Never', 285 | 1: 'Daily', 286 | 7: 'Weekly', 287 | 15: 'Fortnight', 288 | 30: 'Monthly', 289 | }, 290 | selected: 0, 291 | onChange: (value) { 292 | debugPrint('key-dropdown-sync-period-2: $value'); 293 | }, 294 | ) 295 | ], 296 | ), 297 | SettingsGroup( 298 | title: 'Other settings', 299 | children: [ 300 | SliderSettingsTile( 301 | title: 'Volume [Auto-Adjusting to 20]', 302 | settingKey: 'key-slider-volume', 303 | defaultValue: 20, 304 | min: 0, 305 | max: 100, 306 | step: 1, 307 | leading: Icon(Icons.volume_up), 308 | decimalPrecision: 0, 309 | onChange: (value) { 310 | debugPrint('\n===== on change end =====\n' 311 | 'key-slider-volume: $value' 312 | '\n==========\n'); 313 | Future.delayed(Duration(seconds: 1), () { 314 | // Reset value only if the current value is not 20 315 | if (Settings.getValue('key-slider-volume') != 20) { 316 | debugPrint('\n===== on change end =====\n' 317 | 'Resetting value to 20' 318 | '\n==========\n'); 319 | Settings.setValue('key-slider-volume', 20.0, 320 | notify: true); 321 | } 322 | }); 323 | }, 324 | ), 325 | ColorPickerSettingsTile( 326 | settingKey: 'key-color-picker', 327 | title: 'Accent Color', 328 | defaultValue: Colors.blue, 329 | onChange: (value) { 330 | debugPrint('key-color-picker: $value'); 331 | }, 332 | ) 333 | ], 334 | ), 335 | ModalSettingsTile( 336 | title: 'Other settings', 337 | subtitle: 'Other Settings in a Dialog', 338 | children: [ 339 | SliderSettingsTile( 340 | title: 'Custom Ratio', 341 | settingKey: 'key-custom-ratio-slider-2', 342 | defaultValue: 2.5, 343 | min: 1, 344 | max: 5, 345 | step: 0.1, 346 | decimalPrecision: 1, 347 | leading: Icon(Icons.aspect_ratio), 348 | onChange: (value) { 349 | debugPrint('\n===== on change =====\n' 350 | 'key-custom-ratio-slider-2: $value' 351 | '\n==========\n'); 352 | }, 353 | onChangeStart: (value) { 354 | debugPrint('\n===== on change start =====\n' 355 | 'key-custom-ratio-slider-2: $value' 356 | '\n==========\n'); 357 | }, 358 | onChangeEnd: (value) { 359 | debugPrint('\n===== on change end =====\n' 360 | 'key-custom-ratio-slider-2: $value' 361 | '\n==========\n'); 362 | }, 363 | ), 364 | ColorPickerSettingsTile( 365 | settingKey: 'key-color-picker-2', 366 | title: 'Accent Picker', 367 | defaultValue: Colors.blue, 368 | onChange: (value) { 369 | debugPrint('key-color-picker-2: $value'); 370 | }, 371 | ) 372 | ], 373 | ) 374 | ], 375 | ), 376 | ); 377 | } 378 | } 379 | -------------------------------------------------------------------------------- /example/lib/cache_provider.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/foundation.dart'; 2 | import 'package:flutter/material.dart'; 3 | import 'package:flutter_settings_screens/flutter_settings_screens.dart'; 4 | import 'package:hive/hive.dart'; 5 | import 'package:path_provider/path_provider.dart'; 6 | 7 | /// A cache access provider class for shared preferences using Hive library 8 | class HiveCache extends CacheProvider { 9 | Box? _preferences; 10 | final String keyName = 'app_preferences'; 11 | 12 | @override 13 | Future init() async { 14 | WidgetsFlutterBinding.ensureInitialized(); 15 | if (!kIsWeb) { 16 | final defaultDirectory = await getApplicationDocumentsDirectory(); 17 | Hive.init(defaultDirectory.path); 18 | } 19 | if (Hive.isBoxOpen(keyName)) { 20 | _preferences = Hive.box(keyName); 21 | } else { 22 | _preferences = await Hive.openBox(keyName); 23 | } 24 | } 25 | 26 | Set get keys => getKeys(); 27 | 28 | @override 29 | bool? getBool(String key, {bool? defaultValue}) { 30 | return _preferences?.get(key); 31 | } 32 | 33 | @override 34 | double? getDouble(String key, {double? defaultValue}) { 35 | return _preferences?.get(key); 36 | } 37 | 38 | @override 39 | int? getInt(String key, {int? defaultValue}) { 40 | return _preferences?.get(key); 41 | } 42 | 43 | @override 44 | String? getString(String key, {String? defaultValue}) { 45 | return _preferences?.get(key); 46 | } 47 | 48 | @override 49 | Future setBool(String key, bool? value) async { 50 | await _preferences?.put(key, value); 51 | } 52 | 53 | @override 54 | Future setDouble(String key, double? value) async { 55 | await _preferences?.put(key, value); 56 | } 57 | 58 | @override 59 | Future setInt(String key, int? value) async { 60 | await _preferences?.put(key, value); 61 | } 62 | 63 | @override 64 | Future setString(String key, String? value) async { 65 | await _preferences?.put(key, value); 66 | } 67 | 68 | @override 69 | Future setObject(String key, T? value) async { 70 | await _preferences?.put(key, value); 71 | } 72 | 73 | @override 74 | bool containsKey(String key) { 75 | return _preferences?.containsKey(key) ?? false; 76 | } 77 | 78 | @override 79 | Set getKeys() { 80 | return _preferences?.keys.toSet() ?? {}; 81 | } 82 | 83 | @override 84 | Future remove(String key) async { 85 | if (containsKey(key)) { 86 | await _preferences?.delete(key); 87 | } 88 | } 89 | 90 | @override 91 | Future removeAll() async { 92 | final keys = getKeys(); 93 | await _preferences?.deleteAll(keys); 94 | } 95 | 96 | @override 97 | T? getValue(String key, {T? defaultValue}) { 98 | var value = _preferences?.get(key); 99 | if (value is T) { 100 | return value; 101 | } 102 | return defaultValue; 103 | } 104 | } 105 | -------------------------------------------------------------------------------- /example/lib/main.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/foundation.dart'; 2 | import 'package:flutter/material.dart'; 3 | import 'package:flutter_settings_screens/flutter_settings_screens.dart'; 4 | 5 | import 'app_settings_page.dart'; 6 | import 'cache_provider.dart'; 7 | 8 | void main() { 9 | initSettings().then((accentColor) { 10 | runApp(MyApp(accentColor: accentColor)); 11 | }); 12 | } 13 | 14 | Future> initSettings() async { 15 | await Settings.init( 16 | cacheProvider: _isUsingHive ? HiveCache() : SharePreferenceCache(), 17 | ); 18 | final _accentColor = ValueNotifier(Colors.blueAccent); 19 | return _accentColor; 20 | } 21 | 22 | bool _isDarkTheme = true; 23 | bool _isUsingHive = true; 24 | 25 | class MyApp extends StatelessWidget { 26 | final ValueNotifier accentColor; 27 | 28 | const MyApp({Key? key, required this.accentColor}) : super(key: key); 29 | 30 | // This widget is the root of your application. 31 | @override 32 | Widget build(BuildContext context) { 33 | return MyHomePage( 34 | title: 'Flutter Demo Home Page', 35 | accentColor: accentColor, 36 | ); 37 | } 38 | } 39 | 40 | class MyHomePage extends StatefulWidget { 41 | final String title; 42 | final ValueNotifier accentColor; 43 | 44 | const MyHomePage({ 45 | Key? key, 46 | required this.accentColor, 47 | required this.title, 48 | }) : super(key: key); 49 | 50 | @override 51 | _MyHomePageState createState() => _MyHomePageState(); 52 | } 53 | 54 | class _MyHomePageState extends State { 55 | @override 56 | Widget build(BuildContext context) { 57 | return ValueListenableBuilder( 58 | valueListenable: widget.accentColor, 59 | builder: (_, color, __) { 60 | final _darkTheme = ThemeData.dark(); 61 | final _lightTheme = ThemeData.light(); 62 | return MaterialApp( 63 | title: 'App Settings Demo', 64 | theme: _isDarkTheme 65 | ? _darkTheme.copyWith( 66 | colorScheme: _darkTheme.colorScheme.copyWith( 67 | secondary: color, 68 | ), 69 | checkboxTheme: CheckboxThemeData( 70 | fillColor: MaterialStateProperty.resolveWith( 71 | (Set states) { 72 | if (states.contains(MaterialState.disabled)) { 73 | return null; 74 | } 75 | if (states.contains(MaterialState.selected)) { 76 | return color; 77 | } 78 | return null; 79 | }), 80 | ), 81 | radioTheme: RadioThemeData( 82 | fillColor: MaterialStateProperty.resolveWith( 83 | (Set states) { 84 | if (states.contains(MaterialState.disabled)) { 85 | return null; 86 | } 87 | if (states.contains(MaterialState.selected)) { 88 | return color; 89 | } 90 | return null; 91 | }), 92 | ), 93 | switchTheme: SwitchThemeData( 94 | thumbColor: MaterialStateProperty.resolveWith( 95 | (Set states) { 96 | if (states.contains(MaterialState.disabled)) { 97 | return null; 98 | } 99 | if (states.contains(MaterialState.selected)) { 100 | return color; 101 | } 102 | return null; 103 | }), 104 | trackColor: MaterialStateProperty.resolveWith( 105 | (Set states) { 106 | if (states.contains(MaterialState.disabled)) { 107 | return null; 108 | } 109 | if (states.contains(MaterialState.selected)) { 110 | return color; 111 | } 112 | return null; 113 | }), 114 | ), 115 | ) 116 | : _lightTheme.copyWith( 117 | colorScheme: _darkTheme.colorScheme.copyWith( 118 | secondary: color, 119 | ), 120 | checkboxTheme: CheckboxThemeData( 121 | fillColor: MaterialStateProperty.resolveWith( 122 | (Set states) { 123 | if (states.contains(MaterialState.disabled)) { 124 | return null; 125 | } 126 | if (states.contains(MaterialState.selected)) { 127 | return color; 128 | } 129 | return null; 130 | }), 131 | ), 132 | radioTheme: RadioThemeData( 133 | fillColor: MaterialStateProperty.resolveWith( 134 | (Set states) { 135 | if (states.contains(MaterialState.disabled)) { 136 | return null; 137 | } 138 | if (states.contains(MaterialState.selected)) { 139 | return color; 140 | } 141 | return null; 142 | }), 143 | ), 144 | switchTheme: SwitchThemeData( 145 | thumbColor: MaterialStateProperty.resolveWith( 146 | (Set states) { 147 | if (states.contains(MaterialState.disabled)) { 148 | return null; 149 | } 150 | if (states.contains(MaterialState.selected)) { 151 | return color; 152 | } 153 | return null; 154 | }), 155 | trackColor: MaterialStateProperty.resolveWith( 156 | (Set states) { 157 | if (states.contains(MaterialState.disabled)) { 158 | return null; 159 | } 160 | if (states.contains(MaterialState.selected)) { 161 | return color; 162 | } 163 | return null; 164 | }), 165 | ), 166 | ), 167 | home: Scaffold( 168 | appBar: AppBar( 169 | title: Text(widget.title), 170 | ), 171 | body: Center( 172 | child: Column( 173 | children: [ 174 | _buildThemeSwitch(context), 175 | _buildPreferenceSwitch(context), 176 | SizedBox( 177 | height: 50.0, 178 | ), 179 | AppBody(), 180 | ], 181 | ), 182 | ), 183 | ), 184 | ); 185 | }, 186 | ); 187 | } 188 | 189 | Widget _buildPreferenceSwitch(BuildContext context) { 190 | return Row( 191 | mainAxisAlignment: MainAxisAlignment.spaceEvenly, 192 | children: [ 193 | Text('Shared Pref'), 194 | Switch( 195 | activeColor: Theme.of(context).colorScheme.secondary, 196 | value: _isUsingHive, 197 | onChanged: (newVal) { 198 | if (kIsWeb) { 199 | return; 200 | } 201 | _isUsingHive = newVal; 202 | setState(() { 203 | initSettings(); 204 | }); 205 | }), 206 | Text('Hive Storage'), 207 | ], 208 | ); 209 | } 210 | 211 | Widget _buildThemeSwitch(BuildContext context) { 212 | return Row( 213 | mainAxisAlignment: MainAxisAlignment.spaceEvenly, 214 | children: [ 215 | Text('Light Theme'), 216 | Switch( 217 | activeColor: Theme.of(context).colorScheme.secondary, 218 | value: _isDarkTheme, 219 | onChanged: (newVal) { 220 | _isDarkTheme = newVal; 221 | setState(() {}); 222 | }), 223 | Text('Dark Theme'), 224 | ], 225 | ); 226 | } 227 | } 228 | 229 | class AppBody extends StatefulWidget { 230 | @override 231 | _AppBodyState createState() => _AppBodyState(); 232 | } 233 | 234 | class _AppBodyState extends State { 235 | @override 236 | Widget build(BuildContext context) { 237 | return Column( 238 | children: [ 239 | _buildClearCacheButton(context), 240 | SizedBox( 241 | height: 25.0, 242 | ), 243 | ElevatedButton( 244 | onPressed: () { 245 | openAppSettings(context); 246 | }, 247 | child: Text('Start Demo'), 248 | ), 249 | ], 250 | ); 251 | } 252 | 253 | void openAppSettings(BuildContext context) { 254 | Navigator.of(context).push(MaterialPageRoute( 255 | builder: (context) => AppSettings(), 256 | )); 257 | } 258 | 259 | Widget _buildClearCacheButton(BuildContext context) { 260 | return ElevatedButton( 261 | onPressed: () { 262 | Settings.clearCache(); 263 | showSnackBar( 264 | context, 265 | 'Cache cleared for selected cache.', 266 | ); 267 | }, 268 | child: Text('Clear selected Cache'), 269 | ); 270 | } 271 | } 272 | 273 | void showSnackBar(BuildContext context, String message) { 274 | ScaffoldMessenger.of(context).showSnackBar( 275 | SnackBar( 276 | content: Text( 277 | message, 278 | style: TextStyle( 279 | color: Colors.white, 280 | ), 281 | ), 282 | backgroundColor: Theme.of(context).primaryColor, 283 | ), 284 | ); 285 | } 286 | -------------------------------------------------------------------------------- /example/macos/.gitignore: -------------------------------------------------------------------------------- 1 | # Flutter-related 2 | **/Flutter/ephemeral/ 3 | **/Pods/ 4 | 5 | # Xcode-related 6 | **/dgph 7 | **/xcuserdata/ 8 | -------------------------------------------------------------------------------- /example/macos/Flutter/Flutter-Debug.xcconfig: -------------------------------------------------------------------------------- 1 | #include? "Pods/Target Support Files/Pods-Runner/Pods-Runner.debug.xcconfig" 2 | #include "ephemeral/Flutter-Generated.xcconfig" 3 | -------------------------------------------------------------------------------- /example/macos/Flutter/Flutter-Release.xcconfig: -------------------------------------------------------------------------------- 1 | #include? "Pods/Target Support Files/Pods-Runner/Pods-Runner.release.xcconfig" 2 | #include "ephemeral/Flutter-Generated.xcconfig" 3 | -------------------------------------------------------------------------------- /example/macos/Flutter/GeneratedPluginRegistrant.swift: -------------------------------------------------------------------------------- 1 | // 2 | // Generated file. Do not edit. 3 | // 4 | 5 | import FlutterMacOS 6 | import Foundation 7 | 8 | import path_provider_foundation 9 | import shared_preferences_foundation 10 | 11 | func RegisterGeneratedPlugins(registry: FlutterPluginRegistry) { 12 | PathProviderPlugin.register(with: registry.registrar(forPlugin: "PathProviderPlugin")) 13 | SharedPreferencesPlugin.register(with: registry.registrar(forPlugin: "SharedPreferencesPlugin")) 14 | } 15 | -------------------------------------------------------------------------------- /example/macos/Podfile: -------------------------------------------------------------------------------- 1 | platform :osx, '10.11' 2 | 3 | # CocoaPods analytics sends network stats synchronously affecting flutter build latency. 4 | ENV['COCOAPODS_DISABLE_STATS'] = 'true' 5 | 6 | project 'Runner', { 7 | 'Debug' => :debug, 8 | 'Profile' => :release, 9 | 'Release' => :release, 10 | } 11 | 12 | def flutter_root 13 | generated_xcode_build_settings_path = File.expand_path(File.join('..', 'Flutter', 'ephemeral', 'Flutter-Generated.xcconfig'), __FILE__) 14 | unless File.exist?(generated_xcode_build_settings_path) 15 | raise "#{generated_xcode_build_settings_path} must exist. If you're running pod install manually, make sure \"flutter pub get\" is executed first" 16 | end 17 | 18 | File.foreach(generated_xcode_build_settings_path) do |line| 19 | matches = line.match(/FLUTTER_ROOT\=(.*)/) 20 | return matches[1].strip if matches 21 | end 22 | raise "FLUTTER_ROOT not found in #{generated_xcode_build_settings_path}. Try deleting Flutter-Generated.xcconfig, then run \"flutter pub get\"" 23 | end 24 | 25 | require File.expand_path(File.join('packages', 'flutter_tools', 'bin', 'podhelper'), flutter_root) 26 | 27 | flutter_macos_podfile_setup 28 | 29 | target 'Runner' do 30 | use_frameworks! 31 | use_modular_headers! 32 | 33 | flutter_install_all_macos_pods File.dirname(File.realpath(__FILE__)) 34 | end 35 | 36 | post_install do |installer| 37 | installer.pods_project.targets.each do |target| 38 | flutter_additional_macos_build_settings(target) 39 | end 40 | end 41 | -------------------------------------------------------------------------------- /example/macos/Runner.xcodeproj/project.pbxproj: -------------------------------------------------------------------------------- 1 | // !$*UTF8*$! 2 | { 3 | archiveVersion = 1; 4 | classes = { 5 | }; 6 | objectVersion = 51; 7 | objects = { 8 | 9 | /* Begin PBXAggregateTarget section */ 10 | 33CC111A2044C6BA0003C045 /* Flutter Assemble */ = { 11 | isa = PBXAggregateTarget; 12 | buildConfigurationList = 33CC111B2044C6BA0003C045 /* Build configuration list for PBXAggregateTarget "Flutter Assemble" */; 13 | buildPhases = ( 14 | 33CC111E2044C6BF0003C045 /* ShellScript */, 15 | ); 16 | dependencies = ( 17 | ); 18 | name = "Flutter Assemble"; 19 | productName = FLX; 20 | }; 21 | /* End PBXAggregateTarget section */ 22 | 23 | /* Begin PBXBuildFile section */ 24 | 335BBD1B22A9A15E00E9071D /* GeneratedPluginRegistrant.swift in Sources */ = {isa = PBXBuildFile; fileRef = 335BBD1A22A9A15E00E9071D /* GeneratedPluginRegistrant.swift */; }; 25 | 33CC10F12044A3C60003C045 /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 33CC10F02044A3C60003C045 /* AppDelegate.swift */; }; 26 | 33CC10F32044A3C60003C045 /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 33CC10F22044A3C60003C045 /* Assets.xcassets */; }; 27 | 33CC10F62044A3C60003C045 /* MainMenu.xib in Resources */ = {isa = PBXBuildFile; fileRef = 33CC10F42044A3C60003C045 /* MainMenu.xib */; }; 28 | 33CC11132044BFA00003C045 /* MainFlutterWindow.swift in Sources */ = {isa = PBXBuildFile; fileRef = 33CC11122044BFA00003C045 /* MainFlutterWindow.swift */; }; 29 | /* End PBXBuildFile section */ 30 | 31 | /* Begin PBXContainerItemProxy section */ 32 | 33CC111F2044C79F0003C045 /* PBXContainerItemProxy */ = { 33 | isa = PBXContainerItemProxy; 34 | containerPortal = 33CC10E52044A3C60003C045 /* Project object */; 35 | proxyType = 1; 36 | remoteGlobalIDString = 33CC111A2044C6BA0003C045; 37 | remoteInfo = FLX; 38 | }; 39 | /* End PBXContainerItemProxy section */ 40 | 41 | /* Begin PBXCopyFilesBuildPhase section */ 42 | 33CC110E2044A8840003C045 /* Bundle Framework */ = { 43 | isa = PBXCopyFilesBuildPhase; 44 | buildActionMask = 2147483647; 45 | dstPath = ""; 46 | dstSubfolderSpec = 10; 47 | files = ( 48 | ); 49 | name = "Bundle Framework"; 50 | runOnlyForDeploymentPostprocessing = 0; 51 | }; 52 | /* End PBXCopyFilesBuildPhase section */ 53 | 54 | /* Begin PBXFileReference section */ 55 | 333000ED22D3DE5D00554162 /* Warnings.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; path = Warnings.xcconfig; sourceTree = ""; }; 56 | 335BBD1A22A9A15E00E9071D /* GeneratedPluginRegistrant.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = GeneratedPluginRegistrant.swift; sourceTree = ""; }; 57 | 33CC10ED2044A3C60003C045 /* example.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = "example.app"; sourceTree = BUILT_PRODUCTS_DIR; }; 58 | 33CC10F02044A3C60003C045 /* AppDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = ""; }; 59 | 33CC10F22044A3C60003C045 /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; name = Assets.xcassets; path = Runner/Assets.xcassets; sourceTree = ""; }; 60 | 33CC10F52044A3C60003C045 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = Base; path = Base.lproj/MainMenu.xib; sourceTree = ""; }; 61 | 33CC10F72044A3C60003C045 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; name = Info.plist; path = Runner/Info.plist; sourceTree = ""; }; 62 | 33CC11122044BFA00003C045 /* MainFlutterWindow.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MainFlutterWindow.swift; sourceTree = ""; }; 63 | 33CEB47222A05771004F2AC0 /* Flutter-Debug.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; path = "Flutter-Debug.xcconfig"; sourceTree = ""; }; 64 | 33CEB47422A05771004F2AC0 /* Flutter-Release.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; path = "Flutter-Release.xcconfig"; sourceTree = ""; }; 65 | 33CEB47722A0578A004F2AC0 /* Flutter-Generated.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; name = "Flutter-Generated.xcconfig"; path = "ephemeral/Flutter-Generated.xcconfig"; sourceTree = ""; }; 66 | 33E51913231747F40026EE4D /* DebugProfile.entitlements */ = {isa = PBXFileReference; lastKnownFileType = text.plist.entitlements; path = DebugProfile.entitlements; sourceTree = ""; }; 67 | 33E51914231749380026EE4D /* Release.entitlements */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.entitlements; path = Release.entitlements; sourceTree = ""; }; 68 | 33E5194F232828860026EE4D /* AppInfo.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; path = AppInfo.xcconfig; sourceTree = ""; }; 69 | 7AFA3C8E1D35360C0083082E /* Release.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; path = Release.xcconfig; sourceTree = ""; }; 70 | 9740EEB21CF90195004384FC /* Debug.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; path = Debug.xcconfig; sourceTree = ""; }; 71 | /* End PBXFileReference section */ 72 | 73 | /* Begin PBXFrameworksBuildPhase section */ 74 | 33CC10EA2044A3C60003C045 /* Frameworks */ = { 75 | isa = PBXFrameworksBuildPhase; 76 | buildActionMask = 2147483647; 77 | files = ( 78 | ); 79 | runOnlyForDeploymentPostprocessing = 0; 80 | }; 81 | /* End PBXFrameworksBuildPhase section */ 82 | 83 | /* Begin PBXGroup section */ 84 | 33BA886A226E78AF003329D5 /* Configs */ = { 85 | isa = PBXGroup; 86 | children = ( 87 | 33E5194F232828860026EE4D /* AppInfo.xcconfig */, 88 | 9740EEB21CF90195004384FC /* Debug.xcconfig */, 89 | 7AFA3C8E1D35360C0083082E /* Release.xcconfig */, 90 | 333000ED22D3DE5D00554162 /* Warnings.xcconfig */, 91 | ); 92 | path = Configs; 93 | sourceTree = ""; 94 | }; 95 | 33CC10E42044A3C60003C045 = { 96 | isa = PBXGroup; 97 | children = ( 98 | 33FAB671232836740065AC1E /* Runner */, 99 | 33CEB47122A05771004F2AC0 /* Flutter */, 100 | 33CC10EE2044A3C60003C045 /* Products */, 101 | D73912EC22F37F3D000D13A0 /* Frameworks */, 102 | ); 103 | sourceTree = ""; 104 | }; 105 | 33CC10EE2044A3C60003C045 /* Products */ = { 106 | isa = PBXGroup; 107 | children = ( 108 | 33CC10ED2044A3C60003C045 /* example.app */, 109 | ); 110 | name = Products; 111 | sourceTree = ""; 112 | }; 113 | 33CC11242044D66E0003C045 /* Resources */ = { 114 | isa = PBXGroup; 115 | children = ( 116 | 33CC10F22044A3C60003C045 /* Assets.xcassets */, 117 | 33CC10F42044A3C60003C045 /* MainMenu.xib */, 118 | 33CC10F72044A3C60003C045 /* Info.plist */, 119 | ); 120 | name = Resources; 121 | path = ..; 122 | sourceTree = ""; 123 | }; 124 | 33CEB47122A05771004F2AC0 /* Flutter */ = { 125 | isa = PBXGroup; 126 | children = ( 127 | 335BBD1A22A9A15E00E9071D /* GeneratedPluginRegistrant.swift */, 128 | 33CEB47222A05771004F2AC0 /* Flutter-Debug.xcconfig */, 129 | 33CEB47422A05771004F2AC0 /* Flutter-Release.xcconfig */, 130 | 33CEB47722A0578A004F2AC0 /* Flutter-Generated.xcconfig */, 131 | ); 132 | path = Flutter; 133 | sourceTree = ""; 134 | }; 135 | 33FAB671232836740065AC1E /* Runner */ = { 136 | isa = PBXGroup; 137 | children = ( 138 | 33CC10F02044A3C60003C045 /* AppDelegate.swift */, 139 | 33CC11122044BFA00003C045 /* MainFlutterWindow.swift */, 140 | 33E51913231747F40026EE4D /* DebugProfile.entitlements */, 141 | 33E51914231749380026EE4D /* Release.entitlements */, 142 | 33CC11242044D66E0003C045 /* Resources */, 143 | 33BA886A226E78AF003329D5 /* Configs */, 144 | ); 145 | path = Runner; 146 | sourceTree = ""; 147 | }; 148 | D73912EC22F37F3D000D13A0 /* Frameworks */ = { 149 | isa = PBXGroup; 150 | children = ( 151 | ); 152 | name = Frameworks; 153 | sourceTree = ""; 154 | }; 155 | /* End PBXGroup section */ 156 | 157 | /* Begin PBXNativeTarget section */ 158 | 33CC10EC2044A3C60003C045 /* Runner */ = { 159 | isa = PBXNativeTarget; 160 | buildConfigurationList = 33CC10FB2044A3C60003C045 /* Build configuration list for PBXNativeTarget "Runner" */; 161 | buildPhases = ( 162 | 33CC10E92044A3C60003C045 /* Sources */, 163 | 33CC10EA2044A3C60003C045 /* Frameworks */, 164 | 33CC10EB2044A3C60003C045 /* Resources */, 165 | 33CC110E2044A8840003C045 /* Bundle Framework */, 166 | 3399D490228B24CF009A79C7 /* ShellScript */, 167 | ); 168 | buildRules = ( 169 | ); 170 | dependencies = ( 171 | 33CC11202044C79F0003C045 /* PBXTargetDependency */, 172 | ); 173 | name = Runner; 174 | productName = Runner; 175 | productReference = 33CC10ED2044A3C60003C045 /* example.app */; 176 | productType = "com.apple.product-type.application"; 177 | }; 178 | /* End PBXNativeTarget section */ 179 | 180 | /* Begin PBXProject section */ 181 | 33CC10E52044A3C60003C045 /* Project object */ = { 182 | isa = PBXProject; 183 | attributes = { 184 | LastSwiftUpdateCheck = 0920; 185 | LastUpgradeCheck = 1300; 186 | ORGANIZATIONNAME = ""; 187 | TargetAttributes = { 188 | 33CC10EC2044A3C60003C045 = { 189 | CreatedOnToolsVersion = 9.2; 190 | LastSwiftMigration = 1100; 191 | ProvisioningStyle = Automatic; 192 | SystemCapabilities = { 193 | com.apple.Sandbox = { 194 | enabled = 1; 195 | }; 196 | }; 197 | }; 198 | 33CC111A2044C6BA0003C045 = { 199 | CreatedOnToolsVersion = 9.2; 200 | ProvisioningStyle = Manual; 201 | }; 202 | }; 203 | }; 204 | buildConfigurationList = 33CC10E82044A3C60003C045 /* Build configuration list for PBXProject "Runner" */; 205 | compatibilityVersion = "Xcode 9.3"; 206 | developmentRegion = en; 207 | hasScannedForEncodings = 0; 208 | knownRegions = ( 209 | en, 210 | Base, 211 | ); 212 | mainGroup = 33CC10E42044A3C60003C045; 213 | productRefGroup = 33CC10EE2044A3C60003C045 /* Products */; 214 | projectDirPath = ""; 215 | projectRoot = ""; 216 | targets = ( 217 | 33CC10EC2044A3C60003C045 /* Runner */, 218 | 33CC111A2044C6BA0003C045 /* Flutter Assemble */, 219 | ); 220 | }; 221 | /* End PBXProject section */ 222 | 223 | /* Begin PBXResourcesBuildPhase section */ 224 | 33CC10EB2044A3C60003C045 /* Resources */ = { 225 | isa = PBXResourcesBuildPhase; 226 | buildActionMask = 2147483647; 227 | files = ( 228 | 33CC10F32044A3C60003C045 /* Assets.xcassets in Resources */, 229 | 33CC10F62044A3C60003C045 /* MainMenu.xib in Resources */, 230 | ); 231 | runOnlyForDeploymentPostprocessing = 0; 232 | }; 233 | /* End PBXResourcesBuildPhase section */ 234 | 235 | /* Begin PBXShellScriptBuildPhase section */ 236 | 3399D490228B24CF009A79C7 /* ShellScript */ = { 237 | isa = PBXShellScriptBuildPhase; 238 | buildActionMask = 2147483647; 239 | files = ( 240 | ); 241 | inputFileListPaths = ( 242 | ); 243 | inputPaths = ( 244 | ); 245 | outputFileListPaths = ( 246 | ); 247 | outputPaths = ( 248 | ); 249 | runOnlyForDeploymentPostprocessing = 0; 250 | shellPath = /bin/sh; 251 | shellScript = "echo \"$PRODUCT_NAME.app\" > \"$PROJECT_DIR\"/Flutter/ephemeral/.app_filename && \"$FLUTTER_ROOT\"/packages/flutter_tools/bin/macos_assemble.sh embed\n"; 252 | }; 253 | 33CC111E2044C6BF0003C045 /* ShellScript */ = { 254 | isa = PBXShellScriptBuildPhase; 255 | buildActionMask = 2147483647; 256 | files = ( 257 | ); 258 | inputFileListPaths = ( 259 | Flutter/ephemeral/FlutterInputs.xcfilelist, 260 | ); 261 | inputPaths = ( 262 | Flutter/ephemeral/tripwire, 263 | ); 264 | outputFileListPaths = ( 265 | Flutter/ephemeral/FlutterOutputs.xcfilelist, 266 | ); 267 | outputPaths = ( 268 | ); 269 | runOnlyForDeploymentPostprocessing = 0; 270 | shellPath = /bin/sh; 271 | shellScript = "\"$FLUTTER_ROOT\"/packages/flutter_tools/bin/macos_assemble.sh && touch Flutter/ephemeral/tripwire"; 272 | }; 273 | /* End PBXShellScriptBuildPhase section */ 274 | 275 | /* Begin PBXSourcesBuildPhase section */ 276 | 33CC10E92044A3C60003C045 /* Sources */ = { 277 | isa = PBXSourcesBuildPhase; 278 | buildActionMask = 2147483647; 279 | files = ( 280 | 33CC11132044BFA00003C045 /* MainFlutterWindow.swift in Sources */, 281 | 33CC10F12044A3C60003C045 /* AppDelegate.swift in Sources */, 282 | 335BBD1B22A9A15E00E9071D /* GeneratedPluginRegistrant.swift in Sources */, 283 | ); 284 | runOnlyForDeploymentPostprocessing = 0; 285 | }; 286 | /* End PBXSourcesBuildPhase section */ 287 | 288 | /* Begin PBXTargetDependency section */ 289 | 33CC11202044C79F0003C045 /* PBXTargetDependency */ = { 290 | isa = PBXTargetDependency; 291 | target = 33CC111A2044C6BA0003C045 /* Flutter Assemble */; 292 | targetProxy = 33CC111F2044C79F0003C045 /* PBXContainerItemProxy */; 293 | }; 294 | /* End PBXTargetDependency section */ 295 | 296 | /* Begin PBXVariantGroup section */ 297 | 33CC10F42044A3C60003C045 /* MainMenu.xib */ = { 298 | isa = PBXVariantGroup; 299 | children = ( 300 | 33CC10F52044A3C60003C045 /* Base */, 301 | ); 302 | name = MainMenu.xib; 303 | path = Runner; 304 | sourceTree = ""; 305 | }; 306 | /* End PBXVariantGroup section */ 307 | 308 | /* Begin XCBuildConfiguration section */ 309 | 338D0CE9231458BD00FA5F75 /* Profile */ = { 310 | isa = XCBuildConfiguration; 311 | baseConfigurationReference = 7AFA3C8E1D35360C0083082E /* Release.xcconfig */; 312 | buildSettings = { 313 | ALWAYS_SEARCH_USER_PATHS = NO; 314 | CLANG_ANALYZER_NONNULL = YES; 315 | CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; 316 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++14"; 317 | CLANG_CXX_LIBRARY = "libc++"; 318 | CLANG_ENABLE_MODULES = YES; 319 | CLANG_ENABLE_OBJC_ARC = YES; 320 | CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; 321 | CLANG_WARN_BOOL_CONVERSION = YES; 322 | CLANG_WARN_CONSTANT_CONVERSION = YES; 323 | CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; 324 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 325 | CLANG_WARN_DOCUMENTATION_COMMENTS = YES; 326 | CLANG_WARN_EMPTY_BODY = YES; 327 | CLANG_WARN_ENUM_CONVERSION = YES; 328 | CLANG_WARN_INFINITE_RECURSION = YES; 329 | CLANG_WARN_INT_CONVERSION = YES; 330 | CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; 331 | CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; 332 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 333 | CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; 334 | CLANG_WARN_SUSPICIOUS_MOVE = YES; 335 | CODE_SIGN_IDENTITY = "-"; 336 | COPY_PHASE_STRIP = NO; 337 | DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; 338 | ENABLE_NS_ASSERTIONS = NO; 339 | ENABLE_STRICT_OBJC_MSGSEND = YES; 340 | GCC_C_LANGUAGE_STANDARD = gnu11; 341 | GCC_NO_COMMON_BLOCKS = YES; 342 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 343 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 344 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 345 | GCC_WARN_UNUSED_FUNCTION = YES; 346 | GCC_WARN_UNUSED_VARIABLE = YES; 347 | MACOSX_DEPLOYMENT_TARGET = 10.11; 348 | MTL_ENABLE_DEBUG_INFO = NO; 349 | SDKROOT = macosx; 350 | SWIFT_COMPILATION_MODE = wholemodule; 351 | SWIFT_OPTIMIZATION_LEVEL = "-O"; 352 | }; 353 | name = Profile; 354 | }; 355 | 338D0CEA231458BD00FA5F75 /* Profile */ = { 356 | isa = XCBuildConfiguration; 357 | baseConfigurationReference = 33E5194F232828860026EE4D /* AppInfo.xcconfig */; 358 | buildSettings = { 359 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; 360 | CLANG_ENABLE_MODULES = YES; 361 | CODE_SIGN_ENTITLEMENTS = Runner/DebugProfile.entitlements; 362 | CODE_SIGN_STYLE = Automatic; 363 | COMBINE_HIDPI_IMAGES = YES; 364 | INFOPLIST_FILE = Runner/Info.plist; 365 | LD_RUNPATH_SEARCH_PATHS = ( 366 | "$(inherited)", 367 | "@executable_path/../Frameworks", 368 | ); 369 | PROVISIONING_PROFILE_SPECIFIER = ""; 370 | SWIFT_VERSION = 5.0; 371 | }; 372 | name = Profile; 373 | }; 374 | 338D0CEB231458BD00FA5F75 /* Profile */ = { 375 | isa = XCBuildConfiguration; 376 | buildSettings = { 377 | CODE_SIGN_STYLE = Manual; 378 | PRODUCT_NAME = "$(TARGET_NAME)"; 379 | }; 380 | name = Profile; 381 | }; 382 | 33CC10F92044A3C60003C045 /* Debug */ = { 383 | isa = XCBuildConfiguration; 384 | baseConfigurationReference = 9740EEB21CF90195004384FC /* Debug.xcconfig */; 385 | buildSettings = { 386 | ALWAYS_SEARCH_USER_PATHS = NO; 387 | CLANG_ANALYZER_NONNULL = YES; 388 | CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; 389 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++14"; 390 | CLANG_CXX_LIBRARY = "libc++"; 391 | CLANG_ENABLE_MODULES = YES; 392 | CLANG_ENABLE_OBJC_ARC = YES; 393 | CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; 394 | CLANG_WARN_BOOL_CONVERSION = YES; 395 | CLANG_WARN_CONSTANT_CONVERSION = YES; 396 | CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; 397 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 398 | CLANG_WARN_DOCUMENTATION_COMMENTS = YES; 399 | CLANG_WARN_EMPTY_BODY = YES; 400 | CLANG_WARN_ENUM_CONVERSION = YES; 401 | CLANG_WARN_INFINITE_RECURSION = YES; 402 | CLANG_WARN_INT_CONVERSION = YES; 403 | CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; 404 | CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; 405 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 406 | CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; 407 | CLANG_WARN_SUSPICIOUS_MOVE = YES; 408 | CODE_SIGN_IDENTITY = "-"; 409 | COPY_PHASE_STRIP = NO; 410 | DEBUG_INFORMATION_FORMAT = dwarf; 411 | ENABLE_STRICT_OBJC_MSGSEND = YES; 412 | ENABLE_TESTABILITY = YES; 413 | GCC_C_LANGUAGE_STANDARD = gnu11; 414 | GCC_DYNAMIC_NO_PIC = NO; 415 | GCC_NO_COMMON_BLOCKS = YES; 416 | GCC_OPTIMIZATION_LEVEL = 0; 417 | GCC_PREPROCESSOR_DEFINITIONS = ( 418 | "DEBUG=1", 419 | "$(inherited)", 420 | ); 421 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 422 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 423 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 424 | GCC_WARN_UNUSED_FUNCTION = YES; 425 | GCC_WARN_UNUSED_VARIABLE = YES; 426 | MACOSX_DEPLOYMENT_TARGET = 10.11; 427 | MTL_ENABLE_DEBUG_INFO = YES; 428 | ONLY_ACTIVE_ARCH = YES; 429 | SDKROOT = macosx; 430 | SWIFT_ACTIVE_COMPILATION_CONDITIONS = DEBUG; 431 | SWIFT_OPTIMIZATION_LEVEL = "-Onone"; 432 | }; 433 | name = Debug; 434 | }; 435 | 33CC10FA2044A3C60003C045 /* Release */ = { 436 | isa = XCBuildConfiguration; 437 | baseConfigurationReference = 7AFA3C8E1D35360C0083082E /* Release.xcconfig */; 438 | buildSettings = { 439 | ALWAYS_SEARCH_USER_PATHS = NO; 440 | CLANG_ANALYZER_NONNULL = YES; 441 | CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; 442 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++14"; 443 | CLANG_CXX_LIBRARY = "libc++"; 444 | CLANG_ENABLE_MODULES = YES; 445 | CLANG_ENABLE_OBJC_ARC = YES; 446 | CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; 447 | CLANG_WARN_BOOL_CONVERSION = YES; 448 | CLANG_WARN_CONSTANT_CONVERSION = YES; 449 | CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; 450 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 451 | CLANG_WARN_DOCUMENTATION_COMMENTS = YES; 452 | CLANG_WARN_EMPTY_BODY = YES; 453 | CLANG_WARN_ENUM_CONVERSION = YES; 454 | CLANG_WARN_INFINITE_RECURSION = YES; 455 | CLANG_WARN_INT_CONVERSION = YES; 456 | CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; 457 | CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; 458 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 459 | CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; 460 | CLANG_WARN_SUSPICIOUS_MOVE = YES; 461 | CODE_SIGN_IDENTITY = "-"; 462 | COPY_PHASE_STRIP = NO; 463 | DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; 464 | ENABLE_NS_ASSERTIONS = NO; 465 | ENABLE_STRICT_OBJC_MSGSEND = YES; 466 | GCC_C_LANGUAGE_STANDARD = gnu11; 467 | GCC_NO_COMMON_BLOCKS = YES; 468 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 469 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 470 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 471 | GCC_WARN_UNUSED_FUNCTION = YES; 472 | GCC_WARN_UNUSED_VARIABLE = YES; 473 | MACOSX_DEPLOYMENT_TARGET = 10.11; 474 | MTL_ENABLE_DEBUG_INFO = NO; 475 | SDKROOT = macosx; 476 | SWIFT_COMPILATION_MODE = wholemodule; 477 | SWIFT_OPTIMIZATION_LEVEL = "-O"; 478 | }; 479 | name = Release; 480 | }; 481 | 33CC10FC2044A3C60003C045 /* Debug */ = { 482 | isa = XCBuildConfiguration; 483 | baseConfigurationReference = 33E5194F232828860026EE4D /* AppInfo.xcconfig */; 484 | buildSettings = { 485 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; 486 | CLANG_ENABLE_MODULES = YES; 487 | CODE_SIGN_ENTITLEMENTS = Runner/DebugProfile.entitlements; 488 | CODE_SIGN_STYLE = Automatic; 489 | COMBINE_HIDPI_IMAGES = YES; 490 | INFOPLIST_FILE = Runner/Info.plist; 491 | LD_RUNPATH_SEARCH_PATHS = ( 492 | "$(inherited)", 493 | "@executable_path/../Frameworks", 494 | ); 495 | PROVISIONING_PROFILE_SPECIFIER = ""; 496 | SWIFT_OPTIMIZATION_LEVEL = "-Onone"; 497 | SWIFT_VERSION = 5.0; 498 | }; 499 | name = Debug; 500 | }; 501 | 33CC10FD2044A3C60003C045 /* Release */ = { 502 | isa = XCBuildConfiguration; 503 | baseConfigurationReference = 33E5194F232828860026EE4D /* AppInfo.xcconfig */; 504 | buildSettings = { 505 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; 506 | CLANG_ENABLE_MODULES = YES; 507 | CODE_SIGN_ENTITLEMENTS = Runner/Release.entitlements; 508 | CODE_SIGN_STYLE = Automatic; 509 | COMBINE_HIDPI_IMAGES = YES; 510 | INFOPLIST_FILE = Runner/Info.plist; 511 | LD_RUNPATH_SEARCH_PATHS = ( 512 | "$(inherited)", 513 | "@executable_path/../Frameworks", 514 | ); 515 | PROVISIONING_PROFILE_SPECIFIER = ""; 516 | SWIFT_VERSION = 5.0; 517 | }; 518 | name = Release; 519 | }; 520 | 33CC111C2044C6BA0003C045 /* Debug */ = { 521 | isa = XCBuildConfiguration; 522 | buildSettings = { 523 | CODE_SIGN_STYLE = Manual; 524 | PRODUCT_NAME = "$(TARGET_NAME)"; 525 | }; 526 | name = Debug; 527 | }; 528 | 33CC111D2044C6BA0003C045 /* Release */ = { 529 | isa = XCBuildConfiguration; 530 | buildSettings = { 531 | CODE_SIGN_STYLE = Automatic; 532 | PRODUCT_NAME = "$(TARGET_NAME)"; 533 | }; 534 | name = Release; 535 | }; 536 | /* End XCBuildConfiguration section */ 537 | 538 | /* Begin XCConfigurationList section */ 539 | 33CC10E82044A3C60003C045 /* Build configuration list for PBXProject "Runner" */ = { 540 | isa = XCConfigurationList; 541 | buildConfigurations = ( 542 | 33CC10F92044A3C60003C045 /* Debug */, 543 | 33CC10FA2044A3C60003C045 /* Release */, 544 | 338D0CE9231458BD00FA5F75 /* Profile */, 545 | ); 546 | defaultConfigurationIsVisible = 0; 547 | defaultConfigurationName = Release; 548 | }; 549 | 33CC10FB2044A3C60003C045 /* Build configuration list for PBXNativeTarget "Runner" */ = { 550 | isa = XCConfigurationList; 551 | buildConfigurations = ( 552 | 33CC10FC2044A3C60003C045 /* Debug */, 553 | 33CC10FD2044A3C60003C045 /* Release */, 554 | 338D0CEA231458BD00FA5F75 /* Profile */, 555 | ); 556 | defaultConfigurationIsVisible = 0; 557 | defaultConfigurationName = Release; 558 | }; 559 | 33CC111B2044C6BA0003C045 /* Build configuration list for PBXAggregateTarget "Flutter Assemble" */ = { 560 | isa = XCConfigurationList; 561 | buildConfigurations = ( 562 | 33CC111C2044C6BA0003C045 /* Debug */, 563 | 33CC111D2044C6BA0003C045 /* Release */, 564 | 338D0CEB231458BD00FA5F75 /* Profile */, 565 | ); 566 | defaultConfigurationIsVisible = 0; 567 | defaultConfigurationName = Release; 568 | }; 569 | /* End XCConfigurationList section */ 570 | }; 571 | rootObject = 33CC10E52044A3C60003C045 /* Project object */; 572 | } 573 | -------------------------------------------------------------------------------- /example/macos/Runner.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | IDEDidComputeMac32BitWarning 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /example/macos/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme: -------------------------------------------------------------------------------- 1 | 2 | 5 | 8 | 9 | 15 | 21 | 22 | 23 | 24 | 25 | 30 | 31 | 37 | 38 | 39 | 40 | 41 | 42 | 52 | 54 | 60 | 61 | 62 | 63 | 69 | 71 | 77 | 78 | 79 | 80 | 82 | 83 | 86 | 87 | 88 | -------------------------------------------------------------------------------- /example/macos/Runner.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /example/macos/Runner.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | IDEDidComputeMac32BitWarning 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /example/macos/Runner/AppDelegate.swift: -------------------------------------------------------------------------------- 1 | import Cocoa 2 | import FlutterMacOS 3 | 4 | @NSApplicationMain 5 | class AppDelegate: FlutterAppDelegate { 6 | override func applicationShouldTerminateAfterLastWindowClosed(_ sender: NSApplication) -> Bool { 7 | return true 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /example/macos/Runner/Assets.xcassets/AppIcon.appiconset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images": [ 3 | { 4 | "size": "16x16", 5 | "idiom": "mac", 6 | "filename": "app_icon_16.png", 7 | "scale": "1x" 8 | }, 9 | { 10 | "size": "16x16", 11 | "idiom": "mac", 12 | "filename": "app_icon_32.png", 13 | "scale": "2x" 14 | }, 15 | { 16 | "size": "32x32", 17 | "idiom": "mac", 18 | "filename": "app_icon_32.png", 19 | "scale": "1x" 20 | }, 21 | { 22 | "size": "32x32", 23 | "idiom": "mac", 24 | "filename": "app_icon_64.png", 25 | "scale": "2x" 26 | }, 27 | { 28 | "size": "128x128", 29 | "idiom": "mac", 30 | "filename": "app_icon_128.png", 31 | "scale": "1x" 32 | }, 33 | { 34 | "size": "128x128", 35 | "idiom": "mac", 36 | "filename": "app_icon_256.png", 37 | "scale": "2x" 38 | }, 39 | { 40 | "size": "256x256", 41 | "idiom": "mac", 42 | "filename": "app_icon_256.png", 43 | "scale": "1x" 44 | }, 45 | { 46 | "size": "256x256", 47 | "idiom": "mac", 48 | "filename": "app_icon_512.png", 49 | "scale": "2x" 50 | }, 51 | { 52 | "size": "512x512", 53 | "idiom": "mac", 54 | "filename": "app_icon_512.png", 55 | "scale": "1x" 56 | }, 57 | { 58 | "size": "512x512", 59 | "idiom": "mac", 60 | "filename": "app_icon_1024.png", 61 | "scale": "2x" 62 | } 63 | ], 64 | "info": { 65 | "version": 1, 66 | "author": "xcode" 67 | } 68 | } 69 | -------------------------------------------------------------------------------- /example/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_1024.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/GAM3RG33K/flutter_settings_screens/18f937739d7fb4c7ceb0d8b9877f20f0b5e9e6d8/example/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_1024.png -------------------------------------------------------------------------------- /example/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_128.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/GAM3RG33K/flutter_settings_screens/18f937739d7fb4c7ceb0d8b9877f20f0b5e9e6d8/example/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_128.png -------------------------------------------------------------------------------- /example/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_16.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/GAM3RG33K/flutter_settings_screens/18f937739d7fb4c7ceb0d8b9877f20f0b5e9e6d8/example/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_16.png -------------------------------------------------------------------------------- /example/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_256.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/GAM3RG33K/flutter_settings_screens/18f937739d7fb4c7ceb0d8b9877f20f0b5e9e6d8/example/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_256.png -------------------------------------------------------------------------------- /example/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_32.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/GAM3RG33K/flutter_settings_screens/18f937739d7fb4c7ceb0d8b9877f20f0b5e9e6d8/example/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_32.png -------------------------------------------------------------------------------- /example/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_512.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/GAM3RG33K/flutter_settings_screens/18f937739d7fb4c7ceb0d8b9877f20f0b5e9e6d8/example/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_512.png -------------------------------------------------------------------------------- /example/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_64.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/GAM3RG33K/flutter_settings_screens/18f937739d7fb4c7ceb0d8b9877f20f0b5e9e6d8/example/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_64.png -------------------------------------------------------------------------------- /example/macos/Runner/Configs/AppInfo.xcconfig: -------------------------------------------------------------------------------- 1 | // Application-level settings for the Runner target. 2 | // 3 | // This may be replaced with something auto-generated from metadata (e.g., pubspec.yaml) in the 4 | // future. If not, the values below would default to using the project name when this becomes a 5 | // 'flutter create' template. 6 | 7 | // The application's name. By default this is also the title of the Flutter window. 8 | PRODUCT_NAME = example 9 | 10 | // The application's bundle identifier 11 | PRODUCT_BUNDLE_IDENTIFIER = com.example.example 12 | 13 | // The copyright displayed in application information 14 | PRODUCT_COPYRIGHT = Copyright © 2022 com.example. All rights reserved. 15 | -------------------------------------------------------------------------------- /example/macos/Runner/Configs/Debug.xcconfig: -------------------------------------------------------------------------------- 1 | #include "../../Flutter/Flutter-Debug.xcconfig" 2 | #include "Warnings.xcconfig" 3 | -------------------------------------------------------------------------------- /example/macos/Runner/Configs/Release.xcconfig: -------------------------------------------------------------------------------- 1 | #include "../../Flutter/Flutter-Release.xcconfig" 2 | #include "Warnings.xcconfig" 3 | -------------------------------------------------------------------------------- /example/macos/Runner/Configs/Warnings.xcconfig: -------------------------------------------------------------------------------- 1 | WARNING_CFLAGS = -Wall -Wconditional-uninitialized -Wnullable-to-nonnull-conversion -Wmissing-method-return-type -Woverlength-strings 2 | GCC_WARN_UNDECLARED_SELECTOR = YES 3 | CLANG_UNDEFINED_BEHAVIOR_SANITIZER_NULLABILITY = YES 4 | CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE 5 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES 6 | CLANG_WARN_PRAGMA_PACK = YES 7 | CLANG_WARN_STRICT_PROTOTYPES = YES 8 | CLANG_WARN_COMMA = YES 9 | GCC_WARN_STRICT_SELECTOR_MATCH = YES 10 | CLANG_WARN_OBJC_REPEATED_USE_OF_WEAK = YES 11 | CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES 12 | GCC_WARN_SHADOW = YES 13 | CLANG_WARN_UNREACHABLE_CODE = YES 14 | -------------------------------------------------------------------------------- /example/macos/Runner/DebugProfile.entitlements: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | com.apple.security.app-sandbox 6 | 7 | com.apple.security.cs.allow-jit 8 | 9 | com.apple.security.network.server 10 | 11 | 12 | 13 | -------------------------------------------------------------------------------- /example/macos/Runner/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | $(DEVELOPMENT_LANGUAGE) 7 | CFBundleExecutable 8 | $(EXECUTABLE_NAME) 9 | CFBundleIconFile 10 | 11 | CFBundleIdentifier 12 | $(PRODUCT_BUNDLE_IDENTIFIER) 13 | CFBundleInfoDictionaryVersion 14 | 6.0 15 | CFBundleName 16 | $(PRODUCT_NAME) 17 | CFBundlePackageType 18 | APPL 19 | CFBundleShortVersionString 20 | $(FLUTTER_BUILD_NAME) 21 | CFBundleVersion 22 | $(FLUTTER_BUILD_NUMBER) 23 | LSMinimumSystemVersion 24 | $(MACOSX_DEPLOYMENT_TARGET) 25 | NSHumanReadableCopyright 26 | $(PRODUCT_COPYRIGHT) 27 | NSMainNibFile 28 | MainMenu 29 | NSPrincipalClass 30 | NSApplication 31 | 32 | 33 | -------------------------------------------------------------------------------- /example/macos/Runner/MainFlutterWindow.swift: -------------------------------------------------------------------------------- 1 | import Cocoa 2 | import FlutterMacOS 3 | 4 | class MainFlutterWindow: NSWindow { 5 | override func awakeFromNib() { 6 | let flutterViewController = FlutterViewController.init() 7 | let windowFrame = self.frame 8 | self.contentViewController = flutterViewController 9 | self.setFrame(windowFrame, display: true) 10 | 11 | RegisterGeneratedPlugins(registry: flutterViewController) 12 | 13 | super.awakeFromNib() 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /example/macos/Runner/Release.entitlements: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | com.apple.security.app-sandbox 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /example/pubspec.yaml: -------------------------------------------------------------------------------- 1 | name: flutter_settings_screens_example 2 | description: Demonstrates flutter_settings_screens plugin features. 3 | publish_to: 'none' 4 | 5 | environment: 6 | sdk: '>=3.2.4 <4.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 | 16 | #library to store the preference/settings using hive library 17 | hive_flutter: ^1.0.0 18 | 19 | dev_dependencies: 20 | flutter_test: 21 | sdk: flutter 22 | 23 | flutter_settings_screens: 24 | path: ../ 25 | 26 | # For information on the generic Dart part of this file, see the 27 | # following page: https://dart.dev/tools/pub/pubspec 28 | 29 | # The following section is specific to Flutter. 30 | flutter: 31 | 32 | # The following line ensures that the Material Icons font is 33 | # included with your application, so that you can use the icons in 34 | # the material Icons class. 35 | uses-material-design: true 36 | 37 | # To add assets to your application, add an assets section, like this: 38 | # assets: 39 | # - images/a_dot_burr.jpeg 40 | # - images/a_dot_ham.jpeg 41 | 42 | # An image asset can refer to one or more resolution-specific "variants", see 43 | # https://flutter.dev/assets-and-images/#resolution-aware. 44 | 45 | # For details regarding adding assets from package dependencies, see 46 | # https://flutter.dev/assets-and-images/#from-packages 47 | 48 | # To add custom fonts to your application, add a fonts section here, 49 | # in this "flutter" section. Each entry in this list should have a 50 | # "family" key with the font family name, and a "fonts" key with a 51 | # list giving the asset and other descriptors for the font. For 52 | # example: 53 | # fonts: 54 | # - family: Schyler 55 | # fonts: 56 | # - asset: fonts/Schyler-Regular.ttf 57 | # - asset: fonts/Schyler-Italic.ttf 58 | # style: italic 59 | # - family: Trajan Pro 60 | # fonts: 61 | # - asset: fonts/TrajanPro.ttf 62 | # - asset: fonts/TrajanPro_Bold.ttf 63 | # weight: 700 64 | # 65 | # For details regarding fonts from package dependencies, 66 | # see https://flutter.dev/custom-fonts/#from-packages 67 | -------------------------------------------------------------------------------- /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_settings_screens_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 | -------------------------------------------------------------------------------- /example/web/favicon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/GAM3RG33K/flutter_settings_screens/18f937739d7fb4c7ceb0d8b9877f20f0b5e9e6d8/example/web/favicon.png -------------------------------------------------------------------------------- /example/web/icons/Icon-192.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/GAM3RG33K/flutter_settings_screens/18f937739d7fb4c7ceb0d8b9877f20f0b5e9e6d8/example/web/icons/Icon-192.png -------------------------------------------------------------------------------- /example/web/icons/Icon-512.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/GAM3RG33K/flutter_settings_screens/18f937739d7fb4c7ceb0d8b9877f20f0b5e9e6d8/example/web/icons/Icon-512.png -------------------------------------------------------------------------------- /example/web/icons/Icon-maskable-192.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/GAM3RG33K/flutter_settings_screens/18f937739d7fb4c7ceb0d8b9877f20f0b5e9e6d8/example/web/icons/Icon-maskable-192.png -------------------------------------------------------------------------------- /example/web/icons/Icon-maskable-512.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/GAM3RG33K/flutter_settings_screens/18f937739d7fb4c7ceb0d8b9877f20f0b5e9e6d8/example/web/icons/Icon-maskable-512.png -------------------------------------------------------------------------------- /example/web/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | example 33 | 34 | 35 | 36 | 39 | 106 | 107 | 108 | -------------------------------------------------------------------------------- /example/web/manifest.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "example", 3 | "short_name": "example", 4 | "start_url": ".", 5 | "display": "standalone", 6 | "background_color": "#0175C2", 7 | "theme_color": "#0175C2", 8 | "description": "A new Flutter project.", 9 | "orientation": "portrait-primary", 10 | "prefer_related_applications": false, 11 | "icons": [ 12 | { 13 | "src": "icons/Icon-192.png", 14 | "sizes": "192x192", 15 | "type": "image/png" 16 | }, 17 | { 18 | "src": "icons/Icon-512.png", 19 | "sizes": "512x512", 20 | "type": "image/png" 21 | }, 22 | { 23 | "src": "icons/Icon-maskable-192.png", 24 | "sizes": "192x192", 25 | "type": "image/png", 26 | "purpose": "maskable" 27 | }, 28 | { 29 | "src": "icons/Icon-maskable-512.png", 30 | "sizes": "512x512", 31 | "type": "image/png", 32 | "purpose": "maskable" 33 | } 34 | ] 35 | } 36 | -------------------------------------------------------------------------------- /lib/flutter_settings_screens.dart: -------------------------------------------------------------------------------- 1 | /// Settings Screen with Custom Storage Interface 2 | /// 3 | /// Author: Harshvardhan Joshi 4 | /// 5 | /// Based on the plugin by Barnabás BARTHA : 6 | /// https://github.com/BarthaBRW/shared_preferences_settings 7 | library flutter_settings_screens; 8 | 9 | export 'src/cache/cache.dart'; 10 | export 'src/settings.dart'; 11 | export 'src/utils/utils.dart'; 12 | export 'src/widgets/settings_widgets.dart'; 13 | -------------------------------------------------------------------------------- /lib/src/cache/cache.dart: -------------------------------------------------------------------------------- 1 | export 'cache_provider.dart'; 2 | export 'cache_provider_impl.dart'; 3 | -------------------------------------------------------------------------------- /lib/src/cache/cache_provider.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter_settings_screens/flutter_settings_screens.dart'; 2 | 3 | /// This is an abstract class to provide access of storage/preferences platform 4 | /// from the developer's existing app to this settings screen 5 | /// 6 | /// For example: 7 | /// the developer can choose to provide the existing preference platform 8 | /// access by providing the implementation for this class. 9 | /// 10 | /// if the developer is using the `shared_preferences` library, then the implementation 11 | /// of one of the methods would look like this: 12 | /// ``` dart 13 | /// // SharedPreferences _preferences = await SharedPreferences.getInstance(); 14 | /// 15 | /// String? getString(String key, {String? defaultValue}) { 16 | /// return _preferences.getString(key) ?? defaultValue; 17 | /// } 18 | /// 19 | /// Future setBool(String key, bool? value) async { 20 | /// await _preferences.setBool(key, value); 21 | /// } 22 | /// ``` 23 | /// 24 | /// and if the developer is using the Hive library or storing preferences/data 25 | /// then the implementation would look like this: 26 | /// 27 | /// ```dart 28 | /// //Box _preferences = await Hive.openBox(keyName); 29 | /// String? getString(String key, {String? defaultValue}) { 30 | /// return _preferences.get(key) ?? defaultValue; 31 | /// } 32 | /// 33 | /// Future setBool(String key, bool? value) async { 34 | /// await _preferences.put(key, value); 35 | /// } 36 | /// ``` 37 | /// 38 | /// Similarly, if the developer is using any other type of library for this purpose, 39 | /// just providing the implementation using that library will be sufficient for 40 | /// using the settings screen 41 | /// 42 | /// 43 | /// For more details on how to properly implement this class, Check out the 44 | /// `cache_provider.dart` file in the example code of this library along with 45 | /// the existing [SharePreferenceCache] implementation. 46 | /// 47 | abstract class CacheProvider { 48 | CacheProvider(); 49 | 50 | /// Method to perform initializations regarding the underlying storage systems 51 | /// ex. Creating instance of the SharedPreferences or Hive boxes 52 | /// 53 | /// This method must be called one the cache provider implementation to ensure 54 | /// smooth operation. 55 | Future init(); 56 | 57 | /// Method to get Int value from the storage, if the retrieved value is null 58 | /// then [defaultValue] should be used, if provided. 59 | /// 60 | /// 61 | /// Example code(SharedPreferences Implementation): 62 | /// /// ```dart 63 | /// int? getInt(String key, {int? defaultValue}) { 64 | /// return _preferences.getInt(key) ?? defaultValue; 65 | /// } 66 | /// ``` 67 | /// 68 | /// The [defaultValue] is an optional & nullable value, you may choose not to provide it 69 | /// in which case the null value will be returned as result. 70 | /// 71 | /// Output can be represented like this: 72 | /// getterOutput -if-absent-> defaultValue -if-absent-> null 73 | /// 74 | /// here [getterOutput] is the expected output of the getter method called. 75 | /// The method must be implementation of one of the definitions from the cache provider 76 | /// 77 | int? getInt(String key, {int? defaultValue}); 78 | 79 | /// Method to get String value from the storage, if the retrieved value is null 80 | /// then [defaultValue] should be used, if provided. 81 | /// 82 | /// 83 | /// Example code(SharedPreferences Implementation): 84 | /// /// ```dart 85 | /// String? getString(String key, {String? defaultValue}) { 86 | /// return _preferences.getString(key) ?? defaultValue; 87 | /// } 88 | /// ``` 89 | /// 90 | /// The [defaultValue] is an optional & nullable value, you may choose not to provide it 91 | /// in which case the null value will be returned as result. 92 | /// 93 | /// Output can be represented like this: 94 | /// getterOutput -if-absent-> defaultValue -if-absent-> null 95 | /// 96 | /// here [getterOutput] is the expected output of the getter method called. 97 | /// The method must be implementation of one of the definitions from the cache provider 98 | /// 99 | String? getString(String key, {String? defaultValue}); 100 | 101 | /// Method to get double value from the storage, if the retrieved value is null 102 | /// then [defaultValue] should be used, if provided. 103 | /// 104 | /// 105 | /// Example code(SharedPreferences Implementation): 106 | /// /// ```dart 107 | /// double? getDouble(String key, {double? defaultValue}) { 108 | /// return _preferences.getDouble(key) ?? defaultValue; 109 | /// } 110 | /// ``` 111 | /// 112 | /// The [defaultValue] is an optional & nullable value, you may choose not to provide it 113 | /// in which case the null value will be returned as result. 114 | /// 115 | /// Output can be represented like this: 116 | /// getterOutput -if-absent-> defaultValue -if-absent-> null 117 | /// 118 | /// here [getterOutput] is the expected output of the getter method called. 119 | /// The method must be implementation of one of the definitions from the cache provider 120 | /// 121 | double? getDouble(String key, {double? defaultValue}); 122 | 123 | /// Method to get boolean value from the storage, if the retrieved value is null 124 | /// then [defaultValue] should be used, if provided. 125 | /// 126 | /// 127 | /// Example code(SharedPreferences Implementation): 128 | /// /// ```dart 129 | /// double? getBool(String key, {bool? defaultValue}) { 130 | /// return _preferences.getBool(key) ?? defaultValue; 131 | /// } 132 | /// ``` 133 | /// 134 | /// The [defaultValue] is an optional & nullable value, you may choose not to provide it 135 | /// in which case the null value will be returned as result. 136 | /// 137 | /// Output can be represented like this: 138 | /// getterOutput -if-absent-> defaultValue -if-absent-> null 139 | /// 140 | /// here [getterOutput] is the expected output of the getter method called. 141 | /// The method must be implementation of one of the definitions from the cache provider 142 | /// 143 | bool? getBool(String key, {bool? defaultValue}); 144 | 145 | /// Method to set int value to the storage, value can be null according 146 | /// to the support by underlying storage system. 147 | /// 148 | /// 149 | /// Example code(SharedPreferences Implementation): 150 | /// /// ```dart 151 | /// Future getInt(String key, int? value) async { 152 | /// await _preferences.setInt(key, value); 153 | /// } 154 | /// ``` 155 | /// 156 | Future setInt(String key, int? value); 157 | 158 | /// Method to set String value to the storage, value can be null according 159 | /// to the support by underlying storage system. 160 | /// 161 | /// 162 | /// Example code(SharedPreferences Implementation): 163 | /// /// ```dart 164 | /// Future setString(String key, String? value) async { 165 | /// await _preferences.setString(key, value); 166 | /// } 167 | /// ``` 168 | /// 169 | Future setString(String key, String? value); 170 | 171 | /// Method to set Double value to the storage, value can be null according 172 | /// to the support by underlying storage system. 173 | /// 174 | /// 175 | /// Example code(SharedPreferences Implementation): 176 | /// /// ```dart 177 | /// Future setDouble(String key, double? value) async { 178 | /// await _preferences.setDouble(key, value); 179 | /// } 180 | /// ``` 181 | /// 182 | Future setDouble(String key, double? value); 183 | 184 | /// Method to set boolean value to the storage, value can be null according 185 | /// to the support by underlying storage system. 186 | /// 187 | /// 188 | /// Example code(SharedPreferences Implementation): 189 | /// /// ```dart 190 | /// Future setBool(String key, bool? value) async { 191 | /// await _preferences.setBool(key, value); 192 | /// } 193 | /// ``` 194 | /// 195 | Future setBool(String key, bool? value); 196 | 197 | /// This method is used to check if a specific [key] is available/stored 198 | /// in the underlying storage 199 | bool containsKey(String key); 200 | 201 | /// This method is used to get a set of available/stored keys 202 | /// in the underlying storage. 203 | /// 204 | /// This method makes easy to iterate over stored keys for various 205 | /// purposes. 206 | /// 207 | /// For example: finding a set of keys from all the available 208 | /// keys that matches a regular expression 209 | Set getKeys(); 210 | 211 | /// This method is used to remove provided [key] from the underlying storage system. 212 | /// 213 | /// For some storage systems, this call can be equivalent to setting null as 214 | /// value for the given [key] 215 | /// 216 | Future remove(String key); 217 | 218 | /// This method is used to remove all the available/stored keys from the 219 | /// underlying storage system. 220 | /// 221 | /// Implementing this method can utilize the [getKeys] method to iterate & remove 222 | /// or can use interface methods with same purpose provided by the underlying 223 | /// storage system 224 | Future removeAll(); 225 | 226 | /// Method to set custom object value to the storage, value can be null according 227 | /// to the support by underlying storage system. 228 | /// 229 | /// Example code(SharedPreferences Implementation): 230 | /// /// ```dart 231 | /// Future setObject(String key, T? value) async { 232 | /// if (T is int || value is int) { 233 | /// await _preferences?.setInt(key, value as int); 234 | /// } 235 | /// if (T is double || value is double) { 236 | /// await _preferences?.setDouble(key, value as double); 237 | /// } 238 | /// if (T is bool || value is bool) { 239 | /// await _preferences?.setBool(key, value as bool); 240 | /// } 241 | /// if (T is String || value is String) { 242 | /// await _preferences?.setString(key, value as String); 243 | /// } 244 | /// throw Exception('No Implementation Found'); 245 | /// } 246 | /// ``` 247 | /// 248 | Future setObject(String key, T? value); 249 | 250 | /// Method to get custom object value from the storage, if the retrieved value is null 251 | /// then [defaultValue] should be used, if provided. 252 | /// 253 | /// 254 | /// Example code(SharedPreferences Implementation): 255 | /// /// ```dart 256 | /// T? getValue(String key, {T? defaultValue}) { 257 | /// if (T is int || defaultValue is int) { 258 | /// return _preferences?.getInt(key) as T; 259 | /// } 260 | /// if (T is double || defaultValue is double) { 261 | /// return _preferences?.getDouble(key) as T; 262 | /// } 263 | /// if (T is bool || defaultValue is bool) { 264 | /// return _preferences?.getBool(key) as T; 265 | /// } 266 | /// if (T is String || defaultValue is String) { 267 | /// return _preferences?.getString(key) as T; 268 | /// } 269 | /// throw Exception('No Implementation Found'); 270 | /// } 271 | /// ``` 272 | /// 273 | /// T - Represents any valid class or primitive types supported by flutter 274 | /// 275 | /// The [defaultValue] is an optional & nullable value, you may choose not to provide it 276 | /// in which case the null value will be returned as result. 277 | /// 278 | /// Output can be represented like this: 279 | /// getterOutput -if-absent-> defaultValue -if-absent-> null 280 | /// 281 | /// here [getterOutput] is the expected output of the getter method called. 282 | /// The method must be implementation of one of the definitions from the cache provider 283 | /// 284 | T? getValue(String key, {T? defaultValue}); 285 | } 286 | -------------------------------------------------------------------------------- /lib/src/cache/cache_provider_impl.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/material.dart'; 2 | import 'package:shared_preferences/shared_preferences.dart'; 3 | 4 | import 'cache_provider.dart'; 5 | 6 | /// A cache access provider class for shared preferences using shared_preferences library. 7 | /// 8 | /// This cache provider implementation is used by default, if none is provided explicitly. 9 | class SharePreferenceCache extends CacheProvider { 10 | SharedPreferences? _preferences; 11 | 12 | @override 13 | Future init() async { 14 | WidgetsFlutterBinding.ensureInitialized(); 15 | _preferences = await SharedPreferences.getInstance(); 16 | } 17 | 18 | Set get keys => getKeys(); 19 | 20 | @override 21 | bool? getBool(String key, {bool? defaultValue}) { 22 | return _preferences?.getBool(key); 23 | } 24 | 25 | @override 26 | double? getDouble(String key, {double? defaultValue}) { 27 | return _preferences?.getDouble(key); 28 | } 29 | 30 | @override 31 | int? getInt(String key, {int? defaultValue}) { 32 | return _preferences?.getInt(key); 33 | } 34 | 35 | @override 36 | String? getString(String key, {String? defaultValue}) { 37 | return _preferences?.getString(key); 38 | } 39 | 40 | @override 41 | Future setBool(String key, bool? value) async { 42 | await _preferences?.setBool(key, value ?? false); 43 | } 44 | 45 | @override 46 | Future setDouble(String key, double? value) async { 47 | await _preferences?.setDouble(key, value!); 48 | } 49 | 50 | @override 51 | Future setInt(String key, int? value) async { 52 | await _preferences?.setInt(key, value!); 53 | } 54 | 55 | @override 56 | Future setString(String key, String? value) async { 57 | await _preferences?.setString(key, value!); 58 | } 59 | 60 | @override 61 | Future setObject(String key, T? value) async { 62 | if (T == int || value is int) { 63 | await _preferences?.setInt(key, value as int); 64 | } else if (T == double || value is double) { 65 | await _preferences?.setDouble(key, value as double); 66 | } else if (T == bool || value is bool) { 67 | await _preferences?.setBool(key, value as bool); 68 | } else if (T == String || value is String) { 69 | await _preferences?.setString(key, value as String); 70 | } else { 71 | throw Exception( 72 | "flutter_settings_screens doesn't handle values of type $T"); 73 | } 74 | } 75 | 76 | @override 77 | bool containsKey(String key) { 78 | return _preferences?.containsKey(key) ?? false; 79 | } 80 | 81 | @override 82 | Set getKeys() { 83 | return _preferences?.getKeys() ?? {}; 84 | } 85 | 86 | @override 87 | Future remove(String key) async { 88 | if (containsKey(key)) { 89 | await _preferences?.remove(key); 90 | } 91 | } 92 | 93 | @override 94 | Future removeAll() async { 95 | await _preferences?.clear(); 96 | } 97 | 98 | @override 99 | T? getValue(String key, {T? defaultValue}) { 100 | if (T == int || defaultValue is int) { 101 | return _preferences?.getInt(key) as T; 102 | } 103 | if (T == double || defaultValue is double) { 104 | return _preferences?.getDouble(key) as T; 105 | } 106 | if (T == bool || defaultValue is bool) { 107 | return _preferences?.getBool(key) as T; 108 | } 109 | if (T == String || defaultValue is String) { 110 | return _preferences?.getString(key) as T; 111 | } 112 | throw Exception( 113 | "flutter_settings_screens doesn't handle values of type $T"); 114 | } 115 | } 116 | -------------------------------------------------------------------------------- /lib/src/settings.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/material.dart'; 2 | 3 | import 'cache/cache.dart'; 4 | 5 | /// This function type is used for rebuilding any given child widgets 6 | /// 7 | /// All Settings Tile are given a [ValueChangeObserver] with a unique settings key. 8 | /// 9 | /// When the value associated with a settings key changes, [ValueChangeObserver] 10 | /// triggers a [InternalWidgetBuilder] function call. 11 | typedef InternalWidgetBuilder = Widget Function( 12 | BuildContext, T, ValueChanged); 13 | 14 | /// This function type is used for building a widget based on the value given to it. 15 | /// It is an alternate version of [WidgetBuilder]. 16 | typedef ItemBuilder = Widget Function(T); 17 | 18 | /// This function type is used for triggering the callback when value 19 | /// associated with a settings key changes. 20 | typedef OnChanged = void Function(T); 21 | 22 | /// This function type is used for verifying that the dialog/modal 23 | /// widget is to be closed or not. 24 | /// 25 | /// if true, the widget will be closed 26 | typedef OnConfirmedCallback = bool Function(); 27 | 28 | /// This class behaves as a bridge between the settings screen widgets and the 29 | /// underlying storage mechanism. 30 | /// 31 | /// To access the storage mechanism an instance of the [CacheProvider] implementation 32 | /// is required. 33 | /// 34 | /// Any Flutter App using this library must call `Settings.init(cacheProvider)` 35 | /// before showing the settings screen. 36 | /// 37 | /// 38 | class Settings { 39 | /// Private constructor 40 | Settings._internal(); 41 | 42 | /// Private instance of this class to keep it singleton 43 | static final Settings _instance = Settings._internal(); 44 | 45 | /// Public factory method to provide the 46 | factory Settings() { 47 | assert( 48 | _cacheProvider != null, 49 | 'Must call Settings.init(cacheProvider)' 50 | ' before using settings!'); 51 | return _instance; 52 | } 53 | 54 | /// Private instance of [CacheProvider] which will allow access to the 55 | /// underlying cache mechanism, which can be any of [SharedPreference],[Hive] 56 | /// or any other cache provider of choice 57 | static CacheProvider? _cacheProvider; 58 | 59 | /// This method will check and ensure that [_cacheProvider] 60 | /// value is set properly. 61 | static void ensureCacheProvider() { 62 | assert( 63 | isInitialized, 64 | 'Must call Settings.init(cacheProvider)' 65 | ' before using settings!'); 66 | } 67 | 68 | /// A getter to know if the settings are already initialized or not 69 | static bool get isInitialized => _cacheProvider != null; 70 | 71 | /// This method is used for initializing the [_cacheProvider] 72 | /// instance. 73 | /// 74 | /// This method must be called before the Settings screen is displayed. 75 | /// 76 | /// Cache provider is optional, default cache provider uses the 77 | /// shared preferences based cache provider implementation. 78 | static Future init({CacheProvider? cacheProvider}) async { 79 | cacheProvider ??= SharePreferenceCache(); 80 | 81 | _cacheProvider = cacheProvider; 82 | await _cacheProvider!.init(); 83 | } 84 | 85 | /// method to check if the cache provider contains given [key] or not. 86 | static bool? containsKey(String key) { 87 | ensureCacheProvider(); 88 | return _cacheProvider?.containsKey(key); 89 | } 90 | 91 | /// method to get a value using the [cacheProvider] for given [key] 92 | /// 93 | /// If there's no value found associated with the [key] then the [defaultValue] 94 | /// is returned. 95 | static T? getValue(String key, {T? defaultValue}) { 96 | ensureCacheProvider(); 97 | final containsKey = _cacheProvider?.containsKey(key); 98 | if (containsKey ?? false) { 99 | final prefValue = 100 | _cacheProvider?.getValue(key, defaultValue: defaultValue); 101 | return prefValue ?? defaultValue; 102 | } 103 | return defaultValue; 104 | } 105 | 106 | /// method to set [value] using the [cacheProvider] for given [key] 107 | static Future setValue( 108 | String key, 109 | T value, { 110 | bool notify = false, 111 | }) async { 112 | ensureCacheProvider(); 113 | if (value == null) { 114 | return _cacheProvider?.remove(key); 115 | } 116 | await _cacheProvider?.setObject(key, value); 117 | if (notify) { 118 | _notifyGlobally(key, value); 119 | } 120 | } 121 | 122 | /// method to clear all the cached data using the [cacheProvider] 123 | static void clearCache() { 124 | ensureCacheProvider(); 125 | _cacheProvider?.removeAll(); 126 | } 127 | } 128 | 129 | /// This class is a customized version of [ValueNotifier] 130 | /// which Takes a [key] and [value]. 131 | /// 132 | /// Value - Setting value which is associated to the [key] 133 | class ValueChangeNotifier extends ValueNotifier { 134 | /// A String which represents a setting (assumed to be unique) 135 | final String key; 136 | 137 | ValueChangeNotifier(this.key, value) : super(value); 138 | 139 | @override 140 | set value(T newValue) { 141 | Settings.setValue(key, newValue); 142 | super.value = newValue; 143 | _notifyGlobally(key, newValue); 144 | } 145 | 146 | @override 147 | void notifyListeners() { 148 | super.notifyListeners(); 149 | } 150 | 151 | @override 152 | String toString() { 153 | return '\n{VCN: \n\tkey: $key \n\tvalue: $value\n}'; 154 | } 155 | } 156 | 157 | void _notifyGlobally(String key, T newValue) { 158 | final notifiers = _fetchNotifiersForKey(key); 159 | if (notifiers == null || notifiers.isEmpty) return; 160 | 161 | for (var notifier in notifiers) { 162 | final currentValue = notifier.value; 163 | if (currentValue != newValue) { 164 | notifier.value = newValue; 165 | // ignore: avoid_print 166 | print(': _notifyGlobally: updating $key notifier'); 167 | } 168 | } 169 | } 170 | 171 | List? _fetchNotifiersForKey(String key) { 172 | final finalKey = key.toLowerCase().trim(); 173 | return _notifiers[finalKey]; 174 | } 175 | 176 | /// This map is used for keeping the track of the notifier(s) associated with 177 | /// a Settings key 178 | /// 179 | /// If a settings key is already added in the map, the new notifier 180 | /// is added to the list of notifiers 181 | Map> _notifiers = 182 | >{}; 183 | 184 | /// A Stateful widget which Takes in a [cacheKey], a [defaultValue] 185 | /// and a [builder] 186 | /// 187 | /// This widget rebuilds whenever there's a change in value associated with the 188 | /// [cacheKey] 189 | class ValueChangeObserver extends StatefulWidget { 190 | final String cacheKey; 191 | final T defaultValue; 192 | final InternalWidgetBuilder builder; 193 | 194 | const ValueChangeObserver({ 195 | super.key, 196 | required this.cacheKey, 197 | required this.defaultValue, 198 | required this.builder, 199 | }); 200 | 201 | @override 202 | State> createState() => _ValueChangeObserverState(); 203 | } 204 | 205 | class _ValueChangeObserverState extends State> { 206 | T? value; 207 | 208 | String get cacheKey => widget.cacheKey; 209 | 210 | T get defaultValue => widget.defaultValue; 211 | 212 | late ValueChangeNotifier notifier; 213 | 214 | @override 215 | void dispose() { 216 | if (!mounted) { 217 | _notifiers.remove(cacheKey); 218 | } 219 | super.dispose(); 220 | } 221 | 222 | @override 223 | void initState() { 224 | //if [cacheKey] is not found, add new cache in the [cacheProvider] with [defaultValue] 225 | final containsKey = Settings.containsKey(cacheKey) ?? false; 226 | if (!containsKey) { 227 | Settings.setValue(cacheKey, defaultValue); 228 | } 229 | 230 | // get cache value from the [cacheProvider] 231 | value = Settings.getValue(cacheKey, defaultValue: defaultValue); 232 | 233 | // assign a notifier 234 | notifier = ValueChangeNotifier(cacheKey, value); 235 | 236 | // add notifier to [_notifiers] map 237 | if (!_notifiers.containsKey(cacheKey)) { 238 | _notifiers[cacheKey] = List>.empty(growable: true); 239 | } 240 | _notifiers[cacheKey]?.add(notifier); 241 | super.initState(); 242 | } 243 | 244 | @override 245 | Widget build(BuildContext context) { 246 | return ValueListenableBuilder( 247 | valueListenable: notifier, 248 | builder: (BuildContext context, T value, Widget? child) { 249 | return widget.builder(context, value, onChange); 250 | }, 251 | ); 252 | } 253 | 254 | /// This method is used to trigger all the associated notifiers 255 | /// when associated value is changed in cache 256 | void onChange(T newValue) { 257 | _notifiers[cacheKey]?.forEach((notifier) { 258 | notifier.value = newValue; 259 | }); 260 | } 261 | } 262 | -------------------------------------------------------------------------------- /lib/src/utils/utils.dart: -------------------------------------------------------------------------------- 1 | import 'dart:ui'; 2 | 3 | class ConversionUtils { 4 | static Color colorFromString(String colorString) { 5 | colorString = colorString.replaceFirst('#', ''); 6 | colorString = colorString.length == 6 ? 'ff$colorString' : colorString; 7 | final colorHexInt = int.parse(colorString, radix: 16); 8 | return Color(colorHexInt); 9 | } 10 | 11 | static int intFromString(String value) { 12 | const alphaString = 'ff000000'; 13 | return int.parse(value, radix: 16) & int.parse(alphaString, radix: 16); 14 | } 15 | 16 | static String stringFromColor(Color color) { 17 | return '#${color.value.toRadixString(16)}'; 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /lib/src/utils/widget_utils.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/material.dart'; 2 | 3 | /// A method that will add default leading padding to all children in the list 4 | List getPaddedParentChildrenList(List childrenIfEnabled) { 5 | return childrenIfEnabled.map((childWidget) { 6 | return Padding( 7 | padding: const EdgeInsets.only(left: 8.0), 8 | child: childWidget, 9 | ); 10 | }).toList(); 11 | } 12 | 13 | TextStyle? headerTextStyle(BuildContext context) => 14 | Theme.of(context).textTheme.titleLarge?.copyWith(fontSize: 16.0); 15 | 16 | TextStyle? subtitleTextStyle(BuildContext context) => Theme.of(context) 17 | .textTheme 18 | .titleSmall 19 | ?.copyWith(fontSize: 13.0, fontWeight: FontWeight.normal); 20 | -------------------------------------------------------------------------------- /lib/src/widgets/color_picker/circle_color.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/material.dart'; 2 | 3 | class CircleColor extends StatelessWidget { 4 | static const double _kColorElevation = 4.0; 5 | 6 | final bool isSelected; 7 | final Color color; 8 | final VoidCallback? onColorChoose; 9 | final double circleSize; 10 | final double? elevation; 11 | final IconData? iconSelected; 12 | 13 | const CircleColor({ 14 | super.key, 15 | required this.color, 16 | required this.circleSize, 17 | this.onColorChoose, 18 | this.isSelected = false, 19 | this.elevation = _kColorElevation, 20 | this.iconSelected, 21 | }) : assert(!isSelected || (isSelected && iconSelected != null)); 22 | 23 | @override 24 | Widget build(BuildContext context) { 25 | final brightness = ThemeData.estimateBrightnessForColor(color); 26 | final icon = brightness == Brightness.light ? Colors.black : Colors.white; 27 | 28 | return GestureDetector( 29 | onTap: onColorChoose, 30 | child: Material( 31 | elevation: elevation ?? _kColorElevation, 32 | shape: const CircleBorder(), 33 | child: CircleAvatar( 34 | radius: circleSize / 2, 35 | backgroundColor: color, 36 | child: isSelected ? Icon(iconSelected, color: icon) : null, 37 | ), 38 | ), 39 | ); 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /lib/src/widgets/color_picker/colors.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/material.dart'; 2 | 3 | const List materialColors = [ 4 | Colors.red, 5 | Colors.pink, 6 | Colors.purple, 7 | Colors.deepPurple, 8 | Colors.indigo, 9 | Colors.blue, 10 | Colors.lightBlue, 11 | Colors.cyan, 12 | Colors.teal, 13 | Colors.green, 14 | Colors.lightGreen, 15 | Colors.lime, 16 | Colors.yellow, 17 | Colors.amber, 18 | Colors.orange, 19 | Colors.deepOrange, 20 | Colors.brown, 21 | Colors.grey, 22 | Colors.blueGrey 23 | ]; 24 | 25 | const List accentColors = [ 26 | Colors.redAccent, 27 | Colors.pinkAccent, 28 | Colors.purpleAccent, 29 | Colors.deepPurpleAccent, 30 | Colors.indigoAccent, 31 | Colors.blueAccent, 32 | Colors.lightBlueAccent, 33 | Colors.cyanAccent, 34 | Colors.tealAccent, 35 | Colors.greenAccent, 36 | Colors.lightGreenAccent, 37 | Colors.limeAccent, 38 | Colors.yellowAccent, 39 | Colors.amberAccent, 40 | Colors.orangeAccent, 41 | Colors.deepOrangeAccent, 42 | ]; 43 | 44 | const List fullMaterialColors = [ 45 | ColorSwatch(0xFFFFFFFF, {500: Colors.white}), 46 | ColorSwatch(0xFF000000, {500: Colors.black}), 47 | Colors.red, 48 | Colors.redAccent, 49 | Colors.pink, 50 | Colors.pinkAccent, 51 | Colors.purple, 52 | Colors.purpleAccent, 53 | Colors.deepPurple, 54 | Colors.deepPurpleAccent, 55 | Colors.indigo, 56 | Colors.indigoAccent, 57 | Colors.blue, 58 | Colors.blueAccent, 59 | Colors.lightBlue, 60 | Colors.lightBlueAccent, 61 | Colors.cyan, 62 | Colors.cyanAccent, 63 | Colors.teal, 64 | Colors.tealAccent, 65 | Colors.green, 66 | Colors.greenAccent, 67 | Colors.lightGreen, 68 | Colors.lightGreenAccent, 69 | Colors.lime, 70 | Colors.limeAccent, 71 | Colors.yellow, 72 | Colors.yellowAccent, 73 | Colors.amber, 74 | Colors.amberAccent, 75 | Colors.orange, 76 | Colors.orangeAccent, 77 | Colors.deepOrange, 78 | Colors.deepOrangeAccent, 79 | Colors.brown, 80 | Colors.grey, 81 | Colors.blueGrey 82 | ]; 83 | -------------------------------------------------------------------------------- /lib/src/widgets/color_picker/material_color_picker.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/material.dart'; 2 | 3 | import 'circle_color.dart'; 4 | import 'colors.dart'; 5 | 6 | class MaterialColorPicker extends StatefulWidget { 7 | final Color? selectedColor; 8 | final ValueChanged? onColorChange; 9 | final ValueChanged? onMainColorChange; 10 | final List? colors; 11 | final bool shrinkWrap; 12 | final ScrollPhysics? physics; 13 | final bool allowShades; 14 | final bool onlyShadeSelection; 15 | final double circleSize; 16 | final double spacing; 17 | final IconData iconSelected; 18 | final VoidCallback? onBack; 19 | final double? elevation; 20 | 21 | const MaterialColorPicker({ 22 | super.key, 23 | this.selectedColor, 24 | this.onColorChange, 25 | this.onMainColorChange, 26 | this.colors, 27 | this.shrinkWrap = false, 28 | this.physics, 29 | this.allowShades = true, 30 | this.onlyShadeSelection = false, 31 | this.iconSelected = Icons.check, 32 | this.circleSize = 45.0, 33 | this.spacing = 9.0, 34 | this.onBack, 35 | this.elevation, 36 | }); 37 | 38 | @override 39 | State createState() => _MaterialColorPickerState(); 40 | } 41 | 42 | class _MaterialColorPickerState extends State { 43 | final _defaultValue = materialColors[0]; 44 | 45 | List? _colors = materialColors; 46 | 47 | ColorSwatch? _mainColor; 48 | Color? _shadeColor; 49 | late bool _isMainSelection; 50 | 51 | @override 52 | void initState() { 53 | super.initState(); 54 | _initSelectedValue(); 55 | } 56 | 57 | @protected 58 | @override 59 | void didUpdateWidget(covariant MaterialColorPicker oldWidget) { 60 | _initSelectedValue(); 61 | super.didUpdateWidget(oldWidget); 62 | } 63 | 64 | void _initSelectedValue() { 65 | if (widget.colors != null) _colors = widget.colors; 66 | 67 | Color? shadeColor = widget.selectedColor ?? _defaultValue; 68 | var mainColor = _findMainColor(shadeColor); 69 | 70 | if (mainColor == null) { 71 | mainColor = _colors![0]; 72 | shadeColor = mainColor[500] ?? mainColor[400]!; 73 | } 74 | 75 | setState(() { 76 | _mainColor = mainColor; 77 | _shadeColor = shadeColor; 78 | _isMainSelection = true; 79 | }); 80 | } 81 | 82 | ColorSwatch? _findMainColor(Color? shadeColor) { 83 | for (final mainColor in _colors!) { 84 | if (_isShadeOfMain(mainColor, shadeColor)) return mainColor; 85 | } 86 | 87 | return (shadeColor is ColorSwatch && _colors!.contains(shadeColor)) 88 | ? shadeColor 89 | : null; 90 | } 91 | 92 | bool _isShadeOfMain(ColorSwatch mainColor, Color? shadeColor) { 93 | for (final shade in _getMaterialColorShades(mainColor)) { 94 | if (shade == shadeColor) return true; 95 | } 96 | return false; 97 | } 98 | 99 | void _onMainColorSelected(ColorSwatch color) { 100 | var isShadeOfMain = _isShadeOfMain(color, _shadeColor); 101 | final shadeColor = isShadeOfMain ? _shadeColor : (color[500] ?? color[400]); 102 | 103 | setState(() { 104 | _mainColor = color; 105 | _shadeColor = shadeColor; 106 | _isMainSelection = false; 107 | }); 108 | if (widget.onMainColorChange != null) widget.onMainColorChange!(color); 109 | if (widget.onlyShadeSelection && !_isMainSelection) { 110 | return; 111 | } 112 | if (widget.allowShades && widget.onColorChange != null) { 113 | widget.onColorChange!(shadeColor); 114 | } 115 | } 116 | 117 | void _onShadeColorSelected(Color? color) { 118 | setState(() => _shadeColor = color); 119 | if (widget.onColorChange != null) widget.onColorChange!(color); 120 | } 121 | 122 | void _onBack() { 123 | setState(() => _isMainSelection = true); 124 | if (widget.onBack != null) widget.onBack!(); 125 | } 126 | 127 | List _buildListMainColor(List colors) { 128 | return [ 129 | for (final color in colors) 130 | CircleColor( 131 | color: color, 132 | circleSize: widget.circleSize, 133 | onColorChoose: () => _onMainColorSelected(color), 134 | isSelected: _mainColor == color, 135 | iconSelected: widget.iconSelected, 136 | elevation: widget.elevation, 137 | ) 138 | ]; 139 | } 140 | 141 | List _getMaterialColorShades(ColorSwatch color) { 142 | return [ 143 | if (color[50] != null) color[50], 144 | if (color[100] != null) color[100], 145 | if (color[200] != null) color[200], 146 | if (color[300] != null) color[300], 147 | if (color[400] != null) color[400], 148 | if (color[500] != null) color[500], 149 | if (color[600] != null) color[600], 150 | if (color[700] != null) color[700], 151 | if (color[800] != null) color[800], 152 | if (color[900] != null) color[900], 153 | ]; 154 | } 155 | 156 | List _buildListShadesColor(ColorSwatch color) { 157 | return [ 158 | IconButton( 159 | icon: const Icon(Icons.arrow_back), 160 | onPressed: _onBack, 161 | padding: const EdgeInsets.only(right: 2.0), 162 | ), 163 | for (final color in _getMaterialColorShades(color)) 164 | CircleColor( 165 | color: color!, 166 | circleSize: widget.circleSize, 167 | onColorChoose: () => _onShadeColorSelected(color), 168 | isSelected: _shadeColor == color, 169 | iconSelected: widget.iconSelected, 170 | elevation: widget.elevation, 171 | ), 172 | ]; 173 | } 174 | 175 | @override 176 | Widget build(BuildContext context) { 177 | final listChildren = _isMainSelection || !widget.allowShades 178 | ? _buildListMainColor(_colors!) 179 | : _buildListShadesColor(_mainColor!); 180 | 181 | // Size of dialog 182 | final width = MediaQuery.of(context).size.width * .80; 183 | // Number of circle per line, depend on width and circleSize 184 | final nbrCircleLine = width ~/ (widget.circleSize + widget.spacing); 185 | 186 | return SizedBox( 187 | width: width, 188 | child: GridView.count( 189 | shrinkWrap: widget.shrinkWrap, 190 | physics: widget.physics, 191 | padding: const EdgeInsets.all(16.0), 192 | crossAxisSpacing: widget.spacing, 193 | mainAxisSpacing: widget.spacing, 194 | crossAxisCount: nbrCircleLine, 195 | children: listChildren, 196 | ), 197 | ); 198 | } 199 | } 200 | -------------------------------------------------------------------------------- /media/example_1.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/GAM3RG33K/flutter_settings_screens/18f937739d7fb4c7ceb0d8b9877f20f0b5e9e6d8/media/example_1.gif -------------------------------------------------------------------------------- /media/example_2.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/GAM3RG33K/flutter_settings_screens/18f937739d7fb4c7ceb0d8b9877f20f0b5e9e6d8/media/example_2.gif -------------------------------------------------------------------------------- /media/example_3.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/GAM3RG33K/flutter_settings_screens/18f937739d7fb4c7ceb0d8b9877f20f0b5e9e6d8/media/example_3.gif -------------------------------------------------------------------------------- /media/example_4.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/GAM3RG33K/flutter_settings_screens/18f937739d7fb4c7ceb0d8b9877f20f0b5e9e6d8/media/example_4.gif -------------------------------------------------------------------------------- /media/example_5.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/GAM3RG33K/flutter_settings_screens/18f937739d7fb4c7ceb0d8b9877f20f0b5e9e6d8/media/example_5.gif -------------------------------------------------------------------------------- /pubspec.yaml: -------------------------------------------------------------------------------- 1 | name: flutter_settings_screens 2 | description: A Simple plugin to implement settings UI screens for your flutter apps. Customize what you want, From UI elements, behaviour or underlying storage library. 3 | repository: https://github.com/GAM3RG33K/flutter_settings_screens 4 | homepage: https://github.com/GAM3RG33K/flutter_settings_screens 5 | version: 0.3.4 6 | 7 | environment: 8 | sdk: '>=3.2.4 <4.0.0' 9 | 10 | dependencies: 11 | flutter: 12 | sdk: flutter 13 | 14 | # library to access storage directories 15 | path_provider: ^2.0.10 16 | 17 | # library to use Provider widgets 18 | provider: ^6.0.3 19 | 20 | # library to store the preference/settings using shared_preferences library 21 | shared_preferences: ^2.0.15 22 | 23 | dev_dependencies: 24 | flutter_test: 25 | sdk: flutter 26 | 27 | # to enforce dart coding standard 28 | flutter_lints: ^3.0.0 29 | 30 | # For information on the generic Dart part of this file, see the 31 | # following page: https://dart.dev/tools/pub/pubspec 32 | 33 | # The following section is specific to Flutter. 34 | flutter: 35 | -------------------------------------------------------------------------------- /test/flutter_settings_screens_test.dart: -------------------------------------------------------------------------------- 1 | //import 'package:flutter/services.dart'; 2 | //import 'package:flutter_test/flutter_test.dart'; 3 | //import 'package:flutter_settings_screens/flutter_settings_screens.dart'; 4 | // 5 | //void main() { 6 | // const MethodChannel channel = MethodChannel('flutter_settings_screens'); 7 | // 8 | // TestWidgetsFlutterBinding.ensureInitialized(); 9 | // 10 | // setUp(() { 11 | // channel.setMockMethodCallHandler((MethodCall methodCall) async { 12 | // return '42'; 13 | // }); 14 | // }); 15 | // 16 | // tearDown(() { 17 | // channel.setMockMethodCallHandler(null); 18 | // }); 19 | // 20 | // test('getPlatformVersion', () async { 21 | // expect(await FlutterSettingsScreens.platformVersion, '42'); 22 | // }); 23 | //} 24 | --------------------------------------------------------------------------------