├── .gitignore ├── CHANGELOG.md ├── LICENSE ├── README.md ├── analysis_options.yaml ├── example ├── .gitignore ├── .metadata ├── README.md ├── analysis_options.yaml ├── android │ ├── .gitignore │ ├── app │ │ ├── build.gradle │ │ └── src │ │ │ ├── debug │ │ │ └── AndroidManifest.xml │ │ │ ├── main │ │ │ ├── AndroidManifest.xml │ │ │ ├── kotlin │ │ │ │ └── com │ │ │ │ │ └── example │ │ │ │ │ └── example │ │ │ │ │ └── MainActivity.kt │ │ │ └── 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.jar │ │ │ └── gradle-wrapper.properties │ ├── gradlew │ ├── gradlew.bat │ └── settings.gradle ├── ios │ ├── .gitignore │ ├── Flutter │ │ ├── AppFrameworkInfo.plist │ │ ├── Debug.xcconfig │ │ └── Release.xcconfig │ ├── 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 │ ├── main.dart │ └── pickers │ │ ├── block_picker.dart │ │ ├── hsv_picker.dart │ │ └── material_picker.dart ├── pubspec.lock ├── pubspec.yaml └── web │ ├── favicon.png │ ├── icons │ ├── Icon-192.png │ ├── Icon-512.png │ ├── Icon-maskable-192.png │ └── Icon-maskable-512.png │ ├── index.html │ └── manifest.json ├── flutter_colorpicker.iml ├── lib ├── flutter_colorpicker.dart └── src │ ├── block_picker.dart │ ├── colorpicker.dart │ ├── colors.dart │ ├── material_picker.dart │ ├── palette.dart │ └── utils.dart ├── pubspec.lock ├── pubspec.yaml └── test └── utils_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 | 18 | # The .vscode folder contains launch configuration and tasks you configure in 19 | # VS Code which you may wish to be included in version control, so this line 20 | # is commented out by default. 21 | .vscode/ 22 | 23 | # Flutter/Dart/Pub related 24 | **/doc/api/ 25 | .dart_tool/ 26 | .flutter-plugins 27 | .flutter-plugins-dependencies 28 | .packages 29 | .pub-cache/ 30 | .pub/ 31 | build/ 32 | 33 | # Android related 34 | **/android/**/gradle-wrapper.jar 35 | **/android/.gradle 36 | **/android/captures/ 37 | **/android/gradlew 38 | **/android/gradlew.bat 39 | **/android/local.properties 40 | **/android/**/GeneratedPluginRegistrant.java 41 | 42 | # iOS/XCode related 43 | **/ios/**/*.mode1v3 44 | **/ios/**/*.mode2v3 45 | **/ios/**/*.moved-aside 46 | **/ios/**/*.pbxuser 47 | **/ios/**/*.perspectivev3 48 | **/ios/**/*sync/ 49 | **/ios/**/.sconsign.dblite 50 | **/ios/**/.tags* 51 | **/ios/**/.vagrant/ 52 | **/ios/**/DerivedData/ 53 | **/ios/**/Icon? 54 | **/ios/**/Pods/ 55 | **/ios/**/.symlinks/ 56 | **/ios/**/profile 57 | **/ios/**/xcuserdata 58 | **/ios/.generated/ 59 | **/ios/Flutter/App.framework 60 | **/ios/Flutter/Flutter.framework 61 | **/ios/Flutter/Flutter.podspec 62 | **/ios/Flutter/Generated.xcconfig 63 | **/ios/Flutter/ephemeral 64 | **/ios/Flutter/app.flx 65 | **/ios/Flutter/app.zip 66 | **/ios/Flutter/flutter_assets/ 67 | **/ios/Flutter/flutter_export_environment.sh 68 | **/ios/ServiceDefinitions.json 69 | **/ios/Runner/GeneratedPluginRegistrant.* 70 | 71 | # Exceptions to above rules. 72 | !**/ios/**/default.mode1v3 73 | !**/ios/**/default.mode2v3 74 | !**/ios/**/default.pbxuser 75 | !**/ios/**/default.perspectivev3 76 | 77 | # dev 78 | lib/src/color.dart 79 | **/ref.dart 80 | **/test.dart 81 | -------------------------------------------------------------------------------- /CHANGELOG.md: -------------------------------------------------------------------------------- 1 | # CHANGELOG 2 | 3 | ## [1.1.0] 4 | 5 | - [#75](https://github.com/mchome/flutter_colorpicker/pull/75) Enable ColorPickerInput in landscape mode. 6 | - [#82](https://github.com/mchome/flutter_colorpicker/pull/82) Fixes Material Picker: Box shadow doesn't respect theme. 7 | - [#101](https://github.com/mchome/flutter_colorpicker/pull/101) Fixed static analysis issues. 8 | - [#106](https://github.com/mchome/flutter_colorpicker/pull/106) Fixed issues when running app with impeller on iOS. 9 | 10 | ## [1.0.3] 11 | 12 | - [#68](https://github.com/mchome/flutter_colorpicker/issues/68) Fix material color picker outline for white color. 13 | - [#69](https://github.com/mchome/flutter_colorpicker/issues/69) Fix the selector in block color picker in showDialog. 14 | 15 | ## [1.0.2] 16 | 17 | - Fix the slider of hsv color picker in landscape mode. 18 | - [#50](https://github.com/mchome/flutter_colorpicker/issues/50) Check the color of input in block color picker. 19 | 20 | ## [1.0.1] 21 | 22 | - Fix late value not initialized in MaterialPicker. 23 | 24 | ## [1.0.0] 25 | 26 | - Update shading label text style in MaterialPicker. 27 | 28 | ## [1.0.0-dev.1] 29 | 30 | - [#21](https://github.com/mchome/flutter_colorpicker/pull/21) Add onPrimaryChanged in MaterialPicker. 31 | - Add shading label with landscape mode in MaterialPicker. 32 | 33 | ## [1.0.0-dev.0] 34 | 35 | - Add some new pickers like RGB palette, HUE Wheel and HUE Ring... 36 | - Move hsv_colorpicker to colorpicker. 37 | - [#58](https://github.com/mchome/flutter_colorpicker/issues/58) Fix the scroll problem in platform web and desktop. 38 | - Add built-in hex input bar. 39 | - Update example. 40 | 41 | ## [0.6.1] 42 | 43 | - [#59](https://github.com/mchome/flutter_colorpicker/pull/59) You can modify the textStyle of label heading now. 44 | - [#61](https://github.com/mchome/flutter_colorpicker/issues/61) Fix _setState_ was called after widget was disposed. 45 | - This is a quick hot fix so not in git, it's fixed in v1.0.0. 46 | 47 | ## [0.6.0] 48 | 49 | - Added **_hexInputController_** for Manual Hex Input [#31](https://github.com/mchome/flutter_colorpicker/issues/31). 50 | - Added 122 tests and documentation for colorToHex() and colorFromHex(). 51 | - Update example app. 52 | 53 | ## [0.5.0] 54 | 55 | - [#45](https://github.com/mchome/flutter_colorpicker/pull/36) GestureRecognizer Cleanup. 56 | [Reference Page](https://flutter.dev/docs/release/breaking-changes/gesture-recognizer-add-allowed-pointer). 57 | 58 | ## [0.4.0] 59 | 60 | - Release null-safety version. 61 | 62 | ## [0.4.0-nullsafety.0] 63 | 64 | - [#36](https://github.com/mchome/flutter_colorpicker/pull/36) Support null safety. 65 | 66 | ## [0.3.5] 67 | 68 | - [#25](https://github.com/mchome/flutter_colorpicker/pull/25) Add MultipleChoiceBlockPicker. 69 | (Thanks [rostIvan](https://github.com/rostIvan)) 70 | 71 | ## [0.3.4] 72 | 73 | - [#20](https://github.com/mchome/flutter_colorpicker/pull/20) Added null control for availableColors parameter. 74 | (Thanks [ekangal](https://github.com/ekangal)) 75 | 76 | ## [0.3.3] 77 | 78 | - [#19](https://github.com/mchome/flutter_colorpicker/pull/19) Handle multiple GestureDetector of ColorPicker. 79 | (Thanks [friebetill](https://github.com/friebetill)) 80 | 81 | ## [0.3.2] 82 | 83 | - SlidePicker add indicatorBorderRadius. 84 | 85 | ## [0.3.1] 86 | 87 | - Back compatibility for stable branch. 88 | 89 | ## [0.3.0] 90 | 91 | - Add SlidePicker. 92 | - Add example web support. 93 | 94 | ## [0.2.6] 95 | 96 | - Update color selection also for tap down. 97 | 98 | ## [0.2.5] 99 | 100 | - Fix enableLabel. 101 | - Fix scrollbar. 102 | 103 | ## [0.2.4] 104 | 105 | - Add hsl palette. 106 | 107 | ## [0.2.3] 108 | 109 | - MaterialPicker: Flexible size. 110 | 111 | ## [0.2.2] 112 | 113 | - Add didUpdateWidget lifecycle to handle changes to pickerColor. 114 | 115 | ## [0.2.1] 116 | 117 | - Rename some types. 118 | 119 | ## [0.2.0] 120 | 121 | - A new block color picker. 122 | - Update example app. 123 | 124 | ## [0.1.0] 125 | 126 | - Improve slider dragging. 127 | - A new material color picker. 128 | - Update example app. 129 | 130 | ## [0.0.7] 131 | 132 | - Fix analysis warning. 133 | 134 | ## [0.0.6] 135 | 136 | - Better landscape view. 137 | 138 | ## [0.0.5] 139 | 140 | - Replace some deprecated functions. 141 | - Bump SDK version. 142 | 143 | ## [0.0.4] 144 | 145 | - Replace a parameter from `colorPainterHeight` to `pickerAreaHeightPercent` to give a ratio on the picker area. 146 | 147 | ## [0.0.3] 148 | 149 | - Optimization for responsive design. 150 | 151 | ## [0.0.2] 152 | 153 | - Change widget's width. 154 | 155 | ## [0.0.1+1] 156 | 157 | - Update readme. 158 | 159 | ## [0.0.1] 160 | 161 | - Initial release. 162 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2021 fuyumi 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: 6 | 7 | The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. 8 | 9 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # flutter_colorpicker 2 | 3 | [![pub package](https://img.shields.io/pub/v/flutter_colorpicker?include_prereleases.svg "Flutter Color Picker")](https://pub.dev/packages/flutter_colorpicker) 4 | [![badge](https://img.shields.io/badge/%20built%20with-%20%E2%9D%A4-ff69b4.svg "build with love")](https://github.com/mchome/flutter_colorpicker) 5 | 6 | HSV(HSB)/HSL/RGB/Material color picker inspired by all the good design for your amazing flutter apps. 7 | Adorable color pickers out of the box with highly customized widgets to all developers' needs. 8 | 9 | [Web Example](https://mchome.github.io/flutter_colorpicker) 10 | 11 | ## Getting Started 12 | 13 | Use it in [showDialog] widget: 14 | 15 | ```dart 16 | // create some values 17 | Color pickerColor = Color(0xff443a49); 18 | Color currentColor = Color(0xff443a49); 19 | 20 | // ValueChanged callback 21 | void changeColor(Color color) { 22 | setState(() => pickerColor = color); 23 | } 24 | 25 | // raise the [showDialog] widget 26 | showDialog( 27 | context: context, 28 | child: AlertDialog( 29 | title: const Text('Pick a color!'), 30 | content: SingleChildScrollView( 31 | child: ColorPicker( 32 | pickerColor: pickerColor, 33 | onColorChanged: changeColor, 34 | ), 35 | // Use Material color picker: 36 | // 37 | // child: MaterialPicker( 38 | // pickerColor: pickerColor, 39 | // onColorChanged: changeColor, 40 | // showLabel: true, // only on portrait mode 41 | // ), 42 | // 43 | // Use Block color picker: 44 | // 45 | // child: BlockPicker( 46 | // pickerColor: currentColor, 47 | // onColorChanged: changeColor, 48 | // ), 49 | // 50 | // child: MultipleChoiceBlockPicker( 51 | // pickerColors: currentColors, 52 | // onColorsChanged: changeColors, 53 | // ), 54 | ), 55 | actions: [ 56 | ElevatedButton( 57 | child: const Text('Got it'), 58 | onPressed: () { 59 | setState(() => currentColor = pickerColor); 60 | Navigator.of(context).pop(); 61 | }, 62 | ), 63 | ], 64 | ), 65 | ) 66 | ``` 67 | 68 | ![preview](https://user-images.githubusercontent.com/7392658/36585408-bb4e96a4-18b8-11e8-8c20-d4dc200e1a7c.gif) 69 | ![SlidePicker](https://user-images.githubusercontent.com/7392658/74600957-5efa3980-50d3-11ea-9458-55842927e565.png) 70 | 71 | 72 | 73 | 74 | Details in [example](https://github.com/mchome/flutter_colorpicker/tree/master/example) folder. 75 | -------------------------------------------------------------------------------- /analysis_options.yaml: -------------------------------------------------------------------------------- 1 | analyzer: 2 | errors: 3 | no_leading_underscores_for_local_identifiers: ignore 4 | include: package:flutter_lints/flutter.yaml 5 | 6 | # Additional information about this file can be found at 7 | # https://dart.dev/guides/language/analysis-options 8 | -------------------------------------------------------------------------------- /example/.gitignore: -------------------------------------------------------------------------------- 1 | # Miscellaneous 2 | *.class 3 | *.log 4 | *.pyc 5 | *.swp 6 | .DS_Store 7 | .atom/ 8 | .buildlog/ 9 | .history 10 | .svn/ 11 | 12 | # IntelliJ related 13 | *.iml 14 | *.ipr 15 | *.iws 16 | .idea/ 17 | 18 | # The .vscode folder contains launch configuration and tasks you configure in 19 | # VS Code which you may wish to be included in version control, so this line 20 | # is commented out by default. 21 | #.vscode/ 22 | 23 | # Flutter/Dart/Pub related 24 | **/doc/api/ 25 | **/ios/Flutter/.last_build_id 26 | .dart_tool/ 27 | .flutter-plugins 28 | .flutter-plugins-dependencies 29 | .packages 30 | .pub-cache/ 31 | .pub/ 32 | /build/ 33 | 34 | # Web related 35 | lib/generated_plugin_registrant.dart 36 | 37 | # Symbolication related 38 | app.*.symbols 39 | 40 | # Obfuscation related 41 | app.*.map.json 42 | 43 | # Android Studio will place build artifacts here 44 | /android/app/debug 45 | /android/app/profile 46 | /android/app/release 47 | -------------------------------------------------------------------------------- /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: 83b9e99cfbb8be5215514d7fa21191961b4a620d 8 | channel: dev 9 | 10 | project_type: app 11 | -------------------------------------------------------------------------------- /example/README.md: -------------------------------------------------------------------------------- 1 | # flutter_colorpicker example project 2 | -------------------------------------------------------------------------------- /example/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 17 | # https://dart-lang.github.io/linter/lints/index.html. 18 | # 19 | # Instead of disabling a lint rule for the entire project in the 20 | # section below, it can also be suppressed for a single line of code 21 | # or a specific dart file by using the `// ignore: name_of_lint` and 22 | # `// ignore_for_file: name_of_lint` syntax on the line or in the file 23 | # producing the lint. 24 | rules: 25 | # avoid_print: false # Uncomment to disable the `avoid_print` rule 26 | # prefer_single_quotes: true # Uncomment to enable the `prefer_single_quotes` rule 27 | 28 | # Additional information about this file can be found at 29 | # https://dart.dev/guides/language/analysis-options 30 | -------------------------------------------------------------------------------- /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 | def localProperties = new Properties() 2 | def localPropertiesFile = rootProject.file('local.properties') 3 | if (localPropertiesFile.exists()) { 4 | localPropertiesFile.withReader('UTF-8') { reader -> 5 | localProperties.load(reader) 6 | } 7 | } 8 | 9 | def flutterRoot = localProperties.getProperty('flutter.sdk') 10 | if (flutterRoot == null) { 11 | throw new GradleException("Flutter SDK not found. Define location with flutter.sdk in the local.properties file.") 12 | } 13 | 14 | def flutterVersionCode = localProperties.getProperty('flutter.versionCode') 15 | if (flutterVersionCode == null) { 16 | flutterVersionCode = '1' 17 | } 18 | 19 | def flutterVersionName = localProperties.getProperty('flutter.versionName') 20 | if (flutterVersionName == null) { 21 | flutterVersionName = '1.0' 22 | } 23 | 24 | apply plugin: 'com.android.application' 25 | apply plugin: 'kotlin-android' 26 | apply from: "$flutterRoot/packages/flutter_tools/gradle/flutter.gradle" 27 | 28 | android { 29 | compileSdkVersion 30 30 | 31 | compileOptions { 32 | sourceCompatibility JavaVersion.VERSION_1_8 33 | targetCompatibility JavaVersion.VERSION_1_8 34 | } 35 | 36 | kotlinOptions { 37 | jvmTarget = '1.8' 38 | } 39 | 40 | sourceSets { 41 | main.java.srcDirs += 'src/main/kotlin' 42 | } 43 | 44 | defaultConfig { 45 | // TODO: Specify your own unique Application ID (https://developer.android.com/studio/build/application-id.html). 46 | applicationId "com.example.example" 47 | minSdkVersion 16 48 | targetSdkVersion 30 49 | versionCode flutterVersionCode.toInteger() 50 | versionName flutterVersionName 51 | } 52 | 53 | buildTypes { 54 | release { 55 | // TODO: Add your own signing config for the release build. 56 | // Signing with the debug keys for now, so `flutter run --release` works. 57 | signingConfig signingConfigs.debug 58 | } 59 | } 60 | } 61 | 62 | flutter { 63 | source '../..' 64 | } 65 | 66 | dependencies { 67 | implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version" 68 | } 69 | -------------------------------------------------------------------------------- /example/android/app/src/debug/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 3 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /example/android/app/src/main/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 3 | 6 | 13 | 17 | 21 | 22 | 23 | 24 | 25 | 26 | 28 | 31 | 32 | 33 | -------------------------------------------------------------------------------- /example/android/app/src/main/kotlin/com/example/example/MainActivity.kt: -------------------------------------------------------------------------------- 1 | package com.example.example 2 | 3 | import io.flutter.embedding.android.FlutterActivity 4 | 5 | class MainActivity: FlutterActivity() { 6 | } 7 | -------------------------------------------------------------------------------- /example/android/app/src/main/res/drawable-v21/launch_background.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 12 | 13 | -------------------------------------------------------------------------------- /example/android/app/src/main/res/drawable/launch_background.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 12 | 13 | -------------------------------------------------------------------------------- /example/android/app/src/main/res/mipmap-hdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mchome/flutter_colorpicker/113618a20644abc0c5c74ea86866bd676284c707/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/mchome/flutter_colorpicker/113618a20644abc0c5c74ea86866bd676284c707/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/mchome/flutter_colorpicker/113618a20644abc0c5c74ea86866bd676284c707/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/mchome/flutter_colorpicker/113618a20644abc0c5c74ea86866bd676284c707/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/mchome/flutter_colorpicker/113618a20644abc0c5c74ea86866bd676284c707/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 | buildscript { 2 | ext.kotlin_version = '1.3.50' 3 | repositories { 4 | google() 5 | mavenCentral() 6 | } 7 | 8 | dependencies { 9 | classpath 'com.android.tools.build:gradle:4.1.0' 10 | classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version" 11 | } 12 | } 13 | 14 | allprojects { 15 | repositories { 16 | google() 17 | mavenCentral() 18 | } 19 | } 20 | 21 | rootProject.buildDir = '../build' 22 | subprojects { 23 | project.buildDir = "${rootProject.buildDir}/${project.name}" 24 | project.evaluationDependsOn(':app') 25 | } 26 | 27 | task clean(type: Delete) { 28 | delete rootProject.buildDir 29 | } 30 | -------------------------------------------------------------------------------- /example/android/gradle.properties: -------------------------------------------------------------------------------- 1 | org.gradle.jvmargs=-Xmx1536M 2 | android.useAndroidX=true 3 | android.enableJetifier=true 4 | -------------------------------------------------------------------------------- /example/android/gradle/wrapper/gradle-wrapper.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mchome/flutter_colorpicker/113618a20644abc0c5c74ea86866bd676284c707/example/android/gradle/wrapper/gradle-wrapper.jar -------------------------------------------------------------------------------- /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-6.7-all.zip 7 | -------------------------------------------------------------------------------- /example/android/gradlew: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | ############################################################################## 4 | ## 5 | ## Gradle start up script for UN*X 6 | ## 7 | ############################################################################## 8 | 9 | # Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. 10 | DEFAULT_JVM_OPTS="" 11 | 12 | APP_NAME="Gradle" 13 | APP_BASE_NAME=`basename "$0"` 14 | 15 | # Use the maximum available, or set MAX_FD != -1 to use that value. 16 | MAX_FD="maximum" 17 | 18 | warn ( ) { 19 | echo "$*" 20 | } 21 | 22 | die ( ) { 23 | echo 24 | echo "$*" 25 | echo 26 | exit 1 27 | } 28 | 29 | # OS specific support (must be 'true' or 'false'). 30 | cygwin=false 31 | msys=false 32 | darwin=false 33 | case "`uname`" in 34 | CYGWIN* ) 35 | cygwin=true 36 | ;; 37 | Darwin* ) 38 | darwin=true 39 | ;; 40 | MINGW* ) 41 | msys=true 42 | ;; 43 | esac 44 | 45 | # Attempt to set APP_HOME 46 | # Resolve links: $0 may be a link 47 | PRG="$0" 48 | # Need this for relative symlinks. 49 | while [ -h "$PRG" ] ; do 50 | ls=`ls -ld "$PRG"` 51 | link=`expr "$ls" : '.*-> \(.*\)$'` 52 | if expr "$link" : '/.*' > /dev/null; then 53 | PRG="$link" 54 | else 55 | PRG=`dirname "$PRG"`"/$link" 56 | fi 57 | done 58 | SAVED="`pwd`" 59 | cd "`dirname \"$PRG\"`/" >/dev/null 60 | APP_HOME="`pwd -P`" 61 | cd "$SAVED" >/dev/null 62 | 63 | CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar 64 | 65 | # Determine the Java command to use to start the JVM. 66 | if [ -n "$JAVA_HOME" ] ; then 67 | if [ -x "$JAVA_HOME/jre/sh/java" ] ; then 68 | # IBM's JDK on AIX uses strange locations for the executables 69 | JAVACMD="$JAVA_HOME/jre/sh/java" 70 | else 71 | JAVACMD="$JAVA_HOME/bin/java" 72 | fi 73 | if [ ! -x "$JAVACMD" ] ; then 74 | die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME 75 | 76 | Please set the JAVA_HOME variable in your environment to match the 77 | location of your Java installation." 78 | fi 79 | else 80 | JAVACMD="java" 81 | which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. 82 | 83 | Please set the JAVA_HOME variable in your environment to match the 84 | location of your Java installation." 85 | fi 86 | 87 | # Increase the maximum file descriptors if we can. 88 | if [ "$cygwin" = "false" -a "$darwin" = "false" ] ; then 89 | MAX_FD_LIMIT=`ulimit -H -n` 90 | if [ $? -eq 0 ] ; then 91 | if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then 92 | MAX_FD="$MAX_FD_LIMIT" 93 | fi 94 | ulimit -n $MAX_FD 95 | if [ $? -ne 0 ] ; then 96 | warn "Could not set maximum file descriptor limit: $MAX_FD" 97 | fi 98 | else 99 | warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT" 100 | fi 101 | fi 102 | 103 | # For Darwin, add options to specify how the application appears in the dock 104 | if $darwin; then 105 | GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\"" 106 | fi 107 | 108 | # For Cygwin, switch paths to Windows format before running java 109 | if $cygwin ; then 110 | APP_HOME=`cygpath --path --mixed "$APP_HOME"` 111 | CLASSPATH=`cygpath --path --mixed "$CLASSPATH"` 112 | JAVACMD=`cygpath --unix "$JAVACMD"` 113 | 114 | # We build the pattern for arguments to be converted via cygpath 115 | ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null` 116 | SEP="" 117 | for dir in $ROOTDIRSRAW ; do 118 | ROOTDIRS="$ROOTDIRS$SEP$dir" 119 | SEP="|" 120 | done 121 | OURCYGPATTERN="(^($ROOTDIRS))" 122 | # Add a user-defined pattern to the cygpath arguments 123 | if [ "$GRADLE_CYGPATTERN" != "" ] ; then 124 | OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)" 125 | fi 126 | # Now convert the arguments - kludge to limit ourselves to /bin/sh 127 | i=0 128 | for arg in "$@" ; do 129 | CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -` 130 | CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option 131 | 132 | if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition 133 | eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"` 134 | else 135 | eval `echo args$i`="\"$arg\"" 136 | fi 137 | i=$((i+1)) 138 | done 139 | case $i in 140 | (0) set -- ;; 141 | (1) set -- "$args0" ;; 142 | (2) set -- "$args0" "$args1" ;; 143 | (3) set -- "$args0" "$args1" "$args2" ;; 144 | (4) set -- "$args0" "$args1" "$args2" "$args3" ;; 145 | (5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;; 146 | (6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;; 147 | (7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;; 148 | (8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;; 149 | (9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;; 150 | esac 151 | fi 152 | 153 | # Split up the JVM_OPTS And GRADLE_OPTS values into an array, following the shell quoting and substitution rules 154 | function splitJvmOpts() { 155 | JVM_OPTS=("$@") 156 | } 157 | eval splitJvmOpts $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS 158 | JVM_OPTS[${#JVM_OPTS[*]}]="-Dorg.gradle.appname=$APP_BASE_NAME" 159 | 160 | exec "$JAVACMD" "${JVM_OPTS[@]}" -classpath "$CLASSPATH" org.gradle.wrapper.GradleWrapperMain "$@" 161 | -------------------------------------------------------------------------------- /example/android/gradlew.bat: -------------------------------------------------------------------------------- 1 | @if "%DEBUG%" == "" @echo off 2 | @rem ########################################################################## 3 | @rem 4 | @rem Gradle startup script for Windows 5 | @rem 6 | @rem ########################################################################## 7 | 8 | @rem Set local scope for the variables with windows NT shell 9 | if "%OS%"=="Windows_NT" setlocal 10 | 11 | @rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. 12 | set DEFAULT_JVM_OPTS= 13 | 14 | set DIRNAME=%~dp0 15 | if "%DIRNAME%" == "" set DIRNAME=. 16 | set APP_BASE_NAME=%~n0 17 | set APP_HOME=%DIRNAME% 18 | 19 | @rem Find java.exe 20 | if defined JAVA_HOME goto findJavaFromJavaHome 21 | 22 | set JAVA_EXE=java.exe 23 | %JAVA_EXE% -version >NUL 2>&1 24 | if "%ERRORLEVEL%" == "0" goto init 25 | 26 | echo. 27 | echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. 28 | echo. 29 | echo Please set the JAVA_HOME variable in your environment to match the 30 | echo location of your Java installation. 31 | 32 | goto fail 33 | 34 | :findJavaFromJavaHome 35 | set JAVA_HOME=%JAVA_HOME:"=% 36 | set JAVA_EXE=%JAVA_HOME%/bin/java.exe 37 | 38 | if exist "%JAVA_EXE%" goto init 39 | 40 | echo. 41 | echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% 42 | echo. 43 | echo Please set the JAVA_HOME variable in your environment to match the 44 | echo location of your Java installation. 45 | 46 | goto fail 47 | 48 | :init 49 | @rem Get command-line arguments, handling Windowz variants 50 | 51 | if not "%OS%" == "Windows_NT" goto win9xME_args 52 | if "%@eval[2+2]" == "4" goto 4NT_args 53 | 54 | :win9xME_args 55 | @rem Slurp the command line arguments. 56 | set CMD_LINE_ARGS= 57 | set _SKIP=2 58 | 59 | :win9xME_args_slurp 60 | if "x%~1" == "x" goto execute 61 | 62 | set CMD_LINE_ARGS=%* 63 | goto execute 64 | 65 | :4NT_args 66 | @rem Get arguments from the 4NT Shell from JP Software 67 | set CMD_LINE_ARGS=%$ 68 | 69 | :execute 70 | @rem Setup the command line 71 | 72 | set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar 73 | 74 | @rem Execute Gradle 75 | "%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS% 76 | 77 | :end 78 | @rem End local scope for the variables with windows NT shell 79 | if "%ERRORLEVEL%"=="0" goto mainEnd 80 | 81 | :fail 82 | rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of 83 | rem the _cmd.exe /c_ return code! 84 | if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1 85 | exit /b 1 86 | 87 | :mainEnd 88 | if "%OS%"=="Windows_NT" endlocal 89 | 90 | :omega 91 | -------------------------------------------------------------------------------- /example/android/settings.gradle: -------------------------------------------------------------------------------- 1 | include ':app' 2 | 3 | def localPropertiesFile = new File(rootProject.projectDir, "local.properties") 4 | def properties = new Properties() 5 | 6 | assert localPropertiesFile.exists() 7 | localPropertiesFile.withReader("UTF-8") { reader -> properties.load(reader) } 8 | 9 | def flutterSdkPath = properties.getProperty("flutter.sdk") 10 | assert flutterSdkPath != null, "flutter.sdk not set in local.properties" 11 | apply from: "$flutterSdkPath/packages/flutter_tools/gradle/app_plugin_loader.gradle" 12 | -------------------------------------------------------------------------------- /example/ios/.gitignore: -------------------------------------------------------------------------------- 1 | *.mode1v3 2 | *.mode2v3 3 | *.moved-aside 4 | *.pbxuser 5 | *.perspectivev3 6 | **/*sync/ 7 | .sconsign.dblite 8 | .tags* 9 | **/.vagrant/ 10 | **/DerivedData/ 11 | Icon? 12 | **/Pods/ 13 | **/.symlinks/ 14 | profile 15 | xcuserdata 16 | **/.generated/ 17 | Flutter/App.framework 18 | Flutter/Flutter.framework 19 | Flutter/Flutter.podspec 20 | Flutter/Generated.xcconfig 21 | Flutter/ephemeral/ 22 | Flutter/app.flx 23 | Flutter/app.zip 24 | Flutter/flutter_assets/ 25 | Flutter/flutter_export_environment.sh 26 | ServiceDefinitions.json 27 | Runner/GeneratedPluginRegistrant.* 28 | 29 | # Exceptions to above rules. 30 | !default.mode1v3 31 | !default.mode2v3 32 | !default.pbxuser 33 | !default.perspectivev3 34 | -------------------------------------------------------------------------------- /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 | 9.0 25 | 26 | 27 | -------------------------------------------------------------------------------- /example/ios/Flutter/Debug.xcconfig: -------------------------------------------------------------------------------- 1 | #include "Generated.xcconfig" 2 | -------------------------------------------------------------------------------- /example/ios/Flutter/Release.xcconfig: -------------------------------------------------------------------------------- 1 | #include "Generated.xcconfig" 2 | -------------------------------------------------------------------------------- /example/ios/Runner.xcodeproj/project.pbxproj: -------------------------------------------------------------------------------- 1 | // !$*UTF8*$! 2 | { 3 | archiveVersion = 1; 4 | classes = { 5 | }; 6 | objectVersion = 50; 7 | objects = { 8 | 9 | /* Begin PBXBuildFile section */ 10 | 1498D2341E8E89220040F4C2 /* GeneratedPluginRegistrant.m in Sources */ = {isa = PBXBuildFile; fileRef = 1498D2331E8E89220040F4C2 /* GeneratedPluginRegistrant.m */; }; 11 | 3B3967161E833CAA004F5970 /* AppFrameworkInfo.plist in Resources */ = {isa = PBXBuildFile; fileRef = 3B3967151E833CAA004F5970 /* AppFrameworkInfo.plist */; }; 12 | 74858FAF1ED2DC5600515810 /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 74858FAE1ED2DC5600515810 /* AppDelegate.swift */; }; 13 | 97C146FC1CF9000F007C117D /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 97C146FA1CF9000F007C117D /* Main.storyboard */; }; 14 | 97C146FE1CF9000F007C117D /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 97C146FD1CF9000F007C117D /* Assets.xcassets */; }; 15 | 97C147011CF9000F007C117D /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 97C146FF1CF9000F007C117D /* LaunchScreen.storyboard */; }; 16 | /* End PBXBuildFile section */ 17 | 18 | /* Begin PBXCopyFilesBuildPhase section */ 19 | 9705A1C41CF9048500538489 /* Embed Frameworks */ = { 20 | isa = PBXCopyFilesBuildPhase; 21 | buildActionMask = 2147483647; 22 | dstPath = ""; 23 | dstSubfolderSpec = 10; 24 | files = ( 25 | ); 26 | name = "Embed Frameworks"; 27 | runOnlyForDeploymentPostprocessing = 0; 28 | }; 29 | /* End PBXCopyFilesBuildPhase section */ 30 | 31 | /* Begin PBXFileReference section */ 32 | 1498D2321E8E86230040F4C2 /* GeneratedPluginRegistrant.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = GeneratedPluginRegistrant.h; sourceTree = ""; }; 33 | 1498D2331E8E89220040F4C2 /* GeneratedPluginRegistrant.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = GeneratedPluginRegistrant.m; sourceTree = ""; }; 34 | 3B3967151E833CAA004F5970 /* AppFrameworkInfo.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; name = AppFrameworkInfo.plist; path = Flutter/AppFrameworkInfo.plist; sourceTree = ""; }; 35 | 74858FAD1ED2DC5600515810 /* Runner-Bridging-Header.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "Runner-Bridging-Header.h"; sourceTree = ""; }; 36 | 74858FAE1ED2DC5600515810 /* AppDelegate.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = ""; }; 37 | 7AFA3C8E1D35360C0083082E /* Release.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; name = Release.xcconfig; path = Flutter/Release.xcconfig; sourceTree = ""; }; 38 | 9740EEB21CF90195004384FC /* Debug.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; name = Debug.xcconfig; path = Flutter/Debug.xcconfig; sourceTree = ""; }; 39 | 9740EEB31CF90195004384FC /* Generated.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; name = Generated.xcconfig; path = Flutter/Generated.xcconfig; sourceTree = ""; }; 40 | 97C146EE1CF9000F007C117D /* Runner.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = Runner.app; sourceTree = BUILT_PRODUCTS_DIR; }; 41 | 97C146FB1CF9000F007C117D /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/Main.storyboard; sourceTree = ""; }; 42 | 97C146FD1CF9000F007C117D /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = ""; }; 43 | 97C147001CF9000F007C117D /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/LaunchScreen.storyboard; sourceTree = ""; }; 44 | 97C147021CF9000F007C117D /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; 45 | /* End PBXFileReference section */ 46 | 47 | /* Begin PBXFrameworksBuildPhase section */ 48 | 97C146EB1CF9000F007C117D /* Frameworks */ = { 49 | isa = PBXFrameworksBuildPhase; 50 | buildActionMask = 2147483647; 51 | files = ( 52 | ); 53 | runOnlyForDeploymentPostprocessing = 0; 54 | }; 55 | /* End PBXFrameworksBuildPhase section */ 56 | 57 | /* Begin PBXGroup section */ 58 | 9740EEB11CF90186004384FC /* Flutter */ = { 59 | isa = PBXGroup; 60 | children = ( 61 | 3B3967151E833CAA004F5970 /* AppFrameworkInfo.plist */, 62 | 9740EEB21CF90195004384FC /* Debug.xcconfig */, 63 | 7AFA3C8E1D35360C0083082E /* Release.xcconfig */, 64 | 9740EEB31CF90195004384FC /* Generated.xcconfig */, 65 | ); 66 | name = Flutter; 67 | sourceTree = ""; 68 | }; 69 | 97C146E51CF9000F007C117D = { 70 | isa = PBXGroup; 71 | children = ( 72 | 9740EEB11CF90186004384FC /* Flutter */, 73 | 97C146F01CF9000F007C117D /* Runner */, 74 | 97C146EF1CF9000F007C117D /* Products */, 75 | ); 76 | sourceTree = ""; 77 | }; 78 | 97C146EF1CF9000F007C117D /* Products */ = { 79 | isa = PBXGroup; 80 | children = ( 81 | 97C146EE1CF9000F007C117D /* Runner.app */, 82 | ); 83 | name = Products; 84 | sourceTree = ""; 85 | }; 86 | 97C146F01CF9000F007C117D /* Runner */ = { 87 | isa = PBXGroup; 88 | children = ( 89 | 97C146FA1CF9000F007C117D /* Main.storyboard */, 90 | 97C146FD1CF9000F007C117D /* Assets.xcassets */, 91 | 97C146FF1CF9000F007C117D /* LaunchScreen.storyboard */, 92 | 97C147021CF9000F007C117D /* Info.plist */, 93 | 1498D2321E8E86230040F4C2 /* GeneratedPluginRegistrant.h */, 94 | 1498D2331E8E89220040F4C2 /* GeneratedPluginRegistrant.m */, 95 | 74858FAE1ED2DC5600515810 /* AppDelegate.swift */, 96 | 74858FAD1ED2DC5600515810 /* Runner-Bridging-Header.h */, 97 | ); 98 | path = Runner; 99 | sourceTree = ""; 100 | }; 101 | /* End PBXGroup section */ 102 | 103 | /* Begin PBXNativeTarget section */ 104 | 97C146ED1CF9000F007C117D /* Runner */ = { 105 | isa = PBXNativeTarget; 106 | buildConfigurationList = 97C147051CF9000F007C117D /* Build configuration list for PBXNativeTarget "Runner" */; 107 | buildPhases = ( 108 | 9740EEB61CF901F6004384FC /* Run Script */, 109 | 97C146EA1CF9000F007C117D /* Sources */, 110 | 97C146EB1CF9000F007C117D /* Frameworks */, 111 | 97C146EC1CF9000F007C117D /* Resources */, 112 | 9705A1C41CF9048500538489 /* Embed Frameworks */, 113 | 3B06AD1E1E4923F5004D2608 /* Thin Binary */, 114 | ); 115 | buildRules = ( 116 | ); 117 | dependencies = ( 118 | ); 119 | name = Runner; 120 | productName = Runner; 121 | productReference = 97C146EE1CF9000F007C117D /* Runner.app */; 122 | productType = "com.apple.product-type.application"; 123 | }; 124 | /* End PBXNativeTarget section */ 125 | 126 | /* Begin PBXProject section */ 127 | 97C146E61CF9000F007C117D /* Project object */ = { 128 | isa = PBXProject; 129 | attributes = { 130 | LastUpgradeCheck = 1300; 131 | ORGANIZATIONNAME = ""; 132 | TargetAttributes = { 133 | 97C146ED1CF9000F007C117D = { 134 | CreatedOnToolsVersion = 7.3.1; 135 | LastSwiftMigration = 1100; 136 | }; 137 | }; 138 | }; 139 | buildConfigurationList = 97C146E91CF9000F007C117D /* Build configuration list for PBXProject "Runner" */; 140 | compatibilityVersion = "Xcode 9.3"; 141 | developmentRegion = en; 142 | hasScannedForEncodings = 0; 143 | knownRegions = ( 144 | en, 145 | Base, 146 | ); 147 | mainGroup = 97C146E51CF9000F007C117D; 148 | productRefGroup = 97C146EF1CF9000F007C117D /* Products */; 149 | projectDirPath = ""; 150 | projectRoot = ""; 151 | targets = ( 152 | 97C146ED1CF9000F007C117D /* Runner */, 153 | ); 154 | }; 155 | /* End PBXProject section */ 156 | 157 | /* Begin PBXResourcesBuildPhase section */ 158 | 97C146EC1CF9000F007C117D /* Resources */ = { 159 | isa = PBXResourcesBuildPhase; 160 | buildActionMask = 2147483647; 161 | files = ( 162 | 97C147011CF9000F007C117D /* LaunchScreen.storyboard in Resources */, 163 | 3B3967161E833CAA004F5970 /* AppFrameworkInfo.plist in Resources */, 164 | 97C146FE1CF9000F007C117D /* Assets.xcassets in Resources */, 165 | 97C146FC1CF9000F007C117D /* Main.storyboard in Resources */, 166 | ); 167 | runOnlyForDeploymentPostprocessing = 0; 168 | }; 169 | /* End PBXResourcesBuildPhase section */ 170 | 171 | /* Begin PBXShellScriptBuildPhase section */ 172 | 3B06AD1E1E4923F5004D2608 /* Thin Binary */ = { 173 | isa = PBXShellScriptBuildPhase; 174 | buildActionMask = 2147483647; 175 | files = ( 176 | ); 177 | inputPaths = ( 178 | ); 179 | name = "Thin Binary"; 180 | outputPaths = ( 181 | ); 182 | runOnlyForDeploymentPostprocessing = 0; 183 | shellPath = /bin/sh; 184 | shellScript = "/bin/sh \"$FLUTTER_ROOT/packages/flutter_tools/bin/xcode_backend.sh\" embed_and_thin"; 185 | }; 186 | 9740EEB61CF901F6004384FC /* Run Script */ = { 187 | isa = PBXShellScriptBuildPhase; 188 | buildActionMask = 2147483647; 189 | files = ( 190 | ); 191 | inputPaths = ( 192 | ); 193 | name = "Run Script"; 194 | outputPaths = ( 195 | ); 196 | runOnlyForDeploymentPostprocessing = 0; 197 | shellPath = /bin/sh; 198 | shellScript = "/bin/sh \"$FLUTTER_ROOT/packages/flutter_tools/bin/xcode_backend.sh\" build"; 199 | }; 200 | /* End PBXShellScriptBuildPhase section */ 201 | 202 | /* Begin PBXSourcesBuildPhase section */ 203 | 97C146EA1CF9000F007C117D /* Sources */ = { 204 | isa = PBXSourcesBuildPhase; 205 | buildActionMask = 2147483647; 206 | files = ( 207 | 74858FAF1ED2DC5600515810 /* AppDelegate.swift in Sources */, 208 | 1498D2341E8E89220040F4C2 /* GeneratedPluginRegistrant.m in Sources */, 209 | ); 210 | runOnlyForDeploymentPostprocessing = 0; 211 | }; 212 | /* End PBXSourcesBuildPhase section */ 213 | 214 | /* Begin PBXVariantGroup section */ 215 | 97C146FA1CF9000F007C117D /* Main.storyboard */ = { 216 | isa = PBXVariantGroup; 217 | children = ( 218 | 97C146FB1CF9000F007C117D /* Base */, 219 | ); 220 | name = Main.storyboard; 221 | sourceTree = ""; 222 | }; 223 | 97C146FF1CF9000F007C117D /* LaunchScreen.storyboard */ = { 224 | isa = PBXVariantGroup; 225 | children = ( 226 | 97C147001CF9000F007C117D /* Base */, 227 | ); 228 | name = LaunchScreen.storyboard; 229 | sourceTree = ""; 230 | }; 231 | /* End PBXVariantGroup section */ 232 | 233 | /* Begin XCBuildConfiguration section */ 234 | 249021D3217E4FDB00AE95B9 /* Profile */ = { 235 | isa = XCBuildConfiguration; 236 | buildSettings = { 237 | ALWAYS_SEARCH_USER_PATHS = NO; 238 | CLANG_ANALYZER_NONNULL = YES; 239 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; 240 | CLANG_CXX_LIBRARY = "libc++"; 241 | CLANG_ENABLE_MODULES = YES; 242 | CLANG_ENABLE_OBJC_ARC = YES; 243 | CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; 244 | CLANG_WARN_BOOL_CONVERSION = YES; 245 | CLANG_WARN_COMMA = YES; 246 | CLANG_WARN_CONSTANT_CONVERSION = YES; 247 | CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; 248 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 249 | CLANG_WARN_EMPTY_BODY = YES; 250 | CLANG_WARN_ENUM_CONVERSION = YES; 251 | CLANG_WARN_INFINITE_RECURSION = YES; 252 | CLANG_WARN_INT_CONVERSION = YES; 253 | CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; 254 | CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; 255 | CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; 256 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 257 | CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; 258 | CLANG_WARN_STRICT_PROTOTYPES = YES; 259 | CLANG_WARN_SUSPICIOUS_MOVE = YES; 260 | CLANG_WARN_UNREACHABLE_CODE = YES; 261 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 262 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; 263 | COPY_PHASE_STRIP = NO; 264 | DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; 265 | ENABLE_NS_ASSERTIONS = NO; 266 | ENABLE_STRICT_OBJC_MSGSEND = YES; 267 | GCC_C_LANGUAGE_STANDARD = gnu99; 268 | GCC_NO_COMMON_BLOCKS = YES; 269 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 270 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 271 | GCC_WARN_UNDECLARED_SELECTOR = YES; 272 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 273 | GCC_WARN_UNUSED_FUNCTION = YES; 274 | GCC_WARN_UNUSED_VARIABLE = YES; 275 | IPHONEOS_DEPLOYMENT_TARGET = 9.0; 276 | MTL_ENABLE_DEBUG_INFO = NO; 277 | SDKROOT = iphoneos; 278 | SUPPORTED_PLATFORMS = iphoneos; 279 | TARGETED_DEVICE_FAMILY = "1,2"; 280 | VALIDATE_PRODUCT = YES; 281 | }; 282 | name = Profile; 283 | }; 284 | 249021D4217E4FDB00AE95B9 /* Profile */ = { 285 | isa = XCBuildConfiguration; 286 | baseConfigurationReference = 7AFA3C8E1D35360C0083082E /* Release.xcconfig */; 287 | buildSettings = { 288 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; 289 | CLANG_ENABLE_MODULES = YES; 290 | CURRENT_PROJECT_VERSION = "$(FLUTTER_BUILD_NUMBER)"; 291 | ENABLE_BITCODE = NO; 292 | INFOPLIST_FILE = Runner/Info.plist; 293 | LD_RUNPATH_SEARCH_PATHS = ( 294 | "$(inherited)", 295 | "@executable_path/Frameworks", 296 | ); 297 | PRODUCT_BUNDLE_IDENTIFIER = com.example.example; 298 | PRODUCT_NAME = "$(TARGET_NAME)"; 299 | SWIFT_OBJC_BRIDGING_HEADER = "Runner/Runner-Bridging-Header.h"; 300 | SWIFT_VERSION = 5.0; 301 | VERSIONING_SYSTEM = "apple-generic"; 302 | }; 303 | name = Profile; 304 | }; 305 | 97C147031CF9000F007C117D /* Debug */ = { 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; 336 | ENABLE_STRICT_OBJC_MSGSEND = YES; 337 | ENABLE_TESTABILITY = YES; 338 | GCC_C_LANGUAGE_STANDARD = gnu99; 339 | GCC_DYNAMIC_NO_PIC = NO; 340 | GCC_NO_COMMON_BLOCKS = YES; 341 | GCC_OPTIMIZATION_LEVEL = 0; 342 | GCC_PREPROCESSOR_DEFINITIONS = ( 343 | "DEBUG=1", 344 | "$(inherited)", 345 | ); 346 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 347 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 348 | GCC_WARN_UNDECLARED_SELECTOR = YES; 349 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 350 | GCC_WARN_UNUSED_FUNCTION = YES; 351 | GCC_WARN_UNUSED_VARIABLE = YES; 352 | IPHONEOS_DEPLOYMENT_TARGET = 9.0; 353 | MTL_ENABLE_DEBUG_INFO = YES; 354 | ONLY_ACTIVE_ARCH = YES; 355 | SDKROOT = iphoneos; 356 | TARGETED_DEVICE_FAMILY = "1,2"; 357 | }; 358 | name = Debug; 359 | }; 360 | 97C147041CF9000F007C117D /* Release */ = { 361 | isa = XCBuildConfiguration; 362 | buildSettings = { 363 | ALWAYS_SEARCH_USER_PATHS = NO; 364 | CLANG_ANALYZER_NONNULL = YES; 365 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; 366 | CLANG_CXX_LIBRARY = "libc++"; 367 | CLANG_ENABLE_MODULES = YES; 368 | CLANG_ENABLE_OBJC_ARC = YES; 369 | CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; 370 | CLANG_WARN_BOOL_CONVERSION = YES; 371 | CLANG_WARN_COMMA = YES; 372 | CLANG_WARN_CONSTANT_CONVERSION = YES; 373 | CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; 374 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 375 | CLANG_WARN_EMPTY_BODY = YES; 376 | CLANG_WARN_ENUM_CONVERSION = YES; 377 | CLANG_WARN_INFINITE_RECURSION = YES; 378 | CLANG_WARN_INT_CONVERSION = YES; 379 | CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; 380 | CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; 381 | CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; 382 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 383 | CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; 384 | CLANG_WARN_STRICT_PROTOTYPES = YES; 385 | CLANG_WARN_SUSPICIOUS_MOVE = YES; 386 | CLANG_WARN_UNREACHABLE_CODE = YES; 387 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 388 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; 389 | COPY_PHASE_STRIP = NO; 390 | DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; 391 | ENABLE_NS_ASSERTIONS = NO; 392 | ENABLE_STRICT_OBJC_MSGSEND = YES; 393 | GCC_C_LANGUAGE_STANDARD = gnu99; 394 | GCC_NO_COMMON_BLOCKS = YES; 395 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 396 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 397 | GCC_WARN_UNDECLARED_SELECTOR = YES; 398 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 399 | GCC_WARN_UNUSED_FUNCTION = YES; 400 | GCC_WARN_UNUSED_VARIABLE = YES; 401 | IPHONEOS_DEPLOYMENT_TARGET = 9.0; 402 | MTL_ENABLE_DEBUG_INFO = NO; 403 | SDKROOT = iphoneos; 404 | SUPPORTED_PLATFORMS = iphoneos; 405 | SWIFT_COMPILATION_MODE = wholemodule; 406 | SWIFT_OPTIMIZATION_LEVEL = "-O"; 407 | TARGETED_DEVICE_FAMILY = "1,2"; 408 | VALIDATE_PRODUCT = YES; 409 | }; 410 | name = Release; 411 | }; 412 | 97C147061CF9000F007C117D /* Debug */ = { 413 | isa = XCBuildConfiguration; 414 | baseConfigurationReference = 9740EEB21CF90195004384FC /* Debug.xcconfig */; 415 | buildSettings = { 416 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; 417 | CLANG_ENABLE_MODULES = YES; 418 | CURRENT_PROJECT_VERSION = "$(FLUTTER_BUILD_NUMBER)"; 419 | ENABLE_BITCODE = NO; 420 | INFOPLIST_FILE = Runner/Info.plist; 421 | LD_RUNPATH_SEARCH_PATHS = ( 422 | "$(inherited)", 423 | "@executable_path/Frameworks", 424 | ); 425 | PRODUCT_BUNDLE_IDENTIFIER = com.example.example; 426 | PRODUCT_NAME = "$(TARGET_NAME)"; 427 | SWIFT_OBJC_BRIDGING_HEADER = "Runner/Runner-Bridging-Header.h"; 428 | SWIFT_OPTIMIZATION_LEVEL = "-Onone"; 429 | SWIFT_VERSION = 5.0; 430 | VERSIONING_SYSTEM = "apple-generic"; 431 | }; 432 | name = Debug; 433 | }; 434 | 97C147071CF9000F007C117D /* Release */ = { 435 | isa = XCBuildConfiguration; 436 | baseConfigurationReference = 7AFA3C8E1D35360C0083082E /* Release.xcconfig */; 437 | buildSettings = { 438 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; 439 | CLANG_ENABLE_MODULES = YES; 440 | CURRENT_PROJECT_VERSION = "$(FLUTTER_BUILD_NUMBER)"; 441 | ENABLE_BITCODE = NO; 442 | INFOPLIST_FILE = Runner/Info.plist; 443 | LD_RUNPATH_SEARCH_PATHS = ( 444 | "$(inherited)", 445 | "@executable_path/Frameworks", 446 | ); 447 | PRODUCT_BUNDLE_IDENTIFIER = com.example.example; 448 | PRODUCT_NAME = "$(TARGET_NAME)"; 449 | SWIFT_OBJC_BRIDGING_HEADER = "Runner/Runner-Bridging-Header.h"; 450 | SWIFT_VERSION = 5.0; 451 | VERSIONING_SYSTEM = "apple-generic"; 452 | }; 453 | name = Release; 454 | }; 455 | /* End XCBuildConfiguration section */ 456 | 457 | /* Begin XCConfigurationList section */ 458 | 97C146E91CF9000F007C117D /* Build configuration list for PBXProject "Runner" */ = { 459 | isa = XCConfigurationList; 460 | buildConfigurations = ( 461 | 97C147031CF9000F007C117D /* Debug */, 462 | 97C147041CF9000F007C117D /* Release */, 463 | 249021D3217E4FDB00AE95B9 /* Profile */, 464 | ); 465 | defaultConfigurationIsVisible = 0; 466 | defaultConfigurationName = Release; 467 | }; 468 | 97C147051CF9000F007C117D /* Build configuration list for PBXNativeTarget "Runner" */ = { 469 | isa = XCConfigurationList; 470 | buildConfigurations = ( 471 | 97C147061CF9000F007C117D /* Debug */, 472 | 97C147071CF9000F007C117D /* Release */, 473 | 249021D4217E4FDB00AE95B9 /* Profile */, 474 | ); 475 | defaultConfigurationIsVisible = 0; 476 | defaultConfigurationName = Release; 477 | }; 478 | /* End XCConfigurationList section */ 479 | }; 480 | rootObject = 97C146E61CF9000F007C117D /* Project object */; 481 | } 482 | -------------------------------------------------------------------------------- /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 | 32 | 33 | 39 | 40 | 41 | 42 | 43 | 44 | 54 | 56 | 62 | 63 | 64 | 65 | 66 | 67 | 73 | 75 | 81 | 82 | 83 | 84 | 86 | 87 | 90 | 91 | 92 | -------------------------------------------------------------------------------- /example/ios/Runner.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /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/mchome/flutter_colorpicker/113618a20644abc0c5c74ea86866bd676284c707/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/mchome/flutter_colorpicker/113618a20644abc0c5c74ea86866bd676284c707/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/mchome/flutter_colorpicker/113618a20644abc0c5c74ea86866bd676284c707/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/mchome/flutter_colorpicker/113618a20644abc0c5c74ea86866bd676284c707/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/mchome/flutter_colorpicker/113618a20644abc0c5c74ea86866bd676284c707/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/mchome/flutter_colorpicker/113618a20644abc0c5c74ea86866bd676284c707/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/mchome/flutter_colorpicker/113618a20644abc0c5c74ea86866bd676284c707/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/mchome/flutter_colorpicker/113618a20644abc0c5c74ea86866bd676284c707/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/mchome/flutter_colorpicker/113618a20644abc0c5c74ea86866bd676284c707/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/mchome/flutter_colorpicker/113618a20644abc0c5c74ea86866bd676284c707/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/mchome/flutter_colorpicker/113618a20644abc0c5c74ea86866bd676284c707/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/mchome/flutter_colorpicker/113618a20644abc0c5c74ea86866bd676284c707/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/mchome/flutter_colorpicker/113618a20644abc0c5c74ea86866bd676284c707/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/mchome/flutter_colorpicker/113618a20644abc0c5c74ea86866bd676284c707/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/mchome/flutter_colorpicker/113618a20644abc0c5c74ea86866bd676284c707/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/mchome/flutter_colorpicker/113618a20644abc0c5c74ea86866bd676284c707/example/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage.png -------------------------------------------------------------------------------- /example/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mchome/flutter_colorpicker/113618a20644abc0c5c74ea86866bd676284c707/example/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@2x.png -------------------------------------------------------------------------------- /example/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mchome/flutter_colorpicker/113618a20644abc0c5c74ea86866bd676284c707/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 | CFBundleExecutable 8 | $(EXECUTABLE_NAME) 9 | CFBundleIdentifier 10 | $(PRODUCT_BUNDLE_IDENTIFIER) 11 | CFBundleInfoDictionaryVersion 12 | 6.0 13 | CFBundleName 14 | flutter_colorpicker example 15 | CFBundlePackageType 16 | APPL 17 | CFBundleShortVersionString 18 | $(FLUTTER_BUILD_NAME) 19 | CFBundleSignature 20 | ???? 21 | CFBundleVersion 22 | $(FLUTTER_BUILD_NUMBER) 23 | LSRequiresIPhoneOS 24 | 25 | UILaunchStoryboardName 26 | LaunchScreen 27 | UIMainStoryboardFile 28 | Main 29 | UISupportedInterfaceOrientations 30 | 31 | UIInterfaceOrientationPortrait 32 | UIInterfaceOrientationLandscapeLeft 33 | UIInterfaceOrientationLandscapeRight 34 | 35 | UISupportedInterfaceOrientations~ipad 36 | 37 | UIInterfaceOrientationPortrait 38 | UIInterfaceOrientationPortraitUpsideDown 39 | UIInterfaceOrientationLandscapeLeft 40 | UIInterfaceOrientationLandscapeRight 41 | 42 | UIViewControllerBasedStatusBarAppearance 43 | 44 | 45 | 46 | -------------------------------------------------------------------------------- /example/ios/Runner/Runner-Bridging-Header.h: -------------------------------------------------------------------------------- 1 | #import "GeneratedPluginRegistrant.h" 2 | -------------------------------------------------------------------------------- /example/lib/main.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/material.dart'; 2 | import 'package:flutter_colorpicker/flutter_colorpicker.dart'; 3 | import './pickers/hsv_picker.dart'; 4 | import './pickers/material_picker.dart'; 5 | import './pickers/block_picker.dart'; 6 | 7 | void main() => runApp(const MaterialApp(home: MyApp())); 8 | 9 | class MyApp extends StatefulWidget { 10 | const MyApp({Key? key}) : super(key: key); 11 | 12 | @override 13 | State createState() => _MyAppState(); 14 | } 15 | 16 | class _MyAppState extends State { 17 | bool lightTheme = true; 18 | Color currentColor = Colors.amber; 19 | List currentColors = [Colors.yellow, Colors.green]; 20 | List colorHistory = []; 21 | 22 | void changeColor(Color color) => setState(() => currentColor = color); 23 | void changeColors(List colors) => setState(() => currentColors = colors); 24 | 25 | @override 26 | Widget build(BuildContext context) { 27 | final foregroundColor = useWhiteForeground(currentColor) ? Colors.white : Colors.black; 28 | return AnimatedTheme( 29 | data: lightTheme ? ThemeData.light() : ThemeData.dark(), 30 | child: Builder(builder: (context) { 31 | return DefaultTabController( 32 | length: 3, 33 | child: Scaffold( 34 | floatingActionButton: FloatingActionButton.extended( 35 | onPressed: () => setState(() => lightTheme = !lightTheme), 36 | icon: Icon(lightTheme ? Icons.dark_mode_rounded : Icons.light_mode_rounded), 37 | label: Text(lightTheme ? 'Night' : ' Day '), 38 | backgroundColor: currentColor, 39 | foregroundColor: foregroundColor, 40 | elevation: 15, 41 | ), 42 | appBar: AppBar( 43 | title: const Text('Flutter Color Picker Example'), 44 | backgroundColor: currentColor, 45 | foregroundColor: foregroundColor, 46 | bottom: TabBar( 47 | labelColor: foregroundColor, 48 | tabs: const [ 49 | Tab(text: 'HSV/HSL/RGB'), 50 | Tab(text: 'Material'), 51 | Tab(text: 'Blocky'), 52 | ], 53 | ), 54 | ), 55 | body: TabBarView( 56 | children: [ 57 | HSVColorPickerExample( 58 | pickerColor: currentColor, 59 | onColorChanged: changeColor, 60 | colorHistory: colorHistory, 61 | onHistoryChanged: (List colors) => colorHistory = colors, 62 | ), 63 | MaterialColorPickerExample(pickerColor: currentColor, onColorChanged: changeColor), 64 | BlockColorPickerExample( 65 | pickerColor: currentColor, 66 | onColorChanged: changeColor, 67 | pickerColors: currentColors, 68 | onColorsChanged: changeColors, 69 | colorHistory: colorHistory, 70 | ), 71 | ], 72 | ), 73 | ), 74 | ); 75 | }), 76 | ); 77 | } 78 | } 79 | -------------------------------------------------------------------------------- /example/lib/pickers/block_picker.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/material.dart'; 2 | import 'package:flutter_colorpicker/flutter_colorpicker.dart'; 3 | 4 | const List colors = [ 5 | Colors.red, 6 | Colors.pink, 7 | Colors.purple, 8 | Colors.deepPurple, 9 | Colors.indigo, 10 | Colors.blue, 11 | Colors.lightBlue, 12 | Colors.cyan, 13 | Colors.teal, 14 | Colors.green, 15 | Colors.lightGreen, 16 | Colors.lime, 17 | Colors.yellow, 18 | Colors.amber, 19 | Colors.orange, 20 | Colors.deepOrange, 21 | Colors.brown, 22 | Colors.grey, 23 | Colors.blueGrey, 24 | Colors.black, 25 | ]; 26 | 27 | class BlockColorPickerExample extends StatefulWidget { 28 | const BlockColorPickerExample({ 29 | Key? key, 30 | required this.pickerColor, 31 | required this.onColorChanged, 32 | required this.pickerColors, 33 | required this.onColorsChanged, 34 | required this.colorHistory, 35 | }) : super(key: key); 36 | 37 | final Color pickerColor; 38 | final ValueChanged onColorChanged; 39 | final List pickerColors; 40 | final ValueChanged> onColorsChanged; 41 | final List colorHistory; 42 | 43 | @override 44 | State createState() => _BlockColorPickerExampleState(); 45 | } 46 | 47 | class _BlockColorPickerExampleState extends State { 48 | int _portraitCrossAxisCount = 4; 49 | int _landscapeCrossAxisCount = 5; 50 | double _borderRadius = 30; 51 | double _blurRadius = 5; 52 | double _iconSize = 24; 53 | 54 | Widget pickerLayoutBuilder(BuildContext context, List colors, PickerItem child) { 55 | Orientation orientation = MediaQuery.of(context).orientation; 56 | 57 | return SizedBox( 58 | width: 300, 59 | height: orientation == Orientation.portrait ? 360 : 240, 60 | child: GridView.count( 61 | crossAxisCount: orientation == Orientation.portrait ? _portraitCrossAxisCount : _landscapeCrossAxisCount, 62 | crossAxisSpacing: 5, 63 | mainAxisSpacing: 5, 64 | children: [for (Color color in colors) child(color)], 65 | ), 66 | ); 67 | } 68 | 69 | Widget pickerItemBuilder(Color color, bool isCurrentColor, void Function() changeColor) { 70 | return Container( 71 | margin: const EdgeInsets.all(8), 72 | decoration: BoxDecoration( 73 | borderRadius: BorderRadius.circular(_borderRadius), 74 | color: color, 75 | boxShadow: [BoxShadow(color: color.withOpacity(0.8), offset: const Offset(1, 2), blurRadius: _blurRadius)], 76 | ), 77 | child: Material( 78 | color: Colors.transparent, 79 | child: InkWell( 80 | onTap: changeColor, 81 | borderRadius: BorderRadius.circular(_borderRadius), 82 | child: AnimatedOpacity( 83 | duration: const Duration(milliseconds: 250), 84 | opacity: isCurrentColor ? 1 : 0, 85 | child: Icon( 86 | Icons.done, 87 | size: _iconSize, 88 | color: useWhiteForeground(color) ? Colors.white : Colors.black, 89 | ), 90 | ), 91 | ), 92 | ), 93 | ); 94 | } 95 | 96 | @override 97 | Widget build(BuildContext context) { 98 | return ListView( 99 | children: [ 100 | const SizedBox(height: 20), 101 | Center( 102 | child: ElevatedButton( 103 | onPressed: () { 104 | showDialog( 105 | context: context, 106 | builder: (BuildContext context) { 107 | return AlertDialog( 108 | titlePadding: const EdgeInsets.all(0), 109 | contentPadding: const EdgeInsets.all(25), 110 | content: SingleChildScrollView( 111 | child: Text( 112 | ''' 113 | Widget pickerLayoutBuilder(BuildContext context, List colors, PickerItem child) { 114 | Orientation orientation = MediaQuery.of(context).orientation; 115 | 116 | return SizedBox( 117 | width: 300, 118 | height: orientation == Orientation.portrait ? 360 : 240, 119 | child: GridView.count( 120 | crossAxisCount: orientation == Orientation.portrait ? $_portraitCrossAxisCount : $_landscapeCrossAxisCount, 121 | crossAxisSpacing: 5, 122 | mainAxisSpacing: 5, 123 | children: [for (Color color in colors) child(color)], 124 | ), 125 | ); 126 | } 127 | ''', 128 | ), 129 | ), 130 | ); 131 | }, 132 | ); 133 | }, 134 | child: Icon(Icons.code, color: useWhiteForeground(widget.pickerColor) ? Colors.white : Colors.black), 135 | style: ElevatedButton.styleFrom( 136 | backgroundColor: widget.pickerColor, 137 | shadowColor: widget.pickerColor.withOpacity(1), 138 | elevation: 10, 139 | ), 140 | ), 141 | ), 142 | ListTile( 143 | title: const Text('Portrait Cross Axis Count'), 144 | subtitle: Text(_portraitCrossAxisCount.toString()), 145 | trailing: SizedBox( 146 | width: 200, 147 | child: Slider( 148 | value: _portraitCrossAxisCount.toDouble(), 149 | min: 1, 150 | max: 10, 151 | divisions: 9, 152 | label: _portraitCrossAxisCount.toString(), 153 | onChanged: (double value) => setState(() => _portraitCrossAxisCount = value.round()), 154 | ), 155 | ), 156 | ), 157 | ListTile( 158 | title: const Text('Landscape Cross Axis Count'), 159 | subtitle: Text(_landscapeCrossAxisCount.toString()), 160 | trailing: SizedBox( 161 | width: 200, 162 | child: Slider( 163 | value: _landscapeCrossAxisCount.toDouble(), 164 | min: 1, 165 | max: 10, 166 | divisions: 9, 167 | label: _landscapeCrossAxisCount.toString(), 168 | onChanged: (double value) => setState(() => _landscapeCrossAxisCount = value.round()), 169 | ), 170 | ), 171 | ), 172 | const Divider(), 173 | const SizedBox(height: 20), 174 | Center( 175 | child: ElevatedButton( 176 | onPressed: () { 177 | showDialog( 178 | context: context, 179 | builder: (BuildContext context) { 180 | return AlertDialog( 181 | titlePadding: const EdgeInsets.all(0), 182 | contentPadding: const EdgeInsets.all(25), 183 | content: SingleChildScrollView( 184 | child: Text( 185 | ''' 186 | Widget pickerItemBuilder(Color color, bool isCurrentColor, void Function() changeColor) { 187 | return Container( 188 | margin: const EdgeInsets.all(8), 189 | decoration: BoxDecoration( 190 | borderRadius: BorderRadius.circular($_borderRadius), 191 | color: color, 192 | boxShadow: [BoxShadow(color: color.withOpacity(0.8), offset: const Offset(1, 2), blurRadius: $_blurRadius)], 193 | ), 194 | child: Material( 195 | color: Colors.transparent, 196 | child: InkWell( 197 | onTap: changeColor, 198 | borderRadius: BorderRadius.circular(_borderRadius), 199 | child: AnimatedOpacity( 200 | duration: const Duration(milliseconds: 250), 201 | opacity: isCurrentColor ? 1 : 0, 202 | child: Icon( 203 | Icons.done, 204 | size: $_iconSize, 205 | color: useWhiteForeground(color) ? Colors.white : Colors.black, 206 | ), 207 | ), 208 | ), 209 | ), 210 | ); 211 | } 212 | ''', 213 | ), 214 | ), 215 | ); 216 | }, 217 | ); 218 | }, 219 | child: Icon(Icons.code, color: useWhiteForeground(widget.pickerColor) ? Colors.white : Colors.black), 220 | style: ElevatedButton.styleFrom( 221 | backgroundColor: widget.pickerColor, 222 | shadowColor: widget.pickerColor.withOpacity(1), 223 | elevation: 10, 224 | ), 225 | ), 226 | ), 227 | ListTile( 228 | title: const Text('Border Radius'), 229 | subtitle: Text(_borderRadius.toString()), 230 | trailing: SizedBox( 231 | width: 200, 232 | child: Slider( 233 | value: _borderRadius, 234 | min: 0, 235 | max: 30, 236 | divisions: 30, 237 | label: _borderRadius.toString(), 238 | onChanged: (double value) => setState(() => _borderRadius = value.round().toDouble()), 239 | ), 240 | ), 241 | ), 242 | ListTile( 243 | title: const Text('Blur Radius'), 244 | subtitle: Text(_blurRadius.toString()), 245 | trailing: SizedBox( 246 | width: 200, 247 | child: Slider( 248 | value: _blurRadius, 249 | min: 0, 250 | max: 5, 251 | divisions: 5, 252 | label: _blurRadius.toString(), 253 | onChanged: (double value) => setState(() => _blurRadius = value.round().toDouble()), 254 | ), 255 | ), 256 | ), 257 | ListTile( 258 | title: const Text('Icon Size'), 259 | subtitle: Text(_iconSize.toString()), 260 | trailing: SizedBox( 261 | width: 200, 262 | child: Slider( 263 | value: _iconSize, 264 | min: 1, 265 | max: 50, 266 | divisions: 49, 267 | label: _iconSize.toString(), 268 | onChanged: (double value) => setState(() => _iconSize = value.round().toDouble()), 269 | ), 270 | ), 271 | ), 272 | const Divider(), 273 | const SizedBox(height: 20), 274 | Row( 275 | mainAxisSize: MainAxisSize.min, 276 | mainAxisAlignment: MainAxisAlignment.center, 277 | children: [ 278 | ElevatedButton( 279 | onPressed: () { 280 | showDialog( 281 | context: context, 282 | builder: (BuildContext context) { 283 | return AlertDialog( 284 | title: const Text('Select a color'), 285 | content: SingleChildScrollView( 286 | child: BlockPicker( 287 | pickerColor: widget.pickerColor, 288 | onColorChanged: widget.onColorChanged, 289 | availableColors: widget.colorHistory.isNotEmpty ? widget.colorHistory : colors, 290 | layoutBuilder: pickerLayoutBuilder, 291 | itemBuilder: pickerItemBuilder, 292 | ), 293 | ), 294 | ); 295 | }, 296 | ); 297 | }, 298 | child: Text( 299 | 'Blocky Color Picker', 300 | style: TextStyle(color: useWhiteForeground(widget.pickerColor) ? Colors.white : Colors.black), 301 | ), 302 | style: ElevatedButton.styleFrom( 303 | backgroundColor: widget.pickerColor, 304 | shadowColor: widget.pickerColor.withOpacity(1), 305 | elevation: 10, 306 | ), 307 | ), 308 | const SizedBox(width: 20), 309 | ElevatedButton( 310 | onPressed: () { 311 | showDialog( 312 | context: context, 313 | builder: (BuildContext context) { 314 | return const AlertDialog( 315 | titlePadding: EdgeInsets.all(0), 316 | contentPadding: EdgeInsets.all(25), 317 | content: SingleChildScrollView( 318 | child: Text( 319 | ''' 320 | BlockPicker( 321 | pickerColor: color, 322 | onColorChanged: changeColor, 323 | availableColors: colors, 324 | layoutBuilder: pickerLayoutBuilder, 325 | itemBuilder: pickerItemBuilder, 326 | ) 327 | ''', 328 | ), 329 | ), 330 | ); 331 | }, 332 | ); 333 | }, 334 | child: Icon(Icons.code, color: useWhiteForeground(widget.pickerColor) ? Colors.white : Colors.black), 335 | style: ElevatedButton.styleFrom( 336 | backgroundColor: widget.pickerColor, 337 | shadowColor: widget.pickerColor.withOpacity(1), 338 | elevation: 10, 339 | ), 340 | ), 341 | ], 342 | ), 343 | const SizedBox(height: 20), 344 | const Divider(), 345 | const SizedBox(height: 20), 346 | Row( 347 | mainAxisSize: MainAxisSize.min, 348 | mainAxisAlignment: MainAxisAlignment.center, 349 | children: [ 350 | ElevatedButton( 351 | onPressed: () { 352 | showDialog( 353 | context: context, 354 | builder: (BuildContext context) { 355 | return AlertDialog( 356 | title: const Text('Select colors'), 357 | content: SingleChildScrollView( 358 | child: MultipleChoiceBlockPicker( 359 | pickerColors: widget.pickerColors, 360 | onColorsChanged: widget.onColorsChanged, 361 | availableColors: widget.colorHistory.isNotEmpty ? widget.colorHistory : colors, 362 | layoutBuilder: pickerLayoutBuilder, 363 | itemBuilder: pickerItemBuilder, 364 | ), 365 | ), 366 | ); 367 | }, 368 | ); 369 | }, 370 | child: Text( 371 | 'Multiple selection Blocky Color Picker', 372 | style: TextStyle(color: useWhiteForeground(widget.pickerColor) ? Colors.white : Colors.black), 373 | ), 374 | style: ElevatedButton.styleFrom( 375 | backgroundColor: widget.pickerColor, 376 | shadowColor: widget.pickerColor.withOpacity(1), 377 | elevation: 10, 378 | ), 379 | ), 380 | const SizedBox(width: 20), 381 | ElevatedButton( 382 | onPressed: () { 383 | showDialog( 384 | context: context, 385 | builder: (BuildContext context) { 386 | return const AlertDialog( 387 | titlePadding: EdgeInsets.all(0), 388 | contentPadding: EdgeInsets.all(25), 389 | content: SingleChildScrollView( 390 | child: Text( 391 | ''' 392 | MultipleChoiceBlockPicker( 393 | pickerColors: colors, 394 | onColorsChanged: changeColors, 395 | availableColors: colors, 396 | layoutBuilder: pickerLayoutBuilder, 397 | itemBuilder: pickerItemBuilder, 398 | ) 399 | ''', 400 | ), 401 | ), 402 | ); 403 | }, 404 | ); 405 | }, 406 | child: Icon(Icons.code, color: useWhiteForeground(widget.pickerColor) ? Colors.white : Colors.black), 407 | style: ElevatedButton.styleFrom( 408 | backgroundColor: widget.pickerColor, 409 | shadowColor: widget.pickerColor.withOpacity(1), 410 | elevation: 10, 411 | ), 412 | ), 413 | ], 414 | ), 415 | const SizedBox(height: 80), 416 | ], 417 | ); 418 | } 419 | } 420 | -------------------------------------------------------------------------------- /example/lib/pickers/hsv_picker.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/cupertino.dart' show CupertinoTextField; 2 | import 'package:flutter/material.dart'; 3 | import 'package:flutter/services.dart'; 4 | import 'package:flutter_colorpicker/flutter_colorpicker.dart'; 5 | 6 | // Just an example of how to use/interpret/format text input's result. 7 | void copyToClipboard(String input) { 8 | String textToCopy = input.replaceFirst('#', '').toUpperCase(); 9 | if (textToCopy.startsWith('FF') && textToCopy.length == 8) { 10 | textToCopy = textToCopy.replaceFirst('FF', ''); 11 | } 12 | Clipboard.setData(ClipboardData(text: '#$textToCopy')); 13 | } 14 | 15 | class HSVColorPickerExample extends StatefulWidget { 16 | const HSVColorPickerExample({ 17 | Key? key, 18 | required this.pickerColor, 19 | required this.onColorChanged, 20 | this.colorHistory, 21 | this.onHistoryChanged, 22 | }) : super(key: key); 23 | 24 | final Color pickerColor; 25 | final ValueChanged onColorChanged; 26 | final List? colorHistory; 27 | final ValueChanged>? onHistoryChanged; 28 | 29 | @override 30 | State createState() => _HSVColorPickerExampleState(); 31 | } 32 | 33 | class _HSVColorPickerExampleState extends State { 34 | // Picker 1 35 | PaletteType _paletteType = PaletteType.hsl; 36 | bool _enableAlpha = true; 37 | bool _displayThumbColor = true; 38 | final List _labelTypes = [ColorLabelType.hsl, ColorLabelType.hsv]; 39 | bool _displayHexInputBar = false; 40 | 41 | // Picker 2 42 | bool _displayThumbColor2 = true; 43 | bool _enableAlpha2 = false; 44 | 45 | // Picker 3 46 | ColorModel _colorModel = ColorModel.rgb; 47 | bool _enableAlpha3 = false; 48 | bool _displayThumbColor3 = true; 49 | bool _showParams = true; 50 | bool _showIndicator = true; 51 | 52 | // Picker 4 53 | final textController = 54 | TextEditingController(text: '#2F19DB'); // The initial value can be provided directly to the controller. 55 | bool _enableAlpha4 = true; 56 | 57 | @override 58 | void dispose() { 59 | textController.dispose(); 60 | super.dispose(); 61 | } 62 | 63 | @override 64 | Widget build(BuildContext context) { 65 | return ListView( 66 | children: [ 67 | const SizedBox(height: 20), 68 | Row( 69 | mainAxisSize: MainAxisSize.min, 70 | mainAxisAlignment: MainAxisAlignment.center, 71 | children: [ 72 | ElevatedButton( 73 | onPressed: () { 74 | showDialog( 75 | context: context, 76 | builder: (BuildContext context) { 77 | return AlertDialog( 78 | titlePadding: const EdgeInsets.all(0), 79 | contentPadding: const EdgeInsets.all(0), 80 | content: SingleChildScrollView( 81 | child: ColorPicker( 82 | pickerColor: widget.pickerColor, 83 | onColorChanged: widget.onColorChanged, 84 | colorPickerWidth: 300, 85 | pickerAreaHeightPercent: 0.7, 86 | enableAlpha: _enableAlpha, 87 | labelTypes: _labelTypes, 88 | displayThumbColor: _displayThumbColor, 89 | paletteType: _paletteType, 90 | pickerAreaBorderRadius: const BorderRadius.only( 91 | topLeft: Radius.circular(2), 92 | topRight: Radius.circular(2), 93 | ), 94 | hexInputBar: _displayHexInputBar, 95 | colorHistory: widget.colorHistory, 96 | onHistoryChanged: widget.onHistoryChanged, 97 | ), 98 | ), 99 | ); 100 | }, 101 | ); 102 | }, 103 | child: Text( 104 | 'Color Picker with Slider', 105 | style: TextStyle(color: useWhiteForeground(widget.pickerColor) ? Colors.white : Colors.black), 106 | ), 107 | style: ElevatedButton.styleFrom( 108 | backgroundColor: widget.pickerColor, 109 | shadowColor: widget.pickerColor.withOpacity(1), 110 | elevation: 10, 111 | ), 112 | ), 113 | const SizedBox(width: 20), 114 | ElevatedButton( 115 | onPressed: () { 116 | showDialog( 117 | context: context, 118 | builder: (BuildContext context) { 119 | return AlertDialog( 120 | content: SingleChildScrollView( 121 | child: Text( 122 | ''' 123 | ColorPicker( 124 | pickerColor: color, 125 | onColorChanged: changeColor, 126 | colorPickerWidth: 300, 127 | pickerAreaHeightPercent: 0.7, 128 | enableAlpha: $_enableAlpha, 129 | labelTypes: $_labelTypes, 130 | displayThumbColor: $_displayThumbColor, 131 | paletteType: $_paletteType, 132 | pickerAreaBorderRadius: const BorderRadius.only( 133 | topLeft: Radius.circular(2), 134 | topRight: Radius.circular(2), 135 | ), 136 | hexInputBar: $_displayHexInputBar, 137 | colorHistory: colorHistory, 138 | onHistoryChanged: changeColorHistory, 139 | ) 140 | ''', 141 | ), 142 | ), 143 | ); 144 | }, 145 | ); 146 | }, 147 | child: Icon(Icons.code, color: useWhiteForeground(widget.pickerColor) ? Colors.white : Colors.black), 148 | style: ElevatedButton.styleFrom( 149 | backgroundColor: widget.pickerColor, 150 | shadowColor: widget.pickerColor.withOpacity(1), 151 | elevation: 10, 152 | ), 153 | ), 154 | ], 155 | ), 156 | SwitchListTile( 157 | title: const Text('Enable Alpha Slider'), 158 | subtitle: const Text('Display alpha slider & label text'), 159 | value: _enableAlpha, 160 | onChanged: (bool value) => setState(() => _enableAlpha = !_enableAlpha), 161 | ), 162 | SwitchListTile( 163 | title: const Text('Display Thumb Color in slider'), 164 | value: _displayThumbColor, 165 | onChanged: (bool value) => setState(() => _displayThumbColor = !_displayThumbColor), 166 | ), 167 | ListTile( 168 | title: const Text('Palette Type'), 169 | trailing: DropdownButtonHideUnderline( 170 | child: DropdownButton( 171 | value: _paletteType, 172 | onChanged: (PaletteType? type) { 173 | if (type != null) setState(() => _paletteType = type); 174 | }, 175 | items: [ 176 | for (PaletteType type in PaletteType.values) 177 | DropdownMenuItem( 178 | value: type, 179 | child: SizedBox( 180 | width: 150, 181 | child: Text(type.toString().split('.').last, textAlign: TextAlign.end), 182 | ), 183 | ) 184 | ], 185 | ), 186 | ), 187 | ), 188 | ExpansionTile( 189 | title: Text(_labelTypes.isNotEmpty ? 'Display Label' : 'Disable Label'), 190 | subtitle: Text( 191 | _labelTypes.isNotEmpty ? _labelTypes.map((e) => e.toString().split('.').last.toUpperCase()).toString() : '', 192 | ), 193 | children: [ 194 | SwitchListTile( 195 | title: const Text(' Display HEX Label Text'), 196 | value: _labelTypes.contains(ColorLabelType.hex), 197 | onChanged: (bool value) => setState( 198 | () => value ? _labelTypes.add(ColorLabelType.hex) : _labelTypes.remove(ColorLabelType.hex), 199 | ), 200 | dense: true, 201 | ), 202 | SwitchListTile( 203 | title: const Text(' Display RGB Label Text'), 204 | value: _labelTypes.contains(ColorLabelType.rgb), 205 | onChanged: (bool value) => setState( 206 | () => value ? _labelTypes.add(ColorLabelType.rgb) : _labelTypes.remove(ColorLabelType.rgb), 207 | ), 208 | dense: true, 209 | ), 210 | SwitchListTile( 211 | title: const Text(' Display HSV Label Text'), 212 | value: _labelTypes.contains(ColorLabelType.hsv), 213 | onChanged: (bool value) => setState( 214 | () => value ? _labelTypes.add(ColorLabelType.hsv) : _labelTypes.remove(ColorLabelType.hsv), 215 | ), 216 | dense: true, 217 | ), 218 | SwitchListTile( 219 | title: const Text(' Display HSL Label Text'), 220 | value: _labelTypes.contains(ColorLabelType.hsl), 221 | onChanged: (bool value) => setState( 222 | () => value ? _labelTypes.add(ColorLabelType.hsl) : _labelTypes.remove(ColorLabelType.hsl), 223 | ), 224 | dense: true, 225 | ), 226 | ], 227 | ), 228 | SwitchListTile( 229 | title: const Text('Display Hex Input Bar'), 230 | value: _displayHexInputBar, 231 | onChanged: (bool value) => setState(() => _displayHexInputBar = !_displayHexInputBar), 232 | ), 233 | const Divider(), 234 | const SizedBox(height: 5), 235 | Row( 236 | mainAxisSize: MainAxisSize.min, 237 | mainAxisAlignment: MainAxisAlignment.center, 238 | children: [ 239 | ElevatedButton( 240 | onPressed: () { 241 | showDialog( 242 | context: context, 243 | builder: (BuildContext context) { 244 | return AlertDialog( 245 | titlePadding: const EdgeInsets.all(0), 246 | contentPadding: const EdgeInsets.all(0), 247 | shape: RoundedRectangleBorder( 248 | borderRadius: MediaQuery.of(context).orientation == Orientation.portrait 249 | ? const BorderRadius.vertical( 250 | top: Radius.circular(500), 251 | bottom: Radius.circular(100), 252 | ) 253 | : const BorderRadius.horizontal(right: Radius.circular(500)), 254 | ), 255 | content: SingleChildScrollView( 256 | child: HueRingPicker( 257 | pickerColor: widget.pickerColor, 258 | onColorChanged: widget.onColorChanged, 259 | enableAlpha: _enableAlpha2, 260 | displayThumbColor: _displayThumbColor2, 261 | ), 262 | ), 263 | ); 264 | }, 265 | ); 266 | }, 267 | child: Text( 268 | 'Hue Ring Picker with Hex Input', 269 | style: TextStyle(color: useWhiteForeground(widget.pickerColor) ? Colors.white : Colors.black), 270 | ), 271 | style: ElevatedButton.styleFrom( 272 | backgroundColor: widget.pickerColor, 273 | shadowColor: widget.pickerColor.withOpacity(1), 274 | elevation: 10, 275 | ), 276 | ), 277 | const SizedBox(width: 20), 278 | ElevatedButton( 279 | onPressed: () { 280 | showDialog( 281 | context: context, 282 | builder: (BuildContext context) { 283 | return AlertDialog( 284 | content: SingleChildScrollView( 285 | child: Text( 286 | ''' 287 | HueRingPicker( 288 | pickerColor: color, 289 | onColorChanged: changeColor, 290 | enableAlpha: $_enableAlpha2, 291 | displayThumbColor: $_displayThumbColor2, 292 | ) 293 | ''', 294 | ), 295 | ), 296 | ); 297 | }, 298 | ); 299 | }, 300 | child: Icon(Icons.code, color: useWhiteForeground(widget.pickerColor) ? Colors.white : Colors.black), 301 | style: ElevatedButton.styleFrom( 302 | backgroundColor: widget.pickerColor, 303 | shadowColor: widget.pickerColor.withOpacity(1), 304 | elevation: 10, 305 | ), 306 | ), 307 | ], 308 | ), 309 | SwitchListTile( 310 | title: const Text('Enable Alpha Slider'), 311 | value: _enableAlpha2, 312 | onChanged: (bool value) => setState(() => _enableAlpha2 = !_enableAlpha2), 313 | ), 314 | SwitchListTile( 315 | title: const Text('Display Thumb Color in Slider'), 316 | value: _displayThumbColor2, 317 | onChanged: (bool value) => setState(() => _displayThumbColor2 = !_displayThumbColor2), 318 | ), 319 | const Divider(), 320 | const SizedBox(height: 5), 321 | Row( 322 | mainAxisSize: MainAxisSize.min, 323 | mainAxisAlignment: MainAxisAlignment.center, 324 | children: [ 325 | ElevatedButton( 326 | onPressed: () { 327 | showDialog( 328 | context: context, 329 | builder: (BuildContext context) { 330 | return AlertDialog( 331 | titlePadding: const EdgeInsets.all(0), 332 | contentPadding: const EdgeInsets.all(0), 333 | shape: const RoundedRectangleBorder(borderRadius: BorderRadius.all(Radius.circular(25))), 334 | content: SingleChildScrollView( 335 | child: SlidePicker( 336 | pickerColor: widget.pickerColor, 337 | onColorChanged: widget.onColorChanged, 338 | colorModel: _colorModel, 339 | enableAlpha: _enableAlpha3, 340 | displayThumbColor: _displayThumbColor3, 341 | showParams: _showParams, 342 | showIndicator: _showIndicator, 343 | indicatorBorderRadius: const BorderRadius.vertical(top: Radius.circular(25)), 344 | ), 345 | ), 346 | ); 347 | }, 348 | ); 349 | }, 350 | child: Text( 351 | 'Slider-only Color Picker', 352 | style: TextStyle(color: useWhiteForeground(widget.pickerColor) ? Colors.white : Colors.black), 353 | ), 354 | style: ElevatedButton.styleFrom( 355 | backgroundColor: widget.pickerColor, 356 | shadowColor: widget.pickerColor.withOpacity(1), 357 | elevation: 10, 358 | ), 359 | ), 360 | const SizedBox(width: 20), 361 | ElevatedButton( 362 | onPressed: () { 363 | showDialog( 364 | context: context, 365 | builder: (BuildContext context) { 366 | return AlertDialog( 367 | content: SingleChildScrollView( 368 | child: Text( 369 | ''' 370 | SlidePicker( 371 | pickerColor: color, 372 | onColorChanged: changeColor, 373 | colorModel: $_colorModel, 374 | enableAlpha: $_enableAlpha3, 375 | displayThumbColor: $_displayThumbColor3, 376 | showParams: $_showParams, 377 | showIndicator: $_showIndicator, 378 | indicatorBorderRadius: const BorderRadius.vertical(top: Radius.circular(25)), 379 | ) 380 | ''', 381 | ), 382 | ), 383 | ); 384 | }, 385 | ); 386 | }, 387 | child: Icon(Icons.code, color: useWhiteForeground(widget.pickerColor) ? Colors.white : Colors.black), 388 | style: ElevatedButton.styleFrom( 389 | backgroundColor: widget.pickerColor, 390 | shadowColor: widget.pickerColor.withOpacity(1), 391 | elevation: 10, 392 | ), 393 | ), 394 | ], 395 | ), 396 | ListTile( 397 | title: const Text('Color Model'), 398 | trailing: DropdownButtonHideUnderline( 399 | child: DropdownButton( 400 | value: _colorModel, 401 | onChanged: (ColorModel? type) { 402 | if (type != null) setState(() => _colorModel = type); 403 | }, 404 | items: [ 405 | for (ColorModel type in ColorModel.values) 406 | DropdownMenuItem( 407 | value: type, 408 | child: SizedBox( 409 | width: 50, 410 | child: Text(type.toString().split('.').last, textAlign: TextAlign.end), 411 | ), 412 | ) 413 | ], 414 | ), 415 | ), 416 | ), 417 | SwitchListTile( 418 | title: const Text('Enable Alpha Slider'), 419 | value: _enableAlpha3, 420 | onChanged: (bool value) => setState(() => _enableAlpha3 = !_enableAlpha3), 421 | ), 422 | SwitchListTile( 423 | title: const Text('Display Thumb Color in Slider'), 424 | value: _displayThumbColor3, 425 | onChanged: (bool value) => setState(() => _displayThumbColor3 = !_displayThumbColor3), 426 | ), 427 | SwitchListTile( 428 | title: const Text('Show Parameters next to Slider'), 429 | value: _showParams, 430 | onChanged: (bool value) => setState(() => _showParams = !_showParams), 431 | ), 432 | SwitchListTile( 433 | title: const Text('Show Color Indicator'), 434 | value: _showIndicator, 435 | onChanged: (bool value) => setState(() => _showIndicator = !_showIndicator), 436 | ), 437 | const Divider(), 438 | const SizedBox(height: 15), 439 | Row( 440 | mainAxisSize: MainAxisSize.min, 441 | mainAxisAlignment: MainAxisAlignment.center, 442 | children: [ 443 | ElevatedButton( 444 | onPressed: () { 445 | showDialog( 446 | context: context, 447 | builder: (BuildContext context) { 448 | return AlertDialog( 449 | scrollable: true, 450 | titlePadding: const EdgeInsets.all(0), 451 | contentPadding: const EdgeInsets.all(0), 452 | content: Column( 453 | children: [ 454 | ColorPicker( 455 | pickerColor: widget.pickerColor, 456 | onColorChanged: widget.onColorChanged, 457 | colorPickerWidth: 300, 458 | pickerAreaHeightPercent: 0.7, 459 | enableAlpha: _enableAlpha4, // hexInputController will respect it too. 460 | displayThumbColor: true, 461 | paletteType: PaletteType.hsvWithHue, 462 | labelTypes: const [], 463 | pickerAreaBorderRadius: const BorderRadius.only( 464 | topLeft: Radius.circular(2), 465 | topRight: Radius.circular(2), 466 | ), 467 | hexInputController: textController, // <- here 468 | portraitOnly: true, 469 | ), 470 | Padding( 471 | padding: const EdgeInsets.fromLTRB(16, 0, 16, 16), 472 | /* It can be any text field, for example: 473 | 474 | * TextField 475 | * TextFormField 476 | * CupertinoTextField 477 | * EditableText 478 | * any text field from 3-rd party package 479 | * your own text field 480 | 481 | so basically anything that supports/uses 482 | a TextEditingController for an editable text. 483 | */ 484 | child: CupertinoTextField( 485 | controller: textController, 486 | // Everything below is purely optional. 487 | prefix: const Padding(padding: EdgeInsets.only(left: 8), child: Icon(Icons.tag)), 488 | suffix: IconButton( 489 | icon: const Icon(Icons.content_paste_rounded), 490 | onPressed: () => copyToClipboard(textController.text), 491 | ), 492 | autofocus: true, 493 | maxLength: 9, 494 | inputFormatters: [ 495 | // Any custom input formatter can be passed 496 | // here or use any Form validator you want. 497 | UpperCaseTextFormatter(), 498 | FilteringTextInputFormatter.allow(RegExp(kValidHexPattern)), 499 | ], 500 | ), 501 | ) 502 | ], 503 | ), 504 | ); 505 | }, 506 | ); 507 | }, 508 | child: Text( 509 | ' HSV Color Picker\n(Your own text field)', 510 | style: TextStyle(color: useWhiteForeground(widget.pickerColor) ? Colors.white : Colors.black), 511 | ), 512 | style: ElevatedButton.styleFrom( 513 | backgroundColor: widget.pickerColor, 514 | shadowColor: widget.pickerColor.withOpacity(1), 515 | elevation: 10, 516 | ), 517 | ), 518 | const SizedBox(width: 20), 519 | ElevatedButton( 520 | onPressed: () { 521 | showDialog( 522 | context: context, 523 | builder: (BuildContext context) { 524 | return AlertDialog( 525 | content: SingleChildScrollView( 526 | child: Text( 527 | ''' 528 | Column( 529 | children: [ 530 | ColorPicker( 531 | pickerColor: color, 532 | onColorChanged: changeColor, 533 | colorPickerWidth: 300, 534 | pickerAreaHeightPercent: 0.7, 535 | enableAlpha: $_enableAlpha4, 536 | displayThumbColor: true, 537 | paletteType: PaletteType.hsvWithHue, 538 | labelTypes: const [], 539 | pickerAreaBorderRadius: const BorderRadius.only( 540 | topLeft: Radius.circular(2), 541 | topRight: Radius.circular(2), 542 | ), 543 | hexInputController: textController, 544 | portraitOnly: true, 545 | ), 546 | Padding( 547 | padding: const EdgeInsets.fromLTRB(16, 0, 16, 16), 548 | child: CupertinoTextField( 549 | controller: textController, 550 | prefix: const Padding(padding: EdgeInsets.only(left: 8), child: Icon(Icons.tag)), 551 | suffix: IconButton( 552 | icon: const Icon(Icons.content_paste_rounded), 553 | onPressed: () => copyToClipboard(textController.text), 554 | ), 555 | autofocus: true, 556 | maxLength: 9, 557 | inputFormatters: [ 558 | UpperCaseTextFormatter(), 559 | FilteringTextInputFormatter.allow(RegExp(kValidHexPattern)), 560 | ], 561 | ), 562 | ) 563 | ], 564 | ) 565 | ''', 566 | ), 567 | ), 568 | ); 569 | }, 570 | ); 571 | }, 572 | child: Icon(Icons.code, color: useWhiteForeground(widget.pickerColor) ? Colors.white : Colors.black), 573 | style: ElevatedButton.styleFrom( 574 | backgroundColor: widget.pickerColor, 575 | shadowColor: widget.pickerColor.withOpacity(1), 576 | elevation: 10, 577 | ), 578 | ), 579 | ], 580 | ), 581 | SwitchListTile( 582 | title: const Text('Enable Alpha Slider'), 583 | value: _enableAlpha4, 584 | onChanged: (bool value) => setState(() => _enableAlpha4 = !_enableAlpha4), 585 | ), 586 | const SizedBox(height: 80), 587 | ], 588 | ); 589 | } 590 | } 591 | -------------------------------------------------------------------------------- /example/lib/pickers/material_picker.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/material.dart'; 2 | import 'package:flutter_colorpicker/flutter_colorpicker.dart'; 3 | 4 | class MaterialColorPickerExample extends StatefulWidget { 5 | const MaterialColorPickerExample({ 6 | Key? key, 7 | required this.pickerColor, 8 | required this.onColorChanged, 9 | }) : super(key: key); 10 | 11 | final Color pickerColor; 12 | final ValueChanged onColorChanged; 13 | 14 | @override 15 | State createState() => _MaterialColorPickerExampleState(); 16 | } 17 | 18 | class _MaterialColorPickerExampleState extends State { 19 | bool _enableLabel = true; 20 | bool _portraitOnly = false; 21 | 22 | @override 23 | Widget build(BuildContext context) { 24 | return ListView( 25 | children: [ 26 | const SizedBox(height: 20), 27 | Row( 28 | mainAxisSize: MainAxisSize.min, 29 | mainAxisAlignment: MainAxisAlignment.center, 30 | children: [ 31 | ElevatedButton( 32 | onPressed: () { 33 | showDialog( 34 | context: context, 35 | builder: (BuildContext context) { 36 | return AlertDialog( 37 | titlePadding: const EdgeInsets.all(0), 38 | contentPadding: const EdgeInsets.all(0), 39 | content: SingleChildScrollView( 40 | child: MaterialPicker( 41 | pickerColor: widget.pickerColor, 42 | onColorChanged: widget.onColorChanged, 43 | enableLabel: _enableLabel, 44 | portraitOnly: _portraitOnly, 45 | ), 46 | ), 47 | ); 48 | }, 49 | ); 50 | }, 51 | child: Text( 52 | 'Kiss Me with Your Finger', 53 | style: TextStyle(color: useWhiteForeground(widget.pickerColor) ? Colors.white : Colors.black), 54 | ), 55 | style: ElevatedButton.styleFrom( 56 | backgroundColor: widget.pickerColor, 57 | shadowColor: widget.pickerColor.withOpacity(1), 58 | elevation: 10, 59 | ), 60 | ), 61 | const SizedBox(width: 20), 62 | ElevatedButton( 63 | onPressed: () { 64 | showDialog( 65 | context: context, 66 | builder: (BuildContext context) { 67 | return AlertDialog( 68 | titlePadding: const EdgeInsets.all(0), 69 | contentPadding: const EdgeInsets.all(25), 70 | content: SingleChildScrollView( 71 | child: Text( 72 | ''' 73 | MaterialPicker( 74 | pickerColor: color, 75 | onColorChanged: changeColor, 76 | enableLabel: $_enableLabel, 77 | portraitOnly: $_portraitOnly, 78 | ) 79 | ''', 80 | ), 81 | ), 82 | ); 83 | }, 84 | ); 85 | }, 86 | child: Icon(Icons.code, color: useWhiteForeground(widget.pickerColor) ? Colors.white : Colors.black), 87 | style: ElevatedButton.styleFrom( 88 | backgroundColor: widget.pickerColor, 89 | shadowColor: widget.pickerColor.withOpacity(1), 90 | elevation: 10, 91 | ), 92 | ), 93 | ], 94 | ), 95 | SwitchListTile( 96 | title: const Text('Enable Label in Portrait Mode'), 97 | value: _enableLabel, 98 | onChanged: (bool value) => setState(() => _enableLabel = !_enableLabel), 99 | ), 100 | SwitchListTile( 101 | title: const Text('Apply Portrait layout to Landscape Mode'), 102 | value: _portraitOnly, 103 | onChanged: (bool value) => setState(() => _portraitOnly = !_portraitOnly), 104 | ), 105 | ], 106 | ); 107 | } 108 | } 109 | -------------------------------------------------------------------------------- /example/pubspec.lock: -------------------------------------------------------------------------------- 1 | # Generated by pub 2 | # See https://dart.dev/tools/pub/glossary#lockfile 3 | packages: 4 | characters: 5 | dependency: transitive 6 | description: 7 | name: characters 8 | sha256: "04a925763edad70e8443c99234dc3328f442e811f1d8fd1a72f1c8ad0f69a605" 9 | url: "https://pub.dev" 10 | source: hosted 11 | version: "1.3.0" 12 | collection: 13 | dependency: transitive 14 | description: 15 | name: collection 16 | sha256: ee67cb0715911d28db6bf4af1026078bd6f0128b07a5f66fb2ed94ec6783c09a 17 | url: "https://pub.dev" 18 | source: hosted 19 | version: "1.18.0" 20 | flutter: 21 | dependency: "direct main" 22 | description: flutter 23 | source: sdk 24 | version: "0.0.0" 25 | flutter_colorpicker: 26 | dependency: "direct main" 27 | description: 28 | path: ".." 29 | relative: true 30 | source: path 31 | version: "1.1.0" 32 | flutter_lints: 33 | dependency: "direct dev" 34 | description: 35 | name: flutter_lints 36 | sha256: b543301ad291598523947dc534aaddc5aaad597b709d2426d3a0e0d44c5cb493 37 | url: "https://pub.dev" 38 | source: hosted 39 | version: "1.0.4" 40 | lints: 41 | dependency: transitive 42 | description: 43 | name: lints 44 | sha256: a2c3d198cb5ea2e179926622d433331d8b58374ab8f29cdda6e863bd62fd369c 45 | url: "https://pub.dev" 46 | source: hosted 47 | version: "1.0.1" 48 | material_color_utilities: 49 | dependency: transitive 50 | description: 51 | name: material_color_utilities 52 | sha256: "0e0a020085b65b6083975e499759762399b4475f766c21668c4ecca34ea74e5a" 53 | url: "https://pub.dev" 54 | source: hosted 55 | version: "0.8.0" 56 | meta: 57 | dependency: transitive 58 | description: 59 | name: meta 60 | sha256: "7687075e408b093f36e6bbf6c91878cc0d4cd10f409506f7bc996f68220b9136" 61 | url: "https://pub.dev" 62 | source: hosted 63 | version: "1.12.0" 64 | sky_engine: 65 | dependency: transitive 66 | description: flutter 67 | source: sdk 68 | version: "0.0.99" 69 | vector_math: 70 | dependency: transitive 71 | description: 72 | name: vector_math 73 | sha256: "80b3257d1492ce4d091729e3a67a60407d227c27241d6927be0130c98e741803" 74 | url: "https://pub.dev" 75 | source: hosted 76 | version: "2.1.4" 77 | sdks: 78 | dart: ">=3.3.0-0 <4.0.0" 79 | flutter: ">=2.0.0" 80 | -------------------------------------------------------------------------------- /example/pubspec.yaml: -------------------------------------------------------------------------------- 1 | name: flutter_colorpicker_example 2 | description: A flutter_colorpicker example Flutter project. 3 | version: 1.0.0+1 4 | 5 | publish_to: none 6 | 7 | dependencies: 8 | flutter: 9 | sdk: flutter 10 | flutter_colorpicker: 11 | path: ../ 12 | 13 | dev_dependencies: 14 | flutter_lints: ^1.0.0 15 | 16 | flutter: 17 | uses-material-design: true 18 | 19 | environment: 20 | sdk: ">=2.12.0 <3.0.0" 21 | -------------------------------------------------------------------------------- /example/web/favicon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mchome/flutter_colorpicker/113618a20644abc0c5c74ea86866bd676284c707/example/web/favicon.png -------------------------------------------------------------------------------- /example/web/icons/Icon-192.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mchome/flutter_colorpicker/113618a20644abc0c5c74ea86866bd676284c707/example/web/icons/Icon-192.png -------------------------------------------------------------------------------- /example/web/icons/Icon-512.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mchome/flutter_colorpicker/113618a20644abc0c5c74ea86866bd676284c707/example/web/icons/Icon-512.png -------------------------------------------------------------------------------- /example/web/icons/Icon-maskable-192.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mchome/flutter_colorpicker/113618a20644abc0c5c74ea86866bd676284c707/example/web/icons/Icon-maskable-192.png -------------------------------------------------------------------------------- /example/web/icons/Icon-maskable-512.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mchome/flutter_colorpicker/113618a20644abc0c5c74ea86866bd676284c707/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 | Flutter Color Picker Example 33 | 34 | 35 | 36 | 39 | 103 | 104 | 105 | -------------------------------------------------------------------------------- /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 | -------------------------------------------------------------------------------- /flutter_colorpicker.iml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | -------------------------------------------------------------------------------- /lib/flutter_colorpicker.dart: -------------------------------------------------------------------------------- 1 | library flutter_colorpicker; 2 | 3 | export 'src/colorpicker.dart'; 4 | export 'src/material_picker.dart'; 5 | export 'src/block_picker.dart'; 6 | export 'src/palette.dart'; 7 | export 'src/utils.dart'; 8 | -------------------------------------------------------------------------------- /lib/src/block_picker.dart: -------------------------------------------------------------------------------- 1 | /// Blocky Color Picker 2 | 3 | library block_colorpicker; 4 | 5 | import 'package:flutter/material.dart'; 6 | import 'utils.dart'; 7 | 8 | /// Child widget for layout builder. 9 | typedef PickerItem = Widget Function(Color color); 10 | 11 | /// Customize the layout. 12 | typedef PickerLayoutBuilder = Widget Function(BuildContext context, List colors, PickerItem child); 13 | 14 | /// Customize the item shape. 15 | typedef PickerItemBuilder = Widget Function(Color color, bool isCurrentColor, void Function() changeColor); 16 | 17 | // Provide a list of colors for block color picker. 18 | const List _defaultColors = [ 19 | Colors.red, 20 | Colors.pink, 21 | Colors.purple, 22 | Colors.deepPurple, 23 | Colors.indigo, 24 | Colors.blue, 25 | Colors.lightBlue, 26 | Colors.cyan, 27 | Colors.teal, 28 | Colors.green, 29 | Colors.lightGreen, 30 | Colors.lime, 31 | Colors.yellow, 32 | Colors.amber, 33 | Colors.orange, 34 | Colors.deepOrange, 35 | Colors.brown, 36 | Colors.grey, 37 | Colors.blueGrey, 38 | Colors.black, 39 | ]; 40 | 41 | // Provide a layout for [BlockPicker]. 42 | Widget _defaultLayoutBuilder(BuildContext context, List colors, PickerItem child) { 43 | Orientation orientation = MediaQuery.of(context).orientation; 44 | 45 | return SizedBox( 46 | width: 300, 47 | height: orientation == Orientation.portrait ? 360 : 200, 48 | child: GridView.count( 49 | crossAxisCount: orientation == Orientation.portrait ? 4 : 6, 50 | crossAxisSpacing: 5, 51 | mainAxisSpacing: 5, 52 | children: [for (Color color in colors) child(color)], 53 | ), 54 | ); 55 | } 56 | 57 | // Provide a shape for [BlockPicker]. 58 | Widget _defaultItemBuilder(Color color, bool isCurrentColor, void Function() changeColor) { 59 | return Container( 60 | margin: const EdgeInsets.all(7), 61 | decoration: BoxDecoration( 62 | shape: BoxShape.circle, 63 | color: color, 64 | boxShadow: [BoxShadow(color: color.withOpacity(0.8), offset: const Offset(1, 2), blurRadius: 5)], 65 | ), 66 | child: Material( 67 | color: Colors.transparent, 68 | child: InkWell( 69 | onTap: changeColor, 70 | borderRadius: BorderRadius.circular(50), 71 | child: AnimatedOpacity( 72 | duration: const Duration(milliseconds: 210), 73 | opacity: isCurrentColor ? 1 : 0, 74 | child: Icon(Icons.done, color: useWhiteForeground(color) ? Colors.white : Colors.black), 75 | ), 76 | ), 77 | ), 78 | ); 79 | } 80 | 81 | // The blocky color picker you can alter the layout and shape. 82 | class BlockPicker extends StatefulWidget { 83 | const BlockPicker({ 84 | Key? key, 85 | required this.pickerColor, 86 | required this.onColorChanged, 87 | this.availableColors = _defaultColors, 88 | this.useInShowDialog = true, 89 | this.layoutBuilder = _defaultLayoutBuilder, 90 | this.itemBuilder = _defaultItemBuilder, 91 | }) : super(key: key); 92 | 93 | final Color? pickerColor; 94 | final ValueChanged onColorChanged; 95 | final List availableColors; 96 | final bool useInShowDialog; 97 | final PickerLayoutBuilder layoutBuilder; 98 | final PickerItemBuilder itemBuilder; 99 | 100 | @override 101 | State createState() => _BlockPickerState(); 102 | } 103 | 104 | class _BlockPickerState extends State { 105 | Color? _currentColor; 106 | 107 | @override 108 | void initState() { 109 | _currentColor = widget.pickerColor; 110 | super.initState(); 111 | } 112 | 113 | void changeColor(Color color) { 114 | setState(() => _currentColor = color); 115 | widget.onColorChanged(color); 116 | } 117 | 118 | @override 119 | Widget build(BuildContext context) { 120 | return widget.layoutBuilder( 121 | context, 122 | widget.availableColors, 123 | (Color color) => widget.itemBuilder( 124 | color, 125 | (_currentColor != null && (widget.useInShowDialog ? true : widget.pickerColor != null)) 126 | ? (_currentColor?.value == color.value) && 127 | (widget.useInShowDialog ? true : widget.pickerColor?.value == color.value) 128 | : false, 129 | () => changeColor(color), 130 | ), 131 | ); 132 | } 133 | } 134 | 135 | // The blocky color picker you can alter the layout and shape with multiple choice. 136 | class MultipleChoiceBlockPicker extends StatefulWidget { 137 | const MultipleChoiceBlockPicker({ 138 | Key? key, 139 | required this.pickerColors, 140 | required this.onColorsChanged, 141 | this.availableColors = _defaultColors, 142 | this.useInShowDialog = true, 143 | this.layoutBuilder = _defaultLayoutBuilder, 144 | this.itemBuilder = _defaultItemBuilder, 145 | }) : super(key: key); 146 | 147 | final List? pickerColors; 148 | final ValueChanged> onColorsChanged; 149 | final List availableColors; 150 | final bool useInShowDialog; 151 | final PickerLayoutBuilder layoutBuilder; 152 | final PickerItemBuilder itemBuilder; 153 | 154 | @override 155 | State createState() => _MultipleChoiceBlockPickerState(); 156 | } 157 | 158 | class _MultipleChoiceBlockPickerState extends State { 159 | List? _currentColors; 160 | 161 | @override 162 | void initState() { 163 | _currentColors = widget.pickerColors; 164 | super.initState(); 165 | } 166 | 167 | void toggleColor(Color color) { 168 | setState(() { 169 | if (_currentColors != null) { 170 | _currentColors!.contains(color) ? _currentColors!.remove(color) : _currentColors!.add(color); 171 | } 172 | }); 173 | widget.onColorsChanged(_currentColors ?? []); 174 | } 175 | 176 | @override 177 | Widget build(BuildContext context) { 178 | return widget.layoutBuilder( 179 | context, 180 | widget.availableColors, 181 | (Color color) => widget.itemBuilder( 182 | color, 183 | (_currentColors != null && (widget.useInShowDialog ? true : widget.pickerColors != null)) 184 | ? _currentColors!.contains(color) && (widget.useInShowDialog ? true : widget.pickerColors!.contains(color)) 185 | : false, 186 | () => toggleColor(color), 187 | ), 188 | ); 189 | } 190 | } 191 | -------------------------------------------------------------------------------- /lib/src/colors.dart: -------------------------------------------------------------------------------- 1 | import 'dart:ui'; 2 | 3 | /// X11 Colors 4 | /// 5 | /// https://en.wikipedia.org/wiki/X11_color_names 6 | 7 | const Map x11Colors = { 8 | 'aliceblue': Color(0xfff0f8ff), 9 | 'antiquewhite': Color(0xfffaebd7), 10 | 'aqua': Color(0xff00ffff), 11 | 'aquamarine': Color(0xff7fffd4), 12 | 'azure': Color(0xfff0ffff), 13 | 'beige': Color(0xfff5f5dc), 14 | 'bisque': Color(0xffffe4c4), 15 | 'black': Color(0xff000000), 16 | 'blanchedalmond': Color(0xffffebcd), 17 | 'blue': Color(0xff0000ff), 18 | 'blueviolet': Color(0xff8a2be2), 19 | 'brown': Color(0xffa52a2a), 20 | 'burlywood': Color(0xffdeb887), 21 | 'cadetblue': Color(0xff5f9ea0), 22 | 'chartreuse': Color(0xff7fff00), 23 | 'chocolate': Color(0xffd2691e), 24 | 'coral': Color(0xffff7f50), 25 | 'cornflower': Color(0xff6495ed), 26 | 'cornflowerblue': Color(0xff6495ed), 27 | 'cornsilk': Color(0xfffff8dc), 28 | 'crimson': Color(0xffdc143c), 29 | 'cyan': Color(0xff00ffff), 30 | 'darkblue': Color(0xff00008b), 31 | 'darkcyan': Color(0xff008b8b), 32 | 'darkgoldenrod': Color(0xffb8860b), 33 | 'darkgray': Color(0xffa9a9a9), 34 | 'darkgreen': Color(0xff006400), 35 | 'darkgrey': Color(0xffa9a9a9), 36 | 'darkkhaki': Color(0xffbdb76b), 37 | 'darkmagenta': Color(0xff8b008b), 38 | 'darkolivegreen': Color(0xff556b2f), 39 | 'darkorange': Color(0xffff8c00), 40 | 'darkorchid': Color(0xff9932cc), 41 | 'darkred': Color(0xff8b0000), 42 | 'darksalmon': Color(0xffe9967a), 43 | 'darkseagreen': Color(0xff8fbc8f), 44 | 'darkslateblue': Color(0xff483d8b), 45 | 'darkslategray': Color(0xff2f4f4f), 46 | 'darkslategrey': Color(0xff2f4f4f), 47 | 'darkturquoise': Color(0xff00ced1), 48 | 'darkviolet': Color(0xff9400d3), 49 | 'deeppink': Color(0xffff1493), 50 | 'deepskyblue': Color(0xff00bfff), 51 | 'dimgray': Color(0xff696969), 52 | 'dimgrey': Color(0xff696969), 53 | 'dodgerblue': Color(0xff1e90ff), 54 | 'firebrick': Color(0xffb22222), 55 | 'floralwhite': Color(0xfffffaf0), 56 | 'forestgreen': Color(0xff228b22), 57 | 'fuchsia': Color(0xffff00ff), 58 | 'gainsboro': Color(0xffdcdcdc), 59 | 'ghostwhite': Color(0xfff8f8ff), 60 | 'gold': Color(0xffffd700), 61 | 'goldenrod': Color(0xffdaa520), 62 | 'gray': Color(0xff808080), 63 | 'green': Color(0xff008000), 64 | 'greenyellow': Color(0xffadff2f), 65 | 'grey': Color(0xff808080), 66 | 'honeydew': Color(0xfff0fff0), 67 | 'hotpink': Color(0xffff69b4), 68 | 'indianred': Color(0xffcd5c5c), 69 | 'indigo': Color(0xff4b0082), 70 | 'ivory': Color(0xfffffff0), 71 | 'khaki': Color(0xfff0e68c), 72 | 'laserlemon': Color(0xffffff54), 73 | 'lavender': Color(0xffe6e6fa), 74 | 'lavenderblush': Color(0xfffff0f5), 75 | 'lawngreen': Color(0xff7cfc00), 76 | 'lemonchiffon': Color(0xfffffacd), 77 | 'lightblue': Color(0xffadd8e6), 78 | 'lightcoral': Color(0xfff08080), 79 | 'lightcyan': Color(0xffe0ffff), 80 | 'lightgoldenrod': Color(0xfffafad2), 81 | 'lightgoldenrodyellow': Color(0xfffafad2), 82 | 'lightgray': Color(0xffd3d3d3), 83 | 'lightgreen': Color(0xff90ee90), 84 | 'lightgrey': Color(0xffd3d3d3), 85 | 'lightpink': Color(0xffffb6c1), 86 | 'lightsalmon': Color(0xffffa07a), 87 | 'lightseagreen': Color(0xff20b2aa), 88 | 'lightskyblue': Color(0xff87cefa), 89 | 'lightslategray': Color(0xff778899), 90 | 'lightslategrey': Color(0xff778899), 91 | 'lightsteelblue': Color(0xffb0c4de), 92 | 'lightyellow': Color(0xffffffe0), 93 | 'lime': Color(0xff00ff00), 94 | 'limegreen': Color(0xff32cd32), 95 | 'linen': Color(0xfffaf0e6), 96 | 'magenta': Color(0xffff00ff), 97 | 'maroon': Color(0xff800000), 98 | 'maroon2': Color(0xff7f0000), 99 | 'maroon3': Color(0xffb03060), 100 | 'mediumaquamarine': Color(0xff66cdaa), 101 | 'mediumblue': Color(0xff0000cd), 102 | 'mediumorchid': Color(0xffba55d3), 103 | 'mediumpurple': Color(0xff9370db), 104 | 'mediumseagreen': Color(0xff3cb371), 105 | 'mediumslateblue': Color(0xff7b68ee), 106 | 'mediumspringgreen': Color(0xff00fa9a), 107 | 'mediumturquoise': Color(0xff48d1cc), 108 | 'mediumvioletred': Color(0xffc71585), 109 | 'midnightblue': Color(0xff191970), 110 | 'mintcream': Color(0xfff5fffa), 111 | 'mistyrose': Color(0xffffe4e1), 112 | 'moccasin': Color(0xffffe4b5), 113 | 'navajowhite': Color(0xffffdead), 114 | 'navy': Color(0xff000080), 115 | 'oldlace': Color(0xfffdf5e6), 116 | 'olive': Color(0xff808000), 117 | 'olivedrab': Color(0xff6b8e23), 118 | 'orange': Color(0xffffa500), 119 | 'orangered': Color(0xffff4500), 120 | 'orchid': Color(0xffda70d6), 121 | 'palegoldenrod': Color(0xffeee8aa), 122 | 'palegreen': Color(0xff98fb98), 123 | 'paleturquoise': Color(0xffafeeee), 124 | 'palevioletred': Color(0xffdb7093), 125 | 'papayawhip': Color(0xffffefd5), 126 | 'peachpuff': Color(0xffffdab9), 127 | 'peru': Color(0xffcd853f), 128 | 'pink': Color(0xffffc0cb), 129 | 'plum': Color(0xffdda0dd), 130 | 'powderblue': Color(0xffb0e0e6), 131 | 'purple': Color(0xff800080), 132 | 'purple2': Color(0xff7f007f), 133 | 'purple3': Color(0xffa020f0), 134 | 'rebeccapurple': Color(0xff663399), 135 | 'red': Color(0xffff0000), 136 | 'rosybrown': Color(0xffbc8f8f), 137 | 'royalblue': Color(0xff4169e1), 138 | 'saddlebrown': Color(0xff8b4513), 139 | 'salmon': Color(0xfffa8072), 140 | 'sandybrown': Color(0xfff4a460), 141 | 'seagreen': Color(0xff2e8b57), 142 | 'seashell': Color(0xfffff5ee), 143 | 'sienna': Color(0xffa0522d), 144 | 'silver': Color(0xffc0c0c0), 145 | 'skyblue': Color(0xff87ceeb), 146 | 'slateblue': Color(0xff6a5acd), 147 | 'slategray': Color(0xff708090), 148 | 'slategrey': Color(0xff708090), 149 | 'snow': Color(0xfffffafa), 150 | 'springgreen': Color(0xff00ff7f), 151 | 'steelblue': Color(0xff4682b4), 152 | 'tan': Color(0xffd2b48c), 153 | 'teal': Color(0xff008080), 154 | 'thistle': Color(0xffd8bfd8), 155 | 'tomato': Color(0xffff6347), 156 | 'turquoise': Color(0xff40e0d0), 157 | 'violet': Color(0xffee82ee), 158 | 'wheat': Color(0xfff5deb3), 159 | 'white': Color(0xffffffff), 160 | 'whitesmoke': Color(0xfff5f5f5), 161 | 'yellow': Color(0xffffff00), 162 | 'yellowgreen': Color(0xff9acd32), 163 | }; 164 | 165 | Color? colorFromName(String val) => x11Colors[val.trim().replaceAll(' ', '').toLowerCase()]; 166 | 167 | extension ColorExtension on String { 168 | Color? toColor() => colorFromName(this); 169 | } 170 | -------------------------------------------------------------------------------- /lib/src/material_picker.dart: -------------------------------------------------------------------------------- 1 | /// Material Color Picker 2 | 3 | library material_colorpicker; 4 | 5 | import 'package:flutter/gestures.dart'; 6 | import 'package:flutter/material.dart'; 7 | import 'utils.dart'; 8 | 9 | // The Color Picker which contains Material Design Color Palette. 10 | class MaterialPicker extends StatefulWidget { 11 | const MaterialPicker({ 12 | Key? key, 13 | required this.pickerColor, 14 | required this.onColorChanged, 15 | this.onPrimaryChanged, 16 | this.enableLabel = false, 17 | this.portraitOnly = false, 18 | }) : super(key: key); 19 | 20 | final Color pickerColor; 21 | final ValueChanged onColorChanged; 22 | final ValueChanged? onPrimaryChanged; 23 | final bool enableLabel; 24 | final bool portraitOnly; 25 | 26 | @override 27 | State createState() => _MaterialPickerState(); 28 | } 29 | 30 | class _MaterialPickerState extends State { 31 | final List> _colorTypes = [ 32 | [Colors.red, Colors.redAccent], 33 | [Colors.pink, Colors.pinkAccent], 34 | [Colors.purple, Colors.purpleAccent], 35 | [Colors.deepPurple, Colors.deepPurpleAccent], 36 | [Colors.indigo, Colors.indigoAccent], 37 | [Colors.blue, Colors.blueAccent], 38 | [Colors.lightBlue, Colors.lightBlueAccent], 39 | [Colors.cyan, Colors.cyanAccent], 40 | [Colors.teal, Colors.tealAccent], 41 | [Colors.green, Colors.greenAccent], 42 | [Colors.lightGreen, Colors.lightGreenAccent], 43 | [Colors.lime, Colors.limeAccent], 44 | [Colors.yellow, Colors.yellowAccent], 45 | [Colors.amber, Colors.amberAccent], 46 | [Colors.orange, Colors.orangeAccent], 47 | [Colors.deepOrange, Colors.deepOrangeAccent], 48 | [Colors.brown], 49 | [Colors.grey], 50 | [Colors.blueGrey], 51 | [Colors.black], 52 | ]; 53 | 54 | List _currentColorType = [Colors.red, Colors.redAccent]; 55 | Color _currentShading = Colors.transparent; 56 | 57 | List> _shadingTypes(List colors) { 58 | List> result = []; 59 | 60 | for (Color colorType in colors) { 61 | if (colorType == Colors.grey) { 62 | result.addAll([50, 100, 200, 300, 350, 400, 500, 600, 700, 800, 850, 900] 63 | .map((int shade) => {Colors.grey[shade]!: shade.toString()}) 64 | .toList()); 65 | } else if (colorType == Colors.black || colorType == Colors.white) { 66 | result.addAll([ 67 | {Colors.black: ''}, 68 | {Colors.white: ''} 69 | ]); 70 | } else if (colorType is MaterialAccentColor) { 71 | result.addAll([100, 200, 400, 700].map((int shade) => {colorType[shade]!: 'A$shade'}).toList()); 72 | } else if (colorType is MaterialColor) { 73 | result.addAll([50, 100, 200, 300, 400, 500, 600, 700, 800, 900] 74 | .map((int shade) => {colorType[shade]!: shade.toString()}) 75 | .toList()); 76 | } else { 77 | result.add({const Color(0x00000000): ''}); 78 | } 79 | } 80 | 81 | return result; 82 | } 83 | 84 | @override 85 | void initState() { 86 | for (List _colors in _colorTypes) { 87 | _shadingTypes(_colors).forEach((Map color) { 88 | if (widget.pickerColor.value == color.keys.first.value) { 89 | return setState(() { 90 | _currentColorType = _colors; 91 | _currentShading = color.keys.first; 92 | }); 93 | } 94 | }); 95 | } 96 | super.initState(); 97 | } 98 | 99 | @override 100 | Widget build(BuildContext context) { 101 | bool _isPortrait = MediaQuery.of(context).orientation == Orientation.portrait || widget.portraitOnly; 102 | 103 | Widget _colorList() { 104 | return Container( 105 | clipBehavior: Clip.hardEdge, 106 | decoration: const BoxDecoration(), 107 | child: Container( 108 | margin: _isPortrait ? const EdgeInsets.only(right: 10) : const EdgeInsets.only(bottom: 10), 109 | width: _isPortrait ? 60 : null, 110 | height: _isPortrait ? null : 60, 111 | decoration: BoxDecoration( 112 | color: Theme.of(context).cardColor, 113 | boxShadow: [BoxShadow(color: (Theme.of(context).brightness == Brightness.light) ? (Theme.of(context).brightness == Brightness.light) ? Colors.grey[300]! : Colors.black38 : Colors.black38, blurRadius: 10)], 114 | border: _isPortrait 115 | ? Border(right: BorderSide(color: (Theme.of(context).brightness == Brightness.light) ? Colors.grey[300]! : Colors.black38, width: 1)) 116 | : Border(top: BorderSide(color: (Theme.of(context).brightness == Brightness.light) ? Colors.grey[300]! : Colors.black38, width: 1)), 117 | ), 118 | child: ScrollConfiguration( 119 | behavior: ScrollConfiguration.of(context).copyWith(dragDevices: PointerDeviceKind.values.toSet()), 120 | child: ListView( 121 | scrollDirection: _isPortrait ? Axis.vertical : Axis.horizontal, 122 | children: [ 123 | _isPortrait 124 | ? const Padding(padding: EdgeInsets.only(top: 7)) 125 | : const Padding(padding: EdgeInsets.only(left: 7)), 126 | ..._colorTypes.map((List _colors) { 127 | Color _colorType = _colors[0]; 128 | return GestureDetector( 129 | onTap: () { 130 | if (widget.onPrimaryChanged != null) widget.onPrimaryChanged!(_colorType); 131 | setState(() => _currentColorType = _colors); 132 | }, 133 | child: Container( 134 | color: const Color(0x00000000), 135 | padding: 136 | _isPortrait ? const EdgeInsets.fromLTRB(0, 7, 0, 7) : const EdgeInsets.fromLTRB(7, 0, 7, 0), 137 | child: Align( 138 | child: AnimatedContainer( 139 | duration: const Duration(milliseconds: 300), 140 | width: 25, 141 | height: 25, 142 | decoration: BoxDecoration( 143 | color: _colorType, 144 | shape: BoxShape.circle, 145 | boxShadow: _currentColorType == _colors 146 | ? [ 147 | _colorType == Theme.of(context).cardColor 148 | ? BoxShadow( 149 | color: (Theme.of(context).brightness == Brightness.light) ? Colors.grey[300]! : Colors.black38, 150 | blurRadius: 10, 151 | ) 152 | : BoxShadow( 153 | color: _colorType, 154 | blurRadius: 10, 155 | ), 156 | ] 157 | : null, 158 | border: _colorType == Theme.of(context).cardColor 159 | ? Border.all(color: (Theme.of(context).brightness == Brightness.light) ? Colors.grey[300]! : Colors.black38, width: 1) 160 | : null, 161 | ), 162 | ), 163 | ), 164 | ), 165 | ); 166 | }), 167 | _isPortrait 168 | ? const Padding(padding: EdgeInsets.only(top: 5)) 169 | : const Padding(padding: EdgeInsets.only(left: 5)), 170 | ], 171 | ), 172 | ), 173 | ), 174 | ); 175 | } 176 | 177 | Widget _shadingList() { 178 | return ScrollConfiguration( 179 | behavior: ScrollConfiguration.of(context).copyWith(dragDevices: PointerDeviceKind.values.toSet()), 180 | child: ListView( 181 | scrollDirection: _isPortrait ? Axis.vertical : Axis.horizontal, 182 | children: [ 183 | _isPortrait 184 | ? const Padding(padding: EdgeInsets.only(top: 15)) 185 | : const Padding(padding: EdgeInsets.only(left: 15)), 186 | ..._shadingTypes(_currentColorType).map((Map color) { 187 | final Color _color = color.keys.first; 188 | return GestureDetector( 189 | onTap: () { 190 | setState(() => _currentShading = _color); 191 | widget.onColorChanged(_color); 192 | }, 193 | child: Container( 194 | color: const Color(0x00000000), 195 | margin: _isPortrait ? const EdgeInsets.only(right: 10) : const EdgeInsets.only(bottom: 10), 196 | padding: _isPortrait ? const EdgeInsets.fromLTRB(0, 7, 0, 7) : const EdgeInsets.fromLTRB(7, 0, 7, 0), 197 | child: Align( 198 | child: AnimatedContainer( 199 | curve: Curves.fastOutSlowIn, 200 | duration: const Duration(milliseconds: 500), 201 | width: 202 | _isPortrait ? (_currentShading == _color ? 250 : 230) : (_currentShading == _color ? 50 : 30), 203 | height: _isPortrait ? 50 : 220, 204 | decoration: BoxDecoration( 205 | color: _color, 206 | boxShadow: _currentShading == _color 207 | ? [ 208 | (_color == Colors.white) || (_color == Colors.black) 209 | ? BoxShadow( 210 | color: (Theme.of(context).brightness == Brightness.light) ? Colors.grey[300]! : Colors.black38, 211 | blurRadius: 10, 212 | ) 213 | : BoxShadow( 214 | color: _color, 215 | blurRadius: 10, 216 | ), 217 | ] 218 | : null, 219 | border: (_color == Colors.white) || (_color == Colors.black) 220 | ? Border.all(color: (Theme.of(context).brightness == Brightness.light) ? Colors.grey[300]! : Colors.black38, width: 1) 221 | : null, 222 | ), 223 | child: widget.enableLabel 224 | ? _isPortrait 225 | ? Row( 226 | children: [ 227 | Text( 228 | ' ${color.values.first}', 229 | style: TextStyle(color: useWhiteForeground(_color) ? Colors.white : Colors.black), 230 | ), 231 | Expanded( 232 | child: Align( 233 | alignment: Alignment.centerRight, 234 | child: Text( 235 | '#${(_color.value.toRadixString(16).padLeft(8, '0')).substring(2).toUpperCase()} ', 236 | style: TextStyle( 237 | color: useWhiteForeground(_color) ? Colors.white : Colors.black, 238 | fontWeight: FontWeight.bold, 239 | ), 240 | ), 241 | ), 242 | ), 243 | ], 244 | ) 245 | : AnimatedOpacity( 246 | duration: const Duration(milliseconds: 300), 247 | opacity: _currentShading == _color ? 1 : 0, 248 | child: Container( 249 | padding: const EdgeInsets.only(top: 16), 250 | alignment: Alignment.topCenter, 251 | child: Text( 252 | color.values.first, 253 | style: TextStyle( 254 | color: useWhiteForeground(_color) ? Colors.white : Colors.black, 255 | fontWeight: FontWeight.bold, 256 | fontSize: 14, 257 | ), 258 | softWrap: false, 259 | ), 260 | ), 261 | ) 262 | : const SizedBox(), 263 | ), 264 | ), 265 | ), 266 | ); 267 | }), 268 | _isPortrait 269 | ? const Padding(padding: EdgeInsets.only(top: 15)) 270 | : const Padding(padding: EdgeInsets.only(left: 15)), 271 | ], 272 | ), 273 | ); 274 | } 275 | 276 | if (_isPortrait) { 277 | return SizedBox( 278 | width: 350, 279 | height: 500, 280 | child: Row( 281 | children: [ 282 | _colorList(), 283 | Expanded( 284 | child: Padding( 285 | padding: const EdgeInsets.symmetric(horizontal: 12), 286 | child: _shadingList(), 287 | ), 288 | ), 289 | ], 290 | ), 291 | ); 292 | } else { 293 | return SizedBox( 294 | width: 500, 295 | height: 300, 296 | child: Column( 297 | children: [ 298 | _colorList(), 299 | Expanded( 300 | child: Padding( 301 | padding: const EdgeInsets.symmetric(vertical: 12), 302 | child: _shadingList(), 303 | ), 304 | ), 305 | ], 306 | ), 307 | ); 308 | } 309 | } 310 | } 311 | -------------------------------------------------------------------------------- /lib/src/utils.dart: -------------------------------------------------------------------------------- 1 | // Common function lib 2 | 3 | import 'dart:math'; 4 | import 'package:flutter/painting.dart'; 5 | import 'colors.dart'; 6 | 7 | /// Check if is good condition to use white foreground color by passing 8 | /// the background color, and optional bias. 9 | /// 10 | /// Reference: 11 | /// 12 | /// Old: https://www.w3.org/TR/WCAG20-TECHS/G18.html 13 | /// 14 | /// New: https://github.com/mchome/flutter_statusbarcolor/issues/40 15 | bool useWhiteForeground(Color backgroundColor, {double bias = 0.0}) { 16 | // Old: 17 | // return 1.05 / (color.computeLuminance() + 0.05) > 4.5; 18 | 19 | // New: 20 | int v = sqrt(pow(backgroundColor.red, 2) * 0.299 + 21 | pow(backgroundColor.green, 2) * 0.587 + 22 | pow(backgroundColor.blue, 2) * 0.114) 23 | .round(); 24 | return v < 130 + bias ? true : false; 25 | } 26 | 27 | /// Convert HSV to HSL 28 | /// 29 | /// Reference: https://en.wikipedia.org/wiki/HSL_and_HSV#HSV_to_HSL 30 | HSLColor hsvToHsl(HSVColor color) { 31 | double s = 0.0; 32 | double l = 0.0; 33 | l = (2 - color.saturation) * color.value / 2; 34 | if (l != 0) { 35 | if (l == 1) { 36 | s = 0.0; 37 | } else if (l < 0.5) { 38 | s = color.saturation * color.value / (l * 2); 39 | } else { 40 | s = color.saturation * color.value / (2 - l * 2); 41 | } 42 | } 43 | return HSLColor.fromAHSL( 44 | color.alpha, 45 | color.hue, 46 | s.clamp(0.0, 1.0), 47 | l.clamp(0.0, 1.0), 48 | ); 49 | } 50 | 51 | /// Convert HSL to HSV 52 | /// 53 | /// Reference: https://en.wikipedia.org/wiki/HSL_and_HSV#HSL_to_HSV 54 | HSVColor hslToHsv(HSLColor color) { 55 | double s = 0.0; 56 | double v = 0.0; 57 | 58 | v = color.lightness + color.saturation * (color.lightness < 0.5 ? color.lightness : 1 - color.lightness); 59 | if (v != 0) s = 2 - 2 * color.lightness / v; 60 | 61 | return HSVColor.fromAHSV( 62 | color.alpha, 63 | color.hue, 64 | s.clamp(0.0, 1.0), 65 | v.clamp(0.0, 1.0), 66 | ); 67 | } 68 | 69 | /// [RegExp] pattern for validation HEX color [String] inputs, allows only: 70 | /// 71 | /// * exactly 1 to 8 digits in HEX format, 72 | /// * only Latin A-F characters, case insensitive, 73 | /// * and integer numbers 0,1,2,3,4,5,6,7,8,9, 74 | /// * with optional hash (`#`) symbol at the beginning (not calculated in length). 75 | /// 76 | /// ```dart 77 | /// final RegExp hexInputValidator = RegExp(kValidHexPattern); 78 | /// if (hexInputValidator.hasMatch(hex)) print('$hex might be a valid HEX color'); 79 | /// ``` 80 | /// Reference: https://en.wikipedia.org/wiki/Web_colors#Hex_triplet 81 | const String kValidHexPattern = r'^#?[0-9a-fA-F]{1,8}'; 82 | 83 | /// [RegExp] pattern for validation complete HEX color [String], allows only: 84 | /// 85 | /// * exactly 6 or 8 digits in HEX format, 86 | /// * only Latin A-F characters, case insensitive, 87 | /// * and integer numbers 0,1,2,3,4,5,6,7,8,9, 88 | /// * with optional hash (`#`) symbol at the beginning (not calculated in length). 89 | /// 90 | /// ```dart 91 | /// final RegExp hexCompleteValidator = RegExp(kCompleteValidHexPattern); 92 | /// if (hexCompleteValidator.hasMatch(hex)) print('$hex is valid HEX color'); 93 | /// ``` 94 | /// Reference: https://en.wikipedia.org/wiki/Web_colors#Hex_triplet 95 | const String kCompleteValidHexPattern = r'^#?([0-9a-fA-F]{3}|[0-9a-fA-F]{6}|[0-9a-fA-F]{8})$'; 96 | 97 | /// Try to convert text input or any [String] to valid [Color]. 98 | /// The [String] must be provided in one of those formats: 99 | /// 100 | /// * RGB 101 | /// * #RGB 102 | /// * RRGGBB 103 | /// * #RRGGBB 104 | /// * AARRGGBB 105 | /// * #AARRGGBB 106 | /// 107 | /// Where: A stands for Alpha, R for Red, G for Green, and B for blue color. 108 | /// It will only accept 3/6/8 long HEXs with an optional hash (`#`) at the beginning. 109 | /// Allowed characters are Latin A-F case insensitive and numbers 0-9. 110 | /// Optional [enableAlpha] can be provided (it's `true` by default). If it's set 111 | /// to `false` transparency information (alpha channel) will be removed. 112 | /// ```dart 113 | /// /// // Valid 3 digit HEXs: 114 | /// colorFromHex('abc') == Color(0xffaabbcc) 115 | /// colorFromHex('ABc') == Color(0xffaabbcc) 116 | /// colorFromHex('ABC') == Color(0xffaabbcc) 117 | /// colorFromHex('#Abc') == Color(0xffaabbcc) 118 | /// colorFromHex('#abc') == Color(0xffaabbcc) 119 | /// colorFromHex('#ABC') == Color(0xffaabbcc) 120 | /// // Valid 6 digit HEXs: 121 | /// colorFromHex('aabbcc') == Color(0xffaabbcc) 122 | /// colorFromHex('AABbcc') == Color(0xffaabbcc) 123 | /// colorFromHex('AABBCC') == Color(0xffaabbcc) 124 | /// colorFromHex('#AABbcc') == Color(0xffaabbcc) 125 | /// colorFromHex('#aabbcc') == Color(0xffaabbcc) 126 | /// colorFromHex('#AABBCC') == Color(0xffaabbcc) 127 | /// // Valid 8 digit HEXs: 128 | /// colorFromHex('ffaabbcc') == Color(0xffaabbcc) 129 | /// colorFromHex('ffAABbcc') == Color(0xffaabbcc) 130 | /// colorFromHex('ffAABBCC') == Color(0xffaabbcc) 131 | /// colorFromHex('ffaabbcc', enableAlpha: true) == Color(0xffaabbcc) 132 | /// colorFromHex('FFAAbbcc', enableAlpha: true) == Color(0xffaabbcc) 133 | /// colorFromHex('ffAABBCC', enableAlpha: true) == Color(0xffaabbcc) 134 | /// colorFromHex('FFaabbcc', enableAlpha: true) == Color(0xffaabbcc) 135 | /// colorFromHex('#ffaabbcc') == Color(0xffaabbcc) 136 | /// colorFromHex('#ffAABbcc') == Color(0xffaabbcc) 137 | /// colorFromHex('#FFAABBCC') == Color(0xffaabbcc) 138 | /// colorFromHex('#ffaabbcc', enableAlpha: true) == Color(0xffaabbcc) 139 | /// colorFromHex('#FFAAbbcc', enableAlpha: true) == Color(0xffaabbcc) 140 | /// colorFromHex('#ffAABBCC', enableAlpha: true) == Color(0xffaabbcc) 141 | /// colorFromHex('#FFaabbcc', enableAlpha: true) == Color(0xffaabbcc) 142 | /// // Invalid HEXs: 143 | /// colorFromHex('bc') == null // length 2 144 | /// colorFromHex('aabbc') == null // length 5 145 | /// colorFromHex('#ffaabbccd') == null // length 9 (+#) 146 | /// colorFromHex('aabbcx') == null // x character 147 | /// colorFromHex('#aabbвв') == null // в non-latin character 148 | /// colorFromHex('') == null // empty 149 | /// ``` 150 | /// Reference: https://en.wikipedia.org/wiki/Web_colors#Hex_triplet 151 | Color? colorFromHex(String inputString, {bool enableAlpha = true}) { 152 | // Registers validator for exactly 6 or 8 digits long HEX (with optional #). 153 | final RegExp hexValidator = RegExp(kCompleteValidHexPattern); 154 | // Validating input, if it does not match — it's not proper HEX. 155 | if (!hexValidator.hasMatch(inputString)) return null; 156 | // Remove optional hash if exists and convert HEX to UPPER CASE. 157 | String hexToParse = inputString.replaceFirst('#', '').toUpperCase(); 158 | // It may allow HEXs with transparency information even if alpha is disabled, 159 | if (!enableAlpha && hexToParse.length == 8) { 160 | // but it will replace this info with 100% non-transparent value (FF). 161 | hexToParse = 'FF${hexToParse.substring(2)}'; 162 | } 163 | // HEX may be provided in 3-digits format, let's just duplicate each letter. 164 | if (hexToParse.length == 3) { 165 | hexToParse = hexToParse.split('').expand((i) => [i * 2]).join(); 166 | } 167 | // We will need 8 digits to parse the color, let's add missing digits. 168 | if (hexToParse.length == 6) hexToParse = 'FF$hexToParse'; 169 | // HEX must be valid now, but as a precaution, it will just "try" to parse it. 170 | final intColorValue = int.tryParse(hexToParse, radix: 16); 171 | // If for some reason HEX is not valid — abort the operation, return nothing. 172 | if (intColorValue == null) return null; 173 | // Register output color for the last step. 174 | final color = Color(intColorValue); 175 | // Decide to return color with transparency information or not. 176 | return enableAlpha ? color : color.withAlpha(255); 177 | } 178 | 179 | /// Converts `dart:ui` [Color] to the 6/8 digits HEX [String]. 180 | /// 181 | /// Prefixes a hash (`#`) sign if [includeHashSign] is set to `true`. 182 | /// The result will be provided as UPPER CASE, it can be changed via [toUpperCase] 183 | /// flag set to `false` (default is `true`). Hex can be returned without alpha 184 | /// channel information (transparency), with the [enableAlpha] flag set to `false`. 185 | String colorToHex( 186 | Color color, { 187 | bool includeHashSign = false, 188 | bool enableAlpha = true, 189 | bool toUpperCase = true, 190 | }) { 191 | final String hex = (includeHashSign ? '#' : '') + 192 | (enableAlpha ? _padRadix(color.alpha) : '') + 193 | _padRadix(color.red) + 194 | _padRadix(color.green) + 195 | _padRadix(color.blue); 196 | return toUpperCase ? hex.toUpperCase() : hex; 197 | } 198 | 199 | // Shorthand for padLeft of RadixString, DRY. 200 | String _padRadix(int value) => value.toRadixString(16).padLeft(2, '0'); 201 | 202 | // Extension for String 203 | extension ColorExtension1 on String { 204 | Color? toColor() { 205 | Color? color = colorFromName(this); 206 | if (color != null) return color; 207 | return colorFromHex(this); 208 | } 209 | } 210 | 211 | // Extension from Color 212 | extension ColorExtension2 on Color { 213 | String toHexString({ 214 | bool includeHashSign = false, 215 | bool enableAlpha = true, 216 | bool toUpperCase = true, 217 | }) { 218 | return colorToHex( 219 | this, 220 | includeHashSign: includeHashSign, 221 | enableAlpha: enableAlpha, 222 | toUpperCase: toUpperCase, 223 | ); 224 | } 225 | } 226 | -------------------------------------------------------------------------------- /pubspec.lock: -------------------------------------------------------------------------------- 1 | # Generated by pub 2 | # See https://dart.dev/tools/pub/glossary#lockfile 3 | packages: 4 | async: 5 | dependency: transitive 6 | description: 7 | name: async 8 | sha256: "947bfcf187f74dbc5e146c9eb9c0f10c9f8b30743e341481c1e2ed3ecc18c20c" 9 | url: "https://pub.dev" 10 | source: hosted 11 | version: "2.11.0" 12 | boolean_selector: 13 | dependency: transitive 14 | description: 15 | name: boolean_selector 16 | sha256: "6cfb5af12253eaf2b368f07bacc5a80d1301a071c73360d746b7f2e32d762c66" 17 | url: "https://pub.dev" 18 | source: hosted 19 | version: "2.1.1" 20 | characters: 21 | dependency: transitive 22 | description: 23 | name: characters 24 | sha256: "04a925763edad70e8443c99234dc3328f442e811f1d8fd1a72f1c8ad0f69a605" 25 | url: "https://pub.dev" 26 | source: hosted 27 | version: "1.3.0" 28 | clock: 29 | dependency: transitive 30 | description: 31 | name: clock 32 | sha256: cb6d7f03e1de671e34607e909a7213e31d7752be4fb66a86d29fe1eb14bfb5cf 33 | url: "https://pub.dev" 34 | source: hosted 35 | version: "1.1.1" 36 | collection: 37 | dependency: transitive 38 | description: 39 | name: collection 40 | sha256: ee67cb0715911d28db6bf4af1026078bd6f0128b07a5f66fb2ed94ec6783c09a 41 | url: "https://pub.dev" 42 | source: hosted 43 | version: "1.18.0" 44 | fake_async: 45 | dependency: transitive 46 | description: 47 | name: fake_async 48 | sha256: "511392330127add0b769b75a987850d136345d9227c6b94c96a04cf4a391bf78" 49 | url: "https://pub.dev" 50 | source: hosted 51 | version: "1.3.1" 52 | flutter: 53 | dependency: "direct main" 54 | description: flutter 55 | source: sdk 56 | version: "0.0.0" 57 | flutter_lints: 58 | dependency: "direct dev" 59 | description: 60 | name: flutter_lints 61 | sha256: "3f41d009ba7172d5ff9be5f6e6e6abb4300e263aab8866d2a0842ed2a70f8f0c" 62 | url: "https://pub.dev" 63 | source: hosted 64 | version: "4.0.0" 65 | flutter_test: 66 | dependency: "direct dev" 67 | description: flutter 68 | source: sdk 69 | version: "0.0.0" 70 | leak_tracker: 71 | dependency: transitive 72 | description: 73 | name: leak_tracker 74 | sha256: "7f0df31977cb2c0b88585095d168e689669a2cc9b97c309665e3386f3e9d341a" 75 | url: "https://pub.dev" 76 | source: hosted 77 | version: "10.0.4" 78 | leak_tracker_flutter_testing: 79 | dependency: transitive 80 | description: 81 | name: leak_tracker_flutter_testing 82 | sha256: "06e98f569d004c1315b991ded39924b21af84cf14cc94791b8aea337d25b57f8" 83 | url: "https://pub.dev" 84 | source: hosted 85 | version: "3.0.3" 86 | leak_tracker_testing: 87 | dependency: transitive 88 | description: 89 | name: leak_tracker_testing 90 | sha256: "6ba465d5d76e67ddf503e1161d1f4a6bc42306f9d66ca1e8f079a47290fb06d3" 91 | url: "https://pub.dev" 92 | source: hosted 93 | version: "3.0.1" 94 | lints: 95 | dependency: transitive 96 | description: 97 | name: lints 98 | sha256: "976c774dd944a42e83e2467f4cc670daef7eed6295b10b36ae8c85bcbf828235" 99 | url: "https://pub.dev" 100 | source: hosted 101 | version: "4.0.0" 102 | matcher: 103 | dependency: transitive 104 | description: 105 | name: matcher 106 | sha256: d2323aa2060500f906aa31a895b4030b6da3ebdcc5619d14ce1aada65cd161cb 107 | url: "https://pub.dev" 108 | source: hosted 109 | version: "0.12.16+1" 110 | material_color_utilities: 111 | dependency: transitive 112 | description: 113 | name: material_color_utilities 114 | sha256: "0e0a020085b65b6083975e499759762399b4475f766c21668c4ecca34ea74e5a" 115 | url: "https://pub.dev" 116 | source: hosted 117 | version: "0.8.0" 118 | meta: 119 | dependency: transitive 120 | description: 121 | name: meta 122 | sha256: "7687075e408b093f36e6bbf6c91878cc0d4cd10f409506f7bc996f68220b9136" 123 | url: "https://pub.dev" 124 | source: hosted 125 | version: "1.12.0" 126 | path: 127 | dependency: transitive 128 | description: 129 | name: path 130 | sha256: "087ce49c3f0dc39180befefc60fdb4acd8f8620e5682fe2476afd0b3688bb4af" 131 | url: "https://pub.dev" 132 | source: hosted 133 | version: "1.9.0" 134 | sky_engine: 135 | dependency: transitive 136 | description: flutter 137 | source: sdk 138 | version: "0.0.99" 139 | source_span: 140 | dependency: transitive 141 | description: 142 | name: source_span 143 | sha256: "53e943d4206a5e30df338fd4c6e7a077e02254531b138a15aec3bd143c1a8b3c" 144 | url: "https://pub.dev" 145 | source: hosted 146 | version: "1.10.0" 147 | stack_trace: 148 | dependency: transitive 149 | description: 150 | name: stack_trace 151 | sha256: "73713990125a6d93122541237550ee3352a2d84baad52d375a4cad2eb9b7ce0b" 152 | url: "https://pub.dev" 153 | source: hosted 154 | version: "1.11.1" 155 | stream_channel: 156 | dependency: transitive 157 | description: 158 | name: stream_channel 159 | sha256: ba2aa5d8cc609d96bbb2899c28934f9e1af5cddbd60a827822ea467161eb54e7 160 | url: "https://pub.dev" 161 | source: hosted 162 | version: "2.1.2" 163 | string_scanner: 164 | dependency: transitive 165 | description: 166 | name: string_scanner 167 | sha256: "556692adab6cfa87322a115640c11f13cb77b3f076ddcc5d6ae3c20242bedcde" 168 | url: "https://pub.dev" 169 | source: hosted 170 | version: "1.2.0" 171 | term_glyph: 172 | dependency: transitive 173 | description: 174 | name: term_glyph 175 | sha256: a29248a84fbb7c79282b40b8c72a1209db169a2e0542bce341da992fe1bc7e84 176 | url: "https://pub.dev" 177 | source: hosted 178 | version: "1.2.1" 179 | test_api: 180 | dependency: transitive 181 | description: 182 | name: test_api 183 | sha256: "9955ae474176f7ac8ee4e989dadfb411a58c30415bcfb648fa04b2b8a03afa7f" 184 | url: "https://pub.dev" 185 | source: hosted 186 | version: "0.7.0" 187 | vector_math: 188 | dependency: transitive 189 | description: 190 | name: vector_math 191 | sha256: "80b3257d1492ce4d091729e3a67a60407d227c27241d6927be0130c98e741803" 192 | url: "https://pub.dev" 193 | source: hosted 194 | version: "2.1.4" 195 | vm_service: 196 | dependency: transitive 197 | description: 198 | name: vm_service 199 | sha256: "3923c89304b715fb1eb6423f017651664a03bf5f4b29983627c4da791f74a4ec" 200 | url: "https://pub.dev" 201 | source: hosted 202 | version: "14.2.1" 203 | sdks: 204 | dart: ">=3.3.0 <4.0.0" 205 | flutter: ">=3.18.0-18.0.pre.54" 206 | -------------------------------------------------------------------------------- /pubspec.yaml: -------------------------------------------------------------------------------- 1 | name: flutter_colorpicker 2 | description: HSV(HSB)/HSL/RGB/Material color picker inspired by all the good design for your amazing flutter apps. 3 | version: 1.1.0 4 | homepage: https://github.com/mchome/flutter_colorpicker 5 | 6 | environment: 7 | sdk: ">=2.14.0 <4.0.0" 8 | flutter: ">=2.0.0" 9 | 10 | dependencies: 11 | flutter: 12 | sdk: flutter 13 | 14 | dev_dependencies: 15 | flutter_test: 16 | sdk: flutter 17 | flutter_lints: ^4.0.0 18 | -------------------------------------------------------------------------------- /test/utils_test.dart: -------------------------------------------------------------------------------- 1 | import 'dart:ui' show Color; 2 | 3 | import 'package:flutter_colorpicker/src/utils.dart'; 4 | import 'package:flutter_test/flutter_test.dart'; 5 | 6 | void main() { 7 | group('Test colorFromHex:', () { 8 | group('Valid formats test:', () { 9 | const Set valid6digits = {'aBc', '#aBc', 'aaBBcc', '#aaBBcc'}, valid8digits = {'00aaBBcc', '#00aaBBcc'}; 10 | 11 | const Color expectedColor = Color(0xffaabbcc), expectedColorTransparent = Color(0x00aabbcc); 12 | 13 | for (var format in valid6digits) { 14 | test( 15 | 'It should accept text input with a format: $format, with disabled alpha', 16 | () => expect(colorFromHex(format, enableAlpha: false), expectedColor), 17 | ); 18 | } 19 | 20 | for (var format in valid6digits) { 21 | final upperCaseFormat = format.toUpperCase(); 22 | test( 23 | 'It should accept text input with a format: $upperCaseFormat, with disabled alpha', 24 | () => expect(colorFromHex(upperCaseFormat, enableAlpha: false), expectedColor), 25 | ); 26 | } 27 | 28 | for (var format in valid6digits) { 29 | final lowerCaseFormat = format.toLowerCase(); 30 | test( 31 | 'It should accept text input with a format: $lowerCaseFormat, with disabled alpha', 32 | () => expect(colorFromHex(lowerCaseFormat, enableAlpha: false), expectedColor), 33 | ); 34 | } 35 | 36 | for (var format in valid6digits) { 37 | test( 38 | 'It should accept text input with a format: $format', 39 | () => expect(colorFromHex(format), expectedColor), 40 | ); 41 | } 42 | 43 | for (var format in valid6digits) { 44 | final upperCaseFormat = format.toUpperCase(); 45 | test( 46 | 'It should accept text input with a format: $upperCaseFormat', 47 | () => expect(colorFromHex(upperCaseFormat), expectedColor), 48 | ); 49 | } 50 | 51 | for (var format in valid6digits) { 52 | final lowerCaseFormat = format.toLowerCase(); 53 | test( 54 | 'It should accept text input with a format: $lowerCaseFormat', 55 | () => expect(colorFromHex(lowerCaseFormat), expectedColor), 56 | ); 57 | } 58 | 59 | for (var format in valid8digits) { 60 | test( 61 | 'It should accept text input with a format: $format, with disabled alpha', 62 | () => expect(colorFromHex(format, enableAlpha: false), expectedColor), 63 | ); 64 | } 65 | 66 | for (var format in valid8digits) { 67 | final upperCaseFormat = format.toUpperCase(); 68 | test( 69 | 'It should accept text input with a format: $upperCaseFormat, with disabled alpha', 70 | () => expect(colorFromHex(upperCaseFormat, enableAlpha: false), expectedColor), 71 | ); 72 | } 73 | 74 | for (var format in valid8digits) { 75 | final lowerCaseFormat = format.toLowerCase(); 76 | test( 77 | 'It should accept text input with a format: $lowerCaseFormat, with disabled alpha', 78 | () => expect(colorFromHex(lowerCaseFormat, enableAlpha: false), expectedColor), 79 | ); 80 | } 81 | 82 | for (var format in valid8digits) { 83 | test( 84 | 'It should accept text input with a format: $format', 85 | () => expect(colorFromHex(format), expectedColorTransparent), 86 | ); 87 | } 88 | 89 | for (var format in valid8digits) { 90 | final upperCaseFormat = format.toUpperCase(); 91 | test( 92 | 'It should accept text input with a format: $upperCaseFormat', 93 | () => expect(colorFromHex(upperCaseFormat), expectedColorTransparent), 94 | ); 95 | } 96 | 97 | for (var format in valid8digits) { 98 | final lowerCaseFormat = format.toLowerCase(); 99 | test( 100 | 'It should accept text input with a format: $lowerCaseFormat', 101 | () => expect(colorFromHex(lowerCaseFormat), expectedColorTransparent), 102 | ); 103 | } 104 | }); 105 | 106 | group('Invalid formats test:', () { 107 | const Set invalidFormats = { 108 | // x char. 109 | 'aaBBcx', 110 | '#aaBBcx', 111 | '00aaBBcx', 112 | '#00aaBBcx', 113 | // á char. 114 | 'áaBBcc', 115 | '#áaBBcc', 116 | '00áaBBcc', 117 | '#00áaBBcc', 118 | // cyrillic а char. 119 | 'аaBBcc', 120 | '#аaBBcc', 121 | '00аaBBcc', 122 | '#00аaBBcc', 123 | }; 124 | test( 125 | 'It should return null if text length is not 3, 6 or 8', 126 | () { 127 | final StringBuffer buffer = StringBuffer(); 128 | for (int i = 0; i <= 9; i++) { 129 | buffer.write(i.toString()); 130 | expect(colorFromHex(buffer.toString()), (i == 7 || i == 5 || i == 2) ? isNot(null) : null); 131 | } 132 | }, 133 | ); 134 | 135 | test( 136 | 'It should return null if text length is not 3, 6 or 8, with alpha disabled', 137 | () { 138 | final StringBuffer buffer = StringBuffer(); 139 | for (int i = 0; i <= 9; i++) { 140 | buffer.write(i.toString()); 141 | expect( 142 | colorFromHex(buffer.toString(), enableAlpha: false), (i == 7 || i == 5 || i == 2) ? isNot(null) : null); 143 | } 144 | }, 145 | ); 146 | 147 | for (var format in invalidFormats) { 148 | final lowerCaseFormat = format.toLowerCase(); 149 | test( 150 | 'It should return null if format is: $lowerCaseFormat', 151 | () => expect(colorFromHex(lowerCaseFormat), null), 152 | ); 153 | } 154 | 155 | for (var format in invalidFormats) { 156 | final upperCaseFormat = format.toUpperCase(); 157 | test( 158 | 'It should return null if format is: $upperCaseFormat', 159 | () => expect(colorFromHex(upperCaseFormat), null), 160 | ); 161 | } 162 | 163 | for (var format in invalidFormats) { 164 | test( 165 | 'It should return null if format is: $format', 166 | () => expect(colorFromHex(format), null), 167 | ); 168 | } 169 | 170 | for (var format in invalidFormats) { 171 | final lowerCaseFormat = format.toLowerCase(); 172 | test( 173 | 'It should return null if format is: $lowerCaseFormat, with alpha disabled', 174 | () => expect(colorFromHex(lowerCaseFormat, enableAlpha: false), null), 175 | ); 176 | } 177 | 178 | for (var format in invalidFormats) { 179 | final upperCaseFormat = format.toUpperCase(); 180 | test( 181 | 'It should return null if format is: $upperCaseFormat, with alpha disabled', 182 | () => expect(colorFromHex(upperCaseFormat, enableAlpha: false), null), 183 | ); 184 | } 185 | 186 | for (var format in invalidFormats) { 187 | test( 188 | 'It should return null if format is: $format, with alpha disabled', 189 | () => expect(colorFromHex(format, enableAlpha: false), null), 190 | ); 191 | } 192 | }); 193 | }); 194 | 195 | group('Test colorToHex:', () { 196 | final Map colorsMap = { 197 | const Color(0xffffffff): 'FFFFFF', 198 | const Color(0x00000000): '000000', 199 | const Color(0xF0F0F0F0): 'F0F0F0' 200 | }; 201 | 202 | colorsMap.forEach((color, string) { 203 | final String transparency = string.substring(4); 204 | test( 205 | 'It should convert $color: to ${transparency + string}', 206 | () => expect(colorToHex(color), transparency + string), 207 | ); 208 | }); 209 | 210 | colorsMap.forEach((color, string) { 211 | final String transparency = string.substring(4); 212 | test( 213 | 'It should convert $color: to #${transparency + string} with hash', 214 | () => expect(colorToHex(color, includeHashSign: true), '#$transparency$string'), 215 | ); 216 | }); 217 | 218 | colorsMap.forEach((color, string) { 219 | final String transparency = string.substring(4).toLowerCase(); 220 | test( 221 | 'It should convert $color: to #${transparency + string.toLowerCase()}, with hash, to lower case', 222 | () => expect( 223 | colorToHex(color, includeHashSign: true, toUpperCase: false), '#$transparency${string.toLowerCase()}'), 224 | ); 225 | }); 226 | 227 | colorsMap.forEach((color, string) { 228 | final String transparency = string.substring(4).toLowerCase(); 229 | test( 230 | 'It should convert $color to ${transparency + string.toLowerCase()}, with lower case', 231 | () => expect(colorToHex(color, toUpperCase: false), transparency + string.toLowerCase()), 232 | ); 233 | }); 234 | 235 | colorsMap.forEach((color, string) => test( 236 | 'It should convert $color: to $string, with alpha disabled', 237 | () => expect(colorToHex(color, enableAlpha: false), string), 238 | )); 239 | 240 | colorsMap.forEach((color, string) => test( 241 | 'It should convert $color: to #$string, with alpha disabled and hash', 242 | () => expect(colorToHex(color, enableAlpha: false, includeHashSign: true), '#$string'), 243 | )); 244 | 245 | colorsMap.forEach((color, string) => test( 246 | 'It should convert $color: to #${string.toLowerCase()}, with alpha disabled and hash, to lower case', 247 | () => expect(colorToHex(color, enableAlpha: false, includeHashSign: true, toUpperCase: false), 248 | '#$string'.toLowerCase()), 249 | )); 250 | 251 | colorsMap.forEach((color, string) => test( 252 | 'It should convert $color to ${string.toLowerCase()}, with alpha disabled, to lower case', 253 | () => expect(colorToHex(color, enableAlpha: false, toUpperCase: false), string.toLowerCase()), 254 | )); 255 | }); 256 | 257 | group('Test ColorExtension2.toHexString:', () { 258 | final Map colorsMap = { 259 | const Color(0xffffffff): 'FFFFFF', 260 | const Color(0x00000000): '000000', 261 | const Color(0xF0F0F0F0): 'F0F0F0' 262 | }; 263 | 264 | colorsMap.forEach((color, string) { 265 | final String transparency = string.substring(4); 266 | test( 267 | 'It should convert $color: to ${transparency + string}', 268 | () => expect(color.toHexString(), transparency + string), 269 | ); 270 | }); 271 | 272 | colorsMap.forEach((color, string) { 273 | final String transparency = string.substring(4); 274 | test( 275 | 'It should convert $color: to #${transparency + string} with hash', 276 | () => expect( 277 | color.toHexString(includeHashSign: true), '#$transparency$string'), 278 | ); 279 | }); 280 | 281 | colorsMap.forEach((color, string) { 282 | final String transparency = string.substring(4).toLowerCase(); 283 | test( 284 | 'It should convert $color: to #${transparency + string.toLowerCase()}, with hash, to lower case', 285 | () => expect( 286 | color.toHexString(includeHashSign: true, toUpperCase: false), 287 | '#$transparency${string.toLowerCase()}'), 288 | ); 289 | }); 290 | 291 | colorsMap.forEach((color, string) { 292 | final String transparency = string.substring(4).toLowerCase(); 293 | test( 294 | 'It should convert $color to ${transparency + string.toLowerCase()}, with lower case', 295 | () => expect( 296 | color.toHexString(toUpperCase: false), 297 | transparency + string.toLowerCase(), 298 | ), 299 | ); 300 | }); 301 | 302 | colorsMap.forEach((color, string) => test( 303 | 'It should convert $color: to $string, with alpha disabled', 304 | () => expect( 305 | color.toHexString(enableAlpha: false), 306 | string, 307 | ), 308 | )); 309 | 310 | colorsMap.forEach((color, string) => test( 311 | 'It should convert $color: to #$string, with alpha disabled and hash', 312 | () => expect( 313 | color.toHexString(enableAlpha: false, includeHashSign: true), 314 | '#$string'), 315 | )); 316 | 317 | colorsMap.forEach((color, string) => test( 318 | 'It should convert $color: to #${string.toLowerCase()}, with alpha disabled and hash, to lower case', 319 | () => expect( 320 | color.toHexString( 321 | enableAlpha: false, 322 | includeHashSign: true, 323 | toUpperCase: false, 324 | ), 325 | '#$string'.toLowerCase(), 326 | ), 327 | )); 328 | 329 | colorsMap.forEach((color, string) => test( 330 | 'It should convert $color to ${string.toLowerCase()}, with alpha disabled, to lower case', 331 | () => expect( 332 | color.toHexString(enableAlpha: false, toUpperCase: false), 333 | string.toLowerCase()), 334 | )); 335 | }); 336 | } 337 | --------------------------------------------------------------------------------