diff --git a/demo_app/.gitignore b/demo_app/.gitignore
new file mode 100644
index 00000000..ae1f1838
--- /dev/null
+++ b/demo_app/.gitignore
@@ -0,0 +1,37 @@
+# Miscellaneous
+*.class
+*.log
+*.pyc
+*.swp
+.DS_Store
+.atom/
+.buildlog/
+.history
+.svn/
+
+# IntelliJ related
+*.iml
+*.ipr
+*.iws
+.idea/
+
+# The .vscode folder contains launch configuration and tasks you configure in
+# VS Code which you may wish to be included in version control, so this line
+# is commented out by default.
+#.vscode/
+
+# Flutter/Dart/Pub related
+**/doc/api/
+.dart_tool/
+.flutter-plugins
+.flutter-plugins-dependencies
+.packages
+.pub-cache/
+.pub/
+/build/
+
+# Web related
+lib/generated_plugin_registrant.dart
+
+# Exceptions to above rules.
+!/packages/flutter_tools/test/data/dart_dependencies_test/**/.packages
diff --git a/demo_app/.metadata b/demo_app/.metadata
new file mode 100644
index 00000000..361e1e4c
--- /dev/null
+++ b/demo_app/.metadata
@@ -0,0 +1,10 @@
+# This file tracks properties of this Flutter project.
+# Used by Flutter tool to assess capabilities and perform upgrades etc.
+#
+# This file should be version controlled and should not be manually edited.
+
+version:
+ revision: 18cd7a3601bcffb36fdf2f679f763b5e827c2e8e
+ channel: beta
+
+project_type: app
diff --git a/demo_app/README.md b/demo_app/README.md
new file mode 100644
index 00000000..ebae316f
--- /dev/null
+++ b/demo_app/README.md
@@ -0,0 +1,16 @@
+# demo_app
+
+A new Flutter project.
+
+## Getting Started
+
+This project is a starting point for a Flutter application.
+
+A few resources to get you started if this is your first Flutter project:
+
+- [Lab: Write your first Flutter app](https://flutter.dev/docs/get-started/codelab)
+- [Cookbook: Useful Flutter samples](https://flutter.dev/docs/cookbook)
+
+For help getting started with Flutter, view our
+[online documentation](https://flutter.dev/docs), which offers tutorials,
+samples, guidance on mobile development, and a full API reference.
diff --git a/demo_app/android/.gitignore b/demo_app/android/.gitignore
new file mode 100644
index 00000000..bc2100d8
--- /dev/null
+++ b/demo_app/android/.gitignore
@@ -0,0 +1,7 @@
+gradle-wrapper.jar
+/.gradle
+/captures/
+/gradlew
+/gradlew.bat
+/local.properties
+GeneratedPluginRegistrant.java
diff --git a/demo_app/android/app/build.gradle b/demo_app/android/app/build.gradle
new file mode 100644
index 00000000..471f73aa
--- /dev/null
+++ b/demo_app/android/app/build.gradle
@@ -0,0 +1,67 @@
+def localProperties = new Properties()
+def localPropertiesFile = rootProject.file('local.properties')
+if (localPropertiesFile.exists()) {
+ localPropertiesFile.withReader('UTF-8') { reader ->
+ localProperties.load(reader)
+ }
+}
+
+def flutterRoot = localProperties.getProperty('flutter.sdk')
+if (flutterRoot == null) {
+ throw new GradleException("Flutter SDK not found. Define location with flutter.sdk in the local.properties file.")
+}
+
+def flutterVersionCode = localProperties.getProperty('flutter.versionCode')
+if (flutterVersionCode == null) {
+ flutterVersionCode = '1'
+}
+
+def flutterVersionName = localProperties.getProperty('flutter.versionName')
+if (flutterVersionName == null) {
+ flutterVersionName = '1.0'
+}
+
+apply plugin: 'com.android.application'
+apply plugin: 'kotlin-android'
+apply from: "$flutterRoot/packages/flutter_tools/gradle/flutter.gradle"
+
+android {
+ compileSdkVersion 28
+
+ sourceSets {
+ main.java.srcDirs += 'src/main/kotlin'
+ }
+
+ lintOptions {
+ disable 'InvalidPackage'
+ }
+
+ defaultConfig {
+ // TODO: Specify your own unique Application ID (https://developer.android.com/studio/build/application-id.html).
+ applicationId "com.example.demo_app"
+ minSdkVersion 16
+ targetSdkVersion 28
+ versionCode flutterVersionCode.toInteger()
+ versionName flutterVersionName
+ testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
+ }
+
+ buildTypes {
+ release {
+ // TODO: Add your own signing config for the release build.
+ // Signing with the debug keys for now, so `flutter run --release` works.
+ signingConfig signingConfigs.debug
+ }
+ }
+}
+
+flutter {
+ source '../..'
+}
+
+dependencies {
+ implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version"
+ testImplementation 'junit:junit:4.12'
+ androidTestImplementation 'androidx.test:runner:1.1.1'
+ androidTestImplementation 'androidx.test.espresso:espresso-core:3.1.1'
+}
diff --git a/demo_app/android/app/src/debug/AndroidManifest.xml b/demo_app/android/app/src/debug/AndroidManifest.xml
new file mode 100644
index 00000000..cef74c20
--- /dev/null
+++ b/demo_app/android/app/src/debug/AndroidManifest.xml
@@ -0,0 +1,7 @@
+
+
+
+
diff --git a/demo_app/android/app/src/main/AndroidManifest.xml b/demo_app/android/app/src/main/AndroidManifest.xml
new file mode 100644
index 00000000..27b7e17a
--- /dev/null
+++ b/demo_app/android/app/src/main/AndroidManifest.xml
@@ -0,0 +1,30 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/demo_app/android/app/src/main/kotlin/com/example/demo_app/MainActivity.kt b/demo_app/android/app/src/main/kotlin/com/example/demo_app/MainActivity.kt
new file mode 100644
index 00000000..c25730bf
--- /dev/null
+++ b/demo_app/android/app/src/main/kotlin/com/example/demo_app/MainActivity.kt
@@ -0,0 +1,12 @@
+package com.example.demo_app
+
+import androidx.annotation.NonNull;
+import io.flutter.embedding.android.FlutterActivity
+import io.flutter.embedding.engine.FlutterEngine
+import io.flutter.plugins.GeneratedPluginRegistrant
+
+class MainActivity: FlutterActivity() {
+ override fun configureFlutterEngine(@NonNull flutterEngine: FlutterEngine) {
+ GeneratedPluginRegistrant.registerWith(flutterEngine);
+ }
+}
diff --git a/demo_app/android/app/src/main/res/drawable/launch_background.xml b/demo_app/android/app/src/main/res/drawable/launch_background.xml
new file mode 100644
index 00000000..304732f8
--- /dev/null
+++ b/demo_app/android/app/src/main/res/drawable/launch_background.xml
@@ -0,0 +1,12 @@
+
+
+
+
+
+
+
+
diff --git a/demo_app/android/app/src/main/res/mipmap-hdpi/ic_launcher.png b/demo_app/android/app/src/main/res/mipmap-hdpi/ic_launcher.png
new file mode 100644
index 00000000..db77bb4b
Binary files /dev/null and b/demo_app/android/app/src/main/res/mipmap-hdpi/ic_launcher.png differ
diff --git a/demo_app/android/app/src/main/res/mipmap-mdpi/ic_launcher.png b/demo_app/android/app/src/main/res/mipmap-mdpi/ic_launcher.png
new file mode 100644
index 00000000..17987b79
Binary files /dev/null and b/demo_app/android/app/src/main/res/mipmap-mdpi/ic_launcher.png differ
diff --git a/demo_app/android/app/src/main/res/mipmap-xhdpi/ic_launcher.png b/demo_app/android/app/src/main/res/mipmap-xhdpi/ic_launcher.png
new file mode 100644
index 00000000..09d43914
Binary files /dev/null and b/demo_app/android/app/src/main/res/mipmap-xhdpi/ic_launcher.png differ
diff --git a/demo_app/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png b/demo_app/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png
new file mode 100644
index 00000000..d5f1c8d3
Binary files /dev/null and b/demo_app/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png differ
diff --git a/demo_app/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png b/demo_app/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png
new file mode 100644
index 00000000..4d6372ee
Binary files /dev/null and b/demo_app/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png differ
diff --git a/demo_app/android/app/src/main/res/values/styles.xml b/demo_app/android/app/src/main/res/values/styles.xml
new file mode 100644
index 00000000..00fa4417
--- /dev/null
+++ b/demo_app/android/app/src/main/res/values/styles.xml
@@ -0,0 +1,8 @@
+
+
+
+
diff --git a/demo_app/android/app/src/profile/AndroidManifest.xml b/demo_app/android/app/src/profile/AndroidManifest.xml
new file mode 100644
index 00000000..cef74c20
--- /dev/null
+++ b/demo_app/android/app/src/profile/AndroidManifest.xml
@@ -0,0 +1,7 @@
+
+
+
+
diff --git a/demo_app/android/build.gradle b/demo_app/android/build.gradle
new file mode 100644
index 00000000..3100ad2d
--- /dev/null
+++ b/demo_app/android/build.gradle
@@ -0,0 +1,31 @@
+buildscript {
+ ext.kotlin_version = '1.3.50'
+ repositories {
+ google()
+ jcenter()
+ }
+
+ dependencies {
+ classpath 'com.android.tools.build:gradle:3.5.0'
+ classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
+ }
+}
+
+allprojects {
+ repositories {
+ google()
+ jcenter()
+ }
+}
+
+rootProject.buildDir = '../build'
+subprojects {
+ project.buildDir = "${rootProject.buildDir}/${project.name}"
+}
+subprojects {
+ project.evaluationDependsOn(':app')
+}
+
+task clean(type: Delete) {
+ delete rootProject.buildDir
+}
diff --git a/demo_app/android/gradle.properties b/demo_app/android/gradle.properties
new file mode 100644
index 00000000..38c8d454
--- /dev/null
+++ b/demo_app/android/gradle.properties
@@ -0,0 +1,4 @@
+org.gradle.jvmargs=-Xmx1536M
+android.enableR8=true
+android.useAndroidX=true
+android.enableJetifier=true
diff --git a/demo_app/android/gradle/wrapper/gradle-wrapper.properties b/demo_app/android/gradle/wrapper/gradle-wrapper.properties
new file mode 100644
index 00000000..296b146b
--- /dev/null
+++ b/demo_app/android/gradle/wrapper/gradle-wrapper.properties
@@ -0,0 +1,6 @@
+#Fri Jun 23 08:50:38 CEST 2017
+distributionBase=GRADLE_USER_HOME
+distributionPath=wrapper/dists
+zipStoreBase=GRADLE_USER_HOME
+zipStorePath=wrapper/dists
+distributionUrl=https\://services.gradle.org/distributions/gradle-5.6.2-all.zip
diff --git a/demo_app/android/settings.gradle b/demo_app/android/settings.gradle
new file mode 100644
index 00000000..5a2f14fb
--- /dev/null
+++ b/demo_app/android/settings.gradle
@@ -0,0 +1,15 @@
+include ':app'
+
+def flutterProjectRoot = rootProject.projectDir.parentFile.toPath()
+
+def plugins = new Properties()
+def pluginsFile = new File(flutterProjectRoot.toFile(), '.flutter-plugins')
+if (pluginsFile.exists()) {
+ pluginsFile.withReader('UTF-8') { reader -> plugins.load(reader) }
+}
+
+plugins.each { name, path ->
+ def pluginDirectory = flutterProjectRoot.resolve(path).resolve('android').toFile()
+ include ":$name"
+ project(":$name").projectDir = pluginDirectory
+}
diff --git a/demo_app/ios/.gitignore b/demo_app/ios/.gitignore
new file mode 100644
index 00000000..e96ef602
--- /dev/null
+++ b/demo_app/ios/.gitignore
@@ -0,0 +1,32 @@
+*.mode1v3
+*.mode2v3
+*.moved-aside
+*.pbxuser
+*.perspectivev3
+**/*sync/
+.sconsign.dblite
+.tags*
+**/.vagrant/
+**/DerivedData/
+Icon?
+**/Pods/
+**/.symlinks/
+profile
+xcuserdata
+**/.generated/
+Flutter/App.framework
+Flutter/Flutter.framework
+Flutter/Flutter.podspec
+Flutter/Generated.xcconfig
+Flutter/app.flx
+Flutter/app.zip
+Flutter/flutter_assets/
+Flutter/flutter_export_environment.sh
+ServiceDefinitions.json
+Runner/GeneratedPluginRegistrant.*
+
+# Exceptions to above rules.
+!default.mode1v3
+!default.mode2v3
+!default.pbxuser
+!default.perspectivev3
diff --git a/demo_app/ios/Flutter/AppFrameworkInfo.plist b/demo_app/ios/Flutter/AppFrameworkInfo.plist
new file mode 100644
index 00000000..6b4c0f78
--- /dev/null
+++ b/demo_app/ios/Flutter/AppFrameworkInfo.plist
@@ -0,0 +1,26 @@
+
+
+
+
+ CFBundleDevelopmentRegion
+ $(DEVELOPMENT_LANGUAGE)
+ CFBundleExecutable
+ App
+ CFBundleIdentifier
+ io.flutter.flutter.app
+ CFBundleInfoDictionaryVersion
+ 6.0
+ CFBundleName
+ App
+ CFBundlePackageType
+ FMWK
+ CFBundleShortVersionString
+ 1.0
+ CFBundleSignature
+ ????
+ CFBundleVersion
+ 1.0
+ MinimumOSVersion
+ 8.0
+
+
diff --git a/demo_app/ios/Flutter/Debug.xcconfig b/demo_app/ios/Flutter/Debug.xcconfig
new file mode 100644
index 00000000..592ceee8
--- /dev/null
+++ b/demo_app/ios/Flutter/Debug.xcconfig
@@ -0,0 +1 @@
+#include "Generated.xcconfig"
diff --git a/demo_app/ios/Flutter/Release.xcconfig b/demo_app/ios/Flutter/Release.xcconfig
new file mode 100644
index 00000000..592ceee8
--- /dev/null
+++ b/demo_app/ios/Flutter/Release.xcconfig
@@ -0,0 +1 @@
+#include "Generated.xcconfig"
diff --git a/demo_app/ios/Runner.xcodeproj/project.pbxproj b/demo_app/ios/Runner.xcodeproj/project.pbxproj
new file mode 100644
index 00000000..af5c5ea0
--- /dev/null
+++ b/demo_app/ios/Runner.xcodeproj/project.pbxproj
@@ -0,0 +1,518 @@
+// !$*UTF8*$!
+{
+ archiveVersion = 1;
+ classes = {
+ };
+ objectVersion = 46;
+ objects = {
+
+/* Begin PBXBuildFile section */
+ 1498D2341E8E89220040F4C2 /* GeneratedPluginRegistrant.m in Sources */ = {isa = PBXBuildFile; fileRef = 1498D2331E8E89220040F4C2 /* GeneratedPluginRegistrant.m */; };
+ 3B3967161E833CAA004F5970 /* AppFrameworkInfo.plist in Resources */ = {isa = PBXBuildFile; fileRef = 3B3967151E833CAA004F5970 /* AppFrameworkInfo.plist */; };
+ 3B80C3941E831B6300D905FE /* App.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 3B80C3931E831B6300D905FE /* App.framework */; };
+ 3B80C3951E831B6300D905FE /* App.framework in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = 3B80C3931E831B6300D905FE /* App.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; };
+ 74858FAF1ED2DC5600515810 /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 74858FAE1ED2DC5600515810 /* AppDelegate.swift */; };
+ 9705A1C61CF904A100538489 /* Flutter.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 9740EEBA1CF902C7004384FC /* Flutter.framework */; };
+ 9705A1C71CF904A300538489 /* Flutter.framework in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = 9740EEBA1CF902C7004384FC /* Flutter.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; };
+ 97C146FC1CF9000F007C117D /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 97C146FA1CF9000F007C117D /* Main.storyboard */; };
+ 97C146FE1CF9000F007C117D /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 97C146FD1CF9000F007C117D /* Assets.xcassets */; };
+ 97C147011CF9000F007C117D /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 97C146FF1CF9000F007C117D /* LaunchScreen.storyboard */; };
+/* End PBXBuildFile section */
+
+/* Begin PBXCopyFilesBuildPhase section */
+ 9705A1C41CF9048500538489 /* Embed Frameworks */ = {
+ isa = PBXCopyFilesBuildPhase;
+ buildActionMask = 2147483647;
+ dstPath = "";
+ dstSubfolderSpec = 10;
+ files = (
+ 3B80C3951E831B6300D905FE /* App.framework in Embed Frameworks */,
+ 9705A1C71CF904A300538489 /* Flutter.framework in Embed Frameworks */,
+ );
+ name = "Embed Frameworks";
+ runOnlyForDeploymentPostprocessing = 0;
+ };
+/* End PBXCopyFilesBuildPhase section */
+
+/* Begin PBXFileReference section */
+ 1498D2321E8E86230040F4C2 /* GeneratedPluginRegistrant.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = GeneratedPluginRegistrant.h; sourceTree = ""; };
+ 1498D2331E8E89220040F4C2 /* GeneratedPluginRegistrant.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = GeneratedPluginRegistrant.m; sourceTree = ""; };
+ 3B3967151E833CAA004F5970 /* AppFrameworkInfo.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; name = AppFrameworkInfo.plist; path = Flutter/AppFrameworkInfo.plist; sourceTree = ""; };
+ 3B80C3931E831B6300D905FE /* App.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = App.framework; path = Flutter/App.framework; sourceTree = ""; };
+ 74858FAD1ED2DC5600515810 /* Runner-Bridging-Header.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "Runner-Bridging-Header.h"; sourceTree = ""; };
+ 74858FAE1ED2DC5600515810 /* AppDelegate.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = ""; };
+ 7AFA3C8E1D35360C0083082E /* Release.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; name = Release.xcconfig; path = Flutter/Release.xcconfig; sourceTree = ""; };
+ 9740EEB21CF90195004384FC /* Debug.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; name = Debug.xcconfig; path = Flutter/Debug.xcconfig; sourceTree = ""; };
+ 9740EEB31CF90195004384FC /* Generated.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; name = Generated.xcconfig; path = Flutter/Generated.xcconfig; sourceTree = ""; };
+ 9740EEBA1CF902C7004384FC /* Flutter.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Flutter.framework; path = Flutter/Flutter.framework; sourceTree = ""; };
+ 97C146EE1CF9000F007C117D /* Runner.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = Runner.app; sourceTree = BUILT_PRODUCTS_DIR; };
+ 97C146FB1CF9000F007C117D /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/Main.storyboard; sourceTree = ""; };
+ 97C146FD1CF9000F007C117D /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = ""; };
+ 97C147001CF9000F007C117D /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/LaunchScreen.storyboard; sourceTree = ""; };
+ 97C147021CF9000F007C117D /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; };
+/* End PBXFileReference section */
+
+/* Begin PBXFrameworksBuildPhase section */
+ 97C146EB1CF9000F007C117D /* Frameworks */ = {
+ isa = PBXFrameworksBuildPhase;
+ buildActionMask = 2147483647;
+ files = (
+ 9705A1C61CF904A100538489 /* Flutter.framework in Frameworks */,
+ 3B80C3941E831B6300D905FE /* App.framework in Frameworks */,
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ };
+/* End PBXFrameworksBuildPhase section */
+
+/* Begin PBXGroup section */
+ 9740EEB11CF90186004384FC /* Flutter */ = {
+ isa = PBXGroup;
+ children = (
+ 3B80C3931E831B6300D905FE /* App.framework */,
+ 3B3967151E833CAA004F5970 /* AppFrameworkInfo.plist */,
+ 9740EEBA1CF902C7004384FC /* Flutter.framework */,
+ 9740EEB21CF90195004384FC /* Debug.xcconfig */,
+ 7AFA3C8E1D35360C0083082E /* Release.xcconfig */,
+ 9740EEB31CF90195004384FC /* Generated.xcconfig */,
+ );
+ name = Flutter;
+ sourceTree = "";
+ };
+ 97C146E51CF9000F007C117D = {
+ isa = PBXGroup;
+ children = (
+ 9740EEB11CF90186004384FC /* Flutter */,
+ 97C146F01CF9000F007C117D /* Runner */,
+ 97C146EF1CF9000F007C117D /* Products */,
+ );
+ sourceTree = "";
+ };
+ 97C146EF1CF9000F007C117D /* Products */ = {
+ isa = PBXGroup;
+ children = (
+ 97C146EE1CF9000F007C117D /* Runner.app */,
+ );
+ name = Products;
+ sourceTree = "";
+ };
+ 97C146F01CF9000F007C117D /* Runner */ = {
+ isa = PBXGroup;
+ children = (
+ 97C146FA1CF9000F007C117D /* Main.storyboard */,
+ 97C146FD1CF9000F007C117D /* Assets.xcassets */,
+ 97C146FF1CF9000F007C117D /* LaunchScreen.storyboard */,
+ 97C147021CF9000F007C117D /* Info.plist */,
+ 97C146F11CF9000F007C117D /* Supporting Files */,
+ 1498D2321E8E86230040F4C2 /* GeneratedPluginRegistrant.h */,
+ 1498D2331E8E89220040F4C2 /* GeneratedPluginRegistrant.m */,
+ 74858FAE1ED2DC5600515810 /* AppDelegate.swift */,
+ 74858FAD1ED2DC5600515810 /* Runner-Bridging-Header.h */,
+ );
+ path = Runner;
+ sourceTree = "";
+ };
+ 97C146F11CF9000F007C117D /* Supporting Files */ = {
+ isa = PBXGroup;
+ children = (
+ );
+ name = "Supporting Files";
+ sourceTree = "";
+ };
+/* End PBXGroup section */
+
+/* Begin PBXNativeTarget section */
+ 97C146ED1CF9000F007C117D /* Runner */ = {
+ isa = PBXNativeTarget;
+ buildConfigurationList = 97C147051CF9000F007C117D /* Build configuration list for PBXNativeTarget "Runner" */;
+ buildPhases = (
+ 9740EEB61CF901F6004384FC /* Run Script */,
+ 97C146EA1CF9000F007C117D /* Sources */,
+ 97C146EB1CF9000F007C117D /* Frameworks */,
+ 97C146EC1CF9000F007C117D /* Resources */,
+ 9705A1C41CF9048500538489 /* Embed Frameworks */,
+ 3B06AD1E1E4923F5004D2608 /* Thin Binary */,
+ );
+ buildRules = (
+ );
+ dependencies = (
+ );
+ name = Runner;
+ productName = Runner;
+ productReference = 97C146EE1CF9000F007C117D /* Runner.app */;
+ productType = "com.apple.product-type.application";
+ };
+/* End PBXNativeTarget section */
+
+/* Begin PBXProject section */
+ 97C146E61CF9000F007C117D /* Project object */ = {
+ isa = PBXProject;
+ attributes = {
+ LastUpgradeCheck = 1020;
+ ORGANIZATIONNAME = "The Chromium Authors";
+ TargetAttributes = {
+ 97C146ED1CF9000F007C117D = {
+ CreatedOnToolsVersion = 7.3.1;
+ LastSwiftMigration = 1100;
+ };
+ };
+ };
+ buildConfigurationList = 97C146E91CF9000F007C117D /* Build configuration list for PBXProject "Runner" */;
+ compatibilityVersion = "Xcode 3.2";
+ developmentRegion = en;
+ hasScannedForEncodings = 0;
+ knownRegions = (
+ en,
+ Base,
+ );
+ mainGroup = 97C146E51CF9000F007C117D;
+ productRefGroup = 97C146EF1CF9000F007C117D /* Products */;
+ projectDirPath = "";
+ projectRoot = "";
+ targets = (
+ 97C146ED1CF9000F007C117D /* Runner */,
+ );
+ };
+/* End PBXProject section */
+
+/* Begin PBXResourcesBuildPhase section */
+ 97C146EC1CF9000F007C117D /* Resources */ = {
+ isa = PBXResourcesBuildPhase;
+ buildActionMask = 2147483647;
+ files = (
+ 97C147011CF9000F007C117D /* LaunchScreen.storyboard in Resources */,
+ 3B3967161E833CAA004F5970 /* AppFrameworkInfo.plist in Resources */,
+ 97C146FE1CF9000F007C117D /* Assets.xcassets in Resources */,
+ 97C146FC1CF9000F007C117D /* Main.storyboard in Resources */,
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ };
+/* End PBXResourcesBuildPhase section */
+
+/* Begin PBXShellScriptBuildPhase section */
+ 3B06AD1E1E4923F5004D2608 /* Thin Binary */ = {
+ isa = PBXShellScriptBuildPhase;
+ buildActionMask = 2147483647;
+ files = (
+ );
+ inputPaths = (
+ );
+ name = "Thin Binary";
+ outputPaths = (
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ shellPath = /bin/sh;
+ shellScript = "/bin/sh \"$FLUTTER_ROOT/packages/flutter_tools/bin/xcode_backend.sh\" thin";
+ };
+ 9740EEB61CF901F6004384FC /* Run Script */ = {
+ isa = PBXShellScriptBuildPhase;
+ buildActionMask = 2147483647;
+ files = (
+ );
+ inputPaths = (
+ );
+ name = "Run Script";
+ outputPaths = (
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ shellPath = /bin/sh;
+ shellScript = "/bin/sh \"$FLUTTER_ROOT/packages/flutter_tools/bin/xcode_backend.sh\" build";
+ };
+/* End PBXShellScriptBuildPhase section */
+
+/* Begin PBXSourcesBuildPhase section */
+ 97C146EA1CF9000F007C117D /* Sources */ = {
+ isa = PBXSourcesBuildPhase;
+ buildActionMask = 2147483647;
+ files = (
+ 74858FAF1ED2DC5600515810 /* AppDelegate.swift in Sources */,
+ 1498D2341E8E89220040F4C2 /* GeneratedPluginRegistrant.m in Sources */,
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ };
+/* End PBXSourcesBuildPhase section */
+
+/* Begin PBXVariantGroup section */
+ 97C146FA1CF9000F007C117D /* Main.storyboard */ = {
+ isa = PBXVariantGroup;
+ children = (
+ 97C146FB1CF9000F007C117D /* Base */,
+ );
+ name = Main.storyboard;
+ sourceTree = "";
+ };
+ 97C146FF1CF9000F007C117D /* LaunchScreen.storyboard */ = {
+ isa = PBXVariantGroup;
+ children = (
+ 97C147001CF9000F007C117D /* Base */,
+ );
+ name = LaunchScreen.storyboard;
+ sourceTree = "";
+ };
+/* End PBXVariantGroup section */
+
+/* Begin XCBuildConfiguration section */
+ 249021D3217E4FDB00AE95B9 /* Profile */ = {
+ isa = XCBuildConfiguration;
+ baseConfigurationReference = 7AFA3C8E1D35360C0083082E /* Release.xcconfig */;
+ buildSettings = {
+ ALWAYS_SEARCH_USER_PATHS = NO;
+ CLANG_ANALYZER_NONNULL = YES;
+ CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x";
+ CLANG_CXX_LIBRARY = "libc++";
+ CLANG_ENABLE_MODULES = YES;
+ CLANG_ENABLE_OBJC_ARC = YES;
+ CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES;
+ CLANG_WARN_BOOL_CONVERSION = YES;
+ CLANG_WARN_COMMA = YES;
+ CLANG_WARN_CONSTANT_CONVERSION = YES;
+ CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES;
+ CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
+ CLANG_WARN_EMPTY_BODY = YES;
+ CLANG_WARN_ENUM_CONVERSION = YES;
+ CLANG_WARN_INFINITE_RECURSION = YES;
+ CLANG_WARN_INT_CONVERSION = YES;
+ CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES;
+ CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES;
+ CLANG_WARN_OBJC_LITERAL_CONVERSION = YES;
+ CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
+ CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
+ CLANG_WARN_STRICT_PROTOTYPES = YES;
+ CLANG_WARN_SUSPICIOUS_MOVE = YES;
+ CLANG_WARN_UNREACHABLE_CODE = YES;
+ CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
+ "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
+ COPY_PHASE_STRIP = NO;
+ DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
+ ENABLE_NS_ASSERTIONS = NO;
+ ENABLE_STRICT_OBJC_MSGSEND = YES;
+ GCC_C_LANGUAGE_STANDARD = gnu99;
+ GCC_NO_COMMON_BLOCKS = YES;
+ GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
+ GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
+ GCC_WARN_UNDECLARED_SELECTOR = YES;
+ GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
+ GCC_WARN_UNUSED_FUNCTION = YES;
+ GCC_WARN_UNUSED_VARIABLE = YES;
+ IPHONEOS_DEPLOYMENT_TARGET = 8.0;
+ MTL_ENABLE_DEBUG_INFO = NO;
+ SDKROOT = iphoneos;
+ SUPPORTED_PLATFORMS = iphoneos;
+ TARGETED_DEVICE_FAMILY = "1,2";
+ VALIDATE_PRODUCT = YES;
+ };
+ name = Profile;
+ };
+ 249021D4217E4FDB00AE95B9 /* Profile */ = {
+ isa = XCBuildConfiguration;
+ baseConfigurationReference = 7AFA3C8E1D35360C0083082E /* Release.xcconfig */;
+ buildSettings = {
+ ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
+ CLANG_ENABLE_MODULES = YES;
+ CURRENT_PROJECT_VERSION = "$(FLUTTER_BUILD_NUMBER)";
+ ENABLE_BITCODE = NO;
+ FRAMEWORK_SEARCH_PATHS = (
+ "$(inherited)",
+ "$(PROJECT_DIR)/Flutter",
+ );
+ INFOPLIST_FILE = Runner/Info.plist;
+ LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks";
+ LIBRARY_SEARCH_PATHS = (
+ "$(inherited)",
+ "$(PROJECT_DIR)/Flutter",
+ );
+ PRODUCT_BUNDLE_IDENTIFIER = com.example.demoApp;
+ PRODUCT_NAME = "$(TARGET_NAME)";
+ SWIFT_OBJC_BRIDGING_HEADER = "Runner/Runner-Bridging-Header.h";
+ SWIFT_VERSION = 5.0;
+ VERSIONING_SYSTEM = "apple-generic";
+ };
+ name = Profile;
+ };
+ 97C147031CF9000F007C117D /* Debug */ = {
+ isa = XCBuildConfiguration;
+ baseConfigurationReference = 9740EEB21CF90195004384FC /* Debug.xcconfig */;
+ buildSettings = {
+ ALWAYS_SEARCH_USER_PATHS = NO;
+ CLANG_ANALYZER_NONNULL = YES;
+ CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x";
+ CLANG_CXX_LIBRARY = "libc++";
+ CLANG_ENABLE_MODULES = YES;
+ CLANG_ENABLE_OBJC_ARC = YES;
+ CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES;
+ CLANG_WARN_BOOL_CONVERSION = YES;
+ CLANG_WARN_COMMA = YES;
+ CLANG_WARN_CONSTANT_CONVERSION = YES;
+ CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES;
+ CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
+ CLANG_WARN_EMPTY_BODY = YES;
+ CLANG_WARN_ENUM_CONVERSION = YES;
+ CLANG_WARN_INFINITE_RECURSION = YES;
+ CLANG_WARN_INT_CONVERSION = YES;
+ CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES;
+ CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES;
+ CLANG_WARN_OBJC_LITERAL_CONVERSION = YES;
+ CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
+ CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
+ CLANG_WARN_STRICT_PROTOTYPES = YES;
+ CLANG_WARN_SUSPICIOUS_MOVE = YES;
+ CLANG_WARN_UNREACHABLE_CODE = YES;
+ CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
+ "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
+ COPY_PHASE_STRIP = NO;
+ DEBUG_INFORMATION_FORMAT = dwarf;
+ ENABLE_STRICT_OBJC_MSGSEND = YES;
+ ENABLE_TESTABILITY = YES;
+ GCC_C_LANGUAGE_STANDARD = gnu99;
+ GCC_DYNAMIC_NO_PIC = NO;
+ GCC_NO_COMMON_BLOCKS = YES;
+ GCC_OPTIMIZATION_LEVEL = 0;
+ GCC_PREPROCESSOR_DEFINITIONS = (
+ "DEBUG=1",
+ "$(inherited)",
+ );
+ GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
+ GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
+ GCC_WARN_UNDECLARED_SELECTOR = YES;
+ GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
+ GCC_WARN_UNUSED_FUNCTION = YES;
+ GCC_WARN_UNUSED_VARIABLE = YES;
+ IPHONEOS_DEPLOYMENT_TARGET = 8.0;
+ MTL_ENABLE_DEBUG_INFO = YES;
+ ONLY_ACTIVE_ARCH = YES;
+ SDKROOT = iphoneos;
+ TARGETED_DEVICE_FAMILY = "1,2";
+ };
+ name = Debug;
+ };
+ 97C147041CF9000F007C117D /* Release */ = {
+ isa = XCBuildConfiguration;
+ baseConfigurationReference = 7AFA3C8E1D35360C0083082E /* Release.xcconfig */;
+ buildSettings = {
+ ALWAYS_SEARCH_USER_PATHS = NO;
+ CLANG_ANALYZER_NONNULL = YES;
+ CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x";
+ CLANG_CXX_LIBRARY = "libc++";
+ CLANG_ENABLE_MODULES = YES;
+ CLANG_ENABLE_OBJC_ARC = YES;
+ CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES;
+ CLANG_WARN_BOOL_CONVERSION = YES;
+ CLANG_WARN_COMMA = YES;
+ CLANG_WARN_CONSTANT_CONVERSION = YES;
+ CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES;
+ CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
+ CLANG_WARN_EMPTY_BODY = YES;
+ CLANG_WARN_ENUM_CONVERSION = YES;
+ CLANG_WARN_INFINITE_RECURSION = YES;
+ CLANG_WARN_INT_CONVERSION = YES;
+ CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES;
+ CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES;
+ CLANG_WARN_OBJC_LITERAL_CONVERSION = YES;
+ CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
+ CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
+ CLANG_WARN_STRICT_PROTOTYPES = YES;
+ CLANG_WARN_SUSPICIOUS_MOVE = YES;
+ CLANG_WARN_UNREACHABLE_CODE = YES;
+ CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
+ "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
+ COPY_PHASE_STRIP = NO;
+ DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
+ ENABLE_NS_ASSERTIONS = NO;
+ ENABLE_STRICT_OBJC_MSGSEND = YES;
+ GCC_C_LANGUAGE_STANDARD = gnu99;
+ GCC_NO_COMMON_BLOCKS = YES;
+ GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
+ GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
+ GCC_WARN_UNDECLARED_SELECTOR = YES;
+ GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
+ GCC_WARN_UNUSED_FUNCTION = YES;
+ GCC_WARN_UNUSED_VARIABLE = YES;
+ IPHONEOS_DEPLOYMENT_TARGET = 8.0;
+ MTL_ENABLE_DEBUG_INFO = NO;
+ SDKROOT = iphoneos;
+ SUPPORTED_PLATFORMS = iphoneos;
+ SWIFT_OPTIMIZATION_LEVEL = "-Owholemodule";
+ TARGETED_DEVICE_FAMILY = "1,2";
+ VALIDATE_PRODUCT = YES;
+ };
+ name = Release;
+ };
+ 97C147061CF9000F007C117D /* Debug */ = {
+ isa = XCBuildConfiguration;
+ baseConfigurationReference = 9740EEB21CF90195004384FC /* Debug.xcconfig */;
+ buildSettings = {
+ ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
+ CLANG_ENABLE_MODULES = YES;
+ CURRENT_PROJECT_VERSION = "$(FLUTTER_BUILD_NUMBER)";
+ ENABLE_BITCODE = NO;
+ FRAMEWORK_SEARCH_PATHS = (
+ "$(inherited)",
+ "$(PROJECT_DIR)/Flutter",
+ );
+ INFOPLIST_FILE = Runner/Info.plist;
+ LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks";
+ LIBRARY_SEARCH_PATHS = (
+ "$(inherited)",
+ "$(PROJECT_DIR)/Flutter",
+ );
+ PRODUCT_BUNDLE_IDENTIFIER = com.example.demoApp;
+ PRODUCT_NAME = "$(TARGET_NAME)";
+ SWIFT_OBJC_BRIDGING_HEADER = "Runner/Runner-Bridging-Header.h";
+ SWIFT_OPTIMIZATION_LEVEL = "-Onone";
+ SWIFT_VERSION = 5.0;
+ VERSIONING_SYSTEM = "apple-generic";
+ };
+ name = Debug;
+ };
+ 97C147071CF9000F007C117D /* Release */ = {
+ isa = XCBuildConfiguration;
+ baseConfigurationReference = 7AFA3C8E1D35360C0083082E /* Release.xcconfig */;
+ buildSettings = {
+ ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
+ CLANG_ENABLE_MODULES = YES;
+ CURRENT_PROJECT_VERSION = "$(FLUTTER_BUILD_NUMBER)";
+ ENABLE_BITCODE = NO;
+ FRAMEWORK_SEARCH_PATHS = (
+ "$(inherited)",
+ "$(PROJECT_DIR)/Flutter",
+ );
+ INFOPLIST_FILE = Runner/Info.plist;
+ LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks";
+ LIBRARY_SEARCH_PATHS = (
+ "$(inherited)",
+ "$(PROJECT_DIR)/Flutter",
+ );
+ PRODUCT_BUNDLE_IDENTIFIER = com.example.demoApp;
+ PRODUCT_NAME = "$(TARGET_NAME)";
+ SWIFT_OBJC_BRIDGING_HEADER = "Runner/Runner-Bridging-Header.h";
+ SWIFT_VERSION = 5.0;
+ VERSIONING_SYSTEM = "apple-generic";
+ };
+ name = Release;
+ };
+/* End XCBuildConfiguration section */
+
+/* Begin XCConfigurationList section */
+ 97C146E91CF9000F007C117D /* Build configuration list for PBXProject "Runner" */ = {
+ isa = XCConfigurationList;
+ buildConfigurations = (
+ 97C147031CF9000F007C117D /* Debug */,
+ 97C147041CF9000F007C117D /* Release */,
+ 249021D3217E4FDB00AE95B9 /* Profile */,
+ );
+ defaultConfigurationIsVisible = 0;
+ defaultConfigurationName = Release;
+ };
+ 97C147051CF9000F007C117D /* Build configuration list for PBXNativeTarget "Runner" */ = {
+ isa = XCConfigurationList;
+ buildConfigurations = (
+ 97C147061CF9000F007C117D /* Debug */,
+ 97C147071CF9000F007C117D /* Release */,
+ 249021D4217E4FDB00AE95B9 /* Profile */,
+ );
+ defaultConfigurationIsVisible = 0;
+ defaultConfigurationName = Release;
+ };
+/* End XCConfigurationList section */
+ };
+ rootObject = 97C146E61CF9000F007C117D /* Project object */;
+}
diff --git a/demo_app/ios/Runner.xcodeproj/project.xcworkspace/contents.xcworkspacedata b/demo_app/ios/Runner.xcodeproj/project.xcworkspace/contents.xcworkspacedata
new file mode 100644
index 00000000..1d526a16
--- /dev/null
+++ b/demo_app/ios/Runner.xcodeproj/project.xcworkspace/contents.xcworkspacedata
@@ -0,0 +1,7 @@
+
+
+
+
+
diff --git a/demo_app/ios/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme b/demo_app/ios/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme
new file mode 100644
index 00000000..a28140cf
--- /dev/null
+++ b/demo_app/ios/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme
@@ -0,0 +1,91 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/demo_app/ios/Runner.xcworkspace/contents.xcworkspacedata b/demo_app/ios/Runner.xcworkspace/contents.xcworkspacedata
new file mode 100644
index 00000000..1d526a16
--- /dev/null
+++ b/demo_app/ios/Runner.xcworkspace/contents.xcworkspacedata
@@ -0,0 +1,7 @@
+
+
+
+
+
diff --git a/demo_app/ios/Runner/AppDelegate.swift b/demo_app/ios/Runner/AppDelegate.swift
new file mode 100644
index 00000000..70693e4a
--- /dev/null
+++ b/demo_app/ios/Runner/AppDelegate.swift
@@ -0,0 +1,13 @@
+import UIKit
+import Flutter
+
+@UIApplicationMain
+@objc class AppDelegate: FlutterAppDelegate {
+ override func application(
+ _ application: UIApplication,
+ didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?
+ ) -> Bool {
+ GeneratedPluginRegistrant.register(with: self)
+ return super.application(application, didFinishLaunchingWithOptions: launchOptions)
+ }
+}
diff --git a/demo_app/ios/Runner/Assets.xcassets/AppIcon.appiconset/Contents.json b/demo_app/ios/Runner/Assets.xcassets/AppIcon.appiconset/Contents.json
new file mode 100644
index 00000000..d36b1fab
--- /dev/null
+++ b/demo_app/ios/Runner/Assets.xcassets/AppIcon.appiconset/Contents.json
@@ -0,0 +1,122 @@
+{
+ "images" : [
+ {
+ "size" : "20x20",
+ "idiom" : "iphone",
+ "filename" : "Icon-App-20x20@2x.png",
+ "scale" : "2x"
+ },
+ {
+ "size" : "20x20",
+ "idiom" : "iphone",
+ "filename" : "Icon-App-20x20@3x.png",
+ "scale" : "3x"
+ },
+ {
+ "size" : "29x29",
+ "idiom" : "iphone",
+ "filename" : "Icon-App-29x29@1x.png",
+ "scale" : "1x"
+ },
+ {
+ "size" : "29x29",
+ "idiom" : "iphone",
+ "filename" : "Icon-App-29x29@2x.png",
+ "scale" : "2x"
+ },
+ {
+ "size" : "29x29",
+ "idiom" : "iphone",
+ "filename" : "Icon-App-29x29@3x.png",
+ "scale" : "3x"
+ },
+ {
+ "size" : "40x40",
+ "idiom" : "iphone",
+ "filename" : "Icon-App-40x40@2x.png",
+ "scale" : "2x"
+ },
+ {
+ "size" : "40x40",
+ "idiom" : "iphone",
+ "filename" : "Icon-App-40x40@3x.png",
+ "scale" : "3x"
+ },
+ {
+ "size" : "60x60",
+ "idiom" : "iphone",
+ "filename" : "Icon-App-60x60@2x.png",
+ "scale" : "2x"
+ },
+ {
+ "size" : "60x60",
+ "idiom" : "iphone",
+ "filename" : "Icon-App-60x60@3x.png",
+ "scale" : "3x"
+ },
+ {
+ "size" : "20x20",
+ "idiom" : "ipad",
+ "filename" : "Icon-App-20x20@1x.png",
+ "scale" : "1x"
+ },
+ {
+ "size" : "20x20",
+ "idiom" : "ipad",
+ "filename" : "Icon-App-20x20@2x.png",
+ "scale" : "2x"
+ },
+ {
+ "size" : "29x29",
+ "idiom" : "ipad",
+ "filename" : "Icon-App-29x29@1x.png",
+ "scale" : "1x"
+ },
+ {
+ "size" : "29x29",
+ "idiom" : "ipad",
+ "filename" : "Icon-App-29x29@2x.png",
+ "scale" : "2x"
+ },
+ {
+ "size" : "40x40",
+ "idiom" : "ipad",
+ "filename" : "Icon-App-40x40@1x.png",
+ "scale" : "1x"
+ },
+ {
+ "size" : "40x40",
+ "idiom" : "ipad",
+ "filename" : "Icon-App-40x40@2x.png",
+ "scale" : "2x"
+ },
+ {
+ "size" : "76x76",
+ "idiom" : "ipad",
+ "filename" : "Icon-App-76x76@1x.png",
+ "scale" : "1x"
+ },
+ {
+ "size" : "76x76",
+ "idiom" : "ipad",
+ "filename" : "Icon-App-76x76@2x.png",
+ "scale" : "2x"
+ },
+ {
+ "size" : "83.5x83.5",
+ "idiom" : "ipad",
+ "filename" : "Icon-App-83.5x83.5@2x.png",
+ "scale" : "2x"
+ },
+ {
+ "size" : "1024x1024",
+ "idiom" : "ios-marketing",
+ "filename" : "Icon-App-1024x1024@1x.png",
+ "scale" : "1x"
+ }
+ ],
+ "info" : {
+ "version" : 1,
+ "author" : "xcode"
+ }
+}
diff --git a/demo_app/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-1024x1024@1x.png b/demo_app/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-1024x1024@1x.png
new file mode 100644
index 00000000..dc9ada47
Binary files /dev/null and b/demo_app/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-1024x1024@1x.png differ
diff --git a/demo_app/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@1x.png b/demo_app/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@1x.png
new file mode 100644
index 00000000..28c6bf03
Binary files /dev/null and b/demo_app/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@1x.png differ
diff --git a/demo_app/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@2x.png b/demo_app/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@2x.png
new file mode 100644
index 00000000..2ccbfd96
Binary files /dev/null and b/demo_app/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@2x.png differ
diff --git a/demo_app/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@3x.png b/demo_app/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@3x.png
new file mode 100644
index 00000000..f091b6b0
Binary files /dev/null and b/demo_app/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@3x.png differ
diff --git a/demo_app/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@1x.png b/demo_app/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@1x.png
new file mode 100644
index 00000000..4cde1211
Binary files /dev/null and b/demo_app/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@1x.png differ
diff --git a/demo_app/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@2x.png b/demo_app/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@2x.png
new file mode 100644
index 00000000..d0ef06e7
Binary files /dev/null and b/demo_app/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@2x.png differ
diff --git a/demo_app/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@3x.png b/demo_app/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@3x.png
new file mode 100644
index 00000000..dcdc2306
Binary files /dev/null and b/demo_app/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@3x.png differ
diff --git a/demo_app/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@1x.png b/demo_app/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@1x.png
new file mode 100644
index 00000000..2ccbfd96
Binary files /dev/null and b/demo_app/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@1x.png differ
diff --git a/demo_app/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@2x.png b/demo_app/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@2x.png
new file mode 100644
index 00000000..c8f9ed8f
Binary files /dev/null and b/demo_app/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@2x.png differ
diff --git a/demo_app/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@3x.png b/demo_app/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@3x.png
new file mode 100644
index 00000000..a6d6b860
Binary files /dev/null and b/demo_app/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@3x.png differ
diff --git a/demo_app/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@2x.png b/demo_app/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@2x.png
new file mode 100644
index 00000000..a6d6b860
Binary files /dev/null and b/demo_app/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@2x.png differ
diff --git a/demo_app/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@3x.png b/demo_app/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@3x.png
new file mode 100644
index 00000000..75b2d164
Binary files /dev/null and b/demo_app/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@3x.png differ
diff --git a/demo_app/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@1x.png b/demo_app/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@1x.png
new file mode 100644
index 00000000..c4df70d3
Binary files /dev/null and b/demo_app/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@1x.png differ
diff --git a/demo_app/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@2x.png b/demo_app/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@2x.png
new file mode 100644
index 00000000..6a84f41e
Binary files /dev/null and b/demo_app/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@2x.png differ
diff --git a/demo_app/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-83.5x83.5@2x.png b/demo_app/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-83.5x83.5@2x.png
new file mode 100644
index 00000000..d0e1f585
Binary files /dev/null and b/demo_app/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-83.5x83.5@2x.png differ
diff --git a/demo_app/ios/Runner/Assets.xcassets/LaunchImage.imageset/Contents.json b/demo_app/ios/Runner/Assets.xcassets/LaunchImage.imageset/Contents.json
new file mode 100644
index 00000000..0bedcf2f
--- /dev/null
+++ b/demo_app/ios/Runner/Assets.xcassets/LaunchImage.imageset/Contents.json
@@ -0,0 +1,23 @@
+{
+ "images" : [
+ {
+ "idiom" : "universal",
+ "filename" : "LaunchImage.png",
+ "scale" : "1x"
+ },
+ {
+ "idiom" : "universal",
+ "filename" : "LaunchImage@2x.png",
+ "scale" : "2x"
+ },
+ {
+ "idiom" : "universal",
+ "filename" : "LaunchImage@3x.png",
+ "scale" : "3x"
+ }
+ ],
+ "info" : {
+ "version" : 1,
+ "author" : "xcode"
+ }
+}
diff --git a/demo_app/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage.png b/demo_app/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage.png
new file mode 100644
index 00000000..9da19eac
Binary files /dev/null and b/demo_app/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage.png differ
diff --git a/demo_app/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@2x.png b/demo_app/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@2x.png
new file mode 100644
index 00000000..9da19eac
Binary files /dev/null and b/demo_app/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@2x.png differ
diff --git a/demo_app/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@3x.png b/demo_app/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@3x.png
new file mode 100644
index 00000000..9da19eac
Binary files /dev/null and b/demo_app/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@3x.png differ
diff --git a/demo_app/ios/Runner/Assets.xcassets/LaunchImage.imageset/README.md b/demo_app/ios/Runner/Assets.xcassets/LaunchImage.imageset/README.md
new file mode 100644
index 00000000..89c2725b
--- /dev/null
+++ b/demo_app/ios/Runner/Assets.xcassets/LaunchImage.imageset/README.md
@@ -0,0 +1,5 @@
+# Launch Screen Assets
+
+You can customize the launch screen with your own desired assets by replacing the image files in this directory.
+
+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.
\ No newline at end of file
diff --git a/demo_app/ios/Runner/Base.lproj/LaunchScreen.storyboard b/demo_app/ios/Runner/Base.lproj/LaunchScreen.storyboard
new file mode 100644
index 00000000..f2e259c7
--- /dev/null
+++ b/demo_app/ios/Runner/Base.lproj/LaunchScreen.storyboard
@@ -0,0 +1,37 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/demo_app/ios/Runner/Base.lproj/Main.storyboard b/demo_app/ios/Runner/Base.lproj/Main.storyboard
new file mode 100644
index 00000000..f3c28516
--- /dev/null
+++ b/demo_app/ios/Runner/Base.lproj/Main.storyboard
@@ -0,0 +1,26 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/demo_app/ios/Runner/Info.plist b/demo_app/ios/Runner/Info.plist
new file mode 100644
index 00000000..5d77f707
--- /dev/null
+++ b/demo_app/ios/Runner/Info.plist
@@ -0,0 +1,45 @@
+
+
+
+
+ CFBundleDevelopmentRegion
+ $(DEVELOPMENT_LANGUAGE)
+ CFBundleExecutable
+ $(EXECUTABLE_NAME)
+ CFBundleIdentifier
+ $(PRODUCT_BUNDLE_IDENTIFIER)
+ CFBundleInfoDictionaryVersion
+ 6.0
+ CFBundleName
+ demo_app
+ CFBundlePackageType
+ APPL
+ CFBundleShortVersionString
+ $(FLUTTER_BUILD_NAME)
+ CFBundleSignature
+ ????
+ CFBundleVersion
+ $(FLUTTER_BUILD_NUMBER)
+ LSRequiresIPhoneOS
+
+ UILaunchStoryboardName
+ LaunchScreen
+ UIMainStoryboardFile
+ Main
+ UISupportedInterfaceOrientations
+
+ UIInterfaceOrientationPortrait
+ UIInterfaceOrientationLandscapeLeft
+ UIInterfaceOrientationLandscapeRight
+
+ UISupportedInterfaceOrientations~ipad
+
+ UIInterfaceOrientationPortrait
+ UIInterfaceOrientationPortraitUpsideDown
+ UIInterfaceOrientationLandscapeLeft
+ UIInterfaceOrientationLandscapeRight
+
+ UIViewControllerBasedStatusBarAppearance
+
+
+
diff --git a/demo_app/ios/Runner/Runner-Bridging-Header.h b/demo_app/ios/Runner/Runner-Bridging-Header.h
new file mode 100644
index 00000000..7335fdf9
--- /dev/null
+++ b/demo_app/ios/Runner/Runner-Bridging-Header.h
@@ -0,0 +1 @@
+#import "GeneratedPluginRegistrant.h"
\ No newline at end of file
diff --git a/demo_app/lib/main.dart b/demo_app/lib/main.dart
new file mode 100644
index 00000000..eea11a65
--- /dev/null
+++ b/demo_app/lib/main.dart
@@ -0,0 +1,19 @@
+import 'package:flutter/material.dart';
+import 'screens/home.dart';
+
+
+void main() => runApp(MyApp());
+
+class MyApp extends StatelessWidget {
+ @override
+ Widget build(BuildContext context) {
+ return MaterialApp(
+ title: 'Flutter Demo',
+ debugShowCheckedModeBanner: false,
+ theme: ThemeData(
+ primarySwatch: Colors.blue,
+ ),
+ home: HomePage(),
+ );
+ }
+}
diff --git a/demo_app/lib/screens/avatars.dart b/demo_app/lib/screens/avatars.dart
new file mode 100644
index 00000000..6b9ac2ad
--- /dev/null
+++ b/demo_app/lib/screens/avatars.dart
@@ -0,0 +1,295 @@
+import 'package:flutter/cupertino.dart';
+import 'package:flutter/material.dart';
+import 'package:ui_kit/components/avatar/gf_avatar.dart';
+import 'package:ui_kit/components/card/gf_card.dart';
+import 'package:ui_kit/components/header/gf_header.dart';
+import 'package:ui_kit/shape/gf_avatar_shape.dart';
+import 'package:ui_kit/types/gf_heading_type.dart';
+import 'package:ui_kit/colors/gf_color.dart';
+
+class Avatars extends StatefulWidget {
+ @override
+ _AvatarsState createState() => _AvatarsState();
+}
+
+class _AvatarsState extends State {
+ @override
+ Widget build(BuildContext context) {
+ return Scaffold(
+ appBar: AppBar(
+ backgroundColor: getGFColor(GFColor.dark),
+ title: Text('Avatar', style: TextStyle(fontSize: 14),),
+ ),
+ body: Container(
+ child: Column(
+ children: [
+ GFCard(
+ content: Column(
+ crossAxisAlignment: CrossAxisAlignment.start,
+ children: [
+ GFHeader(
+ text: 'Circle Avatar',
+ type: GFHeadingType.typo6,
+ ),
+ SizedBox(
+ height: 10,
+ ),
+ Row(
+ mainAxisAlignment: MainAxisAlignment.spaceBetween,
+ children: [
+ GFAvatar(
+ backgroundColor: getGFColor(GFColor.primary),
+ child: Icon(Icons.face),
+ foregroundColor: getGFColor(GFColor.white),
+ ),
+ GFAvatar(
+ backgroundColor: getGFColor(GFColor.secondary),
+ child: Icon(Icons.face),
+ foregroundColor: getGFColor(GFColor.white),
+ ),
+ GFAvatar(
+ backgroundColor: getGFColor(GFColor.success),
+ child: Icon(Icons.face),
+ foregroundColor: getGFColor(GFColor.white),
+ ),
+ GFAvatar(
+ backgroundColor: getGFColor(GFColor.info),
+ child: Icon(Icons.face),
+ foregroundColor: getGFColor(GFColor.white),
+ ),
+ GFAvatar(
+ backgroundColor: getGFColor(GFColor.danger),
+ child: Icon(Icons.face),
+ foregroundColor: getGFColor(GFColor.white),
+ ),
+
+
+ ],
+ ),
+
+ SizedBox(
+ height: 15,
+ ),
+ Row(
+ mainAxisAlignment: MainAxisAlignment.spaceBetween,
+ children: [
+ GFAvatar(
+ backgroundColor: getGFColor(GFColor.warning),
+ child: Icon(Icons.face),
+ foregroundColor: getGFColor(GFColor.white),
+ ),
+ GFAvatar(
+ backgroundColor: getGFColor(GFColor.dark),
+ child: Icon(Icons.face),
+ foregroundColor: getGFColor(GFColor.white),
+ ),
+ GFAvatar(
+ backgroundColor: getGFColor(GFColor.light),
+ child: Icon(Icons.face),
+ foregroundColor: getGFColor(GFColor.white),
+ ),
+ GFAvatar(
+ backgroundColor: getGFColor(GFColor.alt),
+ child: Icon(Icons.face),
+ foregroundColor: getGFColor(GFColor.white),
+ ),
+ GFAvatar(
+ backgroundColor: getGFColor(GFColor.transparent),
+ child: Icon(Icons.face),
+ foregroundColor: getGFColor(GFColor.dark),
+ ),
+
+ ],
+ ),
+
+ ],
+ ),
+ ),
+ GFCard(
+ content: Column(
+ crossAxisAlignment: CrossAxisAlignment.start,
+ children: [
+ GFHeader(
+ text: 'Square Avatar',
+ type: GFHeadingType.typo6,
+ ),
+ SizedBox(
+ height: 10,
+ ),
+ Row(
+ mainAxisAlignment: MainAxisAlignment.spaceBetween,
+ children: [
+ GFAvatar(
+ backgroundColor: getGFColor(GFColor.primary),
+ child: Icon(Icons.face),
+ foregroundColor: getGFColor(GFColor.white),
+ shape: GFAvatarShape.square,
+ ),
+ GFAvatar(
+ backgroundColor: getGFColor(GFColor.secondary),
+ child: Icon(Icons.face),
+ foregroundColor: getGFColor(GFColor.white),
+ shape: GFAvatarShape.square,
+ ),
+ GFAvatar(
+ backgroundColor: getGFColor(GFColor.success),
+ child: Icon(Icons.face),
+ foregroundColor: getGFColor(GFColor.white),
+ shape: GFAvatarShape.square,
+ ),
+ GFAvatar(
+ backgroundColor: getGFColor(GFColor.info),
+ child: Icon(Icons.face),
+ foregroundColor: getGFColor(GFColor.white),
+ shape: GFAvatarShape.square,
+ ),
+ GFAvatar(
+ backgroundColor: getGFColor(GFColor.danger),
+ child: Icon(Icons.face),
+ foregroundColor: getGFColor(GFColor.white),
+ shape: GFAvatarShape.square,
+ ),
+
+
+ ],
+ ),
+
+ SizedBox(
+ height: 15,
+ ),
+ Row(
+ mainAxisAlignment: MainAxisAlignment.spaceBetween,
+ children: [
+ GFAvatar(
+ backgroundColor: getGFColor(GFColor.warning),
+ child: Icon(Icons.face),
+ foregroundColor: getGFColor(GFColor.white),
+ shape: GFAvatarShape.square,
+ ),
+ GFAvatar(
+ backgroundColor: getGFColor(GFColor.dark),
+ child: Icon(Icons.face),
+ foregroundColor: getGFColor(GFColor.white),
+ shape: GFAvatarShape.square,
+ ),
+ GFAvatar(
+ backgroundColor: getGFColor(GFColor.light),
+ child: Icon(Icons.face),
+ foregroundColor: getGFColor(GFColor.white),
+ shape: GFAvatarShape.square,
+ ),
+ GFAvatar(
+ backgroundColor: getGFColor(GFColor.alt),
+ child: Icon(Icons.face),
+ foregroundColor: getGFColor(GFColor.white),
+ shape: GFAvatarShape.square,
+ ),
+ GFAvatar(
+ backgroundColor: getGFColor(GFColor.transparent),
+ child: Icon(Icons.face),
+ foregroundColor: getGFColor(GFColor.dark),
+
+ ),
+
+ ],
+ ),
+ ],
+ ),
+ ),
+ GFCard(
+ content: Column(
+ crossAxisAlignment: CrossAxisAlignment.start,
+ children: [
+ GFHeader(
+ text: 'Standard Avatar',
+ type: GFHeadingType.typo6,
+ ),
+ SizedBox(
+ height: 10,
+ ),
+ Row(
+ mainAxisAlignment: MainAxisAlignment.spaceBetween,
+ children: [
+ GFAvatar(
+ backgroundColor: getGFColor(GFColor.primary),
+ child: Icon(Icons.face),
+ foregroundColor: getGFColor(GFColor.white),
+ shape: GFAvatarShape.standard,
+ ),
+ GFAvatar(
+ backgroundColor: getGFColor(GFColor.secondary),
+ child: Icon(Icons.face),
+ foregroundColor: getGFColor(GFColor.white),
+ shape: GFAvatarShape.standard,
+ ),
+ GFAvatar(
+ backgroundColor: getGFColor(GFColor.success),
+ child: Icon(Icons.face),
+ foregroundColor: getGFColor(GFColor.white),
+ shape: GFAvatarShape.standard,
+ ),
+ GFAvatar(
+ backgroundColor: getGFColor(GFColor.info),
+ child: Icon(Icons.face),
+ foregroundColor: getGFColor(GFColor.white),
+ shape: GFAvatarShape.standard,
+ ),
+ GFAvatar(
+ backgroundColor: getGFColor(GFColor.danger),
+ child: Icon(Icons.face),
+ foregroundColor: getGFColor(GFColor.white),
+ shape: GFAvatarShape.standard,
+ ),
+
+
+ ],
+ ),
+
+ SizedBox(
+ height: 15,
+ ),
+ Row(
+ mainAxisAlignment: MainAxisAlignment.spaceBetween,
+ children: [
+ GFAvatar(
+ backgroundColor: getGFColor(GFColor.warning),
+ child: Icon(Icons.face),
+ foregroundColor: getGFColor(GFColor.white),
+ shape: GFAvatarShape.standard,
+ ),
+ GFAvatar(
+ backgroundColor: getGFColor(GFColor.dark),
+ child: Icon(Icons.face),
+ foregroundColor: getGFColor(GFColor.white),
+ shape: GFAvatarShape.standard,
+ ),
+ GFAvatar(
+ backgroundColor: getGFColor(GFColor.light),
+ child: Icon(Icons.face),
+ foregroundColor: getGFColor(GFColor.white),
+ shape: GFAvatarShape.standard,
+ ),
+ GFAvatar(
+ backgroundColor: getGFColor(GFColor.alt),
+ child: Icon(Icons.face),
+ foregroundColor: getGFColor(GFColor.white),
+ shape: GFAvatarShape.standard,
+ ),
+ GFAvatar(
+ backgroundColor: getGFColor(GFColor.transparent),
+ child: Icon(Icons.face),
+ foregroundColor: getGFColor(GFColor.dark),
+
+ ),
+
+ ],
+ ),
+ ],
+ ),
+ ),
+ ],
+ ),
+ )
+ );
+ }
+}
diff --git a/demo_app/lib/screens/badges.dart b/demo_app/lib/screens/badges.dart
new file mode 100644
index 00000000..c355f07b
--- /dev/null
+++ b/demo_app/lib/screens/badges.dart
@@ -0,0 +1,770 @@
+import 'package:flutter/material.dart';
+import 'package:ui_kit/colors/gf_color.dart';
+import 'package:ui_kit/components/badge/gf_badge.dart';
+import 'package:ui_kit/components/badge/gf_button_badge.dart';
+import 'package:ui_kit/components/badge/gf_icon_badge.dart';
+import 'package:ui_kit/components/card/gf_card.dart';
+import 'package:ui_kit/components/header/gf_header.dart';
+import 'package:ui_kit/components/tabs/gf_tabs.dart';
+import 'package:ui_kit/components/button/gf_icon_button.dart';
+import 'package:ui_kit/position/gf_position.dart';
+import 'package:ui_kit/shape/gf_badge_shape.dart';
+import 'package:ui_kit/shape/gf_button_shape.dart';
+import 'package:ui_kit/size/gf_size.dart';
+import 'package:ui_kit/types/gf_heading_type.dart';
+import 'package:ui_kit/types/gf_type.dart';
+import 'package:ui_kit/components/tabs/gf_tabBarView.dart';
+
+class Badges extends StatefulWidget {
+ @override
+ _BadgesState createState() => _BadgesState();
+}
+
+class _BadgesState extends State {
+ @override
+ Widget build(BuildContext context) {
+ return Scaffold(
+ appBar: AppBar(
+ backgroundColor: getGFColor(GFColor.dark),
+ title: Text(
+ 'Badges',
+ style: TextStyle(fontSize: 14),
+ ),
+ ),
+ body: GFTabs(
+ height: MediaQuery.of(context).size.height,
+ tabBarColor: Color(0xFFD3E9ED),
+ initialIndex: 0,
+ length: 3,
+ tabs: [
+ Padding(
+ padding: EdgeInsets.only(top: 15, bottom: 15),
+ child: Text('Badge'),
+ ),
+ Text('Button Badge'),
+ Text('Icon Badge'),
+ ],
+ tabBarView: GFTabBarView(
+ children: [
+ ListView(
+ children: [
+ GFCard(
+ content: Column(
+ children: [
+ GFHeader(
+ text: 'Types of Badges',
+ type: GFHeadingType.typo6,
+ ),
+ SizedBox(
+ height: 10,
+ ),
+ Row(
+ mainAxisAlignment: MainAxisAlignment.spaceBetween,
+ children: [
+ GFBadge(
+ text: '1',
+ shape: GFBadgeShape.circle,
+ color: GFColor.success,
+ ),
+ GFBadge(
+ text: '1',
+ shape: GFBadgeShape.square,
+ color: GFColor.primary,
+ ),
+ GFBadge(
+ text: '1',
+ shape: GFBadgeShape.pills,
+ color: GFColor.danger,
+ textColor: GFColor.white,
+ ),
+ GFBadge(
+ text: '1',
+ shape: GFBadgeShape.standard,
+ color: GFColor.warning,
+ ),
+ ],
+ ),
+ ],
+ ),
+ ),
+ GFCard(
+ content: Column(
+ children: [
+ GFHeader(
+ text: 'Circled Badges with different Sizes',
+ type: GFHeadingType.typo6,
+ ),
+ SizedBox(
+ height: 10,
+ ),
+ Row(
+ mainAxisAlignment: MainAxisAlignment.spaceBetween,
+ children: [
+ GFBadge(
+ text: '1',
+ shape: GFBadgeShape.circle,
+ size: GFSize.large,
+ color: GFColor.success,
+ ),
+ GFBadge(
+ text: '1',
+ shape: GFBadgeShape.circle,
+ size: GFSize.medium,
+ color: GFColor.success,
+ ),
+ GFBadge(
+ text: '1',
+ shape: GFBadgeShape.circle,
+ size: GFSize.small,
+ color: GFColor.success,
+ ),
+ ],
+ ),
+ ],
+ ),
+ ),
+ GFCard(
+ content: Column(
+ children: [
+ GFHeader(
+ text: 'Squared Badges with different sizes',
+ type: GFHeadingType.typo6,
+ ),
+ SizedBox(
+ height: 10,
+ ),
+ Row(
+ mainAxisAlignment: MainAxisAlignment.spaceBetween,
+ children: [
+ GFBadge(
+ text: '1',
+ shape: GFBadgeShape.square,
+ size: GFSize.large,
+ color: GFColor.primary,
+ ),
+ GFBadge(
+ text: '1',
+ shape: GFBadgeShape.square,
+ size: GFSize.medium,
+ color: GFColor.primary,
+ ),
+ GFBadge(
+ text: '1',
+ shape: GFBadgeShape.square,
+ size: GFSize.small,
+ color: GFColor.primary,
+ ),
+ ],
+ ),
+ ],
+ ),
+ ),
+ GFCard(
+ content: Column(
+ children: [
+ GFHeader(
+ text: 'Pills with different sizes',
+ type: GFHeadingType.typo6,
+ ),
+ SizedBox(
+ height: 10,
+ ),
+ Row(
+ mainAxisAlignment: MainAxisAlignment.spaceBetween,
+ children: [
+ GFBadge(
+ text: '1',
+ shape: GFBadgeShape.pills,
+ size: GFSize.large,
+ color: GFColor.danger,
+ textColor: GFColor.white,
+ ),
+ GFBadge(
+ text: '1',
+ shape: GFBadgeShape.pills,
+ size: GFSize.medium,
+ textColor: GFColor.white,
+ color: GFColor.danger,
+ ),
+ GFBadge(
+ text: '1',
+ shape: GFBadgeShape.pills,
+ size: GFSize.small,
+ textColor: GFColor.white,
+ color: GFColor.danger,
+ ),
+ ],
+ ),
+ ],
+ ),
+ ),
+ GFCard(
+ content: Column(
+ children: [
+ GFHeader(
+ text: 'Standard Badges with different sizes',
+ type: GFHeadingType.typo6,
+ ),
+ SizedBox(
+ height: 10,
+ ),
+ Row(
+ mainAxisAlignment: MainAxisAlignment.spaceBetween,
+ children: [
+ GFBadge(
+ text: '1',
+ shape: GFBadgeShape.standard,
+ size: GFSize.large,
+ color: GFColor.warning,
+ ),
+ GFBadge(
+ text: '1',
+ shape: GFBadgeShape.standard,
+ size: GFSize.medium,
+ color: GFColor.warning,
+ ),
+ GFBadge(
+ text: '1',
+ shape: GFBadgeShape.standard,
+ size: GFSize.small,
+ color: GFColor.warning,
+ ),
+ ],
+ ),
+ ],
+ ),
+ )
+ ],
+ ),
+ ListView(
+ children: [
+ GFCard(
+ content: Column(
+ children: [
+ GFHeader(
+ text: 'Types of Button Badges',
+ type: GFHeadingType.typo6,
+ ),
+ SizedBox(
+ height: 10,
+ ),
+ Row(
+ mainAxisAlignment: MainAxisAlignment.spaceBetween,
+ children: [
+ GFButtonBadge(
+ shape: GFButtonShape.pills,
+ type: GFType.solid,
+ color: GFColor.info,
+ counterChild: GFBadge(
+ text: '12',
+ color: GFColor.warning,
+ shape: GFBadgeShape.circle,
+ ),
+ onPressed: null,
+ text: 'Pills',
+ position: GFPosition.end,
+ ),
+ GFButtonBadge(
+ shape: GFButtonShape.square,
+ type: GFType.solid,
+ color: GFColor.warning,
+ counterChild: GFBadge(
+ text: '12',
+ shape: GFBadgeShape.circle,
+ color: GFColor.info,
+ ),
+ onPressed: null,
+ text: 'Square',
+ ),
+ GFButtonBadge(
+ color: GFColor.success,
+ shape: GFButtonShape.standard,
+ type: GFType.solid,
+ counterChild: GFBadge(
+ text: '12',
+ textColor: GFColor.white,
+ color: GFColor.danger,
+ shape: GFBadgeShape.circle,
+ ),
+ onPressed: null,
+ text: 'Standard',
+ ),
+ ],
+ ),
+ ],
+ ),
+ ),
+ GFCard(
+ content: Column(
+ children: [
+ GFHeader(
+ text: 'Positions of Button Badges',
+ type: GFHeadingType.typo6,
+ ),
+ SizedBox(
+ height: 10,
+ ),
+ Row(
+ mainAxisAlignment: MainAxisAlignment.spaceBetween,
+ children: [
+ GFButtonBadge(
+ shape: GFButtonShape.pills,
+ type: GFType.solid,
+ color: GFColor.info,
+ counterChild: GFBadge(
+ text: '12',
+ color: GFColor.warning,
+ shape: GFBadgeShape.circle,
+ ),
+ onPressed: null,
+ text: 'Pills',
+ position: GFPosition.start,
+ ),
+ GFButtonBadge(
+ shape: GFButtonShape.square,
+ type: GFType.solid,
+ color: GFColor.warning,
+ counterChild: GFBadge(
+ text: '12',
+ shape: GFBadgeShape.circle,
+ color: GFColor.info,
+ ),
+ onPressed: null,
+ text: 'Square',
+ position: GFPosition.start,
+ ),
+ GFButtonBadge(
+ color: GFColor.success,
+ shape: GFButtonShape.standard,
+ type: GFType.solid,
+ counterChild: GFBadge(
+ text: '12',
+ textColor: GFColor.white,
+ color: GFColor.danger,
+ shape: GFBadgeShape.circle,
+ ),
+ onPressed: null,
+ text: 'Standard',
+ position: GFPosition.start,
+ ),
+ ],
+ ),
+ ],
+ ),
+ ),
+ GFCard(
+ content: Column(
+ children: [
+ GFHeader(
+ text: 'Pilled shape Button Badges with sizes',
+ type: GFHeadingType.typo6,
+ ),
+ SizedBox(
+ height: 10,
+ ),
+ Row(
+ mainAxisAlignment: MainAxisAlignment.spaceBetween,
+ children: [
+ GFButtonBadge(
+ shape: GFButtonShape.pills,
+ size: GFSize.large,
+ type: GFType.solid,
+ color: GFColor.info,
+ counterChild: GFBadge(
+ text: '12',
+ color: GFColor.warning,
+ size: GFSize.large,
+ shape: GFBadgeShape.circle,
+ ),
+ onPressed: null,
+ text: 'Solid',
+ position: GFPosition.end,
+ ),
+ GFButtonBadge(
+ shape: GFButtonShape.pills,
+ size: GFSize.medium,
+ type: GFType.outline,
+ color: GFColor.info,
+ counterChild: GFBadge(
+ text: '12',
+ color: GFColor.warning,
+ size: GFSize.medium,
+ shape: GFBadgeShape.circle,
+ ),
+ onPressed: null,
+ text: 'Outline',
+ position: GFPosition.end,
+ ),
+ GFButtonBadge(
+ shape: GFButtonShape.pills,
+ size: GFSize.small,
+ type: GFType.transparent,
+ color: GFColor.info,
+ counterChild: GFBadge(
+ text: '12',
+ color: GFColor.warning,
+ size: GFSize.small,
+ shape: GFBadgeShape.circle,
+ ),
+ onPressed: null,
+ text: 'Transp',
+ position: GFPosition.end,
+ ),
+ ],
+ ),
+ ],
+ ),
+ ),
+ GFCard(
+ content: Column(
+ children: [
+ GFHeader(
+ text: 'Squared shape Button Badges with sizes',
+ type: GFHeadingType.typo6,
+ ),
+ SizedBox(
+ height: 10,
+ ),
+ Row(
+ mainAxisAlignment: MainAxisAlignment.spaceBetween,
+ children: [
+ GFButtonBadge(
+ shape: GFButtonShape.square,
+ size: GFSize.large,
+ type: GFType.solid,
+ color: GFColor.warning,
+ counterChild: GFBadge(
+ text: '12',
+ color: GFColor.info,
+ size: GFSize.large,
+ shape: GFBadgeShape.circle,
+ ),
+ onPressed: null,
+ text: 'Solid',
+ position: GFPosition.end,
+ ),
+ GFButtonBadge(
+ shape: GFButtonShape.square,
+ size: GFSize.medium,
+ type: GFType.outline,
+ color: GFColor.warning,
+ counterChild: GFBadge(
+ text: '12',
+ color: GFColor.info,
+ size: GFSize.medium,
+ shape: GFBadgeShape.circle,
+ ),
+ onPressed: null,
+ text: 'Outline',
+ position: GFPosition.end,
+ ),
+ GFButtonBadge(
+ shape: GFButtonShape.square,
+ size: GFSize.small,
+ type: GFType.transparent,
+ color: GFColor.warning,
+ counterChild: GFBadge(
+ text: '12',
+ color: GFColor.info,
+ size: GFSize.small,
+ shape: GFBadgeShape.circle,
+ ),
+ onPressed: null,
+ text: 'Transp',
+ position: GFPosition.end,
+ ),
+ ],
+ ),
+ ],
+ ),
+ ),
+ GFCard(
+ content: Column(
+ children: [
+ GFHeader(
+ text: 'Standard Button Badges with sizes',
+ type: GFHeadingType.typo6,
+ ),
+ SizedBox(
+ height: 10,
+ ),
+ Row(
+ mainAxisAlignment: MainAxisAlignment.spaceBetween,
+ children: [
+ GFButtonBadge(
+ shape: GFButtonShape.standard,
+ size: GFSize.large,
+ type: GFType.solid,
+ color: GFColor.primary,
+ counterChild: GFBadge(
+ text: '12',
+ color: GFColor.danger,
+ size: GFSize.large,
+ textColor: GFColor.white,
+ shape: GFBadgeShape.circle,
+ ),
+ onPressed: null,
+ text: 'Solid',
+ position: GFPosition.end,
+ ),
+ GFButtonBadge(
+ shape: GFButtonShape.standard,
+ size: GFSize.medium,
+ type: GFType.outline,
+ color: GFColor.primary,
+ counterChild: GFBadge(
+ text: '12',
+ color: GFColor.danger,
+ textColor: GFColor.white,
+ size: GFSize.medium,
+ shape: GFBadgeShape.circle,
+ ),
+ onPressed: null,
+ text: 'Outline',
+ position: GFPosition.end,
+ ),
+ GFButtonBadge(
+ shape: GFButtonShape.standard,
+ size: GFSize.small,
+ type: GFType.transparent,
+ color: GFColor.primary,
+ counterChild: GFBadge(
+ text: '12',
+ color: GFColor.danger,
+ textColor: GFColor.white,
+ size: GFSize.small,
+ shape: GFBadgeShape.circle,
+ ),
+ onPressed: null,
+ text: 'Transp',
+ position: GFPosition.end,
+ ),
+ ],
+ ),
+ ],
+ ),
+ )
+ ],
+ ),
+ ListView(
+ children: [
+ GFCard(
+ content: Column(
+ children: [
+ GFHeader(
+ text: 'Types of Icon Badges',
+ type: GFHeadingType.typo6,
+ ),
+ SizedBox(
+ height: 10,
+ ),
+ Row(
+ mainAxisAlignment: MainAxisAlignment.spaceBetween,
+ children: [
+ GFIconBadge(
+ onPressed: null,
+ child: GFIconButton(
+ shape: GFButtonShape.pills,
+ color: GFColor.success,
+ type: GFType.solid,
+ onPressed: null,
+ icon: Icon(Icons.mail),
+ ),
+ counterChild: GFBadge(
+ text: '12',
+ shape: GFBadgeShape.circle,
+ size: GFSize.small,
+ )),
+ GFIconBadge(
+ onPressed: null,
+ child: GFIconButton(
+ shape: GFButtonShape.square,
+ color: GFColor.primary,
+ type: GFType.solid,
+ onPressed: null,
+ icon: Icon(Icons.mail),
+ ),
+ counterChild: GFBadge(
+ text: '12',
+ shape: GFBadgeShape.circle,
+ size: GFSize.small,
+ )),
+ GFIconBadge(
+ onPressed: null,
+ child: GFIconButton(
+ shape: GFButtonShape.pills,
+ color: GFColor.danger,
+ type: GFType.solid,
+ onPressed: null,
+ icon: Icon(Icons.mail),
+ ),
+ counterChild: GFBadge(
+ text: '12',
+ shape: GFBadgeShape.circle,
+ size: GFSize.small,
+ )),
+ GFIconBadge(
+ onPressed: null,
+ child: GFIconButton(
+ shape: GFButtonShape.standard,
+ type: GFType.solid,
+ color: GFColor.warning,
+ onPressed: null,
+ icon: Icon(Icons.mail),
+ ),
+ counterChild: GFBadge(
+ text: '12',
+ shape: GFBadgeShape.circle,
+ size: GFSize.small,
+ )),
+ ],
+ )
+ ],
+ ),
+ ),
+ GFCard(
+ content: Column(
+ children: [
+ GFHeader(
+ text: 'Shapes of Icon Badges',
+ type: GFHeadingType.typo6,
+ ),
+ SizedBox(
+ height: 10,
+ ),
+ Row(
+ mainAxisAlignment: MainAxisAlignment.spaceBetween,
+ children: [
+ GFIconBadge(
+ onPressed: null,
+ child: GFIconButton(
+ shape: GFButtonShape.pills,
+ onPressed: null,
+ icon: Icon(Icons.mail),
+ ),
+ counterChild: GFBadge(
+ text: '12',
+ shape: GFBadgeShape.circle,
+ size: GFSize.small,
+ )),
+ GFIconBadge(
+ onPressed: null,
+ child: GFIconButton(
+ shape: GFButtonShape.square,
+ onPressed: null,
+ icon: Icon(Icons.mail),
+ ),
+ counterChild: GFBadge(
+ text: '12',
+ color: GFColor.dark,
+ shape: GFBadgeShape.circle,
+ size: GFSize.small,
+ )),
+ GFIconBadge(
+ onPressed: null,
+ child: GFIconButton(
+ shape: GFButtonShape.pills,
+ onPressed: null,
+ icon: Icon(Icons.mail),
+ ),
+ counterChild: GFBadge(
+ text: '12',
+ shape: GFBadgeShape.circle,
+ size: GFSize.small,
+ )),
+ GFIconBadge(
+ onPressed: null,
+ child: GFIconButton(
+ shape: GFButtonShape.standard,
+ onPressed: null,
+ icon: Icon(Icons.mail),
+ ),
+ counterChild: GFBadge(
+ text: '12',
+ shape: GFBadgeShape.circle,
+ size: GFSize.small,
+ ),
+ ),
+ ],
+ )
+ ],
+ ),
+ ),
+ GFCard(
+ content: Column(
+ children: [
+ GFHeader(
+ text: 'Sizes of Icon Badges',
+ type: GFHeadingType.typo6,
+ ),
+ SizedBox(
+ height: 10,
+ ),
+ Row(
+ mainAxisAlignment: MainAxisAlignment.spaceBetween,
+ children: [
+ GFIconBadge(
+ onPressed: null,
+ child: GFIconButton(
+ size: GFSize.large,
+ onPressed: null,
+ icon: Icon(Icons.mail),
+ ),
+ counterChild: GFBadge(
+ text: '12',
+ shape: GFBadgeShape.circle,
+ size: GFSize.small,
+ )),
+ GFIconBadge(
+ onPressed: null,
+ child: GFIconButton(
+ size: GFSize.medium,
+ onPressed: null,
+ icon: Icon(Icons.mail),
+ ),
+ counterChild: GFBadge(
+ text: '12',
+ shape: GFBadgeShape.circle,
+ size: GFSize.small,
+ )),
+ GFIconBadge(
+ onPressed: null,
+ child: GFIconButton(
+ size: GFSize.small,
+ onPressed: null,
+ icon: Icon(Icons.mail),
+ ),
+ counterChild: GFBadge(
+ text: '12',
+ shape: GFBadgeShape.circle,
+ size: GFSize.small,
+ )),
+ ],
+ )
+ ],
+ ),
+ )
+ ],
+ )
+ ],
+ ),
+ indicatorColor: getGFColor(GFColor.dark),
+ indicatorSize: TabBarIndicatorSize.label,
+ labelColor: getGFColor(GFColor.success),
+ unselectedLabelColor: Colors.black,
+ labelStyle: TextStyle(
+ fontWeight: FontWeight.w500,
+ fontSize: 13.0,
+ color: Colors.deepOrange,
+ fontFamily: 'OpenSansBold',
+ ),
+ unselectedLabelStyle: TextStyle(
+ fontWeight: FontWeight.w500,
+ fontSize: 13.0,
+ color: Colors.black,
+ fontFamily: 'OpenSansBold',
+ ),
+ ),
+ );
+ }
+}
diff --git a/demo_app/lib/screens/buttons.dart b/demo_app/lib/screens/buttons.dart
new file mode 100644
index 00000000..0a7055e3
--- /dev/null
+++ b/demo_app/lib/screens/buttons.dart
@@ -0,0 +1,850 @@
+import 'package:flutter/material.dart';
+import 'package:ui_kit/components/header/gf_header.dart';
+import 'package:ui_kit/components/tabs/gf_tabs.dart';
+import 'package:ui_kit/components/button/gf_button.dart';
+import 'package:ui_kit/types/gf_heading_type.dart';
+import 'package:ui_kit/types/gf_type.dart';
+import 'package:ui_kit/shape/gf_button_shape.dart';
+import 'package:ui_kit/colors/gf_color.dart';
+import 'package:ui_kit/components/card/gf_card.dart';
+import 'package:ui_kit/components/tabs/gf_tabBarView.dart';
+
+class Buttons extends StatefulWidget {
+ @override
+ _ButtonsState createState() => _ButtonsState();
+}
+
+class _ButtonsState extends State {
+ @override
+ Widget build(BuildContext context) {
+ return Scaffold(
+ appBar: AppBar(
+ backgroundColor: getGFColor(GFColor.dark),
+ title: Text(
+ 'Buttons',
+ style: TextStyle(fontSize: 14),
+ ),
+ ),
+ body: GFTabs(
+ height: MediaQuery.of(context).size.height,
+ tabBarColor: Color(0xFFD3E9ED),
+ initialIndex: 0,
+ length: 3,
+ indicatorColor: getGFColor(GFColor.info),
+ unselectedLabelColor: getGFColor(GFColor.danger),
+ labelColor: getGFColor(GFColor.warning),
+ tabs: [
+ GFButton(
+ onPressed: null,
+ child: Text(
+ "Solid",
+ style: TextStyle(fontSize: 12),
+ ),
+ type: GFType.solid,
+ textColor: GFColor.white,
+ ),
+ GFButton(
+ onPressed: null,
+ child: Text(
+ "Outline",
+ style: TextStyle(fontSize: 12),
+ ),
+ type: GFType.outline,
+ shape: GFButtonShape.pills,
+ ),
+ GFButton(
+ onPressed: null,
+ text: 'Transparent',
+ textStyle: TextStyle(fontSize: 12, color: getGFColor(GFColor.dark)),
+ type: GFType.transparent,
+ ),
+ ],
+ tabBarView: GFTabBarView(
+ children: [
+ Container(
+// color: Colors.red,
+ child: ListView(
+ children: [
+ GFCard(
+ content: Column(
+ mainAxisAlignment: MainAxisAlignment.start,
+ crossAxisAlignment: CrossAxisAlignment.start,
+ children: [
+ GFHeader(
+ text: 'Standard',
+ type: GFHeadingType.typo6,
+ ),
+ SizedBox(
+ height: 10,
+ ),
+ Row(
+ mainAxisAlignment: MainAxisAlignment.spaceBetween,
+ children: [
+ GFButton(
+ onPressed: null,
+ child: Text("Primary",
+ style: TextStyle(
+ color: getGFColor(GFColor.white))),
+ type: GFType.solid,
+ color: GFColor.primary,
+ ),
+ GFButton(
+ onPressed: null,
+ child: Text("Secondary",
+ style: TextStyle(
+ color: getGFColor(GFColor.white))),
+ type: GFType.solid,
+ color: GFColor.secondary,
+ ),
+ GFButton(
+ onPressed: null,
+ child: Text(
+ "Success",
+ ),
+ type: GFType.solid,
+ color: GFColor.success,
+ ),
+ ],
+ ),
+ Row(
+ mainAxisAlignment: MainAxisAlignment.spaceBetween,
+ children: [
+ GFButton(
+ onPressed: null,
+ child: Text(
+ "Warning",
+ ),
+ type: GFType.solid,
+ color: GFColor.warning,
+ ),
+ GFButton(
+ onPressed: null,
+ child: Text("Danger",
+ style: TextStyle(
+ color: getGFColor(GFColor.white))),
+ type: GFType.solid,
+ color: GFColor.danger,
+ ),
+ GFButton(
+ onPressed: null,
+ child: Text(
+ "Light",
+ ),
+ type: GFType.solid,
+ color: GFColor.light,
+ ),
+ ],
+ ),
+ Row(
+ mainAxisAlignment: MainAxisAlignment.spaceBetween,
+ children: [
+ GFButton(
+ onPressed: null,
+ child: Text(
+ "Info",
+ ),
+ type: GFType.solid,
+ color: GFColor.info,
+ ),
+ GFButton(
+ onPressed: null,
+ child: Text("Alt",
+ style: TextStyle(
+ color: getGFColor(GFColor.white))),
+ type: GFType.solid,
+ color: GFColor.alt,
+ ),
+ GFButton(
+ onPressed: null,
+ child: Text(
+ "Dark",
+ style:
+ TextStyle(color: getGFColor(GFColor.white)),
+ ),
+ type: GFType.solid,
+ color: GFColor.dark,
+ ),
+ ],
+ ),
+ Row(
+ mainAxisAlignment: MainAxisAlignment.spaceBetween,
+ children: [
+ GFButton(
+ onPressed: null,
+ child: Text(
+ "Transparent",
+ ),
+ type: GFType.solid,
+ color: GFColor.transparent,
+ ),
+ ],
+ )
+ ],
+ ),
+ ),
+ GFCard(
+ content: Column(
+ mainAxisAlignment: MainAxisAlignment.start,
+ crossAxisAlignment: CrossAxisAlignment.start,
+ children: [
+ GFHeader(
+ text: 'Pills',
+ type: GFHeadingType.typo6,
+ ),
+ SizedBox(
+ height: 10,
+ ),
+ Row(
+ mainAxisAlignment: MainAxisAlignment.spaceBetween,
+ children: [
+ GFButton(
+ onPressed: null,
+ child: Text("Primary",
+ style: TextStyle(
+ color: getGFColor(GFColor.white))),
+ color: GFColor.primary,
+ shape: GFButtonShape.pills,
+ ),
+ GFButton(
+ onPressed: null,
+ child: Text("Secondary",
+ style: TextStyle(
+ color: getGFColor(GFColor.white))),
+ color: GFColor.secondary,
+ shape: GFButtonShape.pills,
+ ),
+ GFButton(
+ onPressed: null,
+ child: Text(
+ "Success",
+ ),
+ shape: GFButtonShape.pills,
+ color: GFColor.success,
+ ),
+ ],
+ ),
+ Row(
+ mainAxisAlignment: MainAxisAlignment.spaceBetween,
+ children: [
+ GFButton(
+ onPressed: null,
+ child: Text(
+ "Warning",
+ ),
+ shape: GFButtonShape.pills,
+ color: GFColor.warning,
+ ),
+ GFButton(
+ onPressed: null,
+ child: Text("Danger",
+ style: TextStyle(
+ color: getGFColor(GFColor.white))),
+ shape: GFButtonShape.pills,
+ color: GFColor.danger,
+ ),
+ GFButton(
+ onPressed: null,
+ child: Text(
+ "Light",
+ ),
+ shape: GFButtonShape.pills,
+ color: GFColor.light,
+ ),
+ ],
+ ),
+ Row(
+ mainAxisAlignment: MainAxisAlignment.spaceBetween,
+ children: [
+ GFButton(
+ onPressed: null,
+ child: Text(
+ "Info",
+ ),
+ shape: GFButtonShape.pills,
+ color: GFColor.info,
+ ),
+ GFButton(
+ onPressed: null,
+ child: Text("Alt",
+ style: TextStyle(
+ color: getGFColor(GFColor.white))),
+ shape: GFButtonShape.pills,
+ color: GFColor.alt,
+ ),
+ GFButton(
+ onPressed: null,
+ child: Text(
+ "Dark",
+ style:
+ TextStyle(color: getGFColor(GFColor.white)),
+ ),
+ shape: GFButtonShape.pills,
+ color: GFColor.dark,
+ ),
+ ],
+ ),
+ Row(
+ mainAxisAlignment: MainAxisAlignment.spaceBetween,
+ children: [
+ GFButton(
+ onPressed: null,
+ child: Text(
+ "Transparent",
+ ),
+ shape: GFButtonShape.pills,
+ color: GFColor.transparent,
+ ),
+ ],
+ )
+ ],
+ ),
+ ),
+ GFCard(
+ content: Column(
+ mainAxisAlignment: MainAxisAlignment.start,
+ crossAxisAlignment: CrossAxisAlignment.start,
+ children: [
+ GFHeader(
+ text: 'Square',
+ type: GFHeadingType.typo6,
+ ),
+ SizedBox(
+ height: 10,
+ ),
+ Row(
+ mainAxisAlignment: MainAxisAlignment.spaceBetween,
+ children: [
+ GFButton(
+ onPressed: null,
+ child: Text("Primary",
+ style: TextStyle(
+ color: getGFColor(GFColor.white))),
+ color: GFColor.primary,
+ shape: GFButtonShape.square,
+ ),
+ GFButton(
+ onPressed: null,
+ child: Text("Secondary",
+ style: TextStyle(
+ color: getGFColor(GFColor.white))),
+ color: GFColor.secondary,
+ shape: GFButtonShape.square,
+ ),
+ GFButton(
+ onPressed: null,
+ child: Text(
+ "Success",
+ ),
+ shape: GFButtonShape.square,
+ color: GFColor.success,
+ ),
+ ],
+ ),
+ Row(
+ mainAxisAlignment: MainAxisAlignment.spaceBetween,
+ children: [
+ GFButton(
+ onPressed: null,
+ child: Text(
+ "Warning",
+ ),
+ shape: GFButtonShape.square,
+ color: GFColor.warning,
+ ),
+ GFButton(
+ onPressed: null,
+ child: Text("Danger",
+ style: TextStyle(
+ color: getGFColor(GFColor.white))),
+ shape: GFButtonShape.square,
+ color: GFColor.danger,
+ ),
+ GFButton(
+ onPressed: null,
+ child: Text(
+ "Light",
+ ),
+ shape: GFButtonShape.square,
+ color: GFColor.light,
+ ),
+ ],
+ ),
+ Row(
+ mainAxisAlignment: MainAxisAlignment.spaceBetween,
+ children: [
+ GFButton(
+ onPressed: null,
+ child: Text(
+ "Info",
+ ),
+ shape: GFButtonShape.square,
+ color: GFColor.info,
+ ),
+ GFButton(
+ onPressed: null,
+ child: Text("Alt",
+ style: TextStyle(
+ color: getGFColor(GFColor.white))),
+ shape: GFButtonShape.square,
+ color: GFColor.alt,
+ ),
+ GFButton(
+ onPressed: null,
+ child: Text(
+ "Dark",
+ style:
+ TextStyle(color: getGFColor(GFColor.white)),
+ ),
+ shape: GFButtonShape.square,
+ color: GFColor.dark,
+ ),
+ ],
+ ),
+ Row(
+ mainAxisAlignment: MainAxisAlignment.spaceBetween,
+ children: [
+ GFButton(
+ onPressed: null,
+ child: Text(
+ "Transparent",
+ ),
+ shape: GFButtonShape.square,
+ color: GFColor.transparent,
+ ),
+ ],
+ )
+ ],
+ ),
+ ),
+ ],
+ ),
+ ),
+ Container(
+// color: Colors.red,
+ child: ListView(
+ children: [
+ GFCard(
+ content: Column(
+ mainAxisAlignment: MainAxisAlignment.start,
+ crossAxisAlignment: CrossAxisAlignment.start,
+ children: [
+ GFHeader(
+ text: 'Standard',
+ type: GFHeadingType.typo6,
+ ),
+ SizedBox(
+ height: 10,
+ ),
+ Row(
+ mainAxisAlignment: MainAxisAlignment.spaceBetween,
+ children: [
+ GFButton(
+ onPressed: null,
+ child: Text(
+ "Primary",
+ ),
+ type: GFType.outline,
+ ),
+ GFButton(
+ onPressed: null,
+ child: Text("Secondary"),
+ type: GFType.outline,
+ color: GFColor.secondary,
+ ),
+ GFButton(
+ onPressed: null,
+ child: Text(
+ "Success",
+ ),
+ type: GFType.outline,
+ color: GFColor.success,
+ ),
+ ],
+ ),
+ Row(
+ mainAxisAlignment: MainAxisAlignment.spaceBetween,
+ children: [
+ GFButton(
+ onPressed: null,
+ child: Text(
+ "Warning",
+ ),
+ type: GFType.outline,
+ color: GFColor.warning,
+ ),
+ GFButton(
+ onPressed: null,
+ child: Text(
+ "Danger",
+ ),
+ type: GFType.outline,
+ color: GFColor.danger,
+ ),
+ GFButton(
+ onPressed: null,
+ child: Text(
+ "Light",
+ ),
+ type: GFType.outline,
+ color: GFColor.light,
+ ),
+ ],
+ ),
+ Row(
+ mainAxisAlignment: MainAxisAlignment.spaceBetween,
+ children: [
+ GFButton(
+ onPressed: null,
+ child: Text(
+ "Info",
+ ),
+ type: GFType.outline,
+ color: GFColor.info,
+ ),
+ GFButton(
+ onPressed: null,
+ child: Text(
+ "Alt",
+ ),
+ type: GFType.outline,
+ color: GFColor.alt,
+ ),
+ GFButton(
+ onPressed: null,
+ child: Text(
+ "Dark",
+ ),
+ type: GFType.outline,
+ color: GFColor.dark,
+ ),
+ ],
+ ),
+ ],
+ ),
+ ),
+ GFCard(
+ content: Column(
+ mainAxisAlignment: MainAxisAlignment.start,
+ crossAxisAlignment: CrossAxisAlignment.start,
+ children: [
+ GFHeader(
+ text: 'Pills',
+ type: GFHeadingType.typo6,
+ ),
+ SizedBox(
+ height: 10,
+ ),
+ Row(
+ mainAxisAlignment: MainAxisAlignment.spaceBetween,
+ children: [
+ GFButton(
+ onPressed: null,
+ child: Text(
+ "Primary",
+ ),
+ type: GFType.outline,
+ color: GFColor.primary,
+ shape: GFButtonShape.pills,
+ ),
+ GFButton(
+ onPressed: null,
+ child: Text(
+ "Secondary",
+ ),
+ color: GFColor.secondary,
+ shape: GFButtonShape.pills,
+ type: GFType.outline,
+ ),
+ GFButton(
+ onPressed: null,
+ child: Text(
+ "Success",
+ ),
+ shape: GFButtonShape.pills,
+ color: GFColor.success,
+ type: GFType.outline,
+ ),
+ ],
+ ),
+ Row(
+ mainAxisAlignment: MainAxisAlignment.spaceBetween,
+ children: [
+ GFButton(
+ onPressed: null,
+ child: Text(
+ "Warning",
+ ),
+ shape: GFButtonShape.pills,
+ color: GFColor.warning,
+ type: GFType.outline,
+ ),
+ GFButton(
+ onPressed: null,
+ child: Text(
+ "Danger",
+ ),
+ shape: GFButtonShape.pills,
+ color: GFColor.danger,
+ type: GFType.outline,
+ ),
+ GFButton(
+ onPressed: null,
+ child: Text(
+ "Light",
+ ),
+ shape: GFButtonShape.pills,
+ color: GFColor.light,
+ type: GFType.outline,
+ ),
+ ],
+ ),
+ Row(
+ mainAxisAlignment: MainAxisAlignment.spaceBetween,
+ children: [
+ GFButton(
+ onPressed: null,
+ child: Text(
+ "Info",
+ ),
+ shape: GFButtonShape.pills,
+ color: GFColor.info,
+ type: GFType.outline,
+ ),
+ GFButton(
+ onPressed: null,
+ child: Text(
+ "Alt",
+ ),
+ shape: GFButtonShape.pills,
+ color: GFColor.alt,
+ type: GFType.outline,
+ ),
+ GFButton(
+ onPressed: null,
+ child: Text(
+ "Dark",
+ ),
+ shape: GFButtonShape.pills,
+ color: GFColor.dark,
+ type: GFType.outline,
+ ),
+ ],
+ ),
+ ],
+ ),
+ ),
+ GFCard(
+ content: Column(
+ mainAxisAlignment: MainAxisAlignment.start,
+ crossAxisAlignment: CrossAxisAlignment.start,
+ children: [
+ GFHeader(
+ text: 'Square',
+ type: GFHeadingType.typo6,
+ ),
+ SizedBox(
+ height: 10,
+ ),
+ Row(
+ mainAxisAlignment: MainAxisAlignment.spaceBetween,
+ children: [
+ GFButton(
+ onPressed: null,
+ child: Text(
+ "Primary",
+ ),
+ type: GFType.outline,
+ color: GFColor.primary,
+ shape: GFButtonShape.square,
+ ),
+ GFButton(
+ onPressed: null,
+ child: Text(
+ "Secondary",
+ ),
+ color: GFColor.secondary,
+ shape: GFButtonShape.square,
+ type: GFType.outline,
+ ),
+ GFButton(
+ onPressed: null,
+ child: Text(
+ "Success",
+ ),
+ shape: GFButtonShape.square,
+ color: GFColor.success,
+ type: GFType.outline,
+ ),
+ ],
+ ),
+ Row(
+ mainAxisAlignment: MainAxisAlignment.spaceBetween,
+ children: [
+ GFButton(
+ onPressed: null,
+ child: Text(
+ "Warning",
+ ),
+ shape: GFButtonShape.square,
+ color: GFColor.warning,
+ type: GFType.outline,
+ ),
+ GFButton(
+ onPressed: null,
+ child: Text(
+ "Danger",
+ ),
+ shape: GFButtonShape.square,
+ color: GFColor.danger,
+ type: GFType.outline,
+ ),
+ GFButton(
+ onPressed: null,
+ child: Text(
+ "Light",
+ ),
+ shape: GFButtonShape.square,
+ color: GFColor.light,
+ type: GFType.outline,
+ ),
+ ],
+ ),
+ Row(
+ mainAxisAlignment: MainAxisAlignment.spaceBetween,
+ children: [
+ GFButton(
+ onPressed: null,
+ child: Text(
+ "Info",
+ ),
+ shape: GFButtonShape.square,
+ color: GFColor.info,
+ type: GFType.outline,
+ ),
+ GFButton(
+ onPressed: null,
+ child: Text(
+ "Alt",
+ ),
+ shape: GFButtonShape.square,
+ color: GFColor.alt,
+ type: GFType.outline,
+ ),
+ GFButton(
+ onPressed: null,
+ child: Text(
+ "Dark",
+ ),
+ shape: GFButtonShape.square,
+ color: GFColor.dark,
+ type: GFType.outline,
+ ),
+ ],
+ ),
+ ],
+ ),
+ ),
+ ],
+ ),
+ ),
+ Container(
+ margin: EdgeInsets.only(top: 20, right: 20, left: 20),
+ height: 100,
+ child: Column(
+ children: [
+ GFHeader(
+ text: 'Transparent',
+ type: GFHeadingType.typo6,
+ ),
+ Row(
+ children: [
+ GFButton(
+ onPressed: null,
+ child: Text(
+ "Primary",
+ ),
+ type: GFType.transparent,
+ textColor: GFColor.primary,
+ ),
+ GFButton(
+ onPressed: null,
+ child: Text(
+ "Secondary",
+ ),
+ type: GFType.transparent,
+ textColor: GFColor.secondary,
+ ),
+ GFButton(
+ onPressed: null,
+ child: Text(
+ "Success",
+ ),
+ type: GFType.transparent,
+ textColor: GFColor.success,
+ ),
+ ],
+ ),
+ Row(
+ children: [
+ GFButton(
+ onPressed: null,
+ child: Text(
+ "Warning",
+ ),
+ type: GFType.transparent,
+ textColor: GFColor.warning,
+ ),
+ GFButton(
+ onPressed: null,
+ child: Text(
+ "Danger",
+ ),
+ type: GFType.transparent,
+ textColor: GFColor.danger,
+ ),
+ GFButton(
+ onPressed: null,
+ child: Text(
+ "Dark",
+ ),
+ type: GFType.transparent,
+ textColor: GFColor.dark,
+ ),
+ ],
+ ),
+ Row(
+ children: [
+ GFButton(
+ onPressed: null,
+ child: Text(
+ "Light",
+ ),
+ type: GFType.transparent,
+ textColor: GFColor.light,
+ ),
+ GFButton(
+ onPressed: null,
+ child: Text(
+ "Info",
+ ),
+ type: GFType.transparent,
+ textColor: GFColor.info,
+ ),
+ GFButton(
+ onPressed: null,
+ child: Text(
+ "Alt",
+ ),
+ type: GFType.transparent,
+ textColor: GFColor.alt,
+ ),
+ ],
+ ),
+ ],
+ ))
+ ],
+ ),
+ ),
+ );
+ }
+}
diff --git a/demo_app/lib/screens/cards.dart b/demo_app/lib/screens/cards.dart
new file mode 100644
index 00000000..9b5b449c
--- /dev/null
+++ b/demo_app/lib/screens/cards.dart
@@ -0,0 +1,303 @@
+import 'package:flutter/material.dart';
+import 'package:ui_kit/components/card/gf_card.dart';
+import 'package:ui_kit/components/header/gf_header.dart';
+import 'package:ui_kit/components/list_tile/gf_list_tile.dart';
+import 'package:ui_kit/components/avatar/gf_avatar.dart';
+import 'package:ui_kit/position/gf_position.dart';
+import 'package:ui_kit/components/button/gf_icon_button.dart';
+import 'package:ui_kit/components/button_bar/gf_button_bar.dart';
+import 'package:ui_kit/components/button/gf_button.dart';
+import 'package:ui_kit/types/gf_heading_type.dart';
+import 'package:ui_kit/types/gf_type.dart';
+import 'package:ui_kit/colors/gf_color.dart';
+class Cards extends StatefulWidget {
+ @override
+ _CardsState createState() => _CardsState();
+}
+
+class _CardsState extends State {
+ @override
+ Widget build(BuildContext context) {
+ return
+ Scaffold(
+ appBar: AppBar(
+ backgroundColor: getGFColor(GFColor.dark),
+ title: Text('Cards', style: TextStyle(fontSize: 14),),),
+ body: ListView(
+ children: [
+ Padding(padding: EdgeInsets.all(20), child:
+ GFHeader(
+ text: 'Basic Card',
+ type: GFHeadingType.typo6,
+ ),),
+ GFCard(
+ boxFit: BoxFit.cover,
+ colorFilter: new ColorFilter.mode(
+ Colors.black.withOpacity(0.67), BlendMode.darken),
+ image:Image.network('https://cdn.pixabay.com/photo/2016/12/15/03/27/cocoa-1908020_960_720.jpg'),
+// imageOverlay: AssetImage("lib/assets/food.jpeg"),
+ titlePosition: GFPosition.end,
+ title: GFListTile(
+ avatar: GFAvatar(
+ child: Icon(Icons.insert_emoticon)
+ ),
+ title: Text(
+ 'title',
+ style: TextStyle(color: Colors.grey),
+ ),
+ subTitle: Text(
+ 'subtitle',
+ style: TextStyle(color: Colors.grey),
+ ),
+ ),
+ content: Text(
+ "Flutter "
+ "Flutter is Google's mobile UI framework for crafting"
+ " high-quality native interfaces on iOS and Android in "
+ "Flutter ",
+ style: TextStyle(color: Colors.grey),
+ ),
+
+ ),
+
+ Padding(padding: EdgeInsets.all(20), child:
+ GFHeader(
+ text: 'Basic Card 1',
+ type: GFHeadingType.typo6,
+ ),),
+ GFCard(
+ boxFit: BoxFit.cover,
+ colorFilter: new ColorFilter.mode(
+ Colors.black.withOpacity(0.67), BlendMode.darken),
+ image:Image.network('https://cdn.pixabay.com/photo/2016/12/15/03/27/cocoa-1908020_960_720.jpg'),
+// imageOverlay: AssetImage("lib/assets/food.jpeg"),
+ titlePosition: GFPosition.end,
+ title: GFListTile(
+ avatar: GFAvatar(
+ child: Icon(Icons.insert_emoticon)
+ ),
+ title: Text(
+ 'title',
+ style: TextStyle(color: Colors.grey),
+ ),
+ subTitle: Text(
+ 'subtitle',
+ style: TextStyle(color: Colors.grey),
+ ),
+ icon: GFIconButton(
+ onPressed: null,
+ icon: Icon(Icons.favorite_border),
+ type: GFType.transparent,
+ ),
+ ),
+ content: Text(
+ "Flutter "
+ "Flutter is Google's mobile UI framework for crafting"
+ " high-quality native interfaces on iOS and Android in "
+ "Flutter ",
+ style: TextStyle(color: Colors.grey),
+ ),
+
+ ),
+
+ Padding(padding: EdgeInsets.all(20), child:
+ GFHeader(
+ text: 'Basic Card 2',
+ type: GFHeadingType.typo6,
+ ),),
+ GFCard(
+ boxFit: BoxFit.cover,
+ colorFilter: new ColorFilter.mode(
+ Colors.black.withOpacity(0.67), BlendMode.darken),
+ image:Image.network('https://cdn.pixabay.com/photo/2016/12/15/03/27/cocoa-1908020_960_720.jpg'),
+// imageOverlay: AssetImage("lib/assets/food.jpeg"),
+ titlePosition: GFPosition.end,
+ title: GFListTile(
+ avatar: GFAvatar(
+ child: Icon(Icons.insert_emoticon)
+ ),
+ title: Text(
+ 'title',
+ style: TextStyle(color: Colors.grey),
+ ),
+ subTitle: Text(
+ 'subtitle',
+ style: TextStyle(color: Colors.grey),
+ ),
+ icon: GFIconButton(
+ onPressed: null,
+ icon: Icon(Icons.favorite_border),
+ type: GFType.transparent,
+ ),
+ ),
+ content: Text(
+ "Flutter "
+ "Flutter is Google's mobile UI framework for crafting"
+ " high-quality native interfaces on iOS and Android in "
+ "Flutter ",
+ style: TextStyle(color: Colors.grey),
+ ),
+ buttonBar: GFButtonBar(
+ mainAxisSize: MainAxisSize.min,
+ children: [
+ GFButton(
+ onPressed: null,
+ child: Text("favorite"),
+ icon: Icon(Icons.favorite_border),
+ type: GFType.transparent,
+ ),
+ GFButton(
+ onPressed: null,
+ child: Text("share"),
+ icon: Icon(Icons.share),
+ type: GFType.outline,
+ ),
+ ],
+ ),
+ ),
+
+ Padding(padding: EdgeInsets.all(20), child:
+ GFHeader(
+ text: 'Basic Card 3',
+ type: GFHeadingType.typo6,
+ ),),
+ GFCard(
+ boxFit: BoxFit.cover,
+ colorFilter: new ColorFilter.mode(
+ Colors.black.withOpacity(0.67), BlendMode.darken),
+ image:Image.network('https://cdn.pixabay.com/photo/2016/12/15/03/27/cocoa-1908020_960_720.jpg'),
+// imageOverlay: AssetImage("lib/assets/food.jpeg"),
+ titlePosition: GFPosition.end,
+ title: GFListTile(
+
+ title: Text(
+ 'title',
+ style: TextStyle(color: Colors.grey),
+ ),
+ subTitle: Text(
+ 'subtitle',
+ style: TextStyle(color: Colors.grey),
+ ),
+ icon: GFAvatar(
+ child: Icon(Icons.insert_emoticon)
+ )
+ ),
+ content: Text(
+ "Flutter "
+ "Flutter is Google's mobile UI framework for crafting"
+ " high-quality native interfaces on iOS and Android in "
+ "Flutter ",
+ style: TextStyle(color: Colors.grey),
+ ),
+ buttonBar: GFButtonBar(
+ mainAxisSize: MainAxisSize.min,
+ children: [
+ GFButton(
+ onPressed: null,
+ child: Text("favorite"),
+// icon: Icon(Icons.favorite_border),
+ type: GFType.transparent,
+ ),
+ GFButton(
+ onPressed: null,
+ child: Text("share"),
+// icon: Icon(Icons.share),
+ type: GFType.outline,
+ ),
+ GFButton(
+ onPressed: null,
+ child: Text("send", style: TextStyle(color: getGFColor(GFColor.white)),),
+// icon: Icon(Icons.share),
+ type: GFType.solid,
+ ),
+ ],
+ ),
+ ),
+ Padding(padding: EdgeInsets.all(20), child:
+ GFHeader(
+ text: 'Basic Card 4',
+ type: GFHeadingType.typo6,
+ ),),
+ GFCard(
+
+ title: GFListTile(
+
+ title: Text(
+ 'title',
+ style: TextStyle(color: Colors.grey),
+ ),
+ subTitle: Text(
+ 'subtitle',
+ style: TextStyle(color: Colors.grey),
+ ),
+ icon: GFAvatar(
+ child: Icon(Icons.insert_emoticon)
+ )
+ ),
+ content: Text(
+ "Flutter "
+ "Flutter is Google's mobile UI framework for crafting"
+ " high-quality native interfaces on iOS and Android in "
+ "Flutter ",
+ style: TextStyle(color: Colors.grey),
+ ),
+ buttonBar: GFButtonBar(
+
+ alignment: MainAxisAlignment.spaceBetween,
+ children: [
+ GFButton(
+ onPressed: null,
+ child: Text("favorite"),
+ icon: Icon(Icons.favorite_border),
+ type: GFType.transparent,
+ ),
+ GFButton(
+ onPressed: null,
+ child: Text("share"),
+ icon: Icon(Icons.share),
+ type: GFType.outline,
+ ),
+ GFIconButton(icon: Icon(Icons.send), onPressed: null)
+ ],
+ ),
+ ),
+
+ Padding(padding: EdgeInsets.all(20), child:
+ GFHeader(
+ text: 'Basic Card 5',
+ type: GFHeadingType.typo6,
+ ),),
+ GFCard(
+ boxFit: BoxFit.cover,
+ colorFilter: new ColorFilter.mode(
+ Colors.black.withOpacity(0.67), BlendMode.darken),
+// image:Image.network('https://cdn.pixabay.com/photo/2016/12/15/03/27/cocoa-1908020_960_720.jpg'),
+ imageOverlay: NetworkImage('https://cdn.pixabay.com/photo/2016/12/15/03/27/cocoa-1908020_960_720.jpg'),
+// titlePosition: GFPosition.end,
+ title: GFListTile(
+
+ title: Text(
+ 'title',
+ style: TextStyle(color: Colors.grey),
+ ),
+ subTitle: Text(
+ 'subtitle',
+ style: TextStyle(color: Colors.grey),
+ ),
+ icon: GFAvatar(
+ child: Icon(Icons.insert_emoticon)
+ )
+ ),
+ content: Text(
+ "Flutter "
+ "Flutter is Google's mobile UI framework for crafting"
+ " high-quality native interfaces on iOS and Android in "
+ "Flutter ",
+ style: TextStyle(color: Colors.grey),
+ ),
+
+ ),
+ ]),
+ );
+ }
+}
diff --git a/demo_app/lib/screens/headers.dart b/demo_app/lib/screens/headers.dart
new file mode 100644
index 00000000..20517021
--- /dev/null
+++ b/demo_app/lib/screens/headers.dart
@@ -0,0 +1,193 @@
+import 'package:flutter/material.dart';
+import 'package:ui_kit/colors/gf_color.dart';
+import 'package:ui_kit/components/avatar/gf_avatar.dart';
+import 'package:ui_kit/components/card/gf_card.dart';
+import 'package:ui_kit/components/header/gf_header.dart';
+import 'package:ui_kit/types/gf_heading_type.dart';
+
+class Headers extends StatefulWidget {
+ @override
+ _HeadersState createState() => _HeadersState();
+}
+
+class _HeadersState extends State {
+ bool showToast = false;
+ @override
+ Widget build(BuildContext context) {
+ return Scaffold(
+ appBar: AppBar(
+ backgroundColor: getGFColor(GFColor.dark),
+ title: Text(
+ 'Headers',
+ style: TextStyle(fontSize: 14),
+ ),
+ ),
+ body: Container(
+ child: Column(
+ crossAxisAlignment: CrossAxisAlignment.center,
+ children: [
+ GFCard(
+ content: Column(
+ crossAxisAlignment: CrossAxisAlignment.center,
+ mainAxisAlignment: MainAxisAlignment.spaceBetween,
+ children: [
+ GFHeader(
+ text: 'GF Header Typo1',
+ type: GFHeadingType.typo1,
+ backgroundImage: NetworkImage(
+ 'https://cdn.pixabay.com/photo/2019/12/25/16/49/happy-new-year-4718894_960_720.png'),
+ ),
+ SizedBox(
+ height: 40,
+ ),
+ GFHeader(
+ icon: GFAvatar(),
+ text: 'GF Header Typo2',
+ type: GFHeadingType.typo2,
+ dividerColor: GFColor.primary,
+ dividerAlignment: Alignment.center,
+ ),
+ SizedBox(
+ height: 40,
+ ),
+ GFHeader(
+ icon: Icon(Icons.insert_emoticon),
+ text: 'GF Header Typo3',
+ type: GFHeadingType.typo3,
+ dividerWidth: 150,
+ dividerColor: GFColor.warning,
+ dividerBorderRadius: BorderRadius.all(Radius.circular(0)),
+ ),
+ SizedBox(
+ height: 40,
+ ),
+ GFHeader(
+ text: 'GF Header Typo4',
+ type: GFHeadingType.typo4,
+ dividerWidth: 345,
+ icon: Image.network(
+ 'https://cdn.pixabay.com/photo/2016/12/15/03/27/cocoa-1908020_960_720.jpg',
+ width: 50,
+ )),
+ SizedBox(
+ height: 40,
+ ),
+ GFHeader(
+ text: 'GF Header Typo5',
+ type: GFHeadingType.typo5,
+ dividerColor: GFColor.alt,
+ ),
+ SizedBox(
+ height: 40,
+ ),
+ GFHeader(
+ text: 'GF Header Typo6',
+ type: GFHeadingType.typo6,
+ dividerWidth: 20,
+ ),
+ ],
+ )),
+ ],
+ ),
+ ),
+
+// body:
+//
+// Container(
+// child: ListView(
+// children: [
+// GFToast(
+//// width: 70,
+// text: 'Happy New Year',
+// button: GFButton(onPressed: null,
+// text: 'OK',
+// type: GFType.outline,
+// color: GFColor.warning,
+// ),
+// ),
+//
+//
+// GFFloatingWidget(
+//// horizontalPosition: 150,
+// child: showToast? GFToast(
+// width: 200,
+// text: 'Happy New Year',
+// button: GFButton(onPressed: null,
+// text: 'OK',
+// type: GFType.outline,
+// color: GFColor.warning,
+// ),
+// ):Container(),
+// body: Column(
+// crossAxisAlignment: CrossAxisAlignment.center,
+// children: [
+// Container(
+//
+// margin: EdgeInsets.only(top:80, bottom: 10),
+// alignment: Alignment.center,
+// child: GFButton(onPressed: (){
+// setState(() {
+// showToast = !showToast;
+// });
+// },
+// text: 'Click to View the toast',
+// type: GFType.outline,
+// color: GFColor.warning,
+// ),
+// )
+// ],
+// )
+// )
+// ],
+// ),
+// ),
+//
+// body:
+//
+// ListView(
+// children: [
+// GFToast(
+// width: 340,
+// text: 'Happy New Year',
+// button: GFButton(onPressed: null,
+// text: 'OK',
+// type: GFType.outline,
+// color: GFColor.warning,
+// ),
+// ),
+// GFFloatingWidget(
+// horizontalPosition: 80,
+// child: showToast? GFToast(
+// width: 250,
+// text: 'Happy New Year',
+// button: GFButton(onPressed: null,
+// text: 'OK',
+// type: GFType.outline,
+// color: GFColor.warning,
+// ),
+// ):Container(),
+// body: Column(
+// crossAxisAlignment: CrossAxisAlignment.center,
+// children: [
+// Container(
+//
+// margin: EdgeInsets.only(top:0, bottom: 10, right: 40),
+// alignment: Alignment.center,
+// child: GFButton(onPressed: (){
+// setState(() {
+// showToast = !showToast;
+// });
+// },
+// text: 'Click to View the toast',
+// type: GFType.outline,
+// color: GFColor.warning,
+// ),
+// )
+// ],
+// )
+// )
+// ],
+// ),
+ );
+ }
+}
diff --git a/demo_app/lib/screens/home.dart b/demo_app/lib/screens/home.dart
new file mode 100644
index 00000000..926acdd3
--- /dev/null
+++ b/demo_app/lib/screens/home.dart
@@ -0,0 +1,326 @@
+import 'package:demo_app/screens/cards.dart';
+import 'package:demo_app/screens/icon-button.dart';
+import 'package:demo_app/screens/list-tiles.dart';
+import 'package:flutter/material.dart';
+import 'package:ui_kit/colors/gf_color.dart';
+import 'package:ui_kit/components/card/gf_card.dart';
+import 'avatars.dart';
+import 'buttons.dart';
+import 'toggles.dart';
+import 'headers.dart';
+import 'toasts.dart';
+import 'badges.dart';
+
+class HomePage extends StatefulWidget {
+ @override
+ _HomePageState createState() => _HomePageState();
+}
+
+class _HomePageState extends State {
+ @override
+ Widget build(BuildContext context) {
+ return Scaffold(
+ appBar: AppBar(
+ backgroundColor: getGFColor(GFColor.dark),
+ title: Text(
+ 'GET FLUTTER',
+ style: TextStyle(fontSize: 14),
+ ),
+ centerTitle: true,
+ ),
+// body: Container(
+// child: Row(
+// mainAxisAlignment: MainAxisAlignment.spaceBetween,
+// children: [
+// Expanded(child: GestureDetector(
+// onTap: (){
+// Navigator.push(
+// context,
+// MaterialPageRoute(
+// builder: (BuildContext context) => Buttons()),
+// );
+// },
+// child: GFCard(
+// color: getGFColor(GFColor.success),
+// content: Column(
+// mainAxisAlignment: MainAxisAlignment.spaceBetween,
+// children: [
+// Icon(Icons.bubble_chart),
+// Text('Buttons')
+// ],
+// ),
+// ),
+// )),
+// Expanded(child: GestureDetector(
+// onTap: (){
+// Navigator.push(
+// context,
+// MaterialPageRoute(
+// builder: (BuildContext context) => Avatars()),
+// );
+// },
+// child: GFCard(
+// color: getGFColor(GFColor.warning),
+// content: Column(
+// children: [
+// Icon(Icons.face),
+// Text('Avatar')
+// ],
+// ),
+// ),
+// ),)
+// ],
+// ),
+// )
+
+ body:
+
+ Column(
+ children: [
+ Row(
+ children: [
+ Expanded(
+ child: Container(
+ height: 100,
+ child: GestureDetector(
+ onTap: () {
+ Navigator.push(
+ context,
+ MaterialPageRoute(
+ builder: (BuildContext context) => Buttons()),
+ );
+ },
+ child: GFCard(
+ color: getGFColor(GFColor.success),
+ content: Column(
+ mainAxisAlignment: MainAxisAlignment.spaceBetween,
+ children: [
+ Icon(Icons.bubble_chart,
+ color: getGFColor(GFColor.white)),
+ Text(
+ 'Buttons',
+ style: TextStyle(color: getGFColor(GFColor.white)),
+ )
+ ],
+ ),
+ ),
+ ))),
+ Expanded(
+ child: Container(
+ height: 100,
+ child: GestureDetector(
+ onTap: () {
+ Navigator.push(
+ context,
+ MaterialPageRoute(
+ builder: (BuildContext context) => Avatars()),
+ );
+ },
+ child: GFCard(
+ color: getGFColor(GFColor.success),
+ content: Column(
+ mainAxisAlignment: MainAxisAlignment.spaceBetween,
+ children: [
+ Icon(Icons.face, color: getGFColor(GFColor.white)),
+ Text(
+ 'Avatar',
+ style: TextStyle(color: getGFColor(GFColor.white)),
+ )
+ ],
+ ),
+ ),
+ )),
+ ),
+ Expanded(
+ child: Container(
+ height: 100,
+ child: GestureDetector(
+ onTap: () {
+ Navigator.push(
+ context,
+ MaterialPageRoute(
+ builder: (BuildContext context) => Toggles()),
+ );
+ },
+ child: GFCard(
+ color: getGFColor(GFColor.success),
+ content: Column(
+ mainAxisAlignment: MainAxisAlignment.spaceBetween,
+ children: [
+ Icon(Icons.all_inclusive,
+ color: getGFColor(GFColor.white)),
+ Text(
+ 'Toggle',
+ style: TextStyle(color: getGFColor(GFColor.white)),
+ )
+ ],
+ ),
+ ),
+ )))
+ ],
+ ),
+
+ Row(
+ children: [
+ Expanded(child:Container(
+ height: 100,
+ child: GestureDetector(
+ onTap: () {
+ Navigator.push(
+ context,
+ MaterialPageRoute(
+ builder: (BuildContext context) => Headers()),
+ );
+ },
+ child: GFCard(
+ color: getGFColor(GFColor.success),
+ content: Column(
+ mainAxisAlignment: MainAxisAlignment.spaceBetween,
+ children: [
+ Icon(Icons.menu,
+ color: getGFColor(GFColor.white)),
+ Text(
+ 'Header',
+ style: TextStyle(color: getGFColor(GFColor.white)),
+ )
+ ],
+ ),
+ ),
+ )) ),
+ Expanded(child:Container(
+ height: 100,
+ child: GestureDetector(
+ onTap: () {
+ Navigator.push(
+ context,
+ MaterialPageRoute(
+ builder: (BuildContext context) => Toasts()),
+ );
+ },
+ child: GFCard(
+ color: getGFColor(GFColor.success),
+ content: Column(
+ mainAxisAlignment: MainAxisAlignment.spaceBetween,
+ children: [
+ Icon(Icons.call_to_action,
+ color: getGFColor(GFColor.white)),
+ Text(
+ 'Toast',
+ style: TextStyle(color: getGFColor(GFColor.white)),
+ )
+ ],
+ ),
+ ),
+ )) ),
+ Expanded(child:Container(
+ height: 100,
+ child: GestureDetector(
+ onTap: () {
+ Navigator.push(
+ context,
+ MaterialPageRoute(
+ builder: (BuildContext context) => Cards()),
+ );
+ },
+ child: GFCard(
+ color: getGFColor(GFColor.success),
+ content: Column(
+ mainAxisAlignment: MainAxisAlignment.spaceBetween,
+ children: [
+ Icon(Icons.credit_card,
+ color: getGFColor(GFColor.white)),
+ Text(
+ 'Card',
+ style: TextStyle(color: getGFColor(GFColor.white)),
+ )
+ ],
+ ),
+ ),
+ )) )
+ ],
+ ),
+
+ Row(
+ children: [
+ Expanded(child:Container(
+ height: 100,
+ child: GestureDetector(
+ onTap: () {
+ Navigator.push(
+ context,
+ MaterialPageRoute(
+ builder: (BuildContext context) => IconButtons()),
+ );
+ },
+ child: GFCard(
+ color: getGFColor(GFColor.success),
+ content: Column(
+ mainAxisAlignment: MainAxisAlignment.spaceBetween,
+ children: [
+ Icon(Icons.insert_emoticon,
+ color: getGFColor(GFColor.white)),
+ Text(
+ 'Icon Button',
+ style: TextStyle(color: getGFColor(GFColor.white), fontSize: 12),
+ )
+ ],
+ ),
+ ),
+ )) ),
+ Expanded(child:Container(
+ height: 100,
+ child: GestureDetector(
+ onTap: () {
+ Navigator.push(
+ context,
+ MaterialPageRoute(
+ builder: (BuildContext context) => ListTiles()),
+ );
+ },
+ child: GFCard(
+ color: getGFColor(GFColor.success),
+ content: Column(
+ mainAxisAlignment: MainAxisAlignment.spaceBetween,
+ children: [
+ Icon(Icons.list,
+ color: getGFColor(GFColor.white)),
+ Text(
+ 'ListTile',
+ style: TextStyle(color: getGFColor(GFColor.white)),
+ )
+ ],
+ ),
+ ),
+ )) ),
+ Expanded(child:Container(
+ height: 100,
+ child: GestureDetector(
+ onTap: () {
+ Navigator.push(
+ context,
+ MaterialPageRoute(
+ builder: (BuildContext context) => Badges()),
+ );
+ },
+ child: GFCard(
+ color: getGFColor(GFColor.success),
+ content: Column(
+ mainAxisAlignment: MainAxisAlignment.spaceBetween,
+ children: [
+ Icon(Icons.apps,
+ color: getGFColor(GFColor.white)),
+ Text(
+ 'Badges',
+ style: TextStyle(color: getGFColor(GFColor.white)),
+ )
+ ],
+ ),
+ ),
+ )) )
+ ],
+ )
+ ],
+ ),
+ );
+ }
+}
diff --git a/demo_app/lib/screens/icon-button.dart b/demo_app/lib/screens/icon-button.dart
new file mode 100644
index 00000000..0266d586
--- /dev/null
+++ b/demo_app/lib/screens/icon-button.dart
@@ -0,0 +1,240 @@
+import 'package:flutter/material.dart';
+import 'package:ui_kit/colors/gf_color.dart';
+import 'package:ui_kit/components/button/gf_icon_button.dart';
+import 'package:ui_kit/components/card/gf_card.dart';
+import 'package:ui_kit/components/header/gf_header.dart';
+import 'package:ui_kit/types/gf_heading_type.dart';
+import 'package:ui_kit/types/gf_type.dart';
+import 'package:ui_kit/size/gf_size.dart';
+
+class IconButtons extends StatefulWidget {
+ @override
+ _IconButtonsState createState() => _IconButtonsState();
+}
+
+class _IconButtonsState extends State {
+ @override
+ Widget build(BuildContext context) {
+ return Scaffold(
+ appBar: AppBar(
+ backgroundColor: getGFColor(GFColor.dark),
+ title: Text(
+ 'Icon Button',
+ style: TextStyle(fontSize: 14),
+ ),
+ ),
+ body: ListView(
+ children: [
+ GFCard(
+ content: Column(
+ children: [
+ GFHeader(
+ text: 'Solid Icon Button',
+ type: GFHeadingType.typo6,
+ ),
+ SizedBox(
+ height: 15.0,
+ ),
+ Row(
+ mainAxisAlignment: MainAxisAlignment.spaceBetween,
+ children: [
+ GFIconButton(
+ onPressed: null,
+ icon: Icon(Icons.ac_unit),
+// iconSize: 12.0,
+
+ type: GFType.solid,
+ size: GFSize.large,
+ buttonBoxShadow: true,
+ color: GFColor.primary,
+// boxShadow: BoxShadow(
+// color: Colors.pink,
+// blurRadius: 2.0,
+// spreadRadius: 1.0,
+// offset: Offset.zero,
+// ),
+// borderSide: BorderSide(color: Colors.pink, width: 1.0, style: BorderStyle.solid),
+// borderShape: RoundedRectangleBorder(side: BorderSide(color: Colors.pink, width: 2.0, style: BorderStyle.solid), borderRadius: BorderRadius.zero),
+ ),
+ GFIconButton(
+ onPressed: null,
+ icon: Icon(Icons.ac_unit),
+// iconSize: 12.0,
+
+ type: GFType.solid,
+ size: GFSize.medium,
+
+ color: GFColor.warning,
+// boxShadow: BoxShadow(
+// color: Colors.pink,
+// blurRadius: 2.0,
+// spreadRadius: 1.0,
+// offset: Offset.zero,
+// ),
+// borderSide: BorderSide(color: Colors.pink, width: 1.0, style: BorderStyle.solid),
+// borderShape: RoundedRectangleBorder(side: BorderSide(color: Colors.pink, width: 2.0, style: BorderStyle.solid), borderRadius: BorderRadius.zero),
+ ),
+ GFIconButton(
+ onPressed: null,
+ icon: Icon(Icons.ac_unit),
+// iconSize: 12.0,
+
+ type: GFType.solid,
+ size: GFSize.small,
+ buttonBoxShadow: true,
+ color: GFColor.success,
+// boxShadow: BoxShadow(
+// color: Colors.pink,
+// blurRadius: 2.0,
+// spreadRadius: 1.0,
+// offset: Offset.zero,
+// ),
+// borderSide: BorderSide(color: Colors.pink, width: 1.0, style: BorderStyle.solid),
+// borderShape: RoundedRectangleBorder(side: BorderSide(color: Colors.pink, width: 2.0, style: BorderStyle.solid), borderRadius: BorderRadius.zero),
+ ),
+ ],
+ )
+ ],
+ ),
+ ),
+ GFCard(
+ content: Column(
+ children: [
+ GFHeader(
+ text: 'Outline Icon Button',
+ type: GFHeadingType.typo6,
+ ),
+ SizedBox(
+ height: 15.0,
+ ),
+ Row(
+ mainAxisAlignment: MainAxisAlignment.spaceBetween,
+ children: [
+ GFIconButton(
+ onPressed: null,
+ icon: Icon(Icons.ac_unit),
+// iconSize: 12.0,
+
+ type: GFType.outline,
+ size: GFSize.large,
+
+// boxShadow: BoxShadow(
+// color: Colors.pink,
+// blurRadius: 2.0,
+// spreadRadius: 1.0,
+// offset: Offset.zero,
+// ),
+// borderSide: BorderSide(color: Colors.pink, width: 1.0, style: BorderStyle.solid),
+// borderShape: RoundedRectangleBorder(side: BorderSide(color: Colors.pink, width: 2.0, style: BorderStyle.solid), borderRadius: BorderRadius.zero),
+ ),
+ GFIconButton(
+ onPressed: null,
+ icon: Icon(Icons.ac_unit),
+// iconSize: 12.0,
+
+ size: GFSize.medium,
+ type: GFType.outline,
+// boxShadow: BoxShadow(
+// color: Colors.pink,
+// blurRadius: 2.0,
+// spreadRadius: 1.0,
+// offset: Offset.zero,
+// ),
+// borderSide: BorderSide(color: Colors.pink, width: 1.0, style: BorderStyle.solid),
+// borderShape: RoundedRectangleBorder(side: BorderSide(color: Colors.pink, width: 2.0, style: BorderStyle.solid), borderRadius: BorderRadius.zero),
+ ),
+ GFIconButton(
+ onPressed: null,
+ icon: Icon(Icons.ac_unit),
+// iconSize: 12.0,
+
+ type: GFType.outline,
+ size: GFSize.small,
+
+// boxShadow: BoxShadow(
+// color: Colors.pink,
+// blurRadius: 2.0,
+// spreadRadius: 1.0,
+// offset: Offset.zero,
+// ),
+// borderSide: BorderSide(color: Colors.pink, width: 1.0, style: BorderStyle.solid),
+// borderShape: RoundedRectangleBorder(side: BorderSide(color: Colors.pink, width: 2.0, style: BorderStyle.solid), borderRadius: BorderRadius.zero),
+ ),
+ ],
+ )
+ ],
+ ),
+ ),
+ GFCard(
+ content: Column(
+ children: [
+ GFHeader(
+ text: 'Transparent Icon Button',
+ type: GFHeadingType.typo6,
+ ),
+ SizedBox(
+ height: 15.0,
+ ),
+ Row(
+ mainAxisAlignment: MainAxisAlignment.spaceBetween,
+ children: [
+ GFIconButton(
+ onPressed: null,
+ icon: Icon(Icons.ac_unit),
+// iconSize: 12.0,
+
+ type: GFType.transparent,
+ size: GFSize.large,
+
+// boxShadow: BoxShadow(
+// color: Colors.pink,
+// blurRadius: 2.0,
+// spreadRadius: 1.0,
+// offset: Offset.zero,
+// ),
+// borderSide: BorderSide(color: Colors.pink, width: 1.0, style: BorderStyle.solid),
+// borderShape: RoundedRectangleBorder(side: BorderSide(color: Colors.pink, width: 2.0, style: BorderStyle.solid), borderRadius: BorderRadius.zero),
+ ),
+ GFIconButton(
+ onPressed: null,
+ icon: Icon(Icons.ac_unit),
+// iconSize: 12.0,
+
+ size: GFSize.medium,
+ type: GFType.transparent,
+// boxShadow: BoxShadow(
+// color: Colors.pink,
+// blurRadius: 2.0,
+// spreadRadius: 1.0,
+// offset: Offset.zero,
+// ),
+// borderSide: BorderSide(color: Colors.pink, width: 1.0, style: BorderStyle.solid),
+// borderShape: RoundedRectangleBorder(side: BorderSide(color: Colors.pink, width: 2.0, style: BorderStyle.solid), borderRadius: BorderRadius.zero),
+ ),
+ GFIconButton(
+ onPressed: null,
+ icon: Icon(Icons.ac_unit),
+// iconSize: 12.0,
+
+ type: GFType.transparent,
+ size: GFSize.small,
+
+// boxShadow: BoxShadow(
+// color: Colors.pink,
+// blurRadius: 2.0,
+// spreadRadius: 1.0,
+// offset: Offset.zero,
+// ),
+// borderSide: BorderSide(color: Colors.pink, width: 1.0, style: BorderStyle.solid),
+// borderShape: RoundedRectangleBorder(side: BorderSide(color: Colors.pink, width: 2.0, style: BorderStyle.solid), borderRadius: BorderRadius.zero),
+ ),
+ ],
+ )
+ ],
+ ),
+ )
+ ],
+ ),
+ );
+ }
+}
diff --git a/demo_app/lib/screens/list-tiles.dart b/demo_app/lib/screens/list-tiles.dart
new file mode 100644
index 00000000..bec715a6
--- /dev/null
+++ b/demo_app/lib/screens/list-tiles.dart
@@ -0,0 +1,103 @@
+import 'package:flutter/material.dart';
+import 'package:ui_kit/colors/gf_color.dart';
+import 'package:ui_kit/components/avatar/gf_avatar.dart';
+import 'package:ui_kit/components/button/gf_icon_button.dart';
+import 'package:ui_kit/components/card/gf_card.dart';
+import 'package:ui_kit/components/header/gf_header.dart';
+import 'package:ui_kit/components/list_tile/gf_list_tile.dart';
+import 'package:ui_kit/shape/gf_avatar_shape.dart';
+import 'package:ui_kit/types/gf_heading_type.dart';
+
+class ListTiles extends StatefulWidget {
+ @override
+ _ListTilesState createState() => _ListTilesState();
+}
+
+class _ListTilesState extends State {
+ @override
+ Widget build(BuildContext context) {
+ return Scaffold(
+ appBar: AppBar(
+ backgroundColor: getGFColor(GFColor.dark),
+ title: Text('List Tile', style: TextStyle(fontSize: 14),),
+ ),
+ body: ListView(
+ children: [
+
+
+ GFCard(
+ content: GFListTile(
+
+ title: GFHeader(
+ text: 'List tile',
+ type: GFHeadingType.typo5,
+ showDivider: false,
+ ),
+ subTitle: Text('Lorem ipsum', style: TextStyle(color: getGFColor(GFColor.dark)),),
+
+ showDivider: false,
+
+ ),
+ ),
+ GFCard(
+ content: GFListTile(
+ avatar: GFAvatar(
+ shape: GFAvatarShape.standard,
+ ),
+ title: GFHeader(
+ text: 'List tile',
+ type: GFHeadingType.typo5,
+ showDivider: false,
+ ),
+ subTitle: Text('Lorem ipsum', style: TextStyle(color: getGFColor(GFColor.dark)),),
+
+ description: Text('Dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ',
+ style: TextStyle(fontSize: 13, color: getGFColor(GFColor.secondary))),
+ showDivider: false,
+ ),
+ ),
+
+ GFCard(
+ content: GFListTile(
+
+ title: GFHeader(
+ text: 'List tile',
+ type: GFHeadingType.typo5,
+ showDivider: false,
+ ),
+ subTitle: Text('Lorem ipsum', style: TextStyle(color: getGFColor(GFColor.dark)),),
+
+ description: Text('Dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ',
+ style: TextStyle(fontSize: 13, color: getGFColor(GFColor.secondary))),
+ icon: GFAvatar(
+ shape: GFAvatarShape.circle,
+ ),
+ showDivider: false,
+
+ ),
+ ),
+
+ GFCard(
+ content: GFListTile(
+ avatar: GFAvatar(
+ shape: GFAvatarShape.square,
+ ),
+ title: GFHeader(
+ text: 'List tile',
+ type: GFHeadingType.typo5,
+ showDivider: false,
+ ),
+ subTitle: Text('Lorem ipsum', style: TextStyle(color: getGFColor(GFColor.dark)),),
+
+ description: Text('Dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ',
+ style: TextStyle(fontSize: 13, color: getGFColor(GFColor.secondary))),
+ icon: GFIconButton(icon: Icon(Icons.share), onPressed: null),
+ showDivider: false,
+
+ ),
+ )
+ ],
+ ),
+ );
+ }
+}
diff --git a/demo_app/lib/screens/toasts.dart b/demo_app/lib/screens/toasts.dart
new file mode 100644
index 00000000..3ec68dfd
--- /dev/null
+++ b/demo_app/lib/screens/toasts.dart
@@ -0,0 +1,96 @@
+import 'package:flutter/material.dart';
+import 'package:ui_kit/colors/gf_color.dart';
+import 'package:ui_kit/components/button/gf_button.dart';
+import 'package:ui_kit/components/card/gf_card.dart';
+import 'package:ui_kit/components/header/gf_header.dart';
+import 'package:ui_kit/components/toast/gf_toast.dart';
+import 'package:ui_kit/types/gf_heading_type.dart';
+import 'package:ui_kit/types/gf_type.dart';
+
+class Toasts extends StatefulWidget {
+ @override
+ _ToastsState createState() => _ToastsState();
+}
+
+class _ToastsState extends State {
+ bool showToast = false;
+ @override
+ Widget build(BuildContext context) {
+ return Scaffold(
+ appBar: AppBar(
+ backgroundColor: getGFColor(GFColor.dark),
+ title: Text(
+ 'Toast',
+ style: TextStyle(fontSize: 14),
+ ),
+ ),
+ body: ListView(
+ children: [
+ GFCard(
+ content: Column(
+ children: [
+ GFHeader(
+ text: 'Toast',
+ type: GFHeadingType.typo6,
+ ),
+ SizedBox(
+ height: 10,
+ ),
+ GFToast(
+ text: 'Happy New Year',
+ button: GFButton(
+ onPressed: null,
+ text: 'OK',
+ type: GFType.outline,
+ color: GFColor.warning,
+ ),
+ ),
+ ],
+ ),
+ ),
+
+// GFCard(
+// content: Column(
+// children: [
+// GFHeader(
+// text: 'Floating Toast',
+// type: GFHeadingType.typo6,
+// ),
+// GFFloatingWidget(
+// horizontalPosition: 80,
+// child: showToast? GFToast(
+// width: 300,
+// text: 'Happy New Year',
+// button: GFButton(onPressed: null,
+// text: 'OK',
+// type: GFType.outline,
+// color: GFColor.warning,
+// ),
+// ):Container(),
+// body: Column(
+// crossAxisAlignment: CrossAxisAlignment.center,
+// children: [
+// Container(
+//
+// margin: EdgeInsets.only(top:0, bottom: 10, right: 40),
+// alignment: Alignment.center,
+// child: GFButton(onPressed: (){
+// setState(() {
+// showToast = !showToast;
+// });
+// },
+// text: 'Click to View the toast',
+// type: GFType.outline,
+// color: GFColor.warning,
+// ),
+// )
+// ],
+// )
+// )
+// ],
+// ),
+// )
+ ],
+ ));
+ }
+}
diff --git a/demo_app/lib/screens/toggles.dart b/demo_app/lib/screens/toggles.dart
new file mode 100644
index 00000000..9199a3e5
--- /dev/null
+++ b/demo_app/lib/screens/toggles.dart
@@ -0,0 +1,125 @@
+import 'package:flutter/material.dart';
+import 'package:flutter/painting.dart';
+import 'package:ui_kit/components/card/gf_card.dart';
+import 'package:ui_kit/components/header/gf_header.dart';
+import 'package:ui_kit/components/toggle/gf_toggle.dart';
+import 'package:ui_kit/types/gf_heading_type.dart';
+import 'package:ui_kit/types/gf_toggle_type.dart';
+import 'package:ui_kit/colors/gf_color.dart';
+
+class Toggles extends StatefulWidget {
+ @override
+ _TogglesState createState() => _TogglesState();
+}
+
+class _TogglesState extends State {
+ @override
+ Widget build(BuildContext context) {
+ return Scaffold(
+ appBar: AppBar(
+ backgroundColor: getGFColor(GFColor.dark),
+ title: Text('Toggle', style: TextStyle(fontSize: 14),),
+ ),
+ body: Container(
+ margin: EdgeInsets.all(20),
+ child: Column(
+ children: [
+ GFCard(
+ content: Column(
+ children: [
+ GFHeader(
+ text: 'Android',
+ type: GFHeadingType.typo6,
+ ),
+ SizedBox(
+ height: 10,
+ ),
+ GFToggle(onChanged: null, value: null,
+ type: GFToggleType.android,
+ )
+ ],
+ ),
+ ),
+ GFCard(
+ content: Column(
+ children: [
+ GFHeader(
+ text: 'IOS',
+ type: GFHeadingType.typo6,
+ ),
+ SizedBox(
+ height: 10,
+ ),
+ GFToggle(onChanged: null, value: null,
+ type: GFToggleType.ios,
+ )
+ ],
+ ),
+ ),
+ GFCard(
+ content: Column(
+ children: [
+ GFHeader(
+ text: 'Square',
+ type: GFHeadingType.typo6,
+ ),
+ SizedBox(
+ height: 10,
+ ),
+ GFToggle(onChanged: null, value: null,
+ type: GFToggleType.square,
+ )
+ ],
+ ),
+ ),
+ GFCard(
+ content: Column(
+ children: [
+ GFHeader(
+ text: 'Custom',
+ type: GFHeadingType.typo6,
+ ),
+ SizedBox(
+ height: 10,
+ ),
+ Row(
+ mainAxisAlignment: MainAxisAlignment.spaceBetween,
+ children: [
+ GFToggle(onChanged: null, value: null,
+ type: GFToggleType.custom,
+ ),
+ GFToggle(onChanged: null, value: null,
+ type: GFToggleType.android,
+ boxShape: BoxShape.rectangle,
+ enabledTrackColor: getGFColor(GFColor.warning),
+
+ ),
+ GFToggle(onChanged: null, value: null,
+ type: GFToggleType.ios,
+ boxShape: BoxShape.rectangle,
+ enabledTrackColor: getGFColor(GFColor.info),
+
+
+ borderRadius: BorderRadius.all(Radius.circular(0)),
+ ),
+ GFToggle(onChanged: null, value: null,
+ type: GFToggleType.ios,
+ boxShape: BoxShape.rectangle,
+ enabledText: 'ON',
+ disabledText: 'OFF',
+ enabledTrackColor: getGFColor(GFColor.danger),
+ borderRadius: BorderRadius.all(Radius.circular(0)),
+ )
+ ],
+ ),
+
+ ],
+ ),
+ ),
+
+ ],
+ ),
+ ),
+ );
+ }
+}
diff --git a/demo_app/pubspec.lock b/demo_app/pubspec.lock
new file mode 100644
index 00000000..57c5df30
--- /dev/null
+++ b/demo_app/pubspec.lock
@@ -0,0 +1,202 @@
+# Generated by pub
+# See https://dart.dev/tools/pub/glossary#lockfile
+packages:
+ archive:
+ dependency: transitive
+ description:
+ name: archive
+ url: "https://pub.dartlang.org"
+ source: hosted
+ version: "2.0.11"
+ args:
+ dependency: transitive
+ description:
+ name: args
+ url: "https://pub.dartlang.org"
+ source: hosted
+ version: "1.5.2"
+ async:
+ dependency: transitive
+ description:
+ name: async
+ url: "https://pub.dartlang.org"
+ source: hosted
+ version: "2.4.0"
+ boolean_selector:
+ dependency: transitive
+ description:
+ name: boolean_selector
+ url: "https://pub.dartlang.org"
+ source: hosted
+ version: "1.0.5"
+ charcode:
+ dependency: transitive
+ description:
+ name: charcode
+ url: "https://pub.dartlang.org"
+ source: hosted
+ version: "1.1.2"
+ collection:
+ dependency: transitive
+ description:
+ name: collection
+ url: "https://pub.dartlang.org"
+ source: hosted
+ version: "1.14.11"
+ convert:
+ dependency: transitive
+ description:
+ name: convert
+ url: "https://pub.dartlang.org"
+ source: hosted
+ version: "2.1.1"
+ crypto:
+ dependency: transitive
+ description:
+ name: crypto
+ url: "https://pub.dartlang.org"
+ source: hosted
+ version: "2.1.3"
+ cupertino_icons:
+ dependency: "direct main"
+ description:
+ name: cupertino_icons
+ url: "https://pub.dartlang.org"
+ source: hosted
+ version: "0.1.3"
+ flutter:
+ dependency: "direct main"
+ description: flutter
+ source: sdk
+ version: "0.0.0"
+ flutter_test:
+ dependency: "direct dev"
+ description: flutter
+ source: sdk
+ version: "0.0.0"
+ image:
+ dependency: transitive
+ description:
+ name: image
+ url: "https://pub.dartlang.org"
+ source: hosted
+ version: "2.1.4"
+ matcher:
+ dependency: transitive
+ description:
+ name: matcher
+ url: "https://pub.dartlang.org"
+ source: hosted
+ version: "0.12.6"
+ meta:
+ dependency: transitive
+ description:
+ name: meta
+ url: "https://pub.dartlang.org"
+ source: hosted
+ version: "1.1.8"
+ path:
+ dependency: transitive
+ description:
+ name: path
+ url: "https://pub.dartlang.org"
+ source: hosted
+ version: "1.6.4"
+ pedantic:
+ dependency: transitive
+ description:
+ name: pedantic
+ url: "https://pub.dartlang.org"
+ source: hosted
+ version: "1.8.0+1"
+ petitparser:
+ dependency: transitive
+ description:
+ name: petitparser
+ url: "https://pub.dartlang.org"
+ source: hosted
+ version: "2.4.0"
+ quiver:
+ dependency: transitive
+ description:
+ name: quiver
+ url: "https://pub.dartlang.org"
+ source: hosted
+ version: "2.0.5"
+ sky_engine:
+ dependency: transitive
+ description: flutter
+ source: sdk
+ version: "0.0.99"
+ source_span:
+ dependency: transitive
+ description:
+ name: source_span
+ url: "https://pub.dartlang.org"
+ source: hosted
+ version: "1.5.5"
+ stack_trace:
+ dependency: transitive
+ description:
+ name: stack_trace
+ url: "https://pub.dartlang.org"
+ source: hosted
+ version: "1.9.3"
+ stream_channel:
+ dependency: transitive
+ description:
+ name: stream_channel
+ url: "https://pub.dartlang.org"
+ source: hosted
+ version: "2.0.0"
+ string_scanner:
+ dependency: transitive
+ description:
+ name: string_scanner
+ url: "https://pub.dartlang.org"
+ source: hosted
+ version: "1.0.5"
+ term_glyph:
+ dependency: transitive
+ description:
+ name: term_glyph
+ url: "https://pub.dartlang.org"
+ source: hosted
+ version: "1.1.0"
+ test_api:
+ dependency: transitive
+ description:
+ name: test_api
+ url: "https://pub.dartlang.org"
+ source: hosted
+ version: "0.2.11"
+ typed_data:
+ dependency: transitive
+ description:
+ name: typed_data
+ url: "https://pub.dartlang.org"
+ source: hosted
+ version: "1.1.6"
+ ui_kit:
+ dependency: "direct main"
+ description:
+ path: ".."
+ relative: true
+ source: path
+ version: "0.0.1"
+ vector_math:
+ dependency: transitive
+ description:
+ name: vector_math
+ url: "https://pub.dartlang.org"
+ source: hosted
+ version: "2.0.8"
+ xml:
+ dependency: transitive
+ description:
+ name: xml
+ url: "https://pub.dartlang.org"
+ source: hosted
+ version: "3.5.0"
+sdks:
+ dart: ">=2.4.0 <3.0.0"
diff --git a/demo_app/pubspec.yaml b/demo_app/pubspec.yaml
new file mode 100644
index 00000000..47d0c1f5
--- /dev/null
+++ b/demo_app/pubspec.yaml
@@ -0,0 +1,32 @@
+name: demo_app
+description: A new Flutter project.
+
+# The following defines the version and build number for your application.
+# A version number is three numbers separated by dots, like 1.2.43
+# followed by an optional build number separated by a +.
+# Both the version and the builder number may be overridden in flutter
+# build by specifying --build-name and --build-number, respectively.
+# In Android, build-name is used as versionName while build-number used as versionCode.
+# Read more about Android versioning at https://developer.android.com/studio/publish/versioning
+# In iOS, build-name is used as CFBundleShortVersionString while build-number used as CFBundleVersion.
+# Read more about iOS versioning at
+# https://developer.apple.com/library/archive/documentation/General/Reference/InfoPlistKeyReference/Articles/CoreFoundationKeys.html
+version: 1.0.0+1
+
+environment:
+ sdk: ">=2.1.0 <3.0.0"
+
+dependencies:
+ flutter:
+ sdk: flutter
+ ui_kit:
+ path: ../
+
+ cupertino_icons: ^0.1.2
+
+dev_dependencies:
+ flutter_test:
+ sdk: flutter
+
+flutter:
+ uses-material-design: true
diff --git a/demo_app/test/widget_test.dart b/demo_app/test/widget_test.dart
new file mode 100644
index 00000000..5f343444
--- /dev/null
+++ b/demo_app/test/widget_test.dart
@@ -0,0 +1,30 @@
+// This is a basic Flutter widget test.
+//
+// To perform an interaction with a widget in your test, use the WidgetTester
+// utility that Flutter provides. For example, you can send tap and scroll
+// gestures. You can also use WidgetTester to find child widgets in the widget
+// tree, read text, and verify that the values of widget properties are correct.
+
+import 'package:flutter/material.dart';
+import 'package:flutter_test/flutter_test.dart';
+
+import 'package:demo_app/main.dart';
+
+void main() {
+ testWidgets('Counter increments smoke test', (WidgetTester tester) async {
+ // Build our app and trigger a frame.
+ await tester.pumpWidget(MyApp());
+
+ // Verify that our counter starts at 0.
+ expect(find.text('0'), findsOneWidget);
+ expect(find.text('1'), findsNothing);
+
+ // Tap the '+' icon and trigger a frame.
+ await tester.tap(find.byIcon(Icons.add));
+ await tester.pump();
+
+ // Verify that our counter has incremented.
+ expect(find.text('0'), findsNothing);
+ expect(find.text('1'), findsOneWidget);
+ });
+}
diff --git a/demo_app/web/index.html b/demo_app/web/index.html
new file mode 100644
index 00000000..3a82fe25
--- /dev/null
+++ b/demo_app/web/index.html
@@ -0,0 +1,10 @@
+
+
+
+
+ demo_app
+
+
+
+
+
diff --git a/example/lib/main.dart b/example/lib/main.dart
index f7154474..8fbfffc7 100644
--- a/example/lib/main.dart
+++ b/example/lib/main.dart
@@ -1,41 +1,27 @@
import 'package:flutter/material.dart';
-import 'package:ui_kit/colors/gf_color.dart';
-
import 'package:ui_kit/components/button/gf_button.dart';
-
-import 'package:ui_kit/components/button/gf_icon_button.dart';
-
import 'package:ui_kit/components/badge/gf_button_badge.dart';
-
-import 'package:ui_kit/components/badge/gf_icon_badge.dart';
-
import 'package:ui_kit/components/avatar/gf_avatar.dart';
-
import 'package:ui_kit/components/badge/gf_badge.dart';
-
-import 'package:ui_kit/components/card/gf_card.dart';
-
-import 'package:ui_kit/components/list_tile/gf_list_tile.dart';
-
-import 'package:ui_kit/components/image/gf_image_overlay.dart';
-
-import 'package:ui_kit/components/button_bar/gf_button_bar.dart';
-
-import 'package:ui_kit/components/list_tile/gf_list_tile.dart';
-
+import 'package:ui_kit/components/segment_tabs/gf_segment_tabs.dart';
import 'package:ui_kit/types/gf_type.dart';
-import 'package:ui_kit/shape/gf_shape.dart';
-import 'package:ui_kit/components/slider/gf_slider.dart';
+import 'package:ui_kit/shape/gf_button_shape.dart';
+import 'package:ui_kit/shape/gf_badge_shape.dart';
import 'package:flutter/cupertino.dart';
-import 'package:ui_kit/size/gf_size.dart';
-import 'package:ui_kit/position/gf_position.dart';
import 'package:ui_kit/components/tabs/gf_tabs.dart';
+import 'package:ui_kit/components/drawer/gf_drawer.dart';
+import 'package:ui_kit/components/drawer/gf_drawer_header.dart';
+import 'package:ui_kit/components/toast/gf_toast.dart';
+import 'package:ui_kit/components/appbar/gf_appbar.dart';
+import 'package:ui_kit/components/tabs/gf_tabBarView.dart';
final List imageList = [
"https://cdn.pixabay.com/photo/2017/12/03/18/04/christmas-balls-2995437_960_720.jpg",
"https://cdn.pixabay.com/photo/2017/12/13/00/23/christmas-3015776_960_720.jpg",
"https://cdn.pixabay.com/photo/2019/12/19/10/55/christmas-market-4705877_960_720.jpg",
- "https://cdn.pixabay.com/photo/2019/12/20/00/03/road-4707345_960_720.jpg"
+ "https://cdn.pixabay.com/photo/2019/12/20/00/03/road-4707345_960_720.jpg",
+ "https://cdn.pixabay.com/photo/2019/12/22/04/18/x-mas-4711785__340.jpg",
+ "https://cdn.pixabay.com/photo/2016/11/22/07/09/spruce-1848543__340.jpg"
];
void main() => runApp(MyApp());
@@ -63,55 +49,196 @@ class MyHomePage extends StatefulWidget {
_MyHomePageState createState() => _MyHomePageState();
}
-class _MyHomePageState extends State {
+class _MyHomePageState extends State
+ with SingleTickerProviderStateMixin {
+ TabController tabController;
+
+ @override
+ void initState() {
+ super.initState();
+ tabController = TabController(length: 3, vsync: this);
+ }
+
+ @override
+ void dispose() {
+ tabController.dispose();
+ super.dispose();
+ }
+
bool switchValue = true;
+
@override
Widget build(BuildContext context) {
return Scaffold(
- backgroundColor: Colors.orange,
- appBar: AppBar(
- title: Text(widget.title),
+ drawer: GFDrawer(
+ colorFilter: new ColorFilter.mode(
+ Colors.black.withOpacity(0.6), BlendMode.darken),
+ backgroundImage: NetworkImage(
+ "https://cdn.pixabay.com/photo/2017/12/03/18/04/christmas-balls-2995437_960_720.jpg"),
+ gradient: LinearGradient(
+ begin: Alignment.topRight,
+ end: Alignment.bottomLeft,
+ stops: [0.1, 0.5, 0.7, 0.9],
+ colors: [
+ Colors.teal[800],
+ Colors.teal[600],
+ Colors.teal[400],
+ Colors.teal[200],
+ ],
+ ),
+ child: ListView(
+ padding: EdgeInsets.zero,
+ children: [
+ GFDrawerHeader(
+ currentAccountPicture: GFAvatar(
+ radius: 80.0,
+ backgroundImage: NetworkImage(
+ "https://cdn.pixabay.com/photo/2017/12/03/18/04/christmas-balls-2995437_960_720.jpg"),
+ ),
+ decoration: BoxDecoration(
+ color: Colors.teal.withOpacity(0.45),
+ ),
+ otherAccountsPictures: [
+ Image(
+ image: NetworkImage(
+ "https://cdn.pixabay.com/photo/2019/12/20/00/03/road-4707345_960_720.jpg"),
+ fit: BoxFit.cover,
+ ),
+ GFAvatar(
+ child: Text("dcf"),
+ )
+ ],
+ child: Column(
+ mainAxisAlignment: MainAxisAlignment.start,
+ crossAxisAlignment: CrossAxisAlignment.start,
+ children: [
+ Text('user'),
+ Text('user@asdf.com'),
+ ],
+ ),
+ ),
+ ListTile(
+ title: Text('Item 1'),
+ onTap: () {
+ Navigator.pop(context);
+ },
+ ),
+ ListTile(
+ title: Text('Item 2'),
+ onTap: () {},
+ ),
+ ],
+ ),
),
- body: SingleChildScrollView(
+ appBar: GFAppBar(
+// backgroundColor: Colors.tealAccent,
+ centerTitle: true,
+ title: GFSegmentTabs(
+ initialIndex: 0,
+ length: 3,
+ tabs: [
+ Tab(
+ child: Text(
+ "Gelatin",
+ ),
+ ),
+ Tab(
+ child: Text(
+ "Donuts",
+ ),
+ ),
+ Tab(
+ child: Text(
+ "Pastry",
+ ),
+ ),
+ ],
+ ),
+// trailing: [
+// GFIconButton(icon: Icon(Icons.directions_bus), onPressed: null)
+// ],
+ ),
+ backgroundColor: Colors.teal,
+ body:
+// GFTabBarView(controller: tabController, children: [
+// Container(color: Colors.red),
+// Container(color: Colors.green),
+// Container(color: Colors.blue)
+// ]),
+ SingleChildScrollView(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
crossAxisAlignment: CrossAxisAlignment.center,
children: [
-// Container(
-// height: 300.0,
-// child: DefaultTabController(
-// length: 2,
-// child: Scaffold(
-// appBar: AppBar(
-// bottom: TabBar(
-// indicator: UnderlineTabIndicator(
-// borderSide: BorderSide(color: Color(0xDD613896), width: 2.0),
-// insets: EdgeInsets.fromLTRB(5.0, 0.0, 5.0, 4.0),
-// ),
-// tabs: [
-// Tab(icon: Icon(Icons.directions_car), text: "Non persistent",),
-// Tab(icon: Icon(Icons.directions_transit), text: "Persistent"),
-// ],
-// ),
-// title: Text('Persistent Tab Demo'),
-// ),
-// body: TabBarView(
-// children: [
-// Text("cdx"),
-// Text("cdv")
-// ],
-// ),
-// ),
+ GFAvatar(
+ radius: 80.0,
+ backgroundImage: NetworkImage(
+ "https://cdn.pixabay.com/photo/2017/12/03/18/04/christmas-balls-2995437_960_720.jpg"),
+ ),
+
+ GFSegmentTabs(
+// height: 38.0,
+// width: 180.0,
+ initialIndex: 0,
+ length: 3,
+ tabs: [
+ Tab(
+ child: Text(
+ "Gelatin",
+ ),
+ ),
+ Tab(
+ child: Text(
+ "Donuts",
+ ),
+ ),
+ Tab(
+ child: Text(
+ "Pastry",
+ ),
+ ),
+ ],
+// tabBarColor: Colors.pink.withOpacity(0.6),
+// indicatorSize: TabBarIndicatorSize.tab,
+// indicatorColor: Colors.tealAccent,
+// indicator: BoxDecoration(
+// color: Colors.pink,
+// border: Border.all(color: Colors.green, width: 1.0),
+// borderRadius: BorderRadius.circular(50.0)
// ),
+// indicatorPadding: EdgeInsets.all(8.0),
+// indicatorWeight: 2.0,
+// border: Border.all(color: Colors.orange, width: 2.0),
+// borderRadius: BorderRadius.circular(50.0)
+ ),
+
+// GFItemsSlider(
+// rowCount: 3,
+// children: imageList.map(
+// (url) {
+// return Container(
+// margin: EdgeInsets.all(5.0),
+// child: ClipRRect(
+// borderRadius: BorderRadius.all(Radius.circular(5.0)),
+// child: Image.network(
+// url,
+// fit: BoxFit.cover,
+// width: 1000.0
+// ),
+// ),
+// );
+// },
+// ).toList(),
// ),
// GFSlider(
-//// pagerSize: 12.0,
-//// activeIndicator: Colors.pink,
-//// passiveIndicator: Colors.pink.withOpacity(0.4),
-// viewportFraction: 0.9,
+// rowCount: 3,
+// pagerSize: 12.0,
+// activeIndicator: Colors.pink,
+// passiveIndicator: Colors.pink.withOpacity(0.4),
+// viewportFraction: 1.0,
// aspectRatio: 2.0,
-//// autoPlay: true,
+// autoPlay: true,
// enlargeMainPage: true,
// pagination: true,
// items: imageList.map(
@@ -123,7 +250,7 @@ class _MyHomePageState extends State {
// child: Image.network(
// url,
// fit: BoxFit.cover,
-// width: 1000.0,
+// width: 1000.0
// ),
// ),
// );
@@ -136,39 +263,21 @@ class _MyHomePageState extends State {
// },
// ),
- RawMaterialButton(
- onPressed: null,
- child: Text("fv"),
- ),
- FlatButton(onPressed: null, child: Text("cds")),
-
-// Container(
-// decoration: BoxDecoration(
-// color: Colors.teal,
-// boxShadow: [BoxShadow(
-// color: Colors.pink,
-// blurRadius: 1.5,
-// spreadRadius: 2.0,
-// offset: Offset.zero,
-// )
-// ]
-// ),
-// child: OutlineButton(child: Text("Fvd"),)),
-//
-//
GFButton(
- color: Colors.orange,
+// color: Colors.green,
onPressed: null,
child: Text("share"),
type: GFType.outline,
- shape: GFShape.pills,
- buttonBoxShadow: true,
- boxShadow: BoxShadow(
- color: Colors.pink.withOpacity(0.4),
- blurRadius: 1.5,
- spreadRadius: 2.0,
- offset: Offset.zero,
- ),
+ shape: GFButtonShape.pills,
+//textColor: GFColor.danger,
+//borderSide: BorderSide(color: Colors.pink, width: 2.0),
+// buttonBoxShadow: true,
+// boxShadow: BoxShadow(
+// color: Colors.pink,
+// blurRadius: 1.5,
+// spreadRadius: 2.0,
+// offset: Offset.zero,
+// ),
),
GFTabs(
@@ -193,7 +302,7 @@ class _MyHomePageState extends State {
),
),
],
- tabBarView: TabBarView(
+ tabBarView: GFTabBarView(
children: [
Container(
color: Colors.red,
@@ -201,6 +310,16 @@ class _MyHomePageState extends State {
mainAxisAlignment: MainAxisAlignment.center,
crossAxisAlignment: CrossAxisAlignment.center,
children: [
+ GFToast(
+ child: Text("sdc"),
+ backgroundColor: Colors.pink,
+ button: GFButton(
+ text: 'dsx',
+ onPressed: () {
+ print("fdsc");
+ },
+ ),
+ ),
RawMaterialButton(
onPressed: null,
child: Text("fv"),
@@ -211,7 +330,7 @@ class _MyHomePageState extends State {
onPressed: null,
child: Text("share"),
icon: Icon(Icons.share),
- shape: GFShape.pills,
+ shape: GFButtonShape.pills,
type: GFType.transparent,
),
],
@@ -221,24 +340,24 @@ class _MyHomePageState extends State {
Icon(Icons.directions_transit),
],
),
-// indicatorColor: Colors.teal,
-// indicatorSize: TabBarIndicatorSize.label,
-// labelColor: Colors.lightGreen,
-// unselectedLabelColor: Colors.black,
-// labelStyle: TextStyle(
-// fontWeight: FontWeight.w500,
-// fontSize: 13.0,
-// color: Colors.deepOrange,
-// fontFamily: 'OpenSansBold',
-// ),
-// unselectedLabelStyle: TextStyle(
-// fontWeight: FontWeight.w500,
-// fontSize: 13.0,
-// color: Colors.black,
-// fontFamily: 'OpenSansBold',
-// ),
+ indicatorColor: Colors.teal,
+// indicatorSize: TabBarIndicatorSize.label,
+// labelColor: Colors.lightGreen,
+// unselectedLabelColor: Colors.black,
+// labelStyle: TextStyle(
+// fontWeight: FontWeight.w500,
+// fontSize: 13.0,
+// color: Colors.deepOrange,
+// fontFamily: 'OpenSansBold',
+// ),
+// unselectedLabelStyle: TextStyle(
+// fontWeight: FontWeight.w500,
+// fontSize: 13.0,
+// color: Colors.black,
+// fontFamily: 'OpenSansBold',
+// ),
),
-
+//
// GFSlider(
// autoPlay: true,
// viewportFraction: 1.0,
@@ -264,78 +383,81 @@ class _MyHomePageState extends State {
// });
// },
// ),
- GFCard(
- boxFit: BoxFit.cover,
- colorFilter: new ColorFilter.mode(
- Colors.black.withOpacity(0.67), BlendMode.darken),
- image: Image.asset("lib/assets/food.jpeg"),
-// imageOverlay: AssetImage("lib/assets/food.jpeg"),
- titlePosition: GFPosition.end,
- title: GFListTile(
- avatar: GFAvatar(
- child: Text("tb"),
- ),
- title: Text(
- 'title',
- style: TextStyle(color: Colors.grey),
- ),
- subTitle: Text(
- 'subtitle',
- style: TextStyle(color: Colors.grey),
- ),
- icon: GFIconButton(
- onPressed: null,
- icon: Icon(Icons.favorite_border),
- type: GFType.transparent,
- ),
- ),
- content: Text(
- "Flutter "
- "Flutter is Google's mobile UI framework for crafting"
- " high-quality native interfaces on iOS and Android in "
- "Flutter ",
- style: TextStyle(color: Colors.grey),
- ),
- buttonBar: GFButtonBar(
- mainAxisSize: MainAxisSize.min,
- children: [
- GFButton(
- onPressed: null,
- child: Text("favorite"),
- icon: Icon(Icons.favorite_border),
- type: GFType.transparent,
- ),
- GFButton(
- onPressed: null,
- child: Text("share"),
- icon: Icon(Icons.share),
- type: GFType.outline,
- ),
- ],
- ),
- ),
- GFButtonBar(
- mainAxisSize: MainAxisSize.min,
- children: [
- GFButton(
- onPressed: null,
- child: Text("like"),
- icon: Icon(Icons.favorite_border),
- type: GFType.transparent,
- ),
- GFButton(
- onPressed: null,
- child: Text("comment"),
- ),
- GFButton(
- onPressed: null,
- child: Text("share"),
- icon: Icon(Icons.share),
- type: GFType.outline,
- ),
- ],
- ),
-// GFListItem(
+// GFCard(
+// boxFit: BoxFit.cover,
+// colorFilter: new ColorFilter.mode(
+// Colors.black.withOpacity(0.67), BlendMode.darken),
+// image: Image.asset("lib/assets/food.jpeg"),
+//// imageOverlay: AssetImage("lib/assets/food.jpeg"),
+// titlePosition: GFPosition.end,
+// title: GFListTile(
+// avatar: GFAvatar(
+// child: Text("tb"),
+// ),
+// title: Text(
+// 'title',
+// style: TextStyle(color: Colors.grey),
+// ),
+// subTitle: Text(
+// 'subtitle',
+// style: TextStyle(color: Colors.grey),
+// ),
+// icon: GFIconButton(
+// onPressed: null,
+// icon: Icon(Icons.favorite_border),
+// type: GFType.transparent,
+// ),
+// ),
+// content: Text(
+// "Flutter "
+// "Flutter is Google's mobile UI framework for crafting"
+// " high-quality native interfaces on iOS and Android in "
+// "Flutter ",
+// style: TextStyle(color: Colors.grey),
+// ),
+// buttonBar: GFButtonBar(
+// mainAxisSize: MainAxisSize.min,
+// children: [
+// GFButton(
+// onPressed: null,
+// child: Text("favorite"),
+// icon: Icon(Icons.favorite_border),
+// type: GFType.transparent,
+// ),
+// GFButton(
+// onPressed: null,
+// child: Text("share"),
+// icon: Icon(Icons.share),
+// type: GFType.outline,
+// ),
+// ],
+// ),
+// ),
+// GFButtonBar(
+// mainAxisSize: MainAxisSize.min,
+// children: [
+// GFButton(
+// onPressed: null,
+// child: Text("like"),
+// icon: Icon(Icons.favorite_border),
+// type: GFType.transparent,
+// ),
+// GFButton(
+// onPressed: null,
+// child: Text("comment"),
+// ),
+// GFButton(
+// color: Colors.teal,
+// onPressed: (){},
+// child: Text("share"),
+// icon: Icon(Icons.share),
+// type: GFType.outline,
+// ),
+// ],
+// ),
+//
+//
+// GFListTile(
// avatar: GFAvatar(
// child: Text("tb"),
// ),
@@ -397,10 +519,6 @@ class _MyHomePageState extends State {
// 'Hello world',
// style: TextStyle(color: Colors.white),
// ),
-// new Text(
-// 'Hello world',
-// style: TextStyle(color: Colors.white),
-// ),
// ],
// ),
//// color: Colors.orange,
@@ -423,43 +541,43 @@ class _MyHomePageState extends State {
////
//// foregroundColor: Colors.deepOrangeAccent,
////
-//// shape: GFShape.square,
+// shape: GFAvatarShape.standard,
////
//// size: GFSize.medium,
////
//// borderRadius: BorderRadius.circular(20.0),
// ),
-// GFIconBadges(
-// onPressed: null,
-// child: GFIconButton(
-// onPressed: null,
-// icon: Icon(Icons.ac_unit),
-// ),
-// counterChild: GFBadge(
-// text: '12',
+ // GFIconBadges(
+ // onPressed: null,
+ // child: GFIconButton(
+ // onPressed: null,
+ // icon: Icon(Icons.ac_unit),
+ // ),
+ // counterChild: GFBadge(
+ // text: '12',
+
+// color: GFColor.dark
+////,
+// shape: GFBadgeShape.circle,
//
-//// color: GFColor.dark,
-////
-//// shape: GFShape.circle,
-////
-//// size: GFSize.small,
-////
-//// border: BorderSide(color: Colors.pink, width: 1.0, style: BorderStyle.solid),
-////
-//// textColor: GFColor.white,
-////
-//// textStyle: TextStyle(fontWeight: FontWeight.w500, fontSize: 8.0),
-////
-//// borderShape: RoundedRectangleBorder(side: BorderSide(color: Colors.orange, width: 2.0, style: BorderStyle.solid), borderRadius: BorderRadius.zero),
-// ),
-// ),
+// size: GFSize.small,
+//
+// border: BorderSide(color: Colors.pink, width: 1.0, style: BorderStyle.solid),
+//
+// textColor: GFColor.white,
+//
+// textStyle: TextStyle(fontWeight: FontWeight.w500, fontSize: 8.0),
+//
+// borderShape: RoundedRectangleBorder(side: BorderSide(color: Colors.orange, width: 2.0, style: BorderStyle.solid), borderRadius: BorderRadius.zero),
+ // ),
+ // ),
// GFIconButton(
// onPressed: null,
// icon: Icon(Icons.ac_unit),
//// iconSize: 12.0,
-//// type: GFType.solid,
-//// shape: GFShape.pills,
-//// size: GFSize.large,
+// type: GFType.solid,
+// shape: GFButtonShape.pills,
+// size: GFSize.large,
//// buttonBoxShadow: true,
//// color: GFColor.primary,
//// boxShadow: BoxShadow(
@@ -471,38 +589,43 @@ class _MyHomePageState extends State {
//// borderSide: BorderSide(color: Colors.pink, width: 1.0, style: BorderStyle.solid),
//// borderShape: RoundedRectangleBorder(side: BorderSide(color: Colors.pink, width: 2.0, style: BorderStyle.solid), borderRadius: BorderRadius.zero),
// ),
-// GFButtonBadge(
-// onPressed: null,
-//// position: GFIconPosition.start,
-//// borderSide: BorderSide(color: Colors.pink, width: 1.0, style: BorderStyle.solid),
-//// borderShape: RoundedRectangleBorder(side: BorderSide(color: Colors.pink, width: 2.0, style: BorderStyle.solid), borderRadius: BorderRadius.zero),
-// text: 'goodies',
-//// color: GFColor.danger,
-//// shape: GFShape.pills,
-//// type: GFType.outline,
-//// size: GFSize.small,
-// counterChild: GFBadge(
-// child: Text("12"),
-//// color: GFColor.dark,
-//// shape: GFShape.circle,
-//// size: GFSize.small,
-//// border: BorderSide(color: Colors.pink, width: 1.0, style: BorderStyle.solid),
-//// textColor: GFColor.white,
-//// textStyle: TextStyle(fontWeight: FontWeight.w500, fontSize: 8.0),
-// ),
-// ),
+ GFButtonBadge(
+ onPressed: null,
+// position: GFIconPosition.start,
+// borderSide: BorderSide(color: Colors.pink, width: 1.0, style: BorderStyle.solid),
+// borderShape: RoundedRectangleBorder(side: BorderSide(color: Colors.pink, width: 2.0, style: BorderStyle.solid), borderRadius: BorderRadius.zero),
+ text: 'goodies',
+// color: GFColor.danger,
+// shape: GFButtonShape.pills,
+ type: GFType.outline,
+// size: GFSize.small,
+ counterChild: GFBadge(
+ child: Text("12"),
+// color: GFColor.dark,
+ shape: GFBadgeShape.circle,
+// size: GFSize.small,
+// border: BorderSide(color: Colors.pink, width: 1.0, style: BorderStyle.solid),
+// textColor: GFColor.white,
+// textStyle: TextStyle(fontWeight: FontWeight.w500, fontSize: 8.0),
+ ),
+ ),
// GFBadge(
// text: '12',
//// color: GFColor.dark,
-//// shape: GFShape.circle,
+// shape: GFBadgeShape.circle,
//// size: GFSize.small,
//// border: BorderSide(color: Colors.pink, width: 1.0, style: BorderStyle.solid),
//// textColor: GFColor.white,
//// textStyle: TextStyle(fontWeight: FontWeight.w500, fontSize: 8.0),
// ),
// GFButton(
-//// type: GFType.solid,
-//// shape: GFShape.pills,
+// text: 'goodies',
+// onPressed: () {},
+// icon: Icon(Icons.access_alarms),
+// ),
+// GFButton(
+// type: GFType.solid,
+// shape: GFButtonShape.pills,
// text: 'goodies',
// onPressed: () {},
//// textStyle: TextStyle(fontWeight: FontWeight.w500, fontSize: 8.0),
diff --git a/lib/components/appbar/gf_appbar.dart b/lib/components/appbar/gf_appbar.dart
new file mode 100644
index 00000000..5b1f87d2
--- /dev/null
+++ b/lib/components/appbar/gf_appbar.dart
@@ -0,0 +1,1312 @@
+import 'dart:math' as math;
+import 'package:flutter/foundation.dart';
+import 'package:flutter/rendering.dart';
+import 'package:flutter/services.dart';
+import 'package:flutter/widgets.dart';
+import 'package:flutter/material.dart';
+
+const double _kLeadingWidth =
+ kToolbarHeight; // So the leading button is square.
+
+// Bottom justify the kToolbarHeight child which may overflow the top.
+class _ToolbarContainerLayout extends SingleChildLayoutDelegate {
+ const _ToolbarContainerLayout();
+
+ @override
+ BoxConstraints getConstraintsForChild(BoxConstraints constraints) {
+ return constraints.tighten(height: kToolbarHeight);
+ }
+
+ @override
+ Size getSize(BoxConstraints constraints) {
+ return Size(constraints.maxWidth, kToolbarHeight);
+ }
+
+ @override
+ Offset getPositionForChild(Size size, Size childSize) {
+ return Offset(0.0, size.height - childSize.height);
+ }
+
+ @override
+ bool shouldRelayout(_ToolbarContainerLayout oldDelegate) => false;
+}
+
+/// A material design app bar.
+///
+/// An app bar consists of a toolbar and potentially other widgets, such as a
+/// [TabBar] and a [FlexibleSpaceBar]. App bars typically expose one or more
+/// common [actions] with [IconButton]s which are optionally followed by a
+/// [PopupMenuButton] for less common operations (sometimes called the "overflow
+/// menu").
+///
+/// App bars are typically used in the [Scaffold.appBar] property, which places
+/// the app bar as a fixed-height widget at the top of the screen. For a scrollable
+/// app bar, see [SliverGFAppBar], which embeds an [GFAppBar] in a sliver for use in
+/// a [CustomScrollView].
+///
+/// When not used as [Scaffold.appBar], or when wrapped in a [Hero], place the app
+/// bar in a [MediaQuery] to take care of the padding around the content of the
+/// app bar if needed, as the padding will not be handled by [Scaffold].
+///
+/// The GFAppBar displays the toolbar widgets, [leading], [title], and [actions],
+/// above the [bottom] (if any). The [bottom] is usually used for a [TabBar]. If
+/// a [flexibleSpace] widget is specified then it is stacked behind the toolbar
+/// and the bottom widget. The following diagram shows where each of these slots
+/// appears in the toolbar when the writing language is left-to-right (e.g.
+/// English):
+///
+/// 
+///
+/// If the [leading] widget is omitted, but the [GFAppBar] is in a [Scaffold] with
+/// a [Drawer], then a button will be inserted to open the drawer. Otherwise, if
+/// the nearest [Navigator] has any previous routes, a [BackButton] is inserted
+/// instead. This behavior can be turned off by setting the [automaticallyImplyLeading]
+/// to false. In that case a null leading widget will result in the middle/title widget
+/// stretching to start.
+///
+/// {@tool dartpad --template=stateless_widget_material}
+///
+/// This sample shows an [GFAppBar] with two simple actions. The first action
+/// opens a [SnackBar], while the second action navigates to a new page.
+///
+/// ```dart preamble
+/// final GlobalKey scaffoldKey = GlobalKey();
+/// final SnackBar snackBar = const SnackBar(content: Text('Showing Snackbar'));
+///
+/// void openPage(BuildContext context) {
+/// Navigator.push(context, MaterialPageRoute(
+/// builder: (BuildContext context) {
+/// return Scaffold(
+/// appBar: GFAppBar(
+/// title: const Text('Next page'),
+/// ),
+/// body: const Center(
+/// child: Text(
+/// 'This is the next page',
+/// style: TextStyle(fontSize: 24),
+/// ),
+/// ),
+/// );
+/// },
+/// ));
+/// }
+/// ```
+///
+/// ```dart
+/// Widget build(BuildContext context) {
+/// return Scaffold(
+/// key: scaffoldKey,
+/// appBar: GFAppBar(
+/// title: const Text('GFAppBar Demo'),
+/// actions: [
+/// IconButton(
+/// icon: const Icon(Icons.add_alert),
+/// tooltip: 'Show Snackbar',
+/// onPressed: () {
+/// scaffoldKey.currentState.showSnackBar(snackBar);
+/// },
+/// ),
+/// IconButton(
+/// icon: const Icon(Icons.navigate_next),
+/// tooltip: 'Next page',
+/// onPressed: () {
+/// openPage(context);
+/// },
+/// ),
+/// ],
+/// ),
+/// body: const Center(
+/// child: Text(
+/// 'This is the home page',
+/// style: TextStyle(fontSize: 24),
+/// ),
+/// ),
+/// );
+/// }
+/// ```
+/// {@end-tool}
+///
+/// See also:
+///
+/// * [Scaffold], which displays the [GFAppBar] in its [Scaffold.appBar] slot.
+/// * [SliverGFAppBar], which uses [GFAppBar] to provide a flexible app bar that
+/// can be used in a [CustomScrollView].
+/// * [TabBar], which is typically placed in the [bottom] slot of the [GFAppBar]
+/// if the screen has multiple pages arranged in tabs.
+/// * [IconButton], which is used with [actions] to show buttons on the app bar.
+/// * [PopupMenuButton], to show a popup menu on the app bar, via [actions].
+/// * [FlexibleSpaceBar], which is used with [flexibleSpace] when the app bar
+/// can expand and collapse.
+/// *
+class GFAppBar extends StatefulWidget implements PreferredSizeWidget {
+ /// Creates a material design app bar.
+ ///
+ /// The arguments [primary], [toolbarOpacity], [bottomOpacity]
+ /// and [automaticallyImplyLeading] must not be null. Additionally, if
+ /// [elevation] is specified, it must be non-negative.
+ ///
+ /// If [backgroundColor], [elevation], [brightness], [iconTheme],
+ /// [actionsIconTheme], or [textTheme] are null, then their [GFAppBarTheme]
+ /// values will be used. If the corresponding [GFAppBarTheme] property is null,
+ /// then the default specified in the property's documentation will be used.
+ ///
+ /// Typically used in the [Scaffold.appBar] property.
+ GFAppBar({
+ Key key,
+ this.leading,
+ this.automaticallyImplyLeading = true,
+ this.title,
+ this.trailing,
+ this.flexibleSpace,
+ this.bottom,
+ this.elevation,
+ this.shape,
+ this.backgroundColor,
+ this.brightness,
+ this.iconTheme,
+ this.actionsIconTheme,
+ this.textTheme,
+ this.primary = true,
+ this.centerTitle,
+ this.titleSpacing = NavigationToolbar.kMiddleSpacing,
+ this.toolbarOpacity = 1.0,
+ this.bottomOpacity = 1.0,
+ }) : assert(automaticallyImplyLeading != null),
+ assert(elevation == null || elevation >= 0.0),
+ assert(primary != null),
+ assert(titleSpacing != null),
+ assert(toolbarOpacity != null),
+ assert(bottomOpacity != null),
+ preferredSize = Size.fromHeight(
+ kToolbarHeight + (bottom?.preferredSize?.height ?? 0.0)),
+ super(key: key);
+
+ /// A widget to display before the [title].
+ ///
+ /// If this is null and [automaticallyImplyLeading] is set to true, the
+ /// [GFAppBar] will imply an appropriate widget. For example, if the [GFAppBar] is
+ /// in a [Scaffold] that also has a [Drawer], the [Scaffold] will fill this
+ /// widget with an [IconButton] that opens the drawer (using [Icons.menu]). If
+ /// there's no [Drawer] and the parent [Navigator] can go back, the [GFAppBar]
+ /// will use a [BackButton] that calls [Navigator.maybePop].
+ ///
+ /// {@tool sample}
+ ///
+ /// The following code shows how the drawer button could be manually specified
+ /// instead of relying on [automaticallyImplyLeading]:
+ ///
+ /// ```dart
+ /// GFAppBar(
+ /// leading: Builder(
+ /// builder: (BuildContext context) {
+ /// return IconButton(
+ /// icon: const Icon(Icons.menu),
+ /// onPressed: () { Scaffold.of(context).openDrawer(); },
+ /// tooltip: MaterialLocalizations.of(context).openAppDrawerTooltip,
+ /// );
+ /// },
+ /// ),
+ /// )
+ /// ```
+ /// {@end-tool}
+ ///
+ /// The [Builder] is used in this example to ensure that the `context` refers
+ /// to that part of the subtree. That way this code snippet can be used even
+ /// inside the very code that is creating the [Scaffold] (in which case,
+ /// without the [Builder], the `context` wouldn't be able to see the
+ /// [Scaffold], since it would refer to an ancestor of that widget).
+ ///
+ /// See also:
+ ///
+ /// * [Scaffold.appBar], in which an [GFAppBar] is usually placed.
+ /// * [Scaffold.drawer], in which the [Drawer] is usually placed.
+ final Widget leading;
+
+ /// Controls whether we should try to imply the leading widget if null.
+ ///
+ /// If true and [leading] is null, automatically try to deduce what the leading
+ /// widget should be. If false and [leading] is null, leading space is given to [title].
+ /// If leading widget is not null, this parameter has no effect.
+ final bool automaticallyImplyLeading;
+
+ /// The primary widget displayed in the app bar.
+ ///
+ /// Typically a [Text] widget containing a description of the current contents
+ /// of the app.
+ final Widget title;
+
+ /// Widgets to display after the [title] widget.
+ ///
+ /// Typically these widgets are [IconButton]s representing common operations.
+ /// For less common operations, consider using a [PopupMenuButton] as the
+ /// last action.
+ final List trailing;
+
+ /// This widget is stacked behind the toolbar and the tab bar. It's height will
+ /// be the same as the app bar's overall height.
+ ///
+ /// A flexible space isn't actually flexible unless the [GFAppBar]'s container
+ /// changes the [GFAppBar]'s size. A [SliverGFAppBar] in a [CustomScrollView]
+ /// changes the [GFAppBar]'s height when scrolled.
+ ///
+ /// Typically a [FlexibleSpaceBar]. See [FlexibleSpaceBar] for details.
+ final Widget flexibleSpace;
+
+ /// This widget appears across the bottom of the app bar.
+ ///
+ /// Typically a [TabBar]. Only widgets that implement [PreferredSizeWidget] can
+ /// be used at the bottom of an app bar.
+ ///
+ /// See also:
+ ///
+ /// * [PreferredSize], which can be used to give an arbitrary widget a preferred size.
+ final PreferredSizeWidget bottom;
+
+ /// The z-coordinate at which to place this app bar relative to its parent.
+ ///
+ /// This controls the size of the shadow below the app bar.
+ ///
+ /// The value is non-negative.
+ ///
+ /// If this property is null, then [ThemeData.appBarTheme.elevation] is used,
+ /// if that is also null, the default value is 4, the appropriate elevation
+ /// for app bars.
+ final double elevation;
+
+ /// The material's shape as well its shadow.
+ ///
+ /// A shadow is only displayed if the [elevation] is greater than
+ /// zero.
+ final ShapeBorder shape;
+
+ /// The color to use for the app bar's material. Typically this should be set
+ /// along with [brightness], [iconTheme], [textTheme].
+ ///
+ /// If this property is null, then [ThemeData.appBarTheme.color] is used,
+ /// if that is also null, then [ThemeData.primaryColor] is used.
+ final Color backgroundColor;
+
+ /// The brightness of the app bar's material. Typically this is set along
+ /// with [backgroundColor], [iconTheme], [textTheme].
+ ///
+ /// If this property is null, then [ThemeData.appBarTheme.brightness] is used,
+ /// if that is also null, then [ThemeData.primaryColorBrightness] is used.
+ final Brightness brightness;
+
+ /// The color, opacity, and size to use for app bar icons. Typically this
+ /// is set along with [backgroundColor], [brightness], [textTheme].
+ ///
+ /// If this property is null, then [ThemeData.appBarTheme.iconTheme] is used,
+ /// if that is also null, then [ThemeData.primaryIconTheme] is used.
+ final IconThemeData iconTheme;
+
+ /// The color, opacity, and size to use for the icons that appear in the app
+ /// bar's [actions]. This should only be used when the [actions] should be
+ /// themed differently than the icon that appears in the app bar's [leading]
+ /// widget.
+ ///
+ /// If this property is null, then [ThemeData.appBarTheme.actionsIconTheme] is
+ /// used, if that is also null, then this falls back to [iconTheme].
+ final IconThemeData actionsIconTheme;
+
+ /// The typographic styles to use for text in the app bar. Typically this is
+ /// set along with [brightness] [backgroundColor], [iconTheme].
+ ///
+ /// If this property is null, then [ThemeData.appBarTheme.textTheme] is used,
+ /// if that is also null, then [ThemeData.primaryTextTheme] is used.
+ final TextTheme textTheme;
+
+ /// Whether this app bar is being displayed at the top of the screen.
+ ///
+ /// If true, the app bar's toolbar elements and [bottom] widget will be
+ /// padded on top by the height of the system status bar. The layout
+ /// of the [flexibleSpace] is not affected by the [primary] property.
+ final bool primary;
+
+ /// Whether the title should be centered.
+ ///
+ /// Defaults to being adapted to the current [TargetPlatform].
+ final bool centerTitle;
+
+ /// The spacing around [title] content on the horizontal axis. This spacing is
+ /// applied even if there is no [leading] content or [actions]. If you want
+ /// [title] to take all the space available, set this value to 0.0.
+ ///
+ /// Defaults to [NavigationToolbar.kMiddleSpacing].
+ final double titleSpacing;
+
+ /// How opaque the toolbar part of the app bar is.
+ ///
+ /// A value of 1.0 is fully opaque, and a value of 0.0 is fully transparent.
+ ///
+ /// Typically, this value is not changed from its default value (1.0). It is
+ /// used by [SliverGFAppBar] to animate the opacity of the toolbar when the app
+ /// bar is scrolled.
+ final double toolbarOpacity;
+
+ /// How opaque the bottom part of the app bar is.
+ ///
+ /// A value of 1.0 is fully opaque, and a value of 0.0 is fully transparent.
+ ///
+ /// Typically, this value is not changed from its default value (1.0). It is
+ /// used by [SliverGFAppBar] to animate the opacity of the toolbar when the app
+ /// bar is scrolled.
+ final double bottomOpacity;
+
+ /// A size whose height is the sum of [kToolbarHeight] and the [bottom] widget's
+ /// preferred height.
+ ///
+ /// [Scaffold] uses this size to set its app bar's height.
+ @override
+ final Size preferredSize;
+
+ bool _getEffectiveCenterTitle(ThemeData theme) {
+ if (centerTitle != null) return centerTitle;
+ assert(theme.platform != null);
+ switch (theme.platform) {
+ case TargetPlatform.android:
+ case TargetPlatform.fuchsia:
+ return false;
+ case TargetPlatform.iOS:
+ return trailing == null || trailing.length < 2;
+ }
+ return null;
+ }
+
+ @override
+ _GFAppBarState createState() => _GFAppBarState();
+}
+
+class _GFAppBarState extends State {
+ static const double _defaultElevation = 4.0;
+
+ void _handleDrawerButton() {
+ Scaffold.of(context).openDrawer();
+ }
+
+ void _handleDrawerButtonEnd() {
+ Scaffold.of(context).openEndDrawer();
+ }
+
+ @override
+ Widget build(BuildContext context) {
+ assert(!widget.primary || debugCheckHasMediaQuery(context));
+ assert(debugCheckHasMaterialLocalizations(context));
+ final ThemeData theme = Theme.of(context);
+ final AppBarTheme appBarTheme = AppBarTheme.of(context);
+ final ScaffoldState scaffold = Scaffold.of(context, nullOk: true);
+ final ModalRoute parentRoute = ModalRoute.of(context);
+
+ final bool hasDrawer = scaffold?.hasDrawer ?? false;
+ final bool hasEndDrawer = scaffold?.hasEndDrawer ?? false;
+ final bool canPop = parentRoute?.canPop ?? false;
+ final bool useCloseButton =
+ parentRoute is PageRoute && parentRoute.fullscreenDialog;
+
+ IconThemeData overallIconTheme =
+ widget.iconTheme ?? appBarTheme.iconTheme ?? theme.primaryIconTheme;
+ IconThemeData actionsIconTheme = widget.actionsIconTheme ??
+ appBarTheme.actionsIconTheme ??
+ overallIconTheme;
+ TextStyle centerStyle = widget.textTheme?.title ??
+ appBarTheme.textTheme?.title ??
+ theme.primaryTextTheme.title;
+ TextStyle sideStyle = widget.textTheme?.body1 ??
+ appBarTheme.textTheme?.body1 ??
+ theme.primaryTextTheme.body1;
+
+ if (widget.toolbarOpacity != 1.0) {
+ final double opacity =
+ const Interval(0.25, 1.0, curve: Curves.fastOutSlowIn)
+ .transform(widget.toolbarOpacity);
+ if (centerStyle?.color != null)
+ centerStyle =
+ centerStyle.copyWith(color: centerStyle.color.withOpacity(opacity));
+ if (sideStyle?.color != null)
+ sideStyle =
+ sideStyle.copyWith(color: sideStyle.color.withOpacity(opacity));
+ overallIconTheme = overallIconTheme.copyWith(
+ opacity: opacity * (overallIconTheme.opacity ?? 1.0));
+ actionsIconTheme = actionsIconTheme.copyWith(
+ opacity: opacity * (actionsIconTheme.opacity ?? 1.0));
+ }
+
+ Widget leading = widget.leading;
+ if (leading == null && widget.automaticallyImplyLeading) {
+ if (hasDrawer) {
+ leading = IconButton(
+ icon: const Icon(Icons.menu),
+ onPressed: _handleDrawerButton,
+ tooltip: MaterialLocalizations.of(context).openAppDrawerTooltip,
+ );
+ } else {
+ if (canPop)
+ leading = useCloseButton ? const CloseButton() : const BackButton();
+ }
+ }
+ if (leading != null) {
+ leading = ConstrainedBox(
+ constraints: const BoxConstraints.tightFor(width: _kLeadingWidth),
+ child: leading,
+ );
+ }
+
+ Widget title = widget.title;
+ if (title != null) {
+ bool namesRoute;
+ switch (theme.platform) {
+ case TargetPlatform.android:
+ case TargetPlatform.fuchsia:
+ namesRoute = true;
+ break;
+ case TargetPlatform.iOS:
+ break;
+ }
+ title = DefaultTextStyle(
+ style: centerStyle,
+ softWrap: false,
+ overflow: TextOverflow.ellipsis,
+ child: Semantics(
+ namesRoute: namesRoute,
+ child: _GFAppBarTitleBox(child: title),
+ header: true,
+ ),
+ );
+ }
+
+ Widget actions;
+ if (widget.trailing != null && widget.trailing.isNotEmpty) {
+ actions = Row(
+ mainAxisSize: MainAxisSize.min,
+ crossAxisAlignment: CrossAxisAlignment.stretch,
+ children: widget.trailing,
+ );
+ } else if (hasEndDrawer) {
+ actions = IconButton(
+ icon: const Icon(Icons.menu),
+ onPressed: _handleDrawerButtonEnd,
+ tooltip: MaterialLocalizations.of(context).openAppDrawerTooltip,
+ );
+ }
+
+ // Allow the trailing actions to have their own theme if necessary.
+ if (actions != null) {
+ actions = IconTheme.merge(
+ data: actionsIconTheme,
+ child: actions,
+ );
+ }
+
+ final Widget toolbar = NavigationToolbar(
+ leading: leading,
+ middle: title,
+ trailing: actions,
+ centerMiddle: widget._getEffectiveCenterTitle(theme),
+ middleSpacing: widget.titleSpacing,
+ );
+
+ // If the toolbar is allocated less than kToolbarHeight make it
+ // appear to scroll upwards within its shrinking container.
+ Widget appBar = ClipRect(
+ child: CustomSingleChildLayout(
+ delegate: const _ToolbarContainerLayout(),
+ child: IconTheme.merge(
+ data: overallIconTheme,
+ child: DefaultTextStyle(
+ style: sideStyle,
+ child: toolbar,
+ ),
+ ),
+ ),
+ );
+ if (widget.bottom != null) {
+ appBar = Column(
+ mainAxisAlignment: MainAxisAlignment.spaceBetween,
+ children: [
+ Flexible(
+ child: ConstrainedBox(
+ constraints: const BoxConstraints(maxHeight: kToolbarHeight),
+ child: appBar,
+ ),
+ ),
+ Opacity(
+ opacity: const Interval(0.25, 1.0, curve: Curves.fastOutSlowIn)
+ .transform(widget.bottomOpacity),
+ child: widget.bottom,
+ ),
+ ],
+ );
+ }
+
+ // The padding applies to the toolbar and tabbar, not the flexible space.
+ if (widget.primary) {
+ appBar = SafeArea(
+ top: true,
+ child: appBar,
+ );
+ }
+
+ appBar = Align(
+ alignment: Alignment.topCenter,
+ child: appBar,
+ );
+
+ if (widget.flexibleSpace != null) {
+ appBar = Stack(
+ fit: StackFit.passthrough,
+ children: [
+ widget.flexibleSpace,
+ appBar,
+ ],
+ );
+ }
+ final Brightness brightness = widget.brightness ??
+ appBarTheme.brightness ??
+ theme.primaryColorBrightness;
+ final SystemUiOverlayStyle overlayStyle = brightness == Brightness.dark
+ ? SystemUiOverlayStyle.light
+ : SystemUiOverlayStyle.dark;
+
+ return Semantics(
+ container: true,
+ child: AnnotatedRegion(
+ value: overlayStyle,
+ child: Material(
+ color:
+ widget.backgroundColor ?? appBarTheme.color ?? theme.primaryColor,
+ elevation:
+ widget.elevation ?? appBarTheme.elevation ?? _defaultElevation,
+ shape: widget.shape,
+ child: Semantics(
+ explicitChildNodes: true,
+ child: appBar,
+ ),
+ ),
+ ),
+ );
+ }
+}
+
+class _FloatingGFAppBar extends StatefulWidget {
+ const _FloatingGFAppBar({Key key, this.child}) : super(key: key);
+
+ final Widget child;
+
+ @override
+ _FloatingGFAppBarState createState() => _FloatingGFAppBarState();
+}
+
+// A wrapper for the widget created by _SliverGFAppBarDelegate that starts and
+// stops the floating app bar's snap-into-view or snap-out-of-view animation.
+class _FloatingGFAppBarState extends State<_FloatingGFAppBar> {
+ ScrollPosition _position;
+
+ @override
+ void didChangeDependencies() {
+ super.didChangeDependencies();
+ if (_position != null)
+ _position.isScrollingNotifier.removeListener(_isScrollingListener);
+ _position = Scrollable.of(context)?.position;
+ if (_position != null)
+ _position.isScrollingNotifier.addListener(_isScrollingListener);
+ }
+
+ @override
+ void dispose() {
+ if (_position != null)
+ _position.isScrollingNotifier.removeListener(_isScrollingListener);
+ super.dispose();
+ }
+
+ RenderSliverFloatingPersistentHeader _headerRenderer() {
+ return context
+ .findAncestorRenderObjectOfType();
+ }
+
+ void _isScrollingListener() {
+ if (_position == null) return;
+
+ // When a scroll stops, then maybe snap the appbar into view.
+ // Similarly, when a scroll starts, then maybe stop the snap animation.
+ final RenderSliverFloatingPersistentHeader header = _headerRenderer();
+ if (_position.isScrollingNotifier.value)
+ header?.maybeStopSnapAnimation(_position.userScrollDirection);
+ else
+ header?.maybeStartSnapAnimation(_position.userScrollDirection);
+ }
+
+ @override
+ Widget build(BuildContext context) => widget.child;
+}
+
+class _SliverGFAppBarDelegate extends SliverPersistentHeaderDelegate {
+ _SliverGFAppBarDelegate({
+ @required this.leading,
+ @required this.automaticallyImplyLeading,
+ @required this.title,
+ @required this.actions,
+ @required this.flexibleSpace,
+ @required this.bottom,
+ @required this.elevation,
+ @required this.forceElevated,
+ @required this.backgroundColor,
+ @required this.brightness,
+ @required this.iconTheme,
+ @required this.actionsIconTheme,
+ @required this.textTheme,
+ @required this.primary,
+ @required this.centerTitle,
+ @required this.titleSpacing,
+ @required this.expandedHeight,
+ @required this.collapsedHeight,
+ @required this.topPadding,
+ @required this.floating,
+ @required this.pinned,
+ @required this.snapConfiguration,
+ @required this.stretchConfiguration,
+ @required this.shape,
+ }) : assert(primary || topPadding == 0.0),
+ _bottomHeight = bottom?.preferredSize?.height ?? 0.0;
+
+ final Widget leading;
+ final bool automaticallyImplyLeading;
+ final Widget title;
+ final List actions;
+ final Widget flexibleSpace;
+ final PreferredSizeWidget bottom;
+ final double elevation;
+ final bool forceElevated;
+ final Color backgroundColor;
+ final Brightness brightness;
+ final IconThemeData iconTheme;
+ final IconThemeData actionsIconTheme;
+ final TextTheme textTheme;
+ final bool primary;
+ final bool centerTitle;
+ final double titleSpacing;
+ final double expandedHeight;
+ final double collapsedHeight;
+ final double topPadding;
+ final bool floating;
+ final bool pinned;
+ final ShapeBorder shape;
+
+ final double _bottomHeight;
+
+ @override
+ double get minExtent =>
+ collapsedHeight ?? (topPadding + kToolbarHeight + _bottomHeight);
+
+ @override
+ double get maxExtent => math.max(
+ topPadding + (expandedHeight ?? kToolbarHeight + _bottomHeight),
+ minExtent);
+
+ @override
+ final FloatingHeaderSnapConfiguration snapConfiguration;
+
+ @override
+ final OverScrollHeaderStretchConfiguration stretchConfiguration;
+
+ @override
+ Widget build(
+ BuildContext context, double shrinkOffset, bool overlapsContent) {
+ final double visibleMainHeight = maxExtent - shrinkOffset - topPadding;
+
+ // Truth table for `toolbarOpacity`:
+ // pinned | floating | bottom != null || opacity
+ // ----------------------------------------------
+ // 0 | 0 | 0 || fade
+ // 0 | 0 | 1 || fade
+ // 0 | 1 | 0 || fade
+ // 0 | 1 | 1 || fade
+ // 1 | 0 | 0 || 1.0
+ // 1 | 0 | 1 || 1.0
+ // 1 | 1 | 0 || 1.0
+ // 1 | 1 | 1 || fade
+ final double toolbarOpacity = !pinned || (floating && bottom != null)
+ ? ((visibleMainHeight - _bottomHeight) / kToolbarHeight).clamp(0.0, 1.0)
+ : 1.0;
+
+ final Widget appBar = FlexibleSpaceBar.createSettings(
+ minExtent: minExtent,
+ maxExtent: maxExtent,
+ currentExtent: math.max(minExtent, maxExtent - shrinkOffset),
+ toolbarOpacity: toolbarOpacity,
+ child: GFAppBar(
+ leading: leading,
+ automaticallyImplyLeading: automaticallyImplyLeading,
+ title: title,
+ trailing: actions,
+ flexibleSpace: (title == null && flexibleSpace != null)
+ ? Semantics(child: flexibleSpace, header: true)
+ : flexibleSpace,
+ bottom: bottom,
+ elevation: forceElevated ||
+ overlapsContent ||
+ (pinned && shrinkOffset > maxExtent - minExtent)
+ ? elevation ?? 4.0
+ : 0.0,
+ backgroundColor: backgroundColor,
+ brightness: brightness,
+ iconTheme: iconTheme,
+ actionsIconTheme: actionsIconTheme,
+ textTheme: textTheme,
+ primary: primary,
+ centerTitle: centerTitle,
+ titleSpacing: titleSpacing,
+ shape: shape,
+ toolbarOpacity: toolbarOpacity,
+ bottomOpacity:
+ pinned ? 1.0 : (visibleMainHeight / _bottomHeight).clamp(0.0, 1.0),
+ ),
+ );
+ return floating ? _FloatingGFAppBar(child: appBar) : appBar;
+ }
+
+ @override
+ bool shouldRebuild(covariant _SliverGFAppBarDelegate oldDelegate) {
+ return leading != oldDelegate.leading ||
+ automaticallyImplyLeading != oldDelegate.automaticallyImplyLeading ||
+ title != oldDelegate.title ||
+ actions != oldDelegate.actions ||
+ flexibleSpace != oldDelegate.flexibleSpace ||
+ bottom != oldDelegate.bottom ||
+ _bottomHeight != oldDelegate._bottomHeight ||
+ elevation != oldDelegate.elevation ||
+ backgroundColor != oldDelegate.backgroundColor ||
+ brightness != oldDelegate.brightness ||
+ iconTheme != oldDelegate.iconTheme ||
+ actionsIconTheme != oldDelegate.actionsIconTheme ||
+ textTheme != oldDelegate.textTheme ||
+ primary != oldDelegate.primary ||
+ centerTitle != oldDelegate.centerTitle ||
+ titleSpacing != oldDelegate.titleSpacing ||
+ expandedHeight != oldDelegate.expandedHeight ||
+ topPadding != oldDelegate.topPadding ||
+ pinned != oldDelegate.pinned ||
+ floating != oldDelegate.floating ||
+ snapConfiguration != oldDelegate.snapConfiguration ||
+ stretchConfiguration != oldDelegate.stretchConfiguration;
+ }
+
+ @override
+ String toString() {
+ return '${describeIdentity(this)}(topPadding: ${topPadding.toStringAsFixed(1)}, bottomHeight: ${_bottomHeight.toStringAsFixed(1)}, ...)';
+ }
+}
+
+/// A material design app bar that integrates with a [CustomScrollView].
+///
+/// An app bar consists of a toolbar and potentially other widgets, such as a
+/// [TabBar] and a [FlexibleSpaceBar]. App bars typically expose one or more
+/// common actions with [IconButton]s which are optionally followed by a
+/// [PopupMenuButton] for less common operations.
+///
+/// {@youtube 560 315 https://www.youtube.com/watch?v=R9C5KMJKluE}
+///
+/// Sliver app bars are typically used as the first child of a
+/// [CustomScrollView], which lets the app bar integrate with the scroll view so
+/// that it can vary in height according to the scroll offset or float above the
+/// other content in the scroll view. For a fixed-height app bar at the top of
+/// the screen see [GFAppBar], which is used in the [Scaffold.appBar] slot.
+///
+/// The GFAppBar displays the toolbar widgets, [leading], [title], and
+/// [actions], above the [bottom] (if any). If a [flexibleSpace] widget is
+/// specified then it is stacked behind the toolbar and the bottom widget.
+///
+/// {@tool sample}
+///
+/// This is an example that could be included in a [CustomScrollView]'s
+/// [CustomScrollView.slivers] list:
+///
+/// ```dart
+/// SliverGFAppBar(
+/// expandedHeight: 150.0,
+/// flexibleSpace: const FlexibleSpaceBar(
+/// title: Text('Available seats'),
+/// ),
+/// actions: [
+/// IconButton(
+/// icon: const Icon(Icons.add_circle),
+/// tooltip: 'Add new entry',
+/// onPressed: () { /* ... */ },
+/// ),
+/// ]
+/// )
+/// ```
+/// {@end-tool}
+///
+/// ## Animated Examples
+///
+/// The following animations show how app bars with different configurations
+/// behave when a user scrolls up and then down again.
+///
+/// * App bar with [floating]: false, [pinned]: false, [snap]: false:
+/// {@animation 476 400 https://flutter.github.io/assets-for-api-docs/assets/material/app_bar.mp4}
+///
+/// * App bar with [floating]: true, [pinned]: false, [snap]: false:
+/// {@animation 476 400 https://flutter.github.io/assets-for-api-docs/assets/material/app_bar_floating.mp4}
+///
+/// * App bar with [floating]: true, [pinned]: false, [snap]: true:
+/// {@animation 476 400 https://flutter.github.io/assets-for-api-docs/assets/material/app_bar_floating_snap.mp4}
+///
+/// * App bar with [floating]: true, [pinned]: true, [snap]: false:
+/// {@animation 476 400 https://flutter.github.io/assets-for-api-docs/assets/material/app_bar_pinned_floating.mp4}
+///
+/// * App bar with [floating]: true, [pinned]: true, [snap]: true:
+/// {@animation 476 400 https://flutter.github.io/assets-for-api-docs/assets/material/app_bar_pinned_floating_snap.mp4}
+///
+/// * App bar with [floating]: false, [pinned]: true, [snap]: false:
+/// {@animation 476 400 https://flutter.github.io/assets-for-api-docs/assets/material/app_bar_pinned.mp4}
+///
+/// The property [snap] can only be set to true if [floating] is also true.
+///
+/// See also:
+///
+/// * [CustomScrollView], which integrates the [SliverGFAppBar] into its
+/// scrolling.
+/// * [GFAppBar], which is a fixed-height app bar for use in [Scaffold.appBar].
+/// * [TabBar], which is typically placed in the [bottom] slot of the [GFAppBar]
+/// if the screen has multiple pages arranged in tabs.
+/// * [IconButton], which is used with [actions] to show buttons on the app bar.
+/// * [PopupMenuButton], to show a popup menu on the app bar, via [actions].
+/// * [FlexibleSpaceBar], which is used with [flexibleSpace] when the app bar
+/// can expand and collapse.
+/// *
+class SliverGFAppBar extends StatefulWidget {
+ /// Creates a material design app bar that can be placed in a [CustomScrollView].
+ ///
+ /// The arguments [forceElevated], [primary], [floating], [pinned], [snap]
+ /// and [automaticallyImplyLeading] must not be null.
+ const SliverGFAppBar({
+ Key key,
+ this.leading,
+ this.automaticallyImplyLeading = true,
+ this.title,
+ this.actions,
+ this.flexibleSpace,
+ this.bottom,
+ this.elevation,
+ this.forceElevated = false,
+ this.backgroundColor,
+ this.brightness,
+ this.iconTheme,
+ this.actionsIconTheme,
+ this.textTheme,
+ this.primary = true,
+ this.centerTitle,
+ this.titleSpacing = NavigationToolbar.kMiddleSpacing,
+ this.expandedHeight,
+ this.floating = false,
+ this.pinned = false,
+ this.snap = false,
+ this.stretch = false,
+ this.stretchTriggerOffset = 100.0,
+ this.onStretchTrigger,
+ this.shape,
+ }) : assert(automaticallyImplyLeading != null),
+ assert(forceElevated != null),
+ assert(primary != null),
+ assert(titleSpacing != null),
+ assert(floating != null),
+ assert(pinned != null),
+ assert(snap != null),
+ assert(stretch != null),
+ assert(floating || !snap,
+ 'The "snap" argument only makes sense for floating app bars.'),
+ assert(stretchTriggerOffset > 0.0),
+ super(key: key);
+
+ /// A widget to display before the [title].
+ ///
+ /// If this is null and [automaticallyImplyLeading] is set to true, the [GFAppBar] will
+ /// imply an appropriate widget. For example, if the [GFAppBar] is in a [Scaffold]
+ /// that also has a [Drawer], the [Scaffold] will fill this widget with an
+ /// [IconButton] that opens the drawer. If there's no [Drawer] and the parent
+ /// [Navigator] can go back, the [GFAppBar] will use a [BackButton] that calls
+ /// [Navigator.maybePop].
+ final Widget leading;
+
+ /// Controls whether we should try to imply the leading widget if null.
+ ///
+ /// If true and [leading] is null, automatically try to deduce what the leading
+ /// widget should be. If false and [leading] is null, leading space is given to [title].
+ /// If leading widget is not null, this parameter has no effect.
+ final bool automaticallyImplyLeading;
+
+ /// The primary widget displayed in the app bar.
+ ///
+ /// Typically a [Text] widget containing a description of the current contents
+ /// of the app.
+ final Widget title;
+
+ /// Widgets to display after the [title] widget.
+ ///
+ /// Typically these widgets are [IconButton]s representing common operations.
+ /// For less common operations, consider using a [PopupMenuButton] as the
+ /// last action.
+ ///
+ /// {@tool sample}
+ ///
+ /// ```dart
+ /// Scaffold(
+ /// body: CustomScrollView(
+ /// primary: true,
+ /// slivers: [
+ /// SliverGFAppBar(
+ /// title: Text('Hello World'),
+ /// actions: [
+ /// IconButton(
+ /// icon: Icon(Icons.shopping_cart),
+ /// tooltip: 'Open shopping cart',
+ /// onPressed: () {
+ /// // handle the press
+ /// },
+ /// ),
+ /// ],
+ /// ),
+ /// // ...rest of body...
+ /// ],
+ /// ),
+ /// )
+ /// ```
+ /// {@end-tool}
+ final List actions;
+
+ /// This widget is stacked behind the toolbar and the tab bar. It's height will
+ /// be the same as the app bar's overall height.
+ ///
+ /// Typically a [FlexibleSpaceBar]. See [FlexibleSpaceBar] for details.
+ final Widget flexibleSpace;
+
+ /// This widget appears across the bottom of the app bar.
+ ///
+ /// Typically a [TabBar]. Only widgets that implement [PreferredSizeWidget] can
+ /// be used at the bottom of an app bar.
+ ///
+ /// See also:
+ ///
+ /// * [PreferredSize], which can be used to give an arbitrary widget a preferred size.
+ final PreferredSizeWidget bottom;
+
+ /// The z-coordinate at which to place this app bar when it is above other
+ /// content. This controls the size of the shadow below the app bar.
+ ///
+ /// If this property is null, then [ThemeData.appBarTheme.elevation] is used,
+ /// if that is also null, the default value is 4, the appropriate elevation
+ /// for app bars.
+ ///
+ /// If [forceElevated] is false, the elevation is ignored when the app bar has
+ /// no content underneath it. For example, if the app bar is [pinned] but no
+ /// content is scrolled under it, or if it scrolls with the content, then no
+ /// shadow is drawn, regardless of the value of [elevation].
+ final double elevation;
+
+ /// Whether to show the shadow appropriate for the [elevation] even if the
+ /// content is not scrolled under the [GFAppBar].
+ ///
+ /// Defaults to false, meaning that the [elevation] is only applied when the
+ /// [GFAppBar] is being displayed over content that is scrolled under it.
+ ///
+ /// When set to true, the [elevation] is applied regardless.
+ ///
+ /// Ignored when [elevation] is zero.
+ final bool forceElevated;
+
+ /// The color to use for the app bar's material. Typically this should be set
+ /// along with [brightness], [iconTheme], [textTheme].
+ ///
+ /// If this property is null, then [ThemeData.appBarTheme.color] is used,
+ /// if that is also null, then [ThemeData.primaryColor] is used.
+ final Color backgroundColor;
+
+ /// The brightness of the app bar's material. Typically this is set along
+ /// with [backgroundColor], [iconTheme], [textTheme].
+ ///
+ /// If this property is null, then [ThemeData.appBarTheme.brightness] is used,
+ /// if that is also null, then [ThemeData.primaryColorBrightness] is used.
+ final Brightness brightness;
+
+ /// The color, opacity, and size to use for app bar icons. Typically this
+ /// is set along with [backgroundColor], [brightness], [textTheme].
+ ///
+ /// If this property is null, then [ThemeData.appBarTheme.iconTheme] is used,
+ /// if that is also null, then [ThemeData.primaryIconTheme] is used.
+ final IconThemeData iconTheme;
+
+ /// The color, opacity, and size to use for trailing app bar icons. This
+ /// should only be used when the trailing icons should be themed differently
+ /// than the leading icons.
+ ///
+ /// If this property is null, then [ThemeData.appBarTheme.actionsIconTheme] is
+ /// used, if that is also null, then this falls back to [iconTheme].
+ final IconThemeData actionsIconTheme;
+
+ /// The typographic styles to use for text in the app bar. Typically this is
+ /// set along with [brightness] [backgroundColor], [iconTheme].
+ ///
+ /// If this property is null, then [ThemeData.appBarTheme.textTheme] is used,
+ /// if that is also null, then [ThemeData.primaryTextTheme] is used.
+ final TextTheme textTheme;
+
+ /// Whether this app bar is being displayed at the top of the screen.
+ ///
+ /// If this is true, the top padding specified by the [MediaQuery] will be
+ /// added to the top of the toolbar.
+ final bool primary;
+
+ /// Whether the title should be centered.
+ ///
+ /// Defaults to being adapted to the current [TargetPlatform].
+ final bool centerTitle;
+
+ /// The spacing around [title] content on the horizontal axis. This spacing is
+ /// applied even if there is no [leading] content or [actions]. If you want
+ /// [title] to take all the space available, set this value to 0.0.
+ ///
+ /// Defaults to [NavigationToolbar.kMiddleSpacing].
+ final double titleSpacing;
+
+ /// The size of the app bar when it is fully expanded.
+ ///
+ /// By default, the total height of the toolbar and the bottom widget (if
+ /// any). If a [flexibleSpace] widget is specified this height should be big
+ /// enough to accommodate whatever that widget contains.
+ ///
+ /// This does not include the status bar height (which will be automatically
+ /// included if [primary] is true).
+ final double expandedHeight;
+
+ /// Whether the app bar should become visible as soon as the user scrolls
+ /// towards the app bar.
+ ///
+ /// Otherwise, the user will need to scroll near the top of the scroll view to
+ /// reveal the app bar.
+ ///
+ /// If [snap] is true then a scroll that exposes the app bar will trigger an
+ /// animation that slides the entire app bar into view. Similarly if a scroll
+ /// dismisses the app bar, the animation will slide it completely out of view.
+ ///
+ /// ## Animated Examples
+ ///
+ /// The following animations show how the app bar changes its scrolling
+ /// behavior based on the value of this property.
+ ///
+ /// * App bar with [floating] set to false:
+ /// {@animation 476 400 https://flutter.github.io/assets-for-api-docs/assets/material/app_bar.mp4}
+ /// * App bar with [floating] set to true:
+ /// {@animation 476 400 https://flutter.github.io/assets-for-api-docs/assets/material/app_bar_floating.mp4}
+ ///
+ /// See also:
+ ///
+ /// * [SliverGFAppBar] for more animated examples of how this property changes the
+ /// behavior of the app bar in combination with [pinned] and [snap].
+ final bool floating;
+
+ /// Whether the app bar should remain visible at the start of the scroll view.
+ ///
+ /// The app bar can still expand and contract as the user scrolls, but it will
+ /// remain visible rather than being scrolled out of view.
+ ///
+ /// ## Animated Examples
+ ///
+ /// The following animations show how the app bar changes its scrolling
+ /// behavior based on the value of this property.
+ ///
+ /// * App bar with [pinned] set to false:
+ /// {@animation 476 400 https://flutter.github.io/assets-for-api-docs/assets/material/app_bar.mp4}
+ /// * App bar with [pinned] set to true:
+ /// {@animation 476 400 https://flutter.github.io/assets-for-api-docs/assets/material/app_bar_pinned.mp4}
+ ///
+ /// See also:
+ ///
+ /// * [SliverGFAppBar] for more animated examples of how this property changes the
+ /// behavior of the app bar in combination with [floating].
+ final bool pinned;
+
+ /// The material's shape as well as its shadow.
+ ///
+ /// A shadow is only displayed if the [elevation] is greater than zero.
+ final ShapeBorder shape;
+
+ /// If [snap] and [floating] are true then the floating app bar will "snap"
+ /// into view.
+ ///
+ /// If [snap] is true then a scroll that exposes the floating app bar will
+ /// trigger an animation that slides the entire app bar into view. Similarly if
+ /// a scroll dismisses the app bar, the animation will slide the app bar
+ /// completely out of view.
+ ///
+ /// Snapping only applies when the app bar is floating, not when the app bar
+ /// appears at the top of its scroll view.
+ ///
+ /// ## Animated Examples
+ ///
+ /// The following animations show how the app bar changes its scrolling
+ /// behavior based on the value of this property.
+ ///
+ /// * App bar with [snap] set to false:
+ /// {@animation 476 400 https://flutter.github.io/assets-for-api-docs/assets/material/app_bar_floating.mp4}
+ /// * App bar with [snap] set to true:
+ /// {@animation 476 400 https://flutter.github.io/assets-for-api-docs/assets/material/app_bar_floating_snap.mp4}
+ ///
+ /// See also:
+ ///
+ /// * [SliverGFAppBar] for more animated examples of how this property changes the
+ /// behavior of the app bar in combination with [pinned] and [floating].
+ final bool snap;
+
+ /// Whether the app bar should stretch to fill the over-scroll area.
+ ///
+ /// The app bar can still expand and contract as the user scrolls, but it will
+ /// also stretch when the user over-scrolls.
+ final bool stretch;
+
+ /// The offset of overscroll required to activate [onStretchTrigger].
+ ///
+ /// This defaults to 100.0.
+ final double stretchTriggerOffset;
+
+ /// The callback function to be executed when a user over-scrolls to the
+ /// offset specified by [stretchTriggerOffset].
+ final AsyncCallback onStretchTrigger;
+
+ @override
+ _SliverGFAppBarState createState() => _SliverGFAppBarState();
+}
+
+// This class is only Stateful because it owns the TickerProvider used
+// by the floating appbar snap animation (via FloatingHeaderSnapConfiguration).
+class _SliverGFAppBarState extends State
+ with TickerProviderStateMixin {
+ FloatingHeaderSnapConfiguration _snapConfiguration;
+ OverScrollHeaderStretchConfiguration _stretchConfiguration;
+
+ void _updateSnapConfiguration() {
+ if (widget.snap && widget.floating) {
+ _snapConfiguration = FloatingHeaderSnapConfiguration(
+ vsync: this,
+ curve: Curves.easeOut,
+ duration: const Duration(milliseconds: 200),
+ );
+ } else {
+ _snapConfiguration = null;
+ }
+ }
+
+ void _updateStretchConfiguration() {
+ if (widget.stretch) {
+ _stretchConfiguration = OverScrollHeaderStretchConfiguration(
+ stretchTriggerOffset: widget.stretchTriggerOffset,
+ onStretchTrigger: widget.onStretchTrigger,
+ );
+ } else {
+ _stretchConfiguration = null;
+ }
+ }
+
+ @override
+ void initState() {
+ super.initState();
+ _updateSnapConfiguration();
+ _updateStretchConfiguration();
+ }
+
+ @override
+ void didUpdateWidget(SliverGFAppBar oldWidget) {
+ super.didUpdateWidget(oldWidget);
+ if (widget.snap != oldWidget.snap || widget.floating != oldWidget.floating)
+ _updateSnapConfiguration();
+ if (widget.stretch != oldWidget.stretch) _updateStretchConfiguration();
+ }
+
+ @override
+ Widget build(BuildContext context) {
+ assert(!widget.primary || debugCheckHasMediaQuery(context));
+ final double topPadding =
+ widget.primary ? MediaQuery.of(context).padding.top : 0.0;
+ final double collapsedHeight =
+ (widget.pinned && widget.floating && widget.bottom != null)
+ ? widget.bottom.preferredSize.height + topPadding
+ : null;
+
+ return MediaQuery.removePadding(
+ context: context,
+ removeBottom: true,
+ child: SliverPersistentHeader(
+ floating: widget.floating,
+ pinned: widget.pinned,
+ delegate: _SliverGFAppBarDelegate(
+ leading: widget.leading,
+ automaticallyImplyLeading: widget.automaticallyImplyLeading,
+ title: widget.title,
+ actions: widget.actions,
+ flexibleSpace: widget.flexibleSpace,
+ bottom: widget.bottom,
+ elevation: widget.elevation,
+ forceElevated: widget.forceElevated,
+ backgroundColor: widget.backgroundColor,
+ brightness: widget.brightness,
+ iconTheme: widget.iconTheme,
+ actionsIconTheme: widget.actionsIconTheme,
+ textTheme: widget.textTheme,
+ primary: widget.primary,
+ centerTitle: widget.centerTitle,
+ titleSpacing: widget.titleSpacing,
+ expandedHeight: widget.expandedHeight,
+ collapsedHeight: collapsedHeight,
+ topPadding: topPadding,
+ floating: widget.floating,
+ pinned: widget.pinned,
+ shape: widget.shape,
+ snapConfiguration: _snapConfiguration,
+ stretchConfiguration: _stretchConfiguration,
+ ),
+ ),
+ );
+ }
+}
+
+// Layout the GFAppBar's title with unconstrained height, vertically
+// center it within its (NavigationToolbar) parent, and allow the
+// parent to constrain the title's actual height.
+class _GFAppBarTitleBox extends SingleChildRenderObjectWidget {
+ const _GFAppBarTitleBox({Key key, @required Widget child})
+ : assert(child != null),
+ super(key: key, child: child);
+
+ @override
+ _RenderGFAppBarTitleBox createRenderObject(BuildContext context) {
+ return _RenderGFAppBarTitleBox(
+ textDirection: Directionality.of(context),
+ );
+ }
+
+ @override
+ void updateRenderObject(
+ BuildContext context, _RenderGFAppBarTitleBox renderObject) {
+ renderObject.textDirection = Directionality.of(context);
+ }
+}
+
+class _RenderGFAppBarTitleBox extends RenderAligningShiftedBox {
+ _RenderGFAppBarTitleBox({
+ RenderBox child,
+ TextDirection textDirection,
+ }) : super(
+ child: child,
+ alignment: Alignment.center,
+ textDirection: textDirection);
+
+ @override
+ void performLayout() {
+ final BoxConstraints innerConstraints =
+ constraints.copyWith(maxHeight: double.infinity);
+ child.layout(innerConstraints, parentUsesSize: true);
+ size = constraints.constrain(child.size);
+ alignChild();
+ }
+}
diff --git a/lib/components/avatar/gf_avatar.dart b/lib/components/avatar/gf_avatar.dart
index 3caae945..7cd3253b 100644
--- a/lib/components/avatar/gf_avatar.dart
+++ b/lib/components/avatar/gf_avatar.dart
@@ -1,17 +1,18 @@
import 'package:flutter/widgets.dart';
import 'package:flutter/material.dart';
-import 'package:ui_kit/shape/gf_shape.dart';
+import 'package:ui_kit/shape/gf_avatar_shape.dart';
import 'package:ui_kit/size/gf_size.dart';
+import 'package:ui_kit/colors/gf_color.dart';
class GFAvatar extends StatelessWidget {
/// Typically a [Text] widget. If the [CircleAvatar] is to have an image, use [backgroundImage] instead.
final Widget child;
- /// The color with which to fill the circle.
- final Color backgroundColor;
+ /// use [Color] or [GFColor]. The color with which to fill the circle.
+ final dynamic backgroundColor;
- /// The default text color for text in the circle.
- final Color foregroundColor;
+ /// use [Color] or [GFColor]. The default text color for text in the circle.
+ final dynamic foregroundColor;
/// The background image of the circle.
final ImageProvider backgroundImage;
@@ -26,29 +27,19 @@ class GFAvatar extends StatelessWidget {
final double maxRadius;
/// size of avatar like [double] or [GFSize] i.e, 1.2, small, medium, large etc.
- final GFSize size;
+ final dynamic size;
- /// shape of avatar [GFShape] i.e, standard, pills, square
- final GFShape shape;
+ /// shape of avatar [GFAvatarShape] i.e, standard, circle, square
+ final GFAvatarShape shape;
/// border radius to give extra radius for avatar square or standard shape
+ /// Not applicable to circleshape
final BorderRadius borderRadius;
- // The default radius if nothing is specified.
- static const double _defaultRadius = 20.0;
-
- // The default radius if avater size GFSize.small selected.
- static const double _smallRadius = 16.0;
-
- // The default radius if avater size GFSize.large selected.
- static const double _largeRadius = 28.0;
-
- // The default min if only the max is specified.
- static const double _defaultMinRadius = 0.0;
-
- // The default max if only the min is specified.
- static const double _defaultMaxRadius = double.infinity;
+ // /// The default max if only the min is specified.
+ // static const double _defaultMaxRadius = double.infinity;
+ /// Create Avatar of all types i,e, square, circle, standard with different sizes.
const GFAvatar(
{Key key,
this.child,
@@ -59,49 +50,33 @@ class GFAvatar extends StatelessWidget {
this.minRadius,
this.maxRadius,
this.borderRadius,
- this.shape = GFShape.pills,
+ this.shape = GFAvatarShape.circle,
this.size = GFSize.medium})
: assert(radius == null || (minRadius == null && maxRadius == null)),
super(key: key);
double get _minDiameter {
if (radius == null && minRadius == null && maxRadius == null) {
- if (size == GFSize.medium) {
- return _defaultRadius * 2.0;
- } else if (size == GFSize.small) {
- return _smallRadius * 2.0;
- } else if (size == GFSize.large) {
- return _largeRadius * 2.0;
- } else {
- return _defaultRadius * 2.0;
- }
+ return getGFSize(size);
} else {
- return 2.0 * (radius ?? minRadius ?? _defaultMinRadius);
+ return 2.0 * (radius ?? minRadius ?? 0);
}
}
double get _maxDiameter {
if (radius == null && minRadius == null && maxRadius == null) {
- if (size == GFSize.medium) {
- return _defaultRadius * 2.0;
- } else if (size == GFSize.small) {
- return _smallRadius * 2.0;
- } else if (size == GFSize.large) {
- return _largeRadius * 2.0;
- } else {
- return _defaultRadius * 2.0;
- }
+ return getGFSize(size);
} else {
- return 2.0 * (radius ?? maxRadius ?? _defaultMaxRadius);
+ return 2.0 * (radius ?? maxRadius ?? 0);
}
}
BoxShape get _avatarShape {
- if (shape == GFShape.pills) {
+ if (shape == GFAvatarShape.circle) {
return BoxShape.circle;
- } else if (shape == GFShape.square) {
+ } else if (shape == GFAvatarShape.square) {
return BoxShape.rectangle;
- } else if (shape == GFShape.standard) {
+ } else if (shape == GFAvatarShape.standard) {
return BoxShape.rectangle;
} else {
return BoxShape.rectangle;
@@ -110,6 +85,8 @@ class GFAvatar extends StatelessWidget {
@override
Widget build(BuildContext context) {
+ Color backgroundColor = getGFColor(this.backgroundColor);
+ Color foregroundColor = getGFColor(this.foregroundColor);
assert(debugCheckHasMediaQuery(context));
final ThemeData theme = Theme.of(context);
TextStyle textStyle =
@@ -151,7 +128,7 @@ class GFAvatar extends StatelessWidget {
? DecorationImage(image: backgroundImage, fit: BoxFit.cover)
: null,
shape: _avatarShape,
- borderRadius: shape == GFShape.standard && borderRadius == null
+ borderRadius: shape == GFAvatarShape.standard && borderRadius == null
? BorderRadius.circular(10.0)
: borderRadius,
),
diff --git a/lib/components/badge/gf_badge.dart b/lib/components/badge/gf_badge.dart
index 2335d6e9..ed667b1b 100644
--- a/lib/components/badge/gf_badge.dart
+++ b/lib/components/badge/gf_badge.dart
@@ -1,5 +1,5 @@
import 'package:flutter/material.dart';
-import 'package:ui_kit/shape/gf_shape.dart';
+import 'package:ui_kit/shape/gf_badge_shape.dart';
import 'package:ui_kit/size/gf_size.dart';
import 'package:ui_kit/colors/gf_color.dart';
@@ -10,8 +10,8 @@ class GFBadge extends StatefulWidget {
/// Typically the counter button's shape.
final ShapeBorder borderShape;
- /// Counter type of [GFShape] i.e, standard, pills, square,
- final GFShape shape;
+ /// Counter type of [GFBadgeShape] i.e, standard, pills, square,
+ final GFBadgeShape shape;
/// Pass [GFColor] or [Color]
final dynamic color;
@@ -19,26 +19,26 @@ class GFBadge extends StatefulWidget {
/// size of [double] or [GFSize] i.e, 1.2, small, medium, large etc.
final GFSize size;
- /// text of type [String] is alternative to child. text will get priority over child
+ /// child of type [Widget] is alternative to child. text will get priority over child
final Widget child;
/// text of type [String] is alternative to child. text will get priority over child
final String text;
- /// text style of counter text
+ /// text style of counter text.
final TextStyle textStyle;
/// Pass [GFColor] or [Color]
final dynamic textColor;
- /// Create badges of all types, check out [GFButtonBadge] for button badges and [GFIconBadge] for icon badges
+ /// Create badges of all types, check out [GFButtonBadge] for button badges and [GFIconBadge] for icon type badges
const GFBadge({
Key key,
this.textStyle,
this.borderShape,
- this.shape = GFShape.standard,
- this.color = GFColor.secondary,
- this.textColor = GFColor.dark,
+ this.shape = GFBadgeShape.standard,
+ this.color = GFColor.danger,
+ this.textColor = GFColor.white,
this.size = GFSize.medium,
this.border,
this.text,
@@ -54,7 +54,7 @@ class _GFBadgeState extends State {
Color color;
Color textColor;
Widget child;
- GFShape counterShape;
+ GFBadgeShape counterShape;
GFSize size;
double height;
double width;
@@ -64,7 +64,7 @@ class _GFBadgeState extends State {
void initState() {
this.color = getGFColor(widget.color);
this.textColor = getGFColor(widget.textColor);
- this.child = widget.child == null ? Text(widget.text) : widget.child;
+ this.child = widget.text != null ? Text(widget.text ?? '') : widget.child;
this.counterShape = widget.shape;
this.size = widget.size;
super.initState();
@@ -81,16 +81,16 @@ class _GFBadgeState extends State {
ShapeBorder shape;
- if (this.counterShape == GFShape.pills) {
+ if (this.counterShape == GFBadgeShape.pills) {
shape = RoundedRectangleBorder(
borderRadius: BorderRadius.circular(50.0), side: shapeBorder);
- } else if (this.counterShape == GFShape.square) {
+ } else if (this.counterShape == GFBadgeShape.square) {
shape = RoundedRectangleBorder(
borderRadius: BorderRadius.circular(0.0), side: shapeBorder);
- } else if (this.counterShape == GFShape.standard) {
+ } else if (this.counterShape == GFBadgeShape.standard) {
shape = RoundedRectangleBorder(
borderRadius: BorderRadius.circular(5.0), side: shapeBorder);
- } else if (this.counterShape == GFShape.circle) {
+ } else if (this.counterShape == GFBadgeShape.circle) {
shape = RoundedRectangleBorder(
borderRadius: BorderRadius.circular(100.0), side: shapeBorder);
} else {
@@ -99,26 +99,28 @@ class _GFBadgeState extends State {
}
if (this.size == GFSize.small) {
- this.height = 18.0;
- this.width = 24.0;
- this.fontSize = 10.0;
+ this.height = getGFSize(this.size) * 0.56;
+ this.width = getGFSize(this.size) * 0.75;
+ this.fontSize = getGFSize(this.size) * 0.31;
} else if (this.size == GFSize.medium) {
- this.height = 20.0;
- this.width = 26.0;
+ this.height = getGFSize(this.size) * 0.5;
+ this.width = getGFSize(this.size) * 0.65;
+ this.fontSize = getGFSize(this.size) * 0.3;
this.fontSize = 12.0;
} else if (this.size == GFSize.large) {
- this.height = 24.0;
- this.width = 30.0;
- this.fontSize = 12.0;
+ this.height = getGFSize(this.size) * 0.428;
+ this.width = getGFSize(this.size) * 0.535;
+ this.fontSize = getGFSize(this.size) * 0.214;
} else {
- this.height = 20.0;
- this.width = 26.0;
- this.fontSize = 12.0;
+ this.height = getGFSize(this.size) * 0.56;
+ this.width = getGFSize(this.size) * 0.75;
+ this.fontSize = getGFSize(this.size) * 0.31;
}
return Container(
height: this.height,
- width: this.counterShape == GFShape.circle ? this.height : this.width,
+ width:
+ this.counterShape == GFBadgeShape.circle ? this.height : this.width,
child: Material(
textStyle: this.textColor != null
? TextStyle(color: this.textColor, fontSize: this.fontSize)
diff --git a/lib/components/badge/gf_button_badge.dart b/lib/components/badge/gf_button_badge.dart
index 7d706fa3..0925bc51 100644
--- a/lib/components/badge/gf_button_badge.dart
+++ b/lib/components/badge/gf_button_badge.dart
@@ -1,5 +1,6 @@
import 'package:flutter/material.dart';
-import 'package:ui_kit/shape/gf_shape.dart';
+import 'package:ui_kit/shape/gf_badge_shape.dart';
+import 'package:ui_kit/shape/gf_button_shape.dart';
import 'package:ui_kit/size/gf_size.dart';
import 'package:ui_kit/types/gf_type.dart';
import 'package:ui_kit/position/gf_position.dart';
@@ -25,8 +26,8 @@ class GFButtonBadge extends StatefulWidget {
/// Badge type of [GFType] i.e, solid, outline, transparent
final GFType type;
- /// Badge type of [GFShape] i.e, standard, pills, square
- final GFShape shape;
+ /// Badge type of [GFBadgeShape] i.e, standard, pills, square, circle
+ final GFButtonShape shape;
/// Pass [GFColor] or [Color]
final dynamic color;
@@ -37,10 +38,11 @@ class GFButtonBadge extends StatefulWidget {
/// size of [double] or [GFSize] i.e, 1.2, small, medium, large etc.
final dynamic size;
- /// text of type [String] is alternative to child. text will get priority over child
+ /// text of type [String] is used to display text on the button.
final String text;
- /// text of type [String] is alternative to child. text will get priority over child
+ /// child of type [Widget] is alternative to child. text will get priority over child.
+ /// You can use [GFBadge] for compatibility.
final Widget counterChild;
/// icon type of [GFPosition] i.e, start, end
@@ -54,9 +56,9 @@ class GFButtonBadge extends StatefulWidget {
this.padding = const EdgeInsets.symmetric(horizontal: 8.0),
this.borderShape,
this.type = GFType.solid,
- this.shape = GFShape.standard,
+ this.shape = GFButtonShape.standard,
this.color = GFColor.primary,
- this.textColor = GFColor.dark,
+ this.textColor,
this.position = GFPosition.end,
this.size = GFSize.medium,
this.borderSide,
@@ -77,14 +79,18 @@ class _GFButtonBadgeState extends State {
Widget icon;
Function onPressed;
GFType type;
- GFShape shape;
+ GFButtonShape shape;
double size;
GFPosition position;
@override
void initState() {
this.color = getGFColor(widget.color);
- this.textColor = getGFColor(widget.textColor);
+ this.textColor = (widget.type == GFType.outline && widget.textColor == null)
+ ? this.color
+ : widget.textColor == null
+ ? getGFColor(GFColor.dark)
+ : getGFColor(widget.textColor);
this.onPressed = widget.onPressed;
this.type = widget.type;
this.shape = widget.shape;
@@ -100,19 +106,19 @@ class _GFButtonBadgeState extends State {
child: Container(
height: this.size,
child: GFButton(
- textStyle: widget.textStyle,
- borderSide: widget.borderSide,
- color: this.color,
- textColor: this.textColor,
- text: widget.text,
- onPressed: this.onPressed,
- type: this.type,
- shape: this.shape,
- position: this.position,
- size: this.size,
- borderShape: widget.borderShape,
- icon: widget.counterChild
- ),
+ textStyle: widget.textStyle,
+ borderSide: widget.borderSide,
+ color: this.color,
+ textColor: this.textColor,
+ text: widget.text,
+ onPressed: this.onPressed,
+ type: this.type,
+ shape: this.shape,
+ position: this.position,
+ size: this.size,
+ borderShape: widget.borderShape,
+ icon: widget.counterChild,
+ ),
),
);
}
diff --git a/lib/components/badge/gf_icon_badge.dart b/lib/components/badge/gf_icon_badge.dart
index 3f566d3c..88f9a269 100644
--- a/lib/components/badge/gf_icon_badge.dart
+++ b/lib/components/badge/gf_icon_badge.dart
@@ -1,23 +1,23 @@
import 'package:flutter/material.dart';
-import 'package:ui_kit/shape/gf_shape.dart';
-import 'package:ui_kit/types/gf_type.dart';
-import 'package:ui_kit/position/gf_position.dart';
+import 'package:ui_kit/components/button/gf_icon_button.dart';
-class GFIconBadges extends StatefulWidget {
+class GFIconBadge extends StatefulWidget {
/// Called when the badge is tapped or otherwise activated.
final VoidCallback onPressed;
- /// text of type [String] is alternative to child. text will get priority over child
- final Widget child;
+ /// child of type [GFIconButton] is used to show icon.
+ /// Use [Icon] widget for compatibility.
+ final GFIconButton child;
- /// text of type [String] is alternative to child. text will get priority over child
+ /// widget of type [Widget] is used to show counter to the top right corner of child.
+ /// You can use [GFBadge] for compatibility.
final Widget counterChild;
/// The internal padding for the badge's [child].
final EdgeInsetsGeometry padding;
/// Create badges of all types, check out [GFBadge] for button badges and [GFIconBadge] for icon badges.
- const GFIconBadges({
+ const GFIconBadge({
Key key,
@required this.onPressed,
this.padding = const EdgeInsets.symmetric(horizontal: 8.0),
@@ -27,19 +27,10 @@ class GFIconBadges extends StatefulWidget {
super(key: key);
@override
- _GFIconBadgesState createState() => _GFIconBadgesState();
+ _GFIconBadgeState createState() => _GFIconBadgeState();
}
-class _GFIconBadgesState extends State {
- Color badgeColor, counterColor;
- Color textColor;
- Widget child;
- Widget icon;
- Function onPressed;
- GFType type;
- GFShape shape;
- GFPosition position;
-
+class _GFIconBadgeState extends State {
@override
void initState() {
super.initState();
@@ -50,13 +41,14 @@ class _GFIconBadgesState extends State {
return Container(
height: 60.0,
width: 60.0,
+ padding: widget.padding,
child: Stack(
children: [
- widget.child,
+ widget.child ?? Container(),
new Positioned(
top: 2,
left: 22,
- child: widget.counterChild,
+ child: widget.counterChild ?? Container(),
),
],
),
diff --git a/lib/components/button/gf_button.dart b/lib/components/button/gf_button.dart
index 58a86555..8b27863e 100644
--- a/lib/components/button/gf_button.dart
+++ b/lib/components/button/gf_button.dart
@@ -4,13 +4,12 @@ import 'package:flutter/gestures.dart';
import 'package:flutter/rendering.dart';
import 'package:flutter/widgets.dart';
import 'package:flutter/material.dart';
-import 'package:ui_kit/shape/gf_shape.dart';
+import 'package:ui_kit/shape/gf_button_shape.dart';
import 'package:ui_kit/size/gf_size.dart';
import 'package:ui_kit/types/gf_type.dart';
import 'package:ui_kit/position/gf_position.dart';
import 'package:ui_kit/colors/gf_color.dart';
-
class GFButton extends StatefulWidget {
/// Called when the button is tapped or otherwise activated.
final VoidCallback onPressed;
@@ -27,17 +26,17 @@ class GFButton extends StatefulWidget {
/// The box shadow for the button's [Material].
final BoxShadow boxShadow;
- /// The color for the button's [Material] when it has the input focus.
- final Color focusColor;
+ /// Pass [GFColor] or [Color]. The color for the button's [Material] when it has the input focus.
+ final dynamic focusColor;
- /// The color for the button's [Material] when a pointer is hovering over it.
- final Color hoverColor;
+ /// Pass [GFColor] or [Color]. The color for the button's [Material] when a pointer is hovering over it.
+ final dynamic hoverColor;
- /// The highlight color for the button's [InkWell].
- final Color highlightColor;
+ /// Pass [GFColor] or [Color]. The highlight color for the button's [InkWell].
+ final dynamic highlightColor;
- /// The splash color for the button's [InkWell].
- final Color splashColor;
+ /// Pass [GFColor] or [Color]. The splash color for the button's [InkWell].
+ final dynamic splashColor;
/// The elevation for the button's [Material] when the button is [enabled] but not pressed.
final double elevation;
@@ -87,8 +86,8 @@ class GFButton extends StatefulWidget {
/// Button type of [GFType] i.e, solid, outline, dashed
final GFType type;
- /// Button type of [GFShape] i.e, standard, pills, square, shadow, icons
- final GFShape shape;
+ /// Button type of [GFButtonShape] i.e, standard, pills, square, shadow, icons
+ final GFButtonShape shape;
/// Pass [GFColor] or [Color]
final dynamic color;
@@ -149,47 +148,47 @@ class GFButton extends StatefulWidget {
final VoidCallback onLongPress;
/// Create buttons of all types. check out [GFIconButton] for icon buttons, and [GFBadge] for badges
- const GFButton({
- Key key,
- @required this.onPressed,
- this.onHighlightChanged,
- this.textStyle,
- this.boxShadow,
- this.buttonBoxShadow,
- this.focusColor,
- this.hoverColor,
- this.highlightColor,
- this.splashColor,
- this.elevation = 2.0,
- this.focusElevation = 4.0,
- this.hoverElevation = 4.0,
- this.highlightElevation = 1.0,
- this.disabledElevation = 0.0,
- this.padding = const EdgeInsets.symmetric(horizontal: 8.0),
- this.constraints,
- this.borderShape,
- this.animationDuration = kThemeChangeDuration,
- this.clipBehavior = Clip.none,
- this.focusNode,
- this.autofocus = false,
- MaterialTapTargetSize materialTapTargetSize,
- this.child,
- this.type = GFType.solid,
- this.shape = GFShape.standard,
- this.color = GFColor.primary,
- this.textColor = GFColor.dark,
- this.position = GFPosition.start,
- this.size = GFSize.medium,
- this.borderSide,
- this.text,
- this.icon,
- this.blockButton,
- this.fullWidthButton,
- this.colorScheme,
- this.enableFeedback,
- this.onLongPress
- }) : materialTapTargetSize =
- materialTapTargetSize ?? MaterialTapTargetSize.padded,
+ const GFButton(
+ {Key key,
+ @required this.onPressed,
+ this.onHighlightChanged,
+ this.textStyle,
+ this.boxShadow,
+ this.buttonBoxShadow,
+ this.focusColor,
+ this.hoverColor,
+ this.highlightColor,
+ this.splashColor,
+ this.elevation = 2.0,
+ this.focusElevation = 4.0,
+ this.hoverElevation = 4.0,
+ this.highlightElevation = 1.0,
+ this.disabledElevation = 0.0,
+ this.padding = const EdgeInsets.symmetric(horizontal: 8.0),
+ this.constraints,
+ this.borderShape,
+ this.animationDuration = kThemeChangeDuration,
+ this.clipBehavior = Clip.none,
+ this.focusNode,
+ this.autofocus = false,
+ MaterialTapTargetSize materialTapTargetSize,
+ this.child,
+ this.type = GFType.solid,
+ this.shape = GFButtonShape.standard,
+ this.color = GFColor.primary,
+ this.textColor,
+ this.position = GFPosition.start,
+ this.size = GFSize.medium,
+ this.borderSide,
+ this.text,
+ this.icon,
+ this.blockButton,
+ this.fullWidthButton,
+ this.colorScheme,
+ this.enableFeedback,
+ this.onLongPress})
+ : materialTapTargetSize =
+ materialTapTargetSize ?? MaterialTapTargetSize.padded,
assert(shape != null, 'Button shape can not be null'),
assert(elevation != null && elevation >= 0.0),
assert(focusElevation != null && focusElevation >= 0.0),
@@ -213,16 +212,21 @@ class _GFButtonState extends State {
Widget icon;
Function onPressed;
GFType type;
- GFShape shape;
+ GFButtonShape shape;
double size;
GFPosition position;
BoxShadow boxShadow;
+
final Set _states = {};
@override
void initState() {
this.color = getGFColor(widget.color);
- this.textColor = getGFColor(widget.textColor);
+ this.textColor = widget.type == GFType.outline && widget.textColor == null
+ ? this.color
+ : widget.textColor == null
+ ? getGFColor(GFColor.dark)
+ : getGFColor(widget.textColor);
this.child = widget.text != null ? Text(widget.text) : widget.child;
this.icon = widget.icon;
this.onPressed = widget.onPressed;
@@ -230,28 +234,21 @@ class _GFButtonState extends State {
this.shape = widget.shape;
this.size = getGFSize(widget.size);
this.position = widget.position;
+
_updateState(MaterialState.disabled, !widget.enabled);
super.initState();
}
bool get _hovered => _states.contains(MaterialState.hovered);
- bool get _focused => _states.contains(MaterialState.focused);
+ // bool get _focused => _states.contains(MaterialState.focused);
bool get _pressed => _states.contains(MaterialState.pressed);
bool get _disabled => _states.contains(MaterialState.disabled);
- double blockWidth(context) {
- return MediaQuery.of(context).size.width * 0.88;
- }
-
- double fullWidth(context) {
- return MediaQuery.of(context).size.width;
- }
-
double buttonWidth() {
if (widget.blockButton == true) {
- return blockWidth(context);
+ return MediaQuery.of(context).size.width * 0.88;
} else if (widget.fullWidthButton == true) {
- return fullWidth(context);
+ return MediaQuery.of(context).size.width;
} else {
return null;
}
@@ -280,13 +277,13 @@ class _GFButtonState extends State {
}
}
- void _handleFocusedChanged(bool value) {
- if (_focused != value) {
- setState(() {
- _updateState(MaterialState.focused, value);
- });
- }
- }
+ // void _handleFocusedChanged(bool value) {
+ // if (_focused != value) {
+ // setState(() {
+ // _updateState(MaterialState.focused, value);
+ // });
+ // }
+ // }
@override
void didUpdateWidget(GFButton oldWidget) {
@@ -301,39 +298,18 @@ class _GFButtonState extends State {
super.didUpdateWidget(oldWidget);
}
-
- double get _effectiveElevation {
- // These conditionals are in order of precedence, so be careful about
- // reorganizing them.
- if (_disabled) {
- return widget.disabledElevation;
- }
- if (_pressed) {
- return widget.highlightElevation;
- }
- if (_hovered) {
- return widget.hoverElevation;
- }
- if (_focused) {
- return widget.focusElevation;
- }
- return widget.elevation;
- }
-
-
@override
Widget build(BuildContext context) {
-
ShapeBorder shape;
- final ShapeBorder effectiveShape = MaterialStateProperty.resolveAs(shape, _states);
-
final Color effectiveTextColor = MaterialStateProperty.resolveAs(
widget.textStyle?.color, _states);
final Color themeColor =
- Theme.of(context).colorScheme.onSurface.withOpacity(0.12);
+ Theme.of(context).colorScheme.onSurface.withOpacity(0.12);
final BorderSide outlineBorder = BorderSide(
- color: widget.borderSide == null ? themeColor : widget.borderSide.color,
+ color: this.color == null
+ ? themeColor
+ : widget.borderSide == null ? this.color : widget.borderSide.color,
width: widget.borderSide?.width ?? 1.0,
);
@@ -353,21 +329,19 @@ class _GFButtonState extends State {
final BorderSide shapeBorder = widget.type == GFType.outline
? outlineBorder
: widget.borderSide != null
- ? widget.borderSide
- : BorderSide(
- color: this.color == null ? themeColor : this.color,
- width: 0.0,
- );
+ ? widget.borderSide
+ : BorderSide(
+ color: this.color == null ? themeColor : this.color,
+ width: 0.0,
+ );
-
-
- if (this.shape == GFShape.pills) {
+ if (this.shape == GFButtonShape.pills) {
shape = RoundedRectangleBorder(
borderRadius: BorderRadius.circular(50.0), side: shapeBorder);
- } else if (this.shape == GFShape.square) {
+ } else if (this.shape == GFButtonShape.square) {
shape = RoundedRectangleBorder(
borderRadius: BorderRadius.circular(0.0), side: shapeBorder);
- } else if (this.shape == GFShape.standard) {
+ } else if (this.shape == GFButtonShape.standard) {
shape = RoundedRectangleBorder(
borderRadius: BorderRadius.circular(5.0), side: shapeBorder);
} else {
@@ -376,87 +350,106 @@ class _GFButtonState extends State {
}
BoxDecoration getBoxShadow() {
- if(widget.type != GFType.transparent){
- if(widget.boxShadow == null && widget.buttonBoxShadow != true){
+ if (widget.type != GFType.transparent) {
+ if (widget.boxShadow == null && widget.buttonBoxShadow != true) {
return null;
- }else{
+ } else {
return BoxDecoration(
- color: widget.type == GFType.transparent || widget.type == GFType.outline ? Colors.transparent : this.color,
- borderRadius: widget.shape == GFShape.pills ? BorderRadius.circular(50.0) :
- widget.shape == GFShape.standard ? BorderRadius.circular(5.0) : BorderRadius.zero,
+ color: widget.type == GFType.transparent ||
+ widget.type == GFType.outline
+ ? Colors.transparent
+ : this.color,
+ borderRadius: widget.shape == GFButtonShape.pills
+ ? BorderRadius.circular(50.0)
+ : widget.shape == GFButtonShape.standard
+ ? BorderRadius.circular(5.0)
+ : BorderRadius.zero,
boxShadow: [
- widget.boxShadow == null && widget.buttonBoxShadow == true ? BoxShadow(
- color: themeColor,
- blurRadius: 1.5,
- spreadRadius: 2.0,
- offset: Offset.zero,
- ) :
- widget.boxShadow != null ? widget.boxShadow :
- BoxShadow(
- color: Theme.of(context).canvasColor,
- blurRadius: 0.0,
- spreadRadius: 0.0,
- offset: Offset.zero,
- )
- ]
- );
+ widget.boxShadow == null && widget.buttonBoxShadow == true
+ ? BoxShadow(
+ color: themeColor,
+ blurRadius: 1.5,
+ spreadRadius: 2.0,
+ offset: Offset.zero,
+ )
+ : widget.boxShadow != null
+ ? widget.boxShadow
+ : BoxShadow(
+ color: Theme.of(context).canvasColor,
+ blurRadius: 0.0,
+ spreadRadius: 0.0,
+ offset: Offset.zero,
+ ),
+ ]);
}
}
+ return null;
}
-
final Widget result = Container(
- constraints: this.icon == null ? BoxConstraints(minHeight: 26.0, minWidth: 88.0) :
- BoxConstraints(minHeight: 26.0, minWidth: 98.0),
+ constraints: this.icon == null
+ ? BoxConstraints(minHeight: 26.0, minWidth: 88.0)
+ : BoxConstraints(minHeight: 26.0, minWidth: 98.0),
decoration: getBoxShadow(),
child: Material(
- elevation: _effectiveElevation,
- textStyle: widget.textStyle == null ? TextStyle(color: this.textColor, fontSize: 14) : widget.textStyle,
- shape: widget.type == GFType.transparent ? null : widget.borderShape == null ? shape : widget.borderShape,
- color: widget.type == GFType.transparent || widget.type == GFType.outline ? Colors.transparent : this.color,
- type: this.color == null ? MaterialType.transparency : MaterialType.button,
+ textStyle: widget.textStyle == null
+ ? TextStyle(color: this.textColor, fontSize: 14)
+ : widget.textStyle,
+ shape: widget.type == GFType.transparent
+ ? null
+ : widget.borderShape == null ? shape : widget.borderShape,
+ color:
+ widget.type == GFType.transparent || widget.type == GFType.outline
+ ? Colors.transparent
+ : this.color,
+ type: this.color == null
+ ? MaterialType.transparency
+ : MaterialType.button,
animationDuration: widget.animationDuration,
clipBehavior: widget.clipBehavior,
child: InkWell(
onHighlightChanged: _handleHighlightChanged,
- splashColor: widget.splashColor,
- highlightColor: widget.highlightColor,
- focusColor: widget.focusColor,
- hoverColor: widget.hoverColor,
+ splashColor: getGFColor(widget.splashColor),
+ highlightColor: getGFColor(widget.highlightColor),
+ focusColor: getGFColor(widget.focusColor),
+ hoverColor: getGFColor(widget.hoverColor),
onHover: _handleHoveredChanged,
onTap: widget.onPressed,
- customBorder: widget.type == GFType.transparent ? null : widget.borderShape == null ? shape : widget.borderShape,
+ customBorder: widget.type == GFType.transparent
+ ? null
+ : widget.borderShape == null ? shape : widget.borderShape,
child: IconTheme.merge(
data: IconThemeData(color: effectiveTextColor),
child: Container(
- height: widget.blockButton == true ? BLOCK
- : widget.fullWidthButton == true ? BLOCK
- : this.size,
+ height: widget.blockButton == true
+ ? BLOCK
+ : widget.fullWidthButton == true ? BLOCK : this.size,
width: buttonWidth(),
padding: widget.padding,
child: Center(
widthFactor: 1.0,
heightFactor: 1.0,
- child: this.icon != null && (this.position == GFPosition.start || this.position == null)?
- Row(
- mainAxisSize: MainAxisSize.min,
- children: [
- this.icon,
- const SizedBox(width: 8.0),
- this.child
- ],
- )
- : this.icon != null &&
- (this.position == GFPosition.end)
+ child: this.icon != null &&
+ (this.position == GFPosition.start ||
+ this.position == null)
? Row(
- mainAxisSize: MainAxisSize.min,
- children: [
- this.child,
- const SizedBox(width: 8.0),
- this.icon
- ],
- )
- : this.child,
+ mainAxisSize: MainAxisSize.min,
+ children: [
+ this.icon,
+ const SizedBox(width: 8.0),
+ this.child
+ ],
+ )
+ : this.icon != null && (this.position == GFPosition.end)
+ ? Row(
+ mainAxisSize: MainAxisSize.min,
+ children: [
+ this.child,
+ const SizedBox(width: 8.0),
+ this.icon
+ ],
+ )
+ : this.child,
),
),
),
@@ -511,7 +504,8 @@ class _InputPadding extends SingleChildRenderObjectWidget {
}
@override
- void updateRenderObject(BuildContext context, covariant _RenderInputPadding renderObject) {
+ void updateRenderObject(
+ BuildContext context, covariant _RenderInputPadding renderObject) {
renderObject.minSize = minSize;
}
}
@@ -522,8 +516,7 @@ class _RenderInputPadding extends RenderShiftedBox {
Size get minSize => _minSize;
Size _minSize;
set minSize(Size value) {
- if (_minSize == value)
- return;
+ if (_minSize == value) return;
_minSize = value;
markNeedsLayout();
}
@@ -571,7 +564,7 @@ class _RenderInputPadding extends RenderShiftedBox {
}
@override
- bool hitTest(BoxHitTestResult result, { Offset position }) {
+ bool hitTest(BoxHitTestResult result, {Offset position}) {
if (super.hitTest(result, position: position)) {
return true;
}
@@ -586,545 +579,3 @@ class _RenderInputPadding extends RenderShiftedBox {
);
}
}
-
-
-
-//class GFButton extends StatefulWidget {
-// /// Called when the button is tapped or otherwise activated.
-// final VoidCallback onPressed;
-//
-// /// Called by the underlying [InkWell] widget's [InkWell.onHighlightChanged] callback.
-// final ValueChanged onHighlightChanged;
-//
-// /// Defines the default text style, with [Material.textStyle], for the button's [child].
-// final TextStyle textStyle;
-//
-// /// The border side for the button's [Material].
-// final BorderSide borderSide;
-//
-// /// The box shadow for the button's [Material].
-// final BoxShadow boxShadow;
-//
-// /// The color for the button's [Material] when it has the input focus.
-// final Color focusColor;
-//
-// /// The color for the button's [Material] when a pointer is hovering over it.
-// final Color hoverColor;
-//
-// /// The highlight color for the button's [InkWell].
-// final Color highlightColor;
-//
-// /// The splash color for the button's [InkWell].
-// final Color splashColor;
-//
-// /// The elevation for the button's [Material] when the button is [enabled] but not pressed.
-// final double elevation;
-//
-// /// The elevation for the button's [Material] when the button is [enabled] and a pointer is hovering over it.
-// final double hoverElevation;
-//
-// /// The elevation for the button's [Material] when the button is [enabled] and has the input focus.
-// final double focusElevation;
-//
-// /// The elevation for the button's [Material] when the button is [enabled] and pressed.
-// final double highlightElevation;
-//
-// /// The elevation for the button's [Material] when the button is not [enabled].
-// final double disabledElevation;
-//
-// /// The internal padding for the button's [child].
-// final EdgeInsetsGeometry padding;
-//
-// /// Defines the button's size.
-// final BoxConstraints constraints;
-//
-// /// The shape of the button's [Material].
-// final ShapeBorder borderShape;
-//
-// /// Defines the duration of animated changes for [shape] and [elevation].
-// final Duration animationDuration;
-//
-// /// Typically the button's label.
-// final Widget child;
-//
-// /// Whether the button is enabled or disabled.
-// bool get enabled => onPressed != null;
-//
-// /// Configures the minimum size of the tap target.
-// final MaterialTapTargetSize materialTapTargetSize;
-//
-// /// {@macro flutter.widgets.Focus.focusNode}
-// final FocusNode focusNode;
-//
-// /// {@macro flutter.widgets.Focus.autofocus}
-// final bool autofocus;
-//
-// /// {@macro flutter.widgets.Clip}
-// final Clip clipBehavior;
-//
-// /// Button type of [GFType] i.e, solid, outline, dashed
-// final GFType type;
-//
-// /// Button type of [GFShape] i.e, standard, pills, square, shadow, icons
-// final GFShape shape;
-//
-// /// Pass [GFColor] or [Color]
-// final dynamic color;
-//
-// /// Pass [GFColor] or [Color]
-// final dynamic textColor;
-//
-// /// size of [double] or [GFSize] i.e, 1.2, small, medium, large etc.
-// final dynamic size;
-//
-// /// text of type [String] is alternative to child. text will get priority over child
-// final String text;
-//
-// /// icon of type [Widget]
-// final Widget icon;
-//
-// /// icon type of [GFIconPosition] i.e, start, end
-// final GFPosition position;
-//
-// /// on true state blockButton gives block size button
-// final bool blockButton;
-//
-// /// on true state full width Button gives full width button
-// final bool fullWidthButton;
-//
-// /// on true state default box shadow appears around button
-// final bool buttonBoxShadow;
-//
-// /// A set of thirteen colors that can be used to derive the button theme's
-// /// colors.
-// ///
-// /// This property was added much later than the theme's set of highly
-// /// specific colors, like [ThemeData.buttonColor], [ThemeData.highlightColor],
-// /// [ThemeData.splashColor] etc.
-// ///
-// /// The colors for new button classes can be defined exclusively in terms
-// /// of [colorScheme]. When it's possible, the existing buttons will
-// /// (continue to) gradually migrate to it.
-// final ColorScheme colorScheme;
-//
-// /// Create buttons of all types. check out [GFIconButton] for icon buttons, and [GFBadge] for badges
-// const GFButton({
-// Key key,
-// @required this.onPressed,
-// this.onHighlightChanged,
-// this.textStyle,
-// this.boxShadow,
-// this.buttonBoxShadow,
-// this.focusColor,
-// this.hoverColor,
-// this.highlightColor,
-// this.splashColor,
-// this.elevation = 2.0,
-// this.focusElevation = 4.0,
-// this.hoverElevation = 4.0,
-// this.highlightElevation = 1.0,
-// this.disabledElevation = 0.0,
-// this.padding = const EdgeInsets.symmetric(horizontal: 8.0),
-// this.constraints,
-// this.borderShape,
-// this.animationDuration = kThemeChangeDuration,
-// this.clipBehavior = Clip.none,
-// this.focusNode,
-// this.autofocus = false,
-// MaterialTapTargetSize materialTapTargetSize,
-// this.child,
-// this.type,
-// this.shape = GFShape.standard,
-// this.color,
-// this.textColor = GFColor.dark,
-// this.position = GFPosition.start,
-// this.size = GFSize.medium,
-// this.borderSide,
-// this.text,
-// this.icon,
-// this.blockButton,
-// this.fullWidthButton,
-// this.colorScheme,
-// }) : materialTapTargetSize =
-// materialTapTargetSize ?? MaterialTapTargetSize.padded,
-// assert(shape != null, 'Button shape can not be null'),
-// assert(elevation != null && elevation >= 0.0),
-// assert(focusElevation != null && focusElevation >= 0.0),
-// assert(hoverElevation != null && hoverElevation >= 0.0),
-// assert(highlightElevation != null && highlightElevation >= 0.0),
-// assert(disabledElevation != null && disabledElevation >= 0.0),
-// assert(padding != null),
-// assert(animationDuration != null),
-// assert(clipBehavior != null),
-// assert(autofocus != null),
-// super(key: key);
-//
-// @override
-// _GFButtonState createState() => _GFButtonState();
-//}
-//
-//class _GFButtonState extends State {
-//// Color color;
-// Color textColor;
-// Widget child;
-// Widget icon;
-// Function onPressed;
-// GFType type;
-// GFShape shape;
-// double size;
-// GFPosition position;
-// BoxShadow boxShadow;
-// final Set _states = {};
-//
-// @override
-// void initState() {
-//// this.color = getGFColor(widget.color);
-// this.textColor = getGFColor(widget.textColor);
-// this.child = widget.text != null ? Text(widget.text) : widget.child;
-// this.icon = widget.icon;
-// this.onPressed = widget.onPressed;
-// this.type = widget.type;
-// this.shape = widget.shape;
-// this.size = getGFSize(widget.size);
-// this.position = widget.position;
-// _updateState(MaterialState.disabled, !widget.enabled);
-// super.initState();
-// }
-//
-// bool get _hovered => _states.contains(MaterialState.hovered);
-// bool get _focused => _states.contains(MaterialState.focused);
-// bool get _pressed => _states.contains(MaterialState.pressed);
-// bool get _disabled => _states.contains(MaterialState.disabled);
-//
-// double blockWidth(context) {
-// return MediaQuery.of(context).size.width * 0.88;
-// }
-//
-// double fullWidth(context) {
-// return MediaQuery.of(context).size.width;
-// }
-//
-// double buttonWidth() {
-// if (widget.blockButton == true) {
-// return blockWidth(context);
-// } else if (widget.fullWidthButton == true) {
-// return fullWidth(context);
-// } else {
-// return null;
-// }
-// }
-//
-// void _updateState(MaterialState state, bool value) {
-// value ? _states.add(state) : _states.remove(state);
-// }
-//
-// void _handleHighlightChanged(bool value) {
-// if (_pressed != value) {
-// setState(() {
-// _updateState(MaterialState.pressed, value);
-// if (widget.onHighlightChanged != null) {
-// widget.onHighlightChanged(value);
-// }
-// });
-// }
-// }
-//
-// void _handleHoveredChanged(bool value) {
-// if (_hovered != value) {
-// setState(() {
-// _updateState(MaterialState.hovered, value);
-// });
-// }
-// }
-//
-// void _handleFocusedChanged(bool value) {
-// if (_focused != value) {
-// setState(() {
-// _updateState(MaterialState.focused, value);
-// });
-// }
-// }
-//
-// @override
-// void didUpdateWidget(GFButton oldWidget) {
-// _updateState(MaterialState.disabled, !widget.enabled);
-// // If the button is disabled while a press gesture is currently ongoing,
-// // InkWell makes a call to handleHighlightChanged. This causes an exception
-// // because it calls setState in the middle of a build. To preempt this, we
-// // manually update pressed to false when this situation occurs.
-// if (_disabled && _pressed) {
-// _handleHighlightChanged(false);
-// }
-// super.didUpdateWidget(oldWidget);
-// }
-//
-// // double get _effectiveElevation {
-// // // These conditionals are in order of precedence, so be careful about
-// // // reorganizing them.
-// // if (_disabled) {
-// // return widget.disabledElevation;
-// // }
-// // if (_pressed) {
-// // return widget.highlightElevation;
-// // }
-// // if (_hovered) {
-// // return widget.hoverElevation;
-// // }
-// // if (_focused) {
-// // return widget.focusElevation;
-// // }
-// // return widget.elevation;
-// // }
-//
-// @override
-// Widget build(BuildContext context) {
-// final Color effectiveTextColor = MaterialStateProperty.resolveAs(
-// widget.textStyle?.color, _states);
-// final Color themeColor =
-// Theme.of(context).colorScheme.onSurface.withOpacity(0.12);
-// final BorderSide outlineBorder = BorderSide(
-// color: widget.borderSide == null ? themeColor : widget.borderSide.color,
-// width: widget.borderSide?.width ?? 1.0,
-// );
-//
-// Size minSize;
-// switch (widget.materialTapTargetSize) {
-// case MaterialTapTargetSize.padded:
-// minSize = const Size(48.0, 48.0);
-// break;
-// case MaterialTapTargetSize.shrinkWrap:
-// minSize = Size.zero;
-// break;
-// default:
-// minSize = Size.zero;
-// break;
-// }
-//
-// final BorderSide shapeBorder = widget.type == GFType.outline
-// ? outlineBorder
-// : widget.borderSide != null
-// ? widget.borderSide
-// : BorderSide(
-// color: widget.color,
-// width: 0.0,
-// );
-//
-// ShapeBorder shape;
-//
-// if (this.shape == GFShape.pills) {
-// shape = RoundedRectangleBorder(
-// borderRadius: BorderRadius.circular(50.0), side: shapeBorder);
-// } else if (this.shape == GFShape.square) {
-// shape = RoundedRectangleBorder(
-// borderRadius: BorderRadius.circular(0.0), side: shapeBorder);
-// } else if (this.shape == GFShape.standard) {
-// shape = RoundedRectangleBorder(
-// borderRadius: BorderRadius.circular(5.0), side: shapeBorder);
-// } else {
-// shape = RoundedRectangleBorder(
-// borderRadius: BorderRadius.circular(50.0), side: shapeBorder);
-// }
-//
-//// print("ccccccccccccccccccccc ${MaterialButton}");
-//
-// Color getFillColor(MaterialButton button) {
-// final Color color = button.enabled ? button.color : button.disabledColor;
-// if (color != null)
-// return color;
-//
-// if (button is FlatButton || button is OutlineButton || button.runtimeType == MaterialButton)
-// return null;
-//
-// if (button.enabled && button is RaisedButton && widget.color != null)
-// return widget.color;
-//
-//
-// assert(false);
-// return null;
-// }
-//
-// print('ffffffffff ${ThemeData.disabledColor}');
-//
-// return Semantics(
-// container: true,
-// button: true,
-// enabled: widget.enabled,
-// child: _InputPadding(
-// minSize: minSize,
-// child: Focus(
-// focusNode: widget.focusNode,
-// onFocusChange: _handleFocusedChanged,
-// autofocus: widget.autofocus,
-// child: Container(
-// constraints: this.icon == null ? BoxConstraints(minHeight: 26.0, minWidth: 88.0) :
-// BoxConstraints(minHeight: 26.0, minWidth: 98.0),
-// decoration: BoxDecoration(
-// borderRadius: widget.shape == GFShape.pills ? BorderRadius.circular(50.0) :
-// widget.shape == GFShape.standard ? BorderRadius.circular(5.0) : BorderRadius.zero,
-// boxShadow: [
-// widget.boxShadow == null && widget.buttonBoxShadow == true ? BoxShadow(
-// color: widget.color.withOpacity(0.4),
-// blurRadius: 1.5,
-// spreadRadius: 2.0,
-// offset: Offset.zero,
-// ) :
-// widget.boxShadow != null ? widget.boxShadow :
-// BoxShadow(
-// color: Theme.of(context).canvasColor,
-// blurRadius: 0.0,
-// spreadRadius: 0.0,
-// offset: Offset.zero,
-// )
-// ]
-// ),
-// child: Material(
-// textStyle: widget.textStyle == null ? TextStyle(color: this.textColor, fontSize: 14) : widget.textStyle,
-// shape: widget.type == GFType.transparent ? null : widget.borderShape == null ? shape : widget.borderShape,
-// color: ThemeData.disabledColor,
-// type: widget.type == GFType.transparent ? MaterialType.transparency : MaterialType.button,
-// animationDuration: widget.animationDuration,
-// clipBehavior: widget.clipBehavior,
-// child: InkWell(
-// onHighlightChanged: _handleHighlightChanged,
-// splashColor: widget.splashColor,
-// highlightColor: widget.highlightColor,
-// focusColor: widget.focusColor,
-// hoverColor: widget.hoverColor,
-// onHover: _handleHoveredChanged,
-// onTap: widget.onPressed,
-// customBorder: widget.type == GFType.transparent ? null : widget.borderShape == null ? shape : widget.borderShape,
-// child: IconTheme.merge(
-// data: IconThemeData(color: effectiveTextColor),
-// child: Container(
-// height: widget.blockButton == true ? BLOCK
-// : widget.fullWidthButton == true ? BLOCK
-// : this.size,
-// width: buttonWidth(),
-// padding: widget.padding,
-// child: Center(
-// widthFactor: 1.0,
-// heightFactor: 1.0,
-// child: this.icon != null && (this.position == GFPosition.start || this.position == null)?
-// Row(
-// mainAxisSize: MainAxisSize.min,
-// children: [
-// this.icon,
-// const SizedBox(width: 8.0),
-// this.child
-// ],
-// )
-// : this.icon != null &&
-// (this.position == GFPosition.end)
-// ? Row(
-// mainAxisSize: MainAxisSize.min,
-// children: [
-// this.child,
-// const SizedBox(width: 8.0),
-// this.icon
-// ],
-// )
-// : this.child,
-// ),
-// ),
-// ),
-// ),
-// ),
-// ),
-// ),
-// ),
-// );
-// }
-//}
-//
-///// A widget to pad the area around a [MaterialButton]'s inner [Material].
-//class _InputPadding extends SingleChildRenderObjectWidget {
-// const _InputPadding({
-// Key key,
-// Widget child,
-// this.minSize,
-// }) : super(key: key, child: child);
-//
-// final Size minSize;
-//
-// @override
-// RenderObject createRenderObject(BuildContext context) {
-// return _RenderInputPadding(minSize);
-// }
-//
-// @override
-// void updateRenderObject(
-// BuildContext context, covariant _RenderInputPadding renderObject) {
-// renderObject.minSize = minSize;
-// }
-//}
-//
-//class _RenderInputPadding extends RenderShiftedBox {
-// _RenderInputPadding(this._minSize, [RenderBox child]) : super(child);
-//
-// Size get minSize => _minSize;
-// Size _minSize;
-//
-// set minSize(Size value) {
-// if (_minSize == value) return;
-// _minSize = value;
-// markNeedsLayout();
-// }
-//
-// @override
-// double computeMinIntrinsicWidth(double height) {
-// if (child != null)
-// return math.max(child.getMinIntrinsicWidth(height), minSize.width);
-// return 0.0;
-// }
-//
-// @override
-// double computeMinIntrinsicHeight(double width) {
-// if (child != null)
-// return math.max(child.getMinIntrinsicHeight(width), minSize.height);
-// return 0.0;
-// }
-//
-// @override
-// double computeMaxIntrinsicWidth(double height) {
-// if (child != null)
-// return math.max(child.getMaxIntrinsicWidth(height), minSize.width);
-// return 0.0;
-// }
-//
-// @override
-// double computeMaxIntrinsicHeight(double width) {
-// if (child != null)
-// return math.max(child.getMaxIntrinsicHeight(width), minSize.height);
-// return 0.0;
-// }
-//
-// @override
-// void performLayout() {
-// if (child != null) {
-// child.layout(constraints, parentUsesSize: true);
-// final double height = math.max(child.size.width, minSize.width);
-// final double width = math.max(child.size.height, minSize.height);
-// size = constraints.constrain(Size(height, width));
-// final BoxParentData childParentData = child.parentData;
-// childParentData.offset = Alignment.center.alongOffset(size - child.size);
-// } else {
-// size = Size.zero;
-// }
-// }
-//
-// @override
-// bool hitTest(BoxHitTestResult result, {Offset position}) {
-// if (super.hitTest(result, position: position)) {
-// return true;
-// }
-// final Offset center = child.size.center(Offset.zero);
-// return result.addWithRawTransform(
-// transform: MatrixUtils.forceToPoint(center),
-// position: center,
-// hitTest: (BoxHitTestResult result, Offset position) {
-// assert(position == center);
-// return child.hitTest(result, position: center);
-// },
-// );
-// }
-//}
diff --git a/lib/components/button/gf_icon_button.dart b/lib/components/button/gf_icon_button.dart
index 560a8b35..573b68a6 100644
--- a/lib/components/button/gf_icon_button.dart
+++ b/lib/components/button/gf_icon_button.dart
@@ -2,7 +2,7 @@ import 'dart:math' as math;
import 'package:flutter/foundation.dart';
import 'package:flutter/widgets.dart';
import 'package:flutter/material.dart';
-import 'package:ui_kit/shape/gf_shape.dart';
+import 'package:ui_kit/shape/gf_button_shape.dart';
import 'package:ui_kit/size/gf_size.dart';
import 'package:ui_kit/types/gf_type.dart';
import 'package:ui_kit/colors/gf_color.dart';
@@ -29,20 +29,20 @@ class GFIconButton extends StatefulWidget {
/// Button type of [GFType] i.e, solid, outline, transparent
final GFType type;
- /// Button type of [GFShape] i.e, standard, pills, square, shadow, icons
- final GFShape shape;
+ /// Button type of [GFButtonShape] i.e, standard, pills, square, shadow, icons
+ final GFButtonShape shape;
/// Pass [GFColor] or [Color]
final dynamic color;
- /// The primary color of the button when the button is in the down (pressed) state.
- final Color splashColor;
+ /// Pass [GFColor] or [Color]. The primary color of the button when the button is in the down (pressed) state.
+ final dynamic splashColor;
- /// The secondary color of the button when the button is in the down (pressed) state.
- final Color highlightColor;
+ /// Pass [GFColor] or [Color]. The secondary color of the button when the button is in the down (pressed) state.
+ final dynamic highlightColor;
- /// The color to use for the icon inside the button, if the icon is disabled.
- final Color disabledColor;
+ /// Pass [GFColor] or [Color]. The color to use for the icon inside the button, if the icon is disabled.
+ final dynamic disabledColor;
/// The callback that is called when the button is tapped or otherwise activated.
final VoidCallback onPressed;
@@ -87,8 +87,8 @@ class GFIconButton extends StatefulWidget {
this.focusNode,
this.autofocus = false,
this.tooltip,
- this.type = GFType.outline,
- this.shape = GFShape.standard,
+ this.type = GFType.transparent,
+ this.shape = GFButtonShape.standard,
this.color = GFColor.primary,
this.borderShape,
this.boxShadow,
@@ -110,7 +110,7 @@ class _GFIconButtonState extends State {
Color color;
Function onPressed;
GFType type;
- GFShape shape;
+ GFButtonShape shape;
BoxShadow boxShadow;
double height;
double width;
@@ -152,13 +152,13 @@ class _GFIconButtonState extends State {
ShapeBorder shape;
- if (this.shape == GFShape.pills) {
+ if (this.shape == GFButtonShape.pills) {
shape = RoundedRectangleBorder(
borderRadius: BorderRadius.circular(50.0), side: shapeBorder);
- } else if (this.shape == GFShape.square) {
+ } else if (this.shape == GFButtonShape.square) {
shape = RoundedRectangleBorder(
borderRadius: BorderRadius.circular(0.0), side: shapeBorder);
- } else if (this.shape == GFShape.standard) {
+ } else if (this.shape == GFButtonShape.standard) {
shape = RoundedRectangleBorder(
borderRadius: BorderRadius.circular(5.0), side: shapeBorder);
} else {
@@ -185,8 +185,9 @@ class _GFIconButtonState extends State {
}
Widget result = Container(
- height: widget.shape == GFShape.pills ? this.height + 6 : this.height,
- width: widget.shape == GFShape.pills ? this.width + 6 : this.width,
+ height:
+ widget.shape == GFButtonShape.pills ? this.height + 6 : this.height,
+ width: widget.shape == GFButtonShape.pills ? this.width + 6 : this.width,
padding: widget.padding,
child: IconTheme.merge(
data: IconThemeData(
@@ -205,32 +206,40 @@ class _GFIconButtonState extends State {
}
BoxDecoration getBoxShadow() {
- if(widget.type != GFType.transparent){
- if(widget.boxShadow == null && widget.buttonBoxShadow != true){
+ if (widget.type != GFType.transparent) {
+ if (widget.boxShadow == null && widget.buttonBoxShadow != true) {
return null;
- }else{
+ } else {
return BoxDecoration(
- color: widget.type == GFType.transparent || widget.type == GFType.outline ? Colors.transparent : this.color,
- borderRadius: widget.shape == GFShape.pills ? BorderRadius.circular(50.0) :
- widget.shape == GFShape.standard ? BorderRadius.circular(5.0) : BorderRadius.zero,
+ color: widget.type == GFType.transparent ||
+ widget.type == GFType.outline
+ ? Colors.transparent
+ : this.color,
+ borderRadius: widget.shape == GFButtonShape.pills
+ ? BorderRadius.circular(50.0)
+ : widget.shape == GFButtonShape.standard
+ ? BorderRadius.circular(5.0)
+ : BorderRadius.zero,
boxShadow: [
- widget.boxShadow == null && widget.buttonBoxShadow == true ? BoxShadow(
- color: themeColor,
- blurRadius: 1.5,
- spreadRadius: 2.0,
- offset: Offset.zero,
- ) :
- widget.boxShadow != null ? widget.boxShadow :
- BoxShadow(
- color: Theme.of(context).canvasColor,
- blurRadius: 0.0,
- spreadRadius: 0.0,
- offset: Offset.zero,
- )
- ]
- );
+ widget.boxShadow == null && widget.buttonBoxShadow == true
+ ? BoxShadow(
+ color: themeColor,
+ blurRadius: 1.5,
+ spreadRadius: 2.0,
+ offset: Offset.zero,
+ )
+ : widget.boxShadow != null
+ ? widget.boxShadow
+ : BoxShadow(
+ color: Theme.of(context).canvasColor,
+ blurRadius: 0.0,
+ spreadRadius: 0.0,
+ offset: Offset.zero,
+ )
+ ]);
}
}
+ return null;
}
return Semantics(
@@ -242,27 +251,39 @@ class _GFIconButtonState extends State {
child: ConstrainedBox(
constraints: BoxConstraints(maxWidth: 60.0, maxHeight: 60.0),
child: Container(
- height:
- widget.shape == GFShape.pills ? this.height + 6 : this.height,
- width: widget.shape == GFShape.pills ? this.width + 6 : this.width,
+ height: widget.shape == GFButtonShape.pills
+ ? this.height + 6
+ : this.height,
+ width: widget.shape == GFButtonShape.pills
+ ? this.width + 6
+ : this.width,
decoration: getBoxShadow(),
child: Material(
shape: widget.type == GFType.transparent
? null
: widget.borderShape == null ? shape : widget.borderShape,
- color: widget.type == GFType.transparent || widget.type == GFType.outline ? Colors.transparent : this.color,
+ color: widget.type == GFType.transparent ||
+ widget.type == GFType.outline
+ ? Colors.transparent
+ : this.color,
type: widget.type == GFType.transparent
? MaterialType.transparency
: MaterialType.button,
child: InkResponse(
onTap: widget.onPressed,
child: result,
- focusColor: widget.focusColor ?? Theme.of(context).focusColor,
- hoverColor: widget.hoverColor ?? Theme.of(context).hoverColor,
- highlightColor:
- widget.highlightColor ?? Theme.of(context).highlightColor,
- splashColor:
- widget.splashColor ?? Theme.of(context).splashColor,
+ focusColor: widget.focusColor != null
+ ? getGFColor(widget.focusColor)
+ : Theme.of(context).focusColor,
+ hoverColor: widget.hoverColor != null
+ ? getGFColor(widget.hoverColor)
+ : Theme.of(context).hoverColor,
+ highlightColor: widget.highlightColor != null
+ ? getGFColor(widget.highlightColor)
+ : Theme.of(context).highlightColor,
+ splashColor: widget.splashColor != null
+ ? getGFColor(widget.splashColor)
+ : Theme.of(context).splashColor,
radius: math.max(
Material.defaultSplashRadius,
(widget.iconSize +
diff --git a/lib/components/drawer/gf_drawer.dart b/lib/components/drawer/gf_drawer.dart
new file mode 100644
index 00000000..1ebdaa3c
--- /dev/null
+++ b/lib/components/drawer/gf_drawer.dart
@@ -0,0 +1,211 @@
+import 'package:flutter/foundation.dart';
+import 'package:flutter/widgets.dart';
+import 'package:flutter/material.dart';
+
+/// The possible alignments of a [GFDrawer].
+enum GFDrawerAlignment {
+ /// Denotes that the [GFDrawer] is at the start side of the [Scaffold].
+ ///
+ /// This corresponds to the left side when the text direction is left-to-right
+ /// and the right side when the text direction is right-to-left.
+ start,
+
+ /// Denotes that the [GFDrawer] is at the end side of the [Scaffold].
+ ///
+ /// This corresponds to the right side when the text direction is left-to-right
+ /// and the left side when the text direction is right-to-left.
+ end,
+}
+
+// Mobile:
+// Width = Screen width − 56 dp
+// Maximum width: 320dp
+// Maximum width applies only when using a left nav. When using a right nav,
+// the panel can cover the full width of the screen.
+
+// Desktop/Tablet:
+// Maximum width for a left nav is 400dp.
+// The right nav can vary depending on content.
+
+const double _kWidth = 304.0;
+// const double _kEdgeDragWidth = 20.0;
+// const double _kMinFlingVelocity = 365.0;
+// const Duration _kBaseSettleDuration = Duration(milliseconds: 246);
+
+/// A material design panel that slides in horizontally from the edge of a
+/// [Scaffold] to show navigation links in an application.
+///
+/// GFDrawers are typically used with the [Scaffold.drawer] property. The child of
+/// the drawer is usually a [ListView] whose first child is a [GFDrawerHeader]
+/// that displays status information about the current user. The remaining
+/// drawer children are often constructed with [ListTile]s, often concluding
+/// with an [AboutListTile].
+///
+/// The [AppBar] automatically displays an appropriate [IconButton] to show the
+/// [GFDrawer] when a [GFDrawer] is available in the [Scaffold]. The [Scaffold]
+/// automatically handles the edge-swipe gesture to show the drawer.
+///
+/// {@animation 350 622 https://flutter.github.io/assets-for-api-docs/assets/material/drawer.mp4}
+///
+/// {@tool sample}
+/// This example shows how to create a [Scaffold] that contains an [AppBar] and
+/// a [GFDrawer]. A user taps the "menu" icon in the [AppBar] to open the
+/// [GFDrawer]. The [GFDrawer] displays four items: A header and three menu items.
+/// The [GFDrawer] displays the four items using a [ListView], which allows the
+/// user to scroll through the items if need be.
+///
+/// ```dart
+/// Scaffold(
+/// appBar: AppBar(
+/// title: const Text('GFDrawer Demo'),
+/// ),
+/// drawer: GFDrawer(
+/// child: ListView(
+/// padding: EdgeInsets.zero,
+/// children: const [
+/// GFDrawerHeader(
+/// decoration: BoxDecoration(
+/// color: Colors.blue,
+/// ),
+/// child: Text(
+/// 'GFDrawer Header',
+/// style: TextStyle(
+/// color: Colors.white,
+/// fontSize: 24,
+/// ),
+/// ),
+/// ),
+/// ListTile(
+/// leading: Icon(Icons.message),
+/// title: Text('Messages'),
+/// ),
+/// ListTile(
+/// leading: Icon(Icons.account_circle),
+/// title: Text('Profile'),
+/// ),
+/// ListTile(
+/// leading: Icon(Icons.settings),
+/// title: Text('Settings'),
+/// ),
+/// ],
+/// ),
+/// ),
+/// )
+/// ```
+/// {@end-tool}
+///
+/// An open drawer can be closed by calling [Navigator.pop]. For example
+/// a drawer item might close the drawer when tapped:
+///
+/// ```dart
+/// ListTile(
+/// leading: Icon(Icons.change_history),
+/// title: Text('Change history'),
+/// onTap: () {
+/// // change app state...
+/// Navigator.pop(context); // close the drawer
+/// },
+/// );
+/// ```
+///
+/// See also:
+///
+/// * [Scaffold.drawer], where one specifies a [GFDrawer] so that it can be
+/// shown.
+/// * [Scaffold.of], to obtain the current [ScaffoldState], which manages the
+/// display and animation of the drawer.
+/// * [ScaffoldState.openGFDrawer], which displays its [GFDrawer].
+///
+class GFDrawer extends StatelessWidget {
+ /// Creates a material design drawer.
+ ///
+ /// Typically used in the [Scaffold.drawer] property.
+ ///
+ /// The [elevation] must be non-negative.
+ const GFDrawer(
+ {Key key,
+ this.elevation = 16.0,
+ this.child,
+ this.semanticLabel,
+ this.backgroundImage,
+ this.colorFilter,
+ this.gradient})
+ : assert(elevation != null && elevation >= 0.0),
+ super(key: key);
+
+ /// The z-coordinate at which to place this drawer relative to its parent.
+ ///
+ /// This controls the size of the shadow below the drawer.
+ ///
+ /// Defaults to 16, the appropriate elevation for drawers. The value is
+ /// always non-negative.
+ final double elevation;
+
+ /// The widget below this widget in the tree.
+ ///
+ /// Typically a [SliverList].
+ ///
+ /// {@macro flutter.widgets.child}
+ final Widget child;
+
+ /// The semantic label of the dialog used by accessibility frameworks to
+ /// announce screen transitions when the drawer is opened and closed.
+ ///
+ /// If this label is not provided, it will default to
+ /// [MaterialLocalizations.drawerLabel].
+ ///
+ /// See also:
+ ///
+ /// * [SemanticsConfiguration.namesRoute], for a description of how this
+ /// value is used.
+ final String semanticLabel;
+
+ /// Background image can be added to the [GFDrawer].
+ final ImageProvider backgroundImage;
+
+ /// A composited layer that applies a color filter to its children.
+ final ColorFilter colorFilter;
+
+ /// Gradient can be used for transforming gradient shaders without
+ /// applying the same transform to the entire canvas.
+ final Gradient gradient;
+
+ @override
+ Widget build(BuildContext context) {
+ assert(debugCheckHasMaterialLocalizations(context));
+ String label = semanticLabel;
+ switch (Theme.of(context).platform) {
+ case TargetPlatform.iOS:
+ label = semanticLabel;
+ break;
+ case TargetPlatform.android:
+ case TargetPlatform.fuchsia:
+ label = semanticLabel ?? MaterialLocalizations.of(context)?.drawerLabel;
+ }
+ return Semantics(
+ scopesRoute: true,
+ namesRoute: true,
+ explicitChildNodes: true,
+ label: label,
+ child: ConstrainedBox(
+ constraints: const BoxConstraints.expand(width: _kWidth),
+ child: Material(
+ elevation: elevation,
+ child: Container(
+ decoration: new BoxDecoration(
+ color: Colors.teal,
+ gradient: gradient,
+ image: backgroundImage != null
+ ? new DecorationImage(
+ image: backgroundImage,
+ fit: BoxFit.cover,
+ colorFilter: colorFilter,
+ )
+ : null,
+ ),
+ child: child),
+ ),
+ ),
+ );
+ }
+}
diff --git a/lib/components/drawer/gf_drawer_header.dart b/lib/components/drawer/gf_drawer_header.dart
new file mode 100644
index 00000000..c56722c3
--- /dev/null
+++ b/lib/components/drawer/gf_drawer_header.dart
@@ -0,0 +1,154 @@
+import 'package:flutter/widgets.dart';
+import 'package:flutter/foundation.dart';
+import 'package:flutter/material.dart';
+
+class DrawerHeaderPictures extends StatelessWidget {
+ const DrawerHeaderPictures({
+ Key key,
+ this.currentAccountPicture,
+ this.otherAccountsPictures,
+ }) : super(key: key);
+
+ final Widget currentAccountPicture;
+ final List otherAccountsPictures;
+
+ @override
+ Widget build(BuildContext context) {
+ return Stack(
+ children: [
+ PositionedDirectional(
+ top: 0.0,
+ end: 0.0,
+ child: Row(
+ children: (otherAccountsPictures ?? [])
+ .take(3)
+ .map((Widget picture) {
+ return Padding(
+ padding: const EdgeInsetsDirectional.only(start: 8.0),
+ child: Semantics(
+ container: true,
+ child: Container(
+ padding: const EdgeInsets.only(left: 8.0, bottom: 8.0),
+ width: 48.0,
+ height: 48.0,
+ child: picture,
+ ),
+ ),
+ );
+ }).toList(),
+ ),
+ ),
+ Positioned(
+ top: 0.0,
+ child: Semantics(
+ explicitChildNodes: true,
+ child: SizedBox(
+ width: 72.0,
+ height: 72.0,
+ child: currentAccountPicture,
+ ),
+ ),
+ ),
+ ],
+ );
+ }
+}
+
+/// A material design [Drawer] header that identifies the app's user.
+///
+/// Requires one of its ancestors to be a [Material] widget.
+///
+/// See also:
+///
+/// * [DrawerHeader], for a drawer header that doesn't show user accounts.
+/// *
+class GFDrawerHeader extends StatefulWidget {
+ /// Creates a material design drawer header.
+ ///
+ /// Requires one of its ancestors to be a [Material] widget.
+ const GFDrawerHeader({
+ Key key,
+ this.decoration,
+ this.margin = const EdgeInsets.only(bottom: 8.0),
+ this.currentAccountPicture,
+ this.otherAccountsPictures,
+ this.child,
+ this.duration = const Duration(milliseconds: 250),
+ this.curve = Curves.fastOutSlowIn,
+ }) : super(key: key);
+
+ /// The header's background. If decoration is null then a [BoxDecoration]
+ /// with its background color set to the current theme's primaryColor is used.
+ final Decoration decoration;
+
+ /// The margin around the drawer header.
+ final EdgeInsetsGeometry margin;
+
+ /// A widget placed in the upper-left corner that represents the current
+ /// user's account. Normally a [CircleAvatar].
+ final Widget currentAccountPicture;
+
+ /// A list of widgets that represent the current user's other accounts.
+ /// Up to three of these widgets will be arranged in a row in the header's
+ /// upper-right corner. Normally a list of [CircleAvatar] widgets.
+ final List otherAccountsPictures;
+
+ /// A widget to be placed inside the drawer header, inset by the [padding].
+ ///
+ /// This widget will be sized to the size of the header. To position the child
+ /// precisely, consider using an [Align] or [Center] widget.
+ ///
+ /// {@macro flutter.widgets.child}
+ final Widget child;
+
+ /// The duration for animations of the [decoration].
+ final Duration duration;
+
+ /// The curve for animations of the [decoration].
+ final Curve curve;
+
+ @override
+ _GFDrawerHeaderState createState() => _GFDrawerHeaderState();
+}
+
+class _GFDrawerHeaderState extends State {
+ @override
+ Widget build(BuildContext context) {
+ assert(debugCheckHasMaterial(context));
+ assert(debugCheckHasMaterialLocalizations(context));
+ return Semantics(
+ container: true,
+ label: MaterialLocalizations.of(context).signedInLabel,
+ child: DrawerHeader(
+ decoration: widget.decoration ??
+ BoxDecoration(
+ color: Theme.of(context).primaryColor,
+ ),
+ margin: widget.margin,
+ padding: const EdgeInsetsDirectional.only(top: 16.0, start: 16.0),
+ child: SafeArea(
+ bottom: false,
+ child: Column(
+ crossAxisAlignment: CrossAxisAlignment.stretch,
+ children: [
+ Expanded(
+ child: Padding(
+ padding: const EdgeInsetsDirectional.only(end: 16.0),
+ child: DrawerHeaderPictures(
+ currentAccountPicture: widget.currentAccountPicture,
+ otherAccountsPictures: widget.otherAccountsPictures,
+ ),
+ ),
+ ),
+ AnimatedContainer(
+ padding: EdgeInsets.only(bottom: 16.0),
+ duration: widget.duration,
+ curve: widget.curve,
+ child: widget.child),
+ ],
+ ),
+ ),
+ ),
+ );
+ }
+}
diff --git a/lib/components/header/gf_header.dart b/lib/components/header/gf_header.dart
index 20f1709f..7dddbdd6 100644
--- a/lib/components/header/gf_header.dart
+++ b/lib/components/header/gf_header.dart
@@ -5,7 +5,7 @@ import 'package:ui_kit/types/gf_heading_type.dart';
class GFHeader extends StatelessWidget {
const GFHeader(
{Key key,
- this.type,
+ this.type = GFHeadingType.typo4,
this.child,
this.text,
this.icon,
diff --git a/lib/components/list/gf_list.dart b/lib/components/list/gf_list.dart
new file mode 100644
index 00000000..bc2685b7
--- /dev/null
+++ b/lib/components/list/gf_list.dart
@@ -0,0 +1,61 @@
+import 'package:flutter/material.dart';
+import 'package:ui_kit/components/avatar/gf_avatar.dart';
+import 'package:ui_kit/components/list_tile/gf_list_tile.dart';
+class GFList extends StatefulWidget {
+
+ const GFList(
+ {Key key,
+ this.child,
+ this.text = 'Lorem ipsum',
+ this.icon = const Icon(Icons.keyboard_arrow_right),
+ this.textStyle,
+ this.showDivider= true
+
+ })
+ : super(key: key);
+
+
+
+ final Widget child;
+
+ final String text;
+
+ final Widget icon;
+
+ final TextStyle textStyle;
+
+ final bool showDivider;
+
+
+ @override
+ _GFListState createState() => _GFListState();
+}
+
+class _GFListState extends State {
+ @override
+ Widget build(BuildContext context) {
+ return Container(
+ height: MediaQuery.of(context).size.height,
+ width: MediaQuery.of(context).size.width,
+ margin: EdgeInsets.only(left: 10),
+ padding: EdgeInsets.only(right: 5, top: 10),
+ child:ListView.builder(
+ shrinkWrap: true,
+// scrollDirection: Axis.horizontal,
+// itemCount: 0,
+ itemBuilder: (BuildContext context, int index) {
+ return Container(
+// height: MediaQuery.of(context).size.height,
+// width: MediaQuery.of(context).size.width,
+ child: GFListTile(
+ title: Text('j'),
+ avatar: GFAvatar(),
+ ),
+ );
+ }
+
+
+)
+ );
+ }
+}
diff --git a/lib/components/list_tile/gf_list_tile.dart b/lib/components/list_tile/gf_list_tile.dart
index 34fb92f5..4f3df6f4 100644
--- a/lib/components/list_tile/gf_list_tile.dart
+++ b/lib/components/list_tile/gf_list_tile.dart
@@ -29,8 +29,8 @@ class GFListTile extends StatelessWidget {
this.color,
this.avatar,
this.title,
- this.subTitle,
- this.description,
+ this.subTitle ,
+ this.description ,
this.icon,
this.showDivider = true
})
diff --git a/lib/components/search_bar/gf_search_bar.dart b/lib/components/search_bar/gf_search_bar.dart
new file mode 100644
index 00000000..e69de29b
diff --git a/lib/components/segment_tabs/gf_segment_tabs.dart b/lib/components/segment_tabs/gf_segment_tabs.dart
new file mode 100644
index 00000000..06b98a34
--- /dev/null
+++ b/lib/components/segment_tabs/gf_segment_tabs.dart
@@ -0,0 +1,217 @@
+import 'package:flutter/material.dart';
+import 'package:flutter/foundation.dart';
+import 'package:flutter/rendering.dart';
+import 'package:flutter/widgets.dart';
+import 'package:ui_kit/components/tabs/gf_tabBarView.dart';
+
+
+class GFSegmentTabs extends StatefulWidget {
+ GFSegmentTabs({
+ Key key,
+ this.initialIndex = 0,
+ @required this.length,
+ this.height,
+ this.width,
+ this.border,
+ this.borderRadius,
+ this.tabBarColor,
+ this.indicatorColor,
+ this.indicatorWeight = 2.0,
+ this.indicatorPadding = EdgeInsets.zero,
+ this.indicator,
+ this.indicatorSize,
+ this.labelColor,
+ this.labelStyle,
+ this.labelPadding,
+ this.unselectedLabelColor,
+ this.unselectedLabelStyle,
+ this.tabBarView,
+ this.tabs,
+ this.tabController
+ }):
+ assert(length != null && length >= 0),
+ assert(initialIndex != null && initialIndex >= 0 && (length == 0 || initialIndex < length));
+
+ /// The initial index of the selected tab. Defaults to zero.
+ final int initialIndex;
+
+ /// The total number of tabs. Typically greater than one. Must match [TabBar.tabs]'s and
+ /// [TabBarView.children]'s length.
+ final int length;
+
+ /// Sets [GFSegmentTabs] height
+ final double height;
+
+ /// Sets [TabBar] color using material color [Color]
+ final Color tabBarColor;
+
+ /// The color of the line that appears below the selected tab.
+ ///
+ /// If this parameter is null, then the value of the Theme's indicatorColor
+ /// property is used.
+ ///
+ /// If [indicator] is specified, this property is ignored.
+ final Color indicatorColor;
+
+ /// The thickness of the line that appears below the selected tab.
+ ///
+ /// The value of this parameter must be greater than zero and its default
+ /// value is 2.0.
+ ///
+ /// If [indicator] is specified, this property is ignored.
+ final double indicatorWeight;
+
+ /// The horizontal padding for the line that appears below the selected tab.
+ ///
+ /// For [isScrollable] tab bars, specifying [kTabLabelPadding] will align
+ /// the indicator with the tab's text for [Tab] widgets and all but the
+ /// shortest [Tab.text] values.
+ ///
+ /// The [EdgeInsets.top] and [EdgeInsets.bottom] values of the
+ /// [indicatorPadding] are ignored.
+ ///
+ /// The default value of [indicatorPadding] is [EdgeInsets.zero].
+ ///
+ /// If [indicator] is specified, this property is ignored.
+ final EdgeInsetsGeometry indicatorPadding;
+
+ /// Defines the appearance of the selected tab indicator.
+ ///
+ /// If [indicator] is specified, the [indicatorColor], [indicatorWeight],
+ /// and [indicatorPadding] properties are ignored.
+ ///
+ /// The default, underline-style, selected tab indicator can be defined with
+ /// [UnderlineTabIndicator].
+ ///
+ /// The indicator's size is based on the tab's bounds. If [indicatorSize]
+ /// is [TabBarIndicatorSize.tab] the tab's bounds are as wide as the space
+ /// occupied by the tab in the tab bar. If [indicatorSize] is
+ /// [TabBarIndicatorSize.label], then the tab's bounds are only as wide as
+ /// the tab widget itself.
+ final Decoration indicator;
+
+ /// Defines how the selected tab indicator's size is computed.
+ ///
+ /// The size of the selected tab indicator is defined relative to the
+ /// tab's overall bounds if [indicatorSize] is [TabBarIndicatorSize.tab]
+ /// (the default) or relative to the bounds of the tab's widget if
+ /// [indicatorSize] is [TabBarIndicatorSize.label].
+ ///
+ /// The selected tab's location appearance can be refined further with
+ /// the [indicatorColor], [indicatorWeight], [indicatorPadding], and
+ /// [indicator] properties.
+ final TabBarIndicatorSize indicatorSize;
+
+ /// The color of selected tab labels.
+ ///
+ /// Unselected tab labels are rendered with the same color rendered at 70%
+ /// opacity unless [unselectedLabelColor] is non-null.
+ ///
+ /// If this parameter is null, then the color of the [ThemeData.primaryTextTheme]'s
+ /// body2 text color is used.
+ final Color labelColor;
+
+ /// The color of unselected tab labels.
+ ///
+ /// If this property is null, unselected tab labels are rendered with the
+ /// [labelColor] with 70% opacity.
+ final Color unselectedLabelColor;
+
+ /// The text style of the selected tab labels.
+ ///
+ /// If [unselectedLabelStyle] is null, then this text style will be used for
+ /// both selected and unselected label styles.
+ ///
+ /// If this property is null, then the text style of the
+ /// [ThemeData.primaryTextTheme]'s body2 definition is used.
+ final TextStyle labelStyle;
+
+ /// The padding added to each of the tab labels.
+ ///
+ /// If this property is null, then kTabLabelPadding is used.
+ final EdgeInsetsGeometry labelPadding;
+
+ /// The text style of the unselected tab labels
+ ///
+ /// If this property is null, then the [labelStyle] value is used. If [labelStyle]
+ /// is null, then the text style of the [ThemeData.primaryTextTheme]'s
+ /// body2 definition is used.
+ final TextStyle unselectedLabelStyle;
+
+ /// One widget per tab.
+ /// Its length must match the length of the [GFSegmentTabs.tabs]
+ /// list, as well as the [controller]'s [GFSegmentTabs.length].
+ final GFTabBarView tabBarView;
+
+ /// Typically a list of two or more [Tab] widgets.
+ ///
+ /// The length of this list must match the [controller]'s [TabController.length]
+ /// and the length of the [TabBarView.children] list.
+ final List tabs;
+
+ final Border border;
+ final BorderRadius borderRadius;
+ final TabController tabController;
+ final double width;
+
+ @override
+ _GFSegmentTabsState createState() => _GFSegmentTabsState();
+}
+
+class _GFSegmentTabsState extends State {
+ @override
+ Widget build(BuildContext context) {
+ return Container(
+ height: widget.height == null ? 28.0 : widget.height,
+ width: widget.width == null ? 240.0 : widget.width,
+ decoration: BoxDecoration(
+ border: widget.border == null ? Border.all(color: Colors.black26, width: 2.0) : widget.border,
+ borderRadius: widget.borderRadius == null ? BorderRadius.circular(8.0) : widget.borderRadius,
+ ),
+ child: DefaultTabController(
+ initialIndex: widget.initialIndex,
+ length: widget.length,
+ child: Material(
+ borderRadius: widget.borderRadius == null ? BorderRadius.circular(8.0) : widget.borderRadius,
+ type: MaterialType.button,
+ color: widget.tabBarColor ?? Colors.transparent,
+ child: TabBar(
+ controller: widget.tabController,
+ labelColor: widget.labelColor,
+ unselectedLabelColor: widget.unselectedLabelColor,
+ labelStyle: widget.labelStyle,
+ unselectedLabelStyle: widget.unselectedLabelStyle,
+ indicatorColor: widget.indicatorColor == null ? Colors.blueGrey : widget.indicatorColor,
+ indicatorSize: widget.indicatorSize,
+ indicator: widget.indicator == null ?
+ BoxDecoration(
+ color: widget.indicatorColor == null ? Colors.blueGrey : widget.indicatorColor,
+ border: Border.all(color: widget.indicatorColor == null ? Colors.blueGrey : widget.indicatorColor, width: 2.0),
+ borderRadius: widget.borderRadius == null ? BorderRadius.circular(6.0) : widget.borderRadius,
+ ) : widget.indicator,
+ indicatorPadding: widget.indicatorPadding,
+ indicatorWeight: widget.indicatorWeight,
+ tabs: widget.tabs,
+ ),
+ ),
+ ),
+ );
+ }
+}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/lib/components/slider/gf_items_slider.dart b/lib/components/slider/gf_items_slider.dart
new file mode 100644
index 00000000..e54d32d1
--- /dev/null
+++ b/lib/components/slider/gf_items_slider.dart
@@ -0,0 +1,209 @@
+library carousel;
+
+import 'dart:async';
+
+import 'package:flutter/material.dart';
+
+/// Signature for when a pointer has contacted the screen and has begun to move.
+///
+/// The `details` object provides the position of the touch when it first
+/// touched the surface.
+typedef GFItemsSliderSlideStartCallback = void Function(
+ DragStartDetails details);
+
+/// Signature for when a pointer that is in contact with the screen and moving
+/// has moved again.
+///
+/// The `details` object provides the position of the touch and the distance it
+/// has travelled since the last update.
+typedef GFItemsSliderSlideCallback = void Function(DragUpdateDetails details);
+
+/// Signature for when a pointer that was previously in contact with the screen
+/// and moving is no longer in contact with the screen.
+///
+/// The velocity at which the pointer was moving when it stopped contacting
+/// the screen is available in the `details`.
+typedef GFItemsSliderSlideEndCallback = void Function(DragEndDetails details);
+
+/// A widget that show draggable cells with animation.
+///
+/// Set [rowCount] of visible cells
+///
+/// Set drag handlers [onSlideStart], [onSlide], [onSlideEnd]
+///
+/// Set left/right arrows [leftArrow], [rightArrow]
+class GFItemsSlider extends StatefulWidget {
+ /// Count of visible cells
+ final int rowCount;
+
+ final List children;
+
+ /// Signature for when a pointer has contacted the screen and has begun to move.
+ final GFItemsSliderSlideStartCallback onSlideStart;
+
+ /// Signature for when a pointer that is in contact with the screen and moving
+ /// has moved again.
+ final GFItemsSliderSlideCallback onSlide;
+
+ /// Signature for when a pointer that was previously in contact with the screen
+ /// and moving is no longer in contact with the screen.
+ final GFItemsSliderSlideEndCallback onSlideEnd;
+
+ GFItemsSlider(
+ {this.rowCount,
+ this.children,
+ this.onSlideStart,
+ this.onSlide,
+ this.onSlideEnd});
+
+ @override
+ _GFItemsSliderState createState() => new _GFItemsSliderState();
+}
+
+class _GFItemsSliderState extends State
+ with TickerProviderStateMixin {
+ /// In milliseconds
+ static final int dragAnimationDuration = 1000;
+
+ /// In milliseconds
+ static final int shiftAnimationDuration = 300;
+
+ /// Size of cell
+ double size = 0;
+
+ /// Width of cells container
+ double width = 0;
+
+ AnimationController animationController;
+
+ /// Shift of cells container
+ double offset;
+
+ @override
+ void initState() {
+ super.initState();
+
+ this.offset = 0;
+
+ this.animationController = AnimationController(
+ duration: new Duration(milliseconds: dragAnimationDuration),
+ vsync: this);
+
+ new Future.delayed(Duration.zero, () {
+ this.setState(() {
+ double width = MediaQuery.of(context).size.width;
+ this.width = width;
+ this.size = this.width / widget.rowCount;
+ });
+ });
+ }
+
+ double calculateOffset(double shift) {
+ double offset = this.offset + shift;
+ double rightLimit = this.size * (widget.children.length - widget.rowCount);
+
+ /// Check cells container limits
+ if (offset > 0) {
+ offset = 0;
+ } else if (offset < -rightLimit) {
+ offset = -rightLimit;
+ }
+
+ return offset;
+ }
+
+ onSlideStart(DragStartDetails details) {
+ this.animationController.stop();
+ if (widget.onSlideStart != null) widget.onSlideStart(details);
+ }
+
+ onSlide(DragUpdateDetails details) {
+ setState(() {
+ this.offset = this.calculateOffset(3 * details.delta.dx);
+ });
+
+ if (widget.onSlide != null) widget.onSlide(details);
+ }
+
+ onSlideEnd(DragEndDetails details) {
+ double dx = details.velocity.pixelsPerSecond.dx;
+
+ if (dx == 0) {
+ return this.runShiftAnimation();
+ }
+
+ this.animationController = new AnimationController(
+ duration: new Duration(milliseconds: dragAnimationDuration),
+ vsync: this);
+
+ Tween tween = new Tween(
+ begin: this.offset, end: this.calculateOffset(0.5 * dx));
+
+ Animation animation = tween.animate(new CurvedAnimation(
+ parent: this.animationController,
+ curve: Curves.easeOut,
+ ));
+
+ animation.addStatusListener((AnimationStatus status) {
+ if (status == AnimationStatus.completed) {
+ this.runShiftAnimation();
+ }
+ });
+
+ animation.addListener(() {
+ setState(() {
+ this.offset = animation.value;
+ });
+ });
+
+ this.animationController.forward();
+ if (widget.onSlideEnd != null) widget.onSlideEnd(details);
+ }
+
+ runShiftAnimation() {
+ double beginAnimation = this.offset;
+ double endAnimation =
+ this.size * (this.offset / this.size).round().toDouble();
+
+ this.animationController = new AnimationController(
+ duration: new Duration(milliseconds: shiftAnimationDuration),
+ vsync: this);
+ Tween tween = new Tween(begin: beginAnimation, end: endAnimation);
+ Animation animation = tween.animate(this.animationController);
+
+ animation.addListener(() {
+ setState(() {
+ this.offset = animation.value;
+ });
+ });
+
+ this.animationController.forward();
+ }
+
+ @override
+ Widget build(BuildContext context) {
+ return GestureDetector(
+ onHorizontalDragStart: this.onSlideStart,
+ onHorizontalDragUpdate: this.onSlide,
+ onHorizontalDragEnd: this.onSlideEnd,
+ child: Container(
+ width: double.infinity,
+ height: this.size,
+ child: Stack(children: [
+ Positioned(
+ left: this.offset,
+ child: Row(
+ children: widget.children.map((child) {
+ return Container(
+ width: this.size,
+ height: this.size,
+ child: child,
+ );
+ }).toList(),
+ ),
+ ),
+ ]),
+ ),
+ );
+ }
+}
diff --git a/lib/components/slider/gf_slider.dart b/lib/components/slider/gf_slider.dart
index fe3a4846..52304775 100644
--- a/lib/components/slider/gf_slider.dart
+++ b/lib/components/slider/gf_slider.dart
@@ -1,5 +1,4 @@
import 'dart:async';
-//import 'dart:ffi';
import 'package:flutter/material.dart';
List map(List list, Function handler) {
@@ -32,6 +31,7 @@ class GFSlider extends StatefulWidget {
this.enlargeMainPage = false,
this.onPageChanged,
this.scrollPhysics,
+ this.rowCount,
this.scrollDirection: Axis.horizontal})
: this.realPage =
enableInfiniteScroll ? realPage + initialPage : initialPage,
@@ -41,6 +41,9 @@ class GFSlider extends StatefulWidget {
enableInfiniteScroll ? realPage + initialPage : initialPage,
);
+ /// Count of visible cells
+ final int rowCount;
+
/// The pagination dots size can be defined using [double].
final double pagerSize;
@@ -164,6 +167,12 @@ class GFSlider extends StatefulWidget {
class _GFSliderState extends State with TickerProviderStateMixin {
Timer timer;
+ /// Size of cell
+ double size = 0;
+
+ /// Width of cells container
+ double width = 0;
+
@override
void initState() {
super.initState();
@@ -261,14 +270,16 @@ class _GFSliderState extends State with TickerProviderStateMixin {
if (widget.scrollDirection == Axis.horizontal) {
return Center(
- child: SizedBox(
- height: distortionValue * height, child: child));
+ child: SizedBox(
+ height: distortionValue * height, child: child),
+ );
} else {
return Center(
- child: SizedBox(
- width: distortionValue *
- MediaQuery.of(context).size.width,
- child: child));
+ child: SizedBox(
+ width:
+ distortionValue * MediaQuery.of(context).size.width,
+ child: child),
+ );
}
},
);
diff --git a/lib/components/tabs/gf_tabBarView.dart b/lib/components/tabs/gf_tabBarView.dart
new file mode 100644
index 00000000..86886f4f
--- /dev/null
+++ b/lib/components/tabs/gf_tabBarView.dart
@@ -0,0 +1,235 @@
+import 'package:flutter/material.dart';
+import 'dart:async';
+import 'package:flutter/rendering.dart';
+import 'package:flutter/widgets.dart';
+import 'package:flutter/gestures.dart' show DragStartBehavior;
+
+/// A page view that displays the widget which corresponds to the currently
+/// selected tab.
+///
+/// This widget is typically used in conjunction with a [TabBar].
+///
+/// If a [TabController] is not provided, then there must be a [DefaultTabController]
+/// ancestor.
+///
+/// The tab controller's [TabController.length] must equal the length of the
+/// [children] list and the length of the [TabBar.tabs] list.
+///
+/// To see a sample implementation, visit the [TabController] documentation.
+class GFTabBarView extends StatefulWidget {
+ /// Creates a page view with one child per tab.
+ ///
+ /// The length of [children] must be the same as the [controller]'s length.
+ const GFTabBarView({
+ Key key,
+ @required this.children,
+ this.controller,
+ this.physics,
+ this.dragStartBehavior = DragStartBehavior.start,
+ }) : assert(children != null),
+ assert(dragStartBehavior != null),
+ super(key: key);
+
+ /// This widget's selection and animation state.
+ ///
+ /// If [TabController] is not provided, then the value of [DefaultTabController.of]
+ /// will be used.
+ final TabController controller;
+
+ /// One widget per tab.
+ ///
+ /// Its length must match the length of the [TabBar.tabs]
+ /// list, as well as the [controller]'s [TabController.length].
+ final List children;
+
+ /// How the page view should respond to user input.
+ ///
+ /// For example, determines how the page view continues to animate after the
+ /// user stops dragging the page view.
+ ///
+ /// The physics are modified to snap to page boundaries using
+ /// [PageScrollPhysics] prior to being used.
+ ///
+ /// Defaults to matching platform conventions.
+ final ScrollPhysics physics;
+
+ /// {@macro flutter.widgets.scrollable.dragStartBehavior}
+ final DragStartBehavior dragStartBehavior;
+
+ @override
+ _GFTabBarViewState createState() => _GFTabBarViewState();
+}
+
+final PageScrollPhysics _kGFTabBarViewPhysics = const PageScrollPhysics().applyTo(const ClampingScrollPhysics());
+
+class _GFTabBarViewState extends State