├── logo.png ├── .gitignore ├── CHANGELOG.md ├── analysis_options.yaml ├── ios ├── Runner │ ├── GeneratedPluginRegistrant.m │ └── GeneratedPluginRegistrant.h └── Flutter │ └── Generated.xcconfig ├── lib ├── flutter_chameleon.dart ├── chameleon_dialog.dart ├── chameleon_activity_indicator.dart ├── chameleon_alert_dialog.dart ├── chameleon_slider.dart ├── chameleon_bottom_navigation_bar.dart ├── chameleon_switch.dart ├── chameleon_button.dart └── chameleon_picker.dart ├── pubspec.yaml ├── README.md ├── flutter_chameleon.iml └── LICENSE /logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/imtoori/flutter_chameleon/HEAD/logo.png -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | .DS_Store 2 | .atom/ 3 | .dart_tool/ 4 | .idea 5 | .packages 6 | .pub/ 7 | packages 8 | .vscode 9 | *.lock 10 | -------------------------------------------------------------------------------- /CHANGELOG.md: -------------------------------------------------------------------------------- 1 | ## [0.1.0] 2 | 3 | First release 4 | 5 | ## [0.1.1] 6 | 7 | Critical fix 8 | 9 | ## [0.1.2] 10 | 11 | minor clean up 12 | 13 | ## [0.1.3] 14 | 15 | change flatbutton with materialbutton 16 | -------------------------------------------------------------------------------- /analysis_options.yaml: -------------------------------------------------------------------------------- 1 | analyzer: 2 | strong-mode: true 3 | 4 | linter: 5 | rules: 6 | - camel_case_types 7 | - hash_and_equals 8 | - iterable_contains_unrelated_type 9 | - list_remove_unrelated_type 10 | - unrelated_type_equality_checks 11 | - valid_regexps -------------------------------------------------------------------------------- /ios/Runner/GeneratedPluginRegistrant.m: -------------------------------------------------------------------------------- 1 | // 2 | // Generated file. Do not edit. 3 | // 4 | 5 | #import "GeneratedPluginRegistrant.h" 6 | 7 | @implementation GeneratedPluginRegistrant 8 | 9 | + (void)registerWithRegistry:(NSObject*)registry { 10 | } 11 | 12 | @end 13 | -------------------------------------------------------------------------------- /lib/flutter_chameleon.dart: -------------------------------------------------------------------------------- 1 | library flutter_chameleon; 2 | 3 | export 'chameleon_bottom_navigation_bar.dart'; 4 | export 'chameleon_alert_dialog.dart'; 5 | export 'chameleon_dialog.dart'; 6 | export 'chameleon_activity_indicator.dart'; 7 | export 'chameleon_slider.dart'; 8 | export 'chameleon_button.dart'; 9 | export 'chameleon_switch.dart'; 10 | export 'chameleon_picker.dart'; 11 | -------------------------------------------------------------------------------- /ios/Runner/GeneratedPluginRegistrant.h: -------------------------------------------------------------------------------- 1 | // 2 | // Generated file. Do not edit. 3 | // 4 | 5 | #ifndef GeneratedPluginRegistrant_h 6 | #define GeneratedPluginRegistrant_h 7 | 8 | #import 9 | 10 | @interface GeneratedPluginRegistrant : NSObject 11 | + (void)registerWithRegistry:(NSObject*)registry; 12 | @end 13 | 14 | #endif /* GeneratedPluginRegistrant_h */ 15 | -------------------------------------------------------------------------------- /pubspec.yaml: -------------------------------------------------------------------------------- 1 | name: flutter_chameleon 2 | description: A new flutter package project. 3 | version: 0.1.3 4 | author: Salvatore Giordano 5 | homepage: https://github.com/Salvatore-Giordano/flutter_chameleon 6 | 7 | environment: 8 | sdk: ">=1.2.0 <=2.0.0" 9 | 10 | dependencies: 11 | flutter: 12 | sdk: flutter 13 | 14 | dev_dependencies: 15 | flutter_test: 16 | sdk: flutter 17 | -------------------------------------------------------------------------------- /ios/Flutter/Generated.xcconfig: -------------------------------------------------------------------------------- 1 | // This is a generated file; do not edit or check into version control. 2 | FLUTTER_ROOT=/Users/salvatore/Development/flutter 3 | FLUTTER_APPLICATION_PATH=/Users/salvatore/Development/flutter_chameleon 4 | FLUTTER_TARGET=lib/main.dart 5 | FLUTTER_BUILD_MODE=debug 6 | FLUTTER_BUILD_DIR=build 7 | SYMROOT=${SOURCE_ROOT}/../build/ios 8 | FLUTTER_FRAMEWORK_DIR=/Users/salvatore/Development/flutter/bin/cache/artifacts/engine/ios 9 | -------------------------------------------------------------------------------- /lib/chameleon_dialog.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/foundation.dart'; 2 | import 'package:flutter/material.dart'; 3 | import 'package:flutter/cupertino.dart'; 4 | 5 | class ChameleonDialog extends Widget { 6 | final Widget child; 7 | 8 | const ChameleonDialog({ 9 | Key key, 10 | this.child, 11 | }); 12 | 13 | @override 14 | Element createElement() { 15 | return defaultTargetPlatform == TargetPlatform.android 16 | ? new Dialog( 17 | key: key, 18 | child: child, 19 | ).createElement() 20 | : new CupertinoDialog( 21 | key: key, 22 | child: child, 23 | ).createElement(); 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | [UNMAINTAINED] 2 | 3 | [![Pub](https://img.shields.io/badge/Pub-0.1.3-orange.svg)](https://pub.dartlang.org/packages/flutter_chameleon) 4 | 5 | 6 | 7 | # flutter_chameleon 8 | 9 | Flutter package to show platform **dependent** widgets. 10 | 11 | ## Usage 12 | 13 | Just use chameleon widgets instead of material or cupertino and they will show up depending on the hosting platform. 14 | 15 | ## Widget included 16 | 17 | * activity indicator 18 | * alert dialog 19 | * bottom navigationbar 20 | * button 21 | * dialog 22 | * slider 23 | * switch 24 | 25 | More to come.. 26 | 27 | ## Contributions 28 | 29 | Contributions of any kind are more than welcome! Feel free to fork and improve flutter_chameleon in any way you want, make a pull request, or open an issue. 30 | -------------------------------------------------------------------------------- /flutter_chameleon.iml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | Copyright (c) 2018 Salvatore Giordano 2 | 3 | Permission is hereby granted, free of charge, to any person 4 | obtaining a copy of this software and associated documentation 5 | files (the "Software"), to deal in the Software without 6 | restriction, including without limitation the rights to use, 7 | copy, modify, merge, publish, distribute, sublicense, and/or sell 8 | copies of the Software, and to permit persons to whom the 9 | Software is furnished to do so, subject to the following 10 | conditions: 11 | 12 | The above copyright notice and this permission notice shall be 13 | included in all copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 16 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES 17 | OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 18 | NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT 19 | HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, 20 | WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 21 | FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR 22 | OTHER DEALINGS IN THE SOFTWARE. -------------------------------------------------------------------------------- /lib/chameleon_activity_indicator.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/foundation.dart'; 2 | import 'package:flutter/material.dart'; 3 | import 'package:flutter/cupertino.dart'; 4 | 5 | class ChameleonActivityIndicator extends Widget { 6 | final double strokeWidth; 7 | final double value; 8 | final Key key; 9 | final Color backgroundColor; 10 | final Animation valueColor; 11 | final bool animating; 12 | 13 | const ChameleonActivityIndicator({ 14 | this.key, 15 | this.value, 16 | this.backgroundColor, 17 | this.valueColor, 18 | this.strokeWidth: 4.0, 19 | this.animating: true, 20 | }); 21 | 22 | @override 23 | Element createElement() { 24 | return defaultTargetPlatform == TargetPlatform.android 25 | ? new CircularProgressIndicator( 26 | value: value, 27 | key: key, 28 | backgroundColor: backgroundColor, 29 | strokeWidth: strokeWidth, 30 | valueColor: valueColor, 31 | ).createElement() 32 | : new CupertinoActivityIndicator( 33 | key: key, 34 | animating: animating, 35 | ).createElement(); 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /lib/chameleon_alert_dialog.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/foundation.dart'; 2 | import 'package:flutter/material.dart'; 3 | import 'package:flutter/cupertino.dart'; 4 | 5 | class ChameleonAlertDialog extends Widget { 6 | final Widget title; 7 | final EdgeInsetsGeometry titlePadding; 8 | final Widget content; 9 | final EdgeInsetsGeometry contentPadding; 10 | final List actions; 11 | final ScrollController scrollController; 12 | 13 | const ChameleonAlertDialog({ 14 | Key key, 15 | this.title, 16 | this.titlePadding, 17 | this.content, 18 | this.contentPadding, 19 | this.actions, 20 | this.scrollController, 21 | }); 22 | 23 | @override 24 | Element createElement() { 25 | return defaultTargetPlatform == TargetPlatform.android 26 | ? new AlertDialog( 27 | key: key, 28 | actions: actions, 29 | content: content, 30 | contentPadding: contentPadding, 31 | title: title, 32 | titlePadding: titlePadding, 33 | ).createElement() 34 | : new CupertinoAlertDialog( 35 | key: key, 36 | content: content, 37 | title: title, 38 | actions: actions, 39 | scrollController: scrollController, 40 | ).createElement(); 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /lib/chameleon_slider.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/material.dart'; 2 | import 'package:flutter/cupertino.dart'; 3 | import 'package:flutter/foundation.dart'; 4 | 5 | class ChameleonSlider extends Widget { 6 | final double value; 7 | final ValueChanged onChanged; 8 | final double min; 9 | final double max; 10 | final int divisions; 11 | final String label; 12 | final Color activeColor; 13 | final Color inactiveColor; 14 | final Key key; 15 | 16 | const ChameleonSlider({ 17 | this.key, 18 | @required this.value, 19 | @required this.onChanged, 20 | this.min: 0.0, 21 | this.max: 1.0, 22 | this.divisions, 23 | this.label, 24 | this.activeColor: CupertinoColors.activeBlue, 25 | this.inactiveColor, 26 | }); 27 | 28 | @override 29 | Element createElement() { 30 | return defaultTargetPlatform == TargetPlatform.android 31 | ? new Slider( 32 | value: value, 33 | key: key, 34 | onChanged: onChanged, 35 | activeColor: activeColor, 36 | divisions: divisions, 37 | inactiveColor: inactiveColor, 38 | label: label, 39 | max: max, 40 | min: min, 41 | ).createElement() 42 | : new CupertinoSlider( 43 | min: min, 44 | max: max, 45 | divisions: divisions, 46 | activeColor: activeColor, 47 | onChanged: onChanged, 48 | key: key, 49 | value: value, 50 | ).createElement(); 51 | } 52 | } 53 | -------------------------------------------------------------------------------- /lib/chameleon_bottom_navigation_bar.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/foundation.dart'; 2 | import 'package:flutter/material.dart'; 3 | import 'package:flutter/cupertino.dart'; 4 | 5 | class ChameleonBottomNavigationBar extends Widget { 6 | final List items; 7 | final ValueChanged onTap; 8 | final int currentIndex; 9 | final BottomNavigationBarType type; 10 | final Color fixedColor; 11 | final double iconSize; 12 | final Color activeColor; 13 | final Color backgroundColor; 14 | final Color inactiveColor; 15 | 16 | const ChameleonBottomNavigationBar({ 17 | Key key, 18 | @required this.items, 19 | this.onTap, 20 | this.currentIndex: 0, 21 | this.type, 22 | this.fixedColor, 23 | this.iconSize: 24.0, 24 | this.activeColor: CupertinoColors.activeBlue, 25 | this.backgroundColor: const Color(0xCCF8F8F8), 26 | this.inactiveColor: CupertinoColors.inactiveGray, 27 | }); 28 | 29 | @override 30 | Element createElement() { 31 | return defaultTargetPlatform == TargetPlatform.android 32 | ? new BottomNavigationBar( 33 | key: key, 34 | items: items, 35 | currentIndex: currentIndex, 36 | fixedColor: fixedColor, 37 | iconSize: iconSize, 38 | onTap: onTap, 39 | type: type, 40 | ).createElement() 41 | : new CupertinoTabBar( 42 | key: key, 43 | items: items, 44 | iconSize: iconSize, 45 | activeColor: activeColor, 46 | backgroundColor: backgroundColor, 47 | onTap: onTap, 48 | currentIndex: currentIndex, 49 | inactiveColor: inactiveColor, 50 | ).createElement(); 51 | } 52 | } 53 | -------------------------------------------------------------------------------- /lib/chameleon_switch.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/foundation.dart'; 2 | import 'package:flutter/material.dart'; 3 | import 'package:flutter/cupertino.dart'; 4 | 5 | class ChameleonSwitch extends Widget { 6 | final bool value; 7 | final ValueChanged onChanged; 8 | final Color activeColor; 9 | final Color activeTrackColor; 10 | final Color inactiveThumbColor; 11 | final Color inactiveTrackColor; 12 | final ImageProvider activeThumbImage; 13 | final ImageProvider inactiveThumbImage; 14 | final BuildContext context; 15 | 16 | const ChameleonSwitch({ 17 | @required this.context, 18 | Key key, 19 | @required this.value, 20 | @required this.onChanged, 21 | this.activeColor: CupertinoColors.activeGreen, 22 | this.activeTrackColor, 23 | this.inactiveThumbColor, 24 | this.inactiveTrackColor, 25 | this.activeThumbImage, 26 | this.inactiveThumbImage, 27 | }); 28 | 29 | @override 30 | Element createElement() { 31 | return defaultTargetPlatform == TargetPlatform.android 32 | ? new Switch( 33 | key: key, 34 | onChanged: onChanged, 35 | value: value, 36 | activeColor: activeColor == CupertinoColors.activeGreen 37 | ? Theme.of(context).primaryColor 38 | : activeColor, 39 | activeThumbImage: activeThumbImage, 40 | activeTrackColor: activeTrackColor, 41 | inactiveThumbColor: inactiveThumbColor, 42 | inactiveThumbImage: inactiveThumbImage, 43 | inactiveTrackColor: inactiveTrackColor, 44 | ).createElement() 45 | : new CupertinoSwitch( 46 | activeColor: activeColor, 47 | onChanged: onChanged, 48 | value: value, 49 | key: key, 50 | ).createElement(); 51 | } 52 | } 53 | -------------------------------------------------------------------------------- /lib/chameleon_button.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/material.dart'; 2 | import 'package:flutter/cupertino.dart'; 3 | import 'package:flutter/foundation.dart'; 4 | 5 | class ChameleonButton extends Widget { 6 | final VoidCallback onPressed; 7 | final ValueChanged onHighlightChanged; 8 | final ButtonTextTheme textTheme; 9 | final Color textColor; 10 | final Color disabledTextColor; 11 | final Color color; 12 | final Color disabledColor; 13 | final Color splashColor; 14 | final Color highlightColor; 15 | final Brightness colorBrightness; 16 | final Widget child; 17 | final double height; 18 | final double highlightElevation; 19 | final double minWidth; 20 | 21 | bool get enabled => onPressed != null; 22 | final EdgeInsetsGeometry padding; 23 | final ShapeBorder shape; 24 | final BorderRadius borderRadius; 25 | final double minSize; 26 | final double pressedOpacity; 27 | final double elevation; 28 | 29 | const ChameleonButton({ 30 | Key key, 31 | @required this.onPressed, 32 | this.onHighlightChanged, 33 | this.textTheme, 34 | this.textColor, 35 | this.height, 36 | this.disabledTextColor, 37 | this.color, 38 | this.disabledColor, 39 | this.highlightColor, 40 | this.splashColor, 41 | this.colorBrightness, 42 | this.padding, 43 | this.shape, 44 | this.minWidth, 45 | this.highlightElevation, 46 | @required this.child, 47 | this.borderRadius: const BorderRadius.all(const Radius.circular(8.0)), 48 | this.minSize, 49 | this.elevation, 50 | this.pressedOpacity: 0.1, 51 | }); 52 | 53 | @override 54 | Element createElement() { 55 | return defaultTargetPlatform == TargetPlatform.android 56 | ? new MaterialButton( 57 | onPressed: onPressed, 58 | child: child, 59 | color: color, 60 | colorBrightness: colorBrightness, 61 | elevation: elevation, 62 | height: height, 63 | highlightElevation: highlightElevation, 64 | minWidth: minWidth, 65 | highlightColor: highlightColor, 66 | key: key, 67 | padding: padding, 68 | splashColor: splashColor, 69 | textColor: textColor, 70 | textTheme: textTheme, 71 | ).createElement() 72 | : new CupertinoButton( 73 | child: child, 74 | padding: padding, 75 | color: color, 76 | onPressed: onPressed, 77 | borderRadius: borderRadius, 78 | minSize: minSize, 79 | pressedOpacity: pressedOpacity, 80 | ).createElement(); 81 | } 82 | } 83 | -------------------------------------------------------------------------------- /lib/chameleon_picker.dart: -------------------------------------------------------------------------------- 1 | import 'dart:async'; 2 | 3 | import 'package:flutter/foundation.dart'; 4 | import 'package:flutter/material.dart'; 5 | import 'package:flutter/cupertino.dart'; 6 | 7 | Future showChameleonModalBottomSheet( 8 | BuildContext context, { 9 | Key key, 10 | AnimationController animationController, 11 | @required VoidCallback onClosing, 12 | double diameterRatio: 1.1, 13 | Color backgroundColor: const Color(0xFFD2D4DB), 14 | ValueChanged onSelectedItemChanged, 15 | double itemExtent, 16 | List> children, 17 | FixedExtentScrollController scrollController, 18 | }) { 19 | return showModalBottomSheet( 20 | builder: (BuildContext c) => new ChameleonPicker( 21 | context, 22 | children: children, 23 | diameterRatio: diameterRatio, 24 | backgroundColor: backgroundColor, 25 | onSelectedItemChanged: onSelectedItemChanged, 26 | itemExtent: itemExtent, 27 | scrollController: scrollController, 28 | animationController: animationController, 29 | onClosing: onClosing, 30 | key: key, 31 | ), 32 | context: context, 33 | ); 34 | } 35 | 36 | class ChameleonPicker extends Widget { 37 | final AnimationController animationController; 38 | final VoidCallback onClosing; 39 | final double diameterRatio; 40 | final Color backgroundColor; 41 | final FixedExtentScrollController scrollController; 42 | final double itemExtent; 43 | final List children; 44 | final ValueChanged onSelectedItemChanged; 45 | final BuildContext buildContext; 46 | 47 | const ChameleonPicker( 48 | this.buildContext, { 49 | Key key, 50 | this.animationController, 51 | @required this.onClosing, 52 | this.diameterRatio: 1.1, 53 | this.backgroundColor: const Color(0xFFD2D4DB), 54 | this.onSelectedItemChanged, 55 | @required this.itemExtent, 56 | this.children, 57 | this.scrollController, 58 | }); 59 | 60 | @override 61 | Element createElement() { 62 | return defaultTargetPlatform == TargetPlatform.android 63 | ? new BottomSheet( 64 | key: key, 65 | builder: (context) { 66 | return new Column( 67 | children: children 68 | ?.map((c) => new SimpleDialogOption( 69 | child: c.widget, 70 | onPressed: () { 71 | Navigator.pop(context, c.value); 72 | }, 73 | )) 74 | ?.toList()); 75 | }, 76 | onClosing: onClosing, 77 | animationController: animationController, 78 | ).createElement() 79 | : new CupertinoPicker( 80 | key: key, 81 | scrollController: scrollController, 82 | children: children 83 | ?.map((c) => new GestureDetector( 84 | child: c.widget, 85 | onTap: () { 86 | Navigator.pop(buildContext, c.value); 87 | }, 88 | )) 89 | ?.toList(), 90 | itemExtent: itemExtent, 91 | onSelectedItemChanged: onSelectedItemChanged, 92 | backgroundColor: backgroundColor, 93 | diameterRatio: diameterRatio, 94 | ).createElement(); 95 | } 96 | } 97 | 98 | class ChameleonBottomSheetItem { 99 | Widget widget; 100 | T value; 101 | 102 | ChameleonBottomSheetItem({@required this.widget, @required this.value}); 103 | } 104 | --------------------------------------------------------------------------------