├── .gitignore
├── .idea
├── .gitignore
├── codeStyles
│ └── Project.xml
├── dictionaries
│ ├── lizhuoyuan.xml
│ └── zhuoy.xml
├── flutter_study.iml
├── libraries
│ ├── Dart_Packages.xml
│ ├── Dart_SDK.xml
│ └── Flutter_Plugins.xml
├── misc.xml
├── modules.xml
└── vcs.xml
├── .metadata
├── README.md
├── android
├── .gitignore
├── .idea
│ ├── gradle.xml
│ ├── misc.xml
│ └── modules.xml
├── .project
├── .settings
│ └── org.eclipse.buildship.core.prefs
├── app
│ ├── .classpath
│ ├── .project
│ ├── .settings
│ │ └── org.eclipse.buildship.core.prefs
│ ├── build.gradle
│ └── src
│ │ └── main
│ │ ├── AndroidManifest.xml
│ │ ├── java
│ │ └── com
│ │ │ └── example
│ │ │ └── flutterapp
│ │ │ └── MainActivity.java
│ │ └── res
│ │ ├── drawable
│ │ └── launch_background.xml
│ │ ├── mipmap-hdpi
│ │ └── ic_launcher.png
│ │ ├── mipmap-mdpi
│ │ └── ic_launcher.png
│ │ ├── mipmap-xhdpi
│ │ └── ic_launcher.png
│ │ ├── mipmap-xxhdpi
│ │ └── ic_launcher.png
│ │ ├── mipmap-xxxhdpi
│ │ └── ic_launcher.png
│ │ ├── values
│ │ ├── string.xml
│ │ └── styles.xml
│ │ └── xml
│ │ └── filepaths.xml
├── build.gradle
├── gradle.properties
├── gradle
│ └── wrapper
│ │ ├── gradle-wrapper.jar
│ │ └── gradle-wrapper.properties
├── gradlew
├── gradlew.bat
└── settings.gradle
├── flutter_app.iml
├── flutter_app_android.iml
├── images
├── a.png
├── beauty.jpg
├── home.png
├── jay.jpg
├── login.png
├── pavlova.png
├── pic1.jpg
├── pic2.jpg
├── pic3.jpg
└── timg.jpg
├── ios
├── .gitignore
├── Flutter
│ ├── AppFrameworkInfo.plist
│ ├── Debug.xcconfig
│ ├── Flutter.podspec
│ ├── Release.xcconfig
│ └── flutter_export_environment.sh
├── Podfile
├── Runner.xcodeproj
│ ├── project.pbxproj
│ ├── project.xcworkspace
│ │ └── contents.xcworkspacedata
│ └── xcshareddata
│ │ └── xcschemes
│ │ └── Runner.xcscheme
├── Runner.xcworkspace
│ └── contents.xcworkspacedata
└── Runner
│ ├── AppDelegate.h
│ ├── AppDelegate.m
│ ├── Assets.xcassets
│ ├── AppIcon.appiconset
│ │ ├── Contents.json
│ │ ├── Icon-App-1024x1024@1x.png
│ │ ├── Icon-App-20x20@1x.png
│ │ ├── Icon-App-20x20@2x.png
│ │ ├── Icon-App-20x20@3x.png
│ │ ├── Icon-App-29x29@1x.png
│ │ ├── Icon-App-29x29@2x.png
│ │ ├── Icon-App-29x29@3x.png
│ │ ├── Icon-App-40x40@1x.png
│ │ ├── Icon-App-40x40@2x.png
│ │ ├── Icon-App-40x40@3x.png
│ │ ├── Icon-App-60x60@2x.png
│ │ ├── Icon-App-60x60@3x.png
│ │ ├── Icon-App-76x76@1x.png
│ │ ├── Icon-App-76x76@2x.png
│ │ └── Icon-App-83.5x83.5@2x.png
│ └── LaunchImage.imageset
│ │ ├── Contents.json
│ │ ├── LaunchImage.png
│ │ ├── LaunchImage@2x.png
│ │ ├── LaunchImage@3x.png
│ │ └── README.md
│ ├── Base.lproj
│ ├── LaunchScreen.storyboard
│ └── Main.storyboard
│ ├── Info.plist
│ └── main.m
├── lib
├── bean
│ ├── number_attribution.dart
│ └── picker_data.dart
├── common
│ └── constant.dart
├── locale
│ ├── i18n_en.json
│ ├── i18n_zh.json
│ └── translations_delegate.dart
├── main.dart
├── model
│ ├── AppModel.dart
│ └── note.dart
├── page
│ ├── ChipPage.dart
│ ├── ExpansionTilePage.dart
│ ├── FavoriteWidget.dart
│ ├── FutureBuilderPage.dart
│ ├── GridViewPage.dart
│ ├── ImagePage.dart
│ ├── KeepAlivePage.dart
│ ├── MyHomePage.dart
│ ├── PavlovaPage.dart
│ ├── RandomWords.dart
│ ├── ScreenUtilTest.dart
│ ├── StateWidgetPage.dart
│ ├── SwiperPage.dart
│ ├── Transform3D.dart
│ ├── alive_home_page.dart
│ ├── animation_page.dart
│ ├── animation_two.dart
│ ├── backdrop_page.dart
│ ├── cupertino_action_sheet_page.dart
│ ├── custom_animation_page.dart
│ ├── custom_scrollview_page.dart
│ ├── draggable_dragtargets.dart
│ ├── draggable_scrollable_sheet_page.dart
│ ├── extension_page.dart
│ ├── flutter_native_web.dart
│ ├── flutter_picker_page.dart
│ ├── fractionally_sized_box_page.dart
│ ├── login_page.dart
│ ├── map_search_page.dart
│ ├── modal_page.dart
│ ├── repaint_boundary_page.dart
│ ├── route_page.dart
│ ├── search_page.dart
│ ├── share_page.dart
│ ├── sliver_page.dart
│ ├── sqflite_page.dart
│ ├── stepper_page.dart
│ ├── tab_page.dart
│ ├── textField.dart
│ ├── theme_page.dart
│ ├── tree_page.dart
│ ├── video_player.dart
│ └── wrap_page.dart
├── routes.dart
├── rxdart
│ ├── bloc_provider.dart
│ └── theme_select.dart
├── theme
│ └── app_theme.dart
├── utils
│ ├── HttpUtil.dart
│ ├── dbHelper.dart
│ ├── image_util.dart
│ └── share_util.dart
└── widget
│ ├── backdrop.dart
│ ├── node.dart
│ ├── searchbar_delegate.dart
│ ├── transform_animation_widget.dart
│ └── verification_code.dart
├── pubspec.lock
├── pubspec.yaml
└── test
├── study.dart
└── widget_test.dart
/.gitignore:
--------------------------------------------------------------------------------
1 | # Created by https://www.toptal.com/developers/gitignore/api/flutter
2 | # Edit at https://www.toptal.com/developers/gitignore?templates=flutter
3 |
4 | # IntelliJ related
5 | *.iml
6 | *.ipr
7 | *.iws
8 | .idea/
9 |
10 | ### Flutter ###
11 | # Flutter/Dart/Pub related
12 | **/doc/api/
13 | .dart_tool/
14 | .flutter-plugins
15 | .flutter-plugins-dependencies
16 | .packages
17 | .pub-cache/
18 | .pub/
19 | build/
20 | lib/generated_plugin_registrant.dart
21 |
22 | # Android related
23 | **/android/**/gradle-wrapper.jar
24 | **/android/.gradle
25 | **/android/captures/
26 | **/android/gradlew
27 | **/android/gradlew.bat
28 | **/android/key.properties
29 | **/android/local.properties
30 | **/android/**/GeneratedPluginRegistrant.java
31 |
32 | # iOS/XCode related
33 | **/ios/**/*.mode1v3
34 | **/ios/**/*.mode2v3
35 | **/ios/**/*.moved-aside
36 | **/ios/**/*.pbxuser
37 | **/ios/**/*.perspectivev3
38 | **/ios/**/*sync/
39 | **/ios/**/.sconsign.dblite
40 | **/ios/**/.tags*
41 | **/ios/**/.vagrant/
42 | **/ios/**/DerivedData/
43 | **/ios/**/Icon?
44 | **/ios/**/Pods/
45 | **/ios/**/.symlinks/
46 | **/ios/**/profile
47 | **/ios/**/xcuserdata
48 | **/ios/.generated/
49 | **/ios/Flutter/App.framework
50 | **/ios/Flutter/Flutter.framework
51 | **/ios/Flutter/Flutter.podspec
52 | **/ios/Flutter/Generated.xcconfig
53 | **/ios/Flutter/app.flx
54 | **/ios/Flutter/app.zip
55 | **/ios/Flutter/flutter_assets/
56 | **/ios/Flutter/flutter_export_environment.sh
57 | **/ios/ServiceDefinitions.json
58 | **/ios/Runner/GeneratedPluginRegistrant.*
59 |
60 | # Exceptions to above rules.
61 | !**/ios/**/default.mode1v3
62 | !**/ios/**/default.mode2v3
63 | !**/ios/**/default.pbxuser
64 | !**/ios/**/default.perspectivev3
65 | !/packages/flutter_tools/test/data/dart_dependencies_test/**/.packages
66 |
67 | # End of https://www.toptal.com/developers/gitignore/api/flutter
--------------------------------------------------------------------------------
/.idea/.gitignore:
--------------------------------------------------------------------------------
1 | # Default ignored files
2 | /workspace.xml
--------------------------------------------------------------------------------
/.idea/codeStyles/Project.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 | xmlns:android
14 |
15 | ^$
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 | xmlns:.*
25 |
26 | ^$
27 |
28 |
29 | BY_NAME
30 |
31 |
32 |
33 |
34 |
35 |
36 | .*:id
37 |
38 | http://schemas.android.com/apk/res/android
39 |
40 |
41 |
42 |
43 |
44 |
45 |
46 |
47 | .*:name
48 |
49 | http://schemas.android.com/apk/res/android
50 |
51 |
52 |
53 |
54 |
55 |
56 |
57 |
58 | name
59 |
60 | ^$
61 |
62 |
63 |
64 |
65 |
66 |
67 |
68 |
69 | style
70 |
71 | ^$
72 |
73 |
74 |
75 |
76 |
77 |
78 |
79 |
80 | .*
81 |
82 | ^$
83 |
84 |
85 | BY_NAME
86 |
87 |
88 |
89 |
90 |
91 |
92 | .*
93 |
94 | http://schemas.android.com/apk/res/android
95 |
96 |
97 | ANDROID_ATTRIBUTE_ORDER
98 |
99 |
100 |
101 |
102 |
103 |
104 | .*
105 |
106 | .*
107 |
108 |
109 | BY_NAME
110 |
111 |
112 |
113 |
114 |
115 |
116 |
--------------------------------------------------------------------------------
/.idea/dictionaries/lizhuoyuan.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | screenutil
5 |
6 |
7 |
--------------------------------------------------------------------------------
/.idea/dictionaries/zhuoy.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | baidu
5 | uint
6 |
7 |
8 |
--------------------------------------------------------------------------------
/.idea/libraries/Dart_SDK.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
--------------------------------------------------------------------------------
/.idea/libraries/Flutter_Plugins.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
--------------------------------------------------------------------------------
/.idea/misc.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
--------------------------------------------------------------------------------
/.idea/modules.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/.idea/vcs.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
--------------------------------------------------------------------------------
/.metadata:
--------------------------------------------------------------------------------
1 | # This file tracks properties of this Flutter project.
2 | # Used by Flutter tool to assess capabilities and perform upgrades etc.
3 | #
4 | # This file should be version controlled and should not be manually edited.
5 |
6 | version:
7 | revision: c7ea3ca377e909469c68f2ab878a5bc53d3cf66b
8 | channel: beta
9 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # flutter_app
2 |
3 | [相关内容的flutter专栏](https://zhuoyuan.blog.csdn.net/column/info/27607)
4 |
5 | [国际化教程](https://github.com/lizhuoyuan/flutter_intl_example)
6 |
7 | 
8 | 
9 | 
10 | 
11 | ## Getting Started
12 |
13 | For help getting started with Flutter, view our online
14 | [documentation](https://flutter.io/).
15 |
16 |
--------------------------------------------------------------------------------
/android/.gitignore:
--------------------------------------------------------------------------------
1 | *.iml
2 | *.class
3 | .gradle
4 | /local.properties
5 | /.idea/workspace.xml
6 | /.idea/libraries
7 | .DS_Store
8 | /build
9 | /captures
10 | GeneratedPluginRegistrant.java
11 |
--------------------------------------------------------------------------------
/android/.idea/gradle.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
43 |
44 |
--------------------------------------------------------------------------------
/android/.idea/misc.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
--------------------------------------------------------------------------------
/android/.idea/modules.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
--------------------------------------------------------------------------------
/android/.project:
--------------------------------------------------------------------------------
1 |
2 |
3 | android
4 | Project android created by Buildship.
5 |
6 |
7 |
8 |
9 | org.eclipse.buildship.core.gradleprojectbuilder
10 |
11 |
12 |
13 |
14 |
15 | org.eclipse.buildship.core.gradleprojectnature
16 |
17 |
18 |
--------------------------------------------------------------------------------
/android/.settings/org.eclipse.buildship.core.prefs:
--------------------------------------------------------------------------------
1 | connection.project.dir=
2 | eclipse.preferences.version=1
3 |
--------------------------------------------------------------------------------
/android/app/.classpath:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
--------------------------------------------------------------------------------
/android/app/.project:
--------------------------------------------------------------------------------
1 |
2 |
3 | app
4 | Project app created by Buildship.
5 |
6 |
7 |
8 |
9 | org.eclipse.jdt.core.javabuilder
10 |
11 |
12 |
13 |
14 | org.eclipse.buildship.core.gradleprojectbuilder
15 |
16 |
17 |
18 |
19 |
20 | org.eclipse.jdt.core.javanature
21 | org.eclipse.buildship.core.gradleprojectnature
22 |
23 |
24 |
--------------------------------------------------------------------------------
/android/app/.settings/org.eclipse.buildship.core.prefs:
--------------------------------------------------------------------------------
1 | connection.project.dir=..
2 | eclipse.preferences.version=1
3 |
--------------------------------------------------------------------------------
/android/app/build.gradle:
--------------------------------------------------------------------------------
1 | def localProperties = new Properties()
2 | def localPropertiesFile = rootProject.file('local.properties')
3 | if (localPropertiesFile.exists()) {
4 | localPropertiesFile.withReader('UTF-8') { reader ->
5 | localProperties.load(reader)
6 | }
7 | }
8 |
9 | def flutterRoot = localProperties.getProperty('flutter.sdk')
10 | if (flutterRoot == null) {
11 | throw new GradleException("Flutter SDK not found. Define location with flutter.sdk in the local.properties file.")
12 | }
13 |
14 | apply plugin: 'com.android.application'
15 | apply from: "$flutterRoot/packages/flutter_tools/gradle/flutter.gradle"
16 |
17 |
18 | android {
19 | compileSdkVersion 28
20 |
21 | lintOptions {
22 | disable 'InvalidPackage'
23 | }
24 |
25 | aaptOptions {
26 | noCompress "webp"
27 | }
28 |
29 | defaultConfig {
30 | // TODO: Specify your own unique Application ID (https://developer.android.com/studio/build/application-id.html).
31 | applicationId "com.example.flutterapp"
32 | minSdkVersion 18
33 | targetSdkVersion 29
34 | versionCode 1
35 | versionName "1.0"
36 | testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
37 | multiDexEnabled true
38 |
39 | }
40 |
41 | signingConfigs {
42 |
43 | }
44 |
45 | buildTypes {
46 |
47 | }
48 | }
49 |
50 | flutter {
51 | source '../..'
52 | }
53 |
54 | dependencies {
55 | testImplementation 'junit:junit:4.12'
56 | androidTestImplementation 'androidx.test:runner:1.1.0-alpha4'
57 | androidTestImplementation 'androidx.test.espresso:espresso-core:3.1.0-alpha4'
58 | implementation 'com.android.support:multidex:1.0.3'
59 | }
60 |
--------------------------------------------------------------------------------
/android/app/src/main/AndroidManifest.xml:
--------------------------------------------------------------------------------
1 |
4 |
5 |
9 |
10 |
11 |
12 |
17 |
22 |
29 |
33 |
36 |
37 |
38 |
39 |
40 |
41 |
44 |
45 |
46 |
47 |
48 |
49 |
50 |
51 |
52 |
53 |
54 |
55 |
56 |
57 |
58 |
63 |
66 |
67 |
68 |
69 |
72 |
73 |
74 |
--------------------------------------------------------------------------------
/android/app/src/main/java/com/example/flutterapp/MainActivity.java:
--------------------------------------------------------------------------------
1 | package com.example.flutterapp;
2 |
3 | import io.flutter.embedding.android.FlutterActivity;
4 |
5 | public class MainActivity extends FlutterActivity {
6 | }
7 |
--------------------------------------------------------------------------------
/android/app/src/main/res/drawable/launch_background.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
12 |
13 |
--------------------------------------------------------------------------------
/android/app/src/main/res/mipmap-hdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/lizhuoyuan/flutter_study/1dd31f1267d37c11c56a6af3e998026543968b9c/android/app/src/main/res/mipmap-hdpi/ic_launcher.png
--------------------------------------------------------------------------------
/android/app/src/main/res/mipmap-mdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/lizhuoyuan/flutter_study/1dd31f1267d37c11c56a6af3e998026543968b9c/android/app/src/main/res/mipmap-mdpi/ic_launcher.png
--------------------------------------------------------------------------------
/android/app/src/main/res/mipmap-xhdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/lizhuoyuan/flutter_study/1dd31f1267d37c11c56a6af3e998026543968b9c/android/app/src/main/res/mipmap-xhdpi/ic_launcher.png
--------------------------------------------------------------------------------
/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/lizhuoyuan/flutter_study/1dd31f1267d37c11c56a6af3e998026543968b9c/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png
--------------------------------------------------------------------------------
/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/lizhuoyuan/flutter_study/1dd31f1267d37c11c56a6af3e998026543968b9c/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png
--------------------------------------------------------------------------------
/android/app/src/main/res/values/string.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | 343254889799245
4 | flutter study.
5 |
6 |
--------------------------------------------------------------------------------
/android/app/src/main/res/values/styles.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
8 |
9 |
--------------------------------------------------------------------------------
/android/app/src/main/res/xml/filepaths.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
--------------------------------------------------------------------------------
/android/build.gradle:
--------------------------------------------------------------------------------
1 | buildscript {
2 | repositories {
3 | google()
4 | jcenter()
5 | }
6 |
7 | dependencies {
8 | classpath 'com.android.tools.build:gradle:4.0.1'
9 | }
10 | }
11 |
12 | allprojects {
13 | repositories {
14 | google()
15 | jcenter()
16 | }
17 | }
18 |
19 | rootProject.buildDir = '../build'
20 | subprojects {
21 | project.buildDir = "${rootProject.buildDir}/${project.name}"
22 | }
23 | subprojects {
24 | project.evaluationDependsOn(':app')
25 | }
26 |
27 | task clean(type: Delete) {
28 | delete rootProject.buildDir
29 | }
30 |
--------------------------------------------------------------------------------
/android/gradle.properties:
--------------------------------------------------------------------------------
1 | android.enableJetifier=true
2 | android.useAndroidX=true
3 | org.gradle.jvmargs=-Xmx1536M
4 | android.enableR8=true
5 |
--------------------------------------------------------------------------------
/android/gradle/wrapper/gradle-wrapper.jar:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/lizhuoyuan/flutter_study/1dd31f1267d37c11c56a6af3e998026543968b9c/android/gradle/wrapper/gradle-wrapper.jar
--------------------------------------------------------------------------------
/android/gradle/wrapper/gradle-wrapper.properties:
--------------------------------------------------------------------------------
1 | #Sun Sep 20 17:26:01 CST 2020
2 | distributionBase=GRADLE_USER_HOME
3 | distributionPath=wrapper/dists
4 | zipStoreBase=GRADLE_USER_HOME
5 | zipStorePath=wrapper/dists
6 | distributionUrl=https\://services.gradle.org/distributions/gradle-6.1.1-all.zip
7 |
--------------------------------------------------------------------------------
/android/gradlew:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env bash
2 |
3 | ##############################################################################
4 | ##
5 | ## Gradle start up script for UN*X
6 | ##
7 | ##############################################################################
8 |
9 | # Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
10 | DEFAULT_JVM_OPTS=""
11 |
12 | APP_NAME="Gradle"
13 | APP_BASE_NAME=`basename "$0"`
14 |
15 | # Use the maximum available, or set MAX_FD != -1 to use that value.
16 | MAX_FD="maximum"
17 |
18 | warn ( ) {
19 | echo "$*"
20 | }
21 |
22 | die ( ) {
23 | echo
24 | echo "$*"
25 | echo
26 | exit 1
27 | }
28 |
29 | # OS specific support (must be 'true' or 'false').
30 | cygwin=false
31 | msys=false
32 | darwin=false
33 | case "`uname`" in
34 | CYGWIN* )
35 | cygwin=true
36 | ;;
37 | Darwin* )
38 | darwin=true
39 | ;;
40 | MINGW* )
41 | msys=true
42 | ;;
43 | esac
44 |
45 | # Attempt to set APP_HOME
46 | # Resolve links: $0 may be a link
47 | PRG="$0"
48 | # Need this for relative symlinks.
49 | while [ -h "$PRG" ] ; do
50 | ls=`ls -ld "$PRG"`
51 | link=`expr "$ls" : '.*-> \(.*\)$'`
52 | if expr "$link" : '/.*' > /dev/null; then
53 | PRG="$link"
54 | else
55 | PRG=`dirname "$PRG"`"/$link"
56 | fi
57 | done
58 | SAVED="`pwd`"
59 | cd "`dirname \"$PRG\"`/" >/dev/null
60 | APP_HOME="`pwd -P`"
61 | cd "$SAVED" >/dev/null
62 |
63 | CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar
64 |
65 | # Determine the Java command to use to start the JVM.
66 | if [ -n "$JAVA_HOME" ] ; then
67 | if [ -x "$JAVA_HOME/jre/sh/java" ] ; then
68 | # IBM's JDK on AIX uses strange locations for the executables
69 | JAVACMD="$JAVA_HOME/jre/sh/java"
70 | else
71 | JAVACMD="$JAVA_HOME/bin/java"
72 | fi
73 | if [ ! -x "$JAVACMD" ] ; then
74 | die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME
75 |
76 | Please set the JAVA_HOME variable in your environment to match the
77 | location of your Java installation."
78 | fi
79 | else
80 | JAVACMD="java"
81 | which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
82 |
83 | Please set the JAVA_HOME variable in your environment to match the
84 | location of your Java installation."
85 | fi
86 |
87 | # Increase the maximum file descriptors if we can.
88 | if [ "$cygwin" = "false" -a "$darwin" = "false" ] ; then
89 | MAX_FD_LIMIT=`ulimit -H -n`
90 | if [ $? -eq 0 ] ; then
91 | if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then
92 | MAX_FD="$MAX_FD_LIMIT"
93 | fi
94 | ulimit -n $MAX_FD
95 | if [ $? -ne 0 ] ; then
96 | warn "Could not set maximum file descriptor limit: $MAX_FD"
97 | fi
98 | else
99 | warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT"
100 | fi
101 | fi
102 |
103 | # For Darwin, add options to specify how the application appears in the dock
104 | if $darwin; then
105 | GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\""
106 | fi
107 |
108 | # For Cygwin, switch paths to Windows format before running java
109 | if $cygwin ; then
110 | APP_HOME=`cygpath --path --mixed "$APP_HOME"`
111 | CLASSPATH=`cygpath --path --mixed "$CLASSPATH"`
112 | JAVACMD=`cygpath --unix "$JAVACMD"`
113 |
114 | # We build the pattern for arguments to be converted via cygpath
115 | ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null`
116 | SEP=""
117 | for dir in $ROOTDIRSRAW ; do
118 | ROOTDIRS="$ROOTDIRS$SEP$dir"
119 | SEP="|"
120 | done
121 | OURCYGPATTERN="(^($ROOTDIRS))"
122 | # Add a user-defined pattern to the cygpath arguments
123 | if [ "$GRADLE_CYGPATTERN" != "" ] ; then
124 | OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)"
125 | fi
126 | # Now convert the arguments - kludge to limit ourselves to /bin/sh
127 | i=0
128 | for arg in "$@" ; do
129 | CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -`
130 | CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option
131 |
132 | if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition
133 | eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"`
134 | else
135 | eval `echo args$i`="\"$arg\""
136 | fi
137 | i=$((i+1))
138 | done
139 | case $i in
140 | (0) set -- ;;
141 | (1) set -- "$args0" ;;
142 | (2) set -- "$args0" "$args1" ;;
143 | (3) set -- "$args0" "$args1" "$args2" ;;
144 | (4) set -- "$args0" "$args1" "$args2" "$args3" ;;
145 | (5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;;
146 | (6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;;
147 | (7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;;
148 | (8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;;
149 | (9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;;
150 | esac
151 | fi
152 |
153 | # Split up the JVM_OPTS And GRADLE_OPTS values into an array, following the shell quoting and substitution rules
154 | function splitJvmOpts() {
155 | JVM_OPTS=("$@")
156 | }
157 | eval splitJvmOpts $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS
158 | JVM_OPTS[${#JVM_OPTS[*]}]="-Dorg.gradle.appname=$APP_BASE_NAME"
159 |
160 | exec "$JAVACMD" "${JVM_OPTS[@]}" -classpath "$CLASSPATH" org.gradle.wrapper.GradleWrapperMain "$@"
161 |
--------------------------------------------------------------------------------
/android/gradlew.bat:
--------------------------------------------------------------------------------
1 | @if "%DEBUG%" == "" @echo off
2 | @rem ##########################################################################
3 | @rem
4 | @rem Gradle startup script for Windows
5 | @rem
6 | @rem ##########################################################################
7 |
8 | @rem Set local scope for the variables with windows NT shell
9 | if "%OS%"=="Windows_NT" setlocal
10 |
11 | @rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
12 | set DEFAULT_JVM_OPTS=
13 |
14 | set DIRNAME=%~dp0
15 | if "%DIRNAME%" == "" set DIRNAME=.
16 | set APP_BASE_NAME=%~n0
17 | set APP_HOME=%DIRNAME%
18 |
19 | @rem Find java.exe
20 | if defined JAVA_HOME goto findJavaFromJavaHome
21 |
22 | set JAVA_EXE=java.exe
23 | %JAVA_EXE% -version >NUL 2>&1
24 | if "%ERRORLEVEL%" == "0" goto init
25 |
26 | echo.
27 | echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
28 | echo.
29 | echo Please set the JAVA_HOME variable in your environment to match the
30 | echo location of your Java installation.
31 |
32 | goto fail
33 |
34 | :findJavaFromJavaHome
35 | set JAVA_HOME=%JAVA_HOME:"=%
36 | set JAVA_EXE=%JAVA_HOME%/bin/java.exe
37 |
38 | if exist "%JAVA_EXE%" goto init
39 |
40 | echo.
41 | echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%
42 | echo.
43 | echo Please set the JAVA_HOME variable in your environment to match the
44 | echo location of your Java installation.
45 |
46 | goto fail
47 |
48 | :init
49 | @rem Get command-line arguments, handling Windowz variants
50 |
51 | if not "%OS%" == "Windows_NT" goto win9xME_args
52 | if "%@eval[2+2]" == "4" goto 4NT_args
53 |
54 | :win9xME_args
55 | @rem Slurp the command line arguments.
56 | set CMD_LINE_ARGS=
57 | set _SKIP=2
58 |
59 | :win9xME_args_slurp
60 | if "x%~1" == "x" goto execute
61 |
62 | set CMD_LINE_ARGS=%*
63 | goto execute
64 |
65 | :4NT_args
66 | @rem Get arguments from the 4NT Shell from JP Software
67 | set CMD_LINE_ARGS=%$
68 |
69 | :execute
70 | @rem Setup the command line
71 |
72 | set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar
73 |
74 | @rem Execute Gradle
75 | "%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS%
76 |
77 | :end
78 | @rem End local scope for the variables with windows NT shell
79 | if "%ERRORLEVEL%"=="0" goto mainEnd
80 |
81 | :fail
82 | rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of
83 | rem the _cmd.exe /c_ return code!
84 | if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1
85 | exit /b 1
86 |
87 | :mainEnd
88 | if "%OS%"=="Windows_NT" endlocal
89 |
90 | :omega
91 |
--------------------------------------------------------------------------------
/android/settings.gradle:
--------------------------------------------------------------------------------
1 | include ':app'
2 |
3 | def flutterProjectRoot = rootProject.projectDir.parentFile.toPath()
4 |
5 | def plugins = new Properties()
6 | def pluginsFile = new File(flutterProjectRoot.toFile(), '.flutter-plugins')
7 | if (pluginsFile.exists()) {
8 | pluginsFile.withReader('UTF-8') { reader -> plugins.load(reader) }
9 | }
10 |
11 | plugins.each { name, path ->
12 | def pluginDirectory = flutterProjectRoot.resolve(path).resolve('android').toFile()
13 | include ":$name"
14 | project(":$name").projectDir = pluginDirectory
15 | }
16 |
--------------------------------------------------------------------------------
/flutter_app.iml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
--------------------------------------------------------------------------------
/flutter_app_android.iml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
--------------------------------------------------------------------------------
/images/a.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/lizhuoyuan/flutter_study/1dd31f1267d37c11c56a6af3e998026543968b9c/images/a.png
--------------------------------------------------------------------------------
/images/beauty.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/lizhuoyuan/flutter_study/1dd31f1267d37c11c56a6af3e998026543968b9c/images/beauty.jpg
--------------------------------------------------------------------------------
/images/home.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/lizhuoyuan/flutter_study/1dd31f1267d37c11c56a6af3e998026543968b9c/images/home.png
--------------------------------------------------------------------------------
/images/jay.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/lizhuoyuan/flutter_study/1dd31f1267d37c11c56a6af3e998026543968b9c/images/jay.jpg
--------------------------------------------------------------------------------
/images/login.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/lizhuoyuan/flutter_study/1dd31f1267d37c11c56a6af3e998026543968b9c/images/login.png
--------------------------------------------------------------------------------
/images/pavlova.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/lizhuoyuan/flutter_study/1dd31f1267d37c11c56a6af3e998026543968b9c/images/pavlova.png
--------------------------------------------------------------------------------
/images/pic1.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/lizhuoyuan/flutter_study/1dd31f1267d37c11c56a6af3e998026543968b9c/images/pic1.jpg
--------------------------------------------------------------------------------
/images/pic2.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/lizhuoyuan/flutter_study/1dd31f1267d37c11c56a6af3e998026543968b9c/images/pic2.jpg
--------------------------------------------------------------------------------
/images/pic3.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/lizhuoyuan/flutter_study/1dd31f1267d37c11c56a6af3e998026543968b9c/images/pic3.jpg
--------------------------------------------------------------------------------
/images/timg.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/lizhuoyuan/flutter_study/1dd31f1267d37c11c56a6af3e998026543968b9c/images/timg.jpg
--------------------------------------------------------------------------------
/ios/.gitignore:
--------------------------------------------------------------------------------
1 | .idea/
2 | .vagrant/
3 | .sconsign.dblite
4 | .svn/
5 |
6 | .DS_Store
7 | *.swp
8 | profile
9 |
10 | DerivedData/
11 | build/
12 | GeneratedPluginRegistrant.h
13 | GeneratedPluginRegistrant.m
14 |
15 | .generated/
16 |
17 | *.pbxuser
18 | *.mode1v3
19 | *.mode2v3
20 | *.perspectivev3
21 |
22 | !default.pbxuser
23 | !default.mode1v3
24 | !default.mode2v3
25 | !default.perspectivev3
26 |
27 | xcuserdata
28 |
29 | *.moved-aside
30 |
31 | *.pyc
32 | *sync/
33 | Icon?
34 | .tags*
35 |
36 | /Flutter/app.flx
37 | /Flutter/app.zip
38 | /Flutter/flutter_assets/
39 | /Flutter/App.framework
40 | /Flutter/Flutter.framework
41 | /Flutter/Generated.xcconfig
42 | /ServiceDefinitions.json
43 |
44 | Pods/
45 | .symlinks/
46 |
--------------------------------------------------------------------------------
/ios/Flutter/AppFrameworkInfo.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | CFBundleDevelopmentRegion
6 | en
7 | CFBundleExecutable
8 | App
9 | CFBundleIdentifier
10 | io.flutter.flutter.app
11 | CFBundleInfoDictionaryVersion
12 | 6.0
13 | CFBundleName
14 | App
15 | CFBundlePackageType
16 | FMWK
17 | CFBundleShortVersionString
18 | 1.0
19 | CFBundleSignature
20 | ????
21 | CFBundleVersion
22 | 1.0
23 | MinimumOSVersion
24 | 8.0
25 |
26 |
27 |
--------------------------------------------------------------------------------
/ios/Flutter/Debug.xcconfig:
--------------------------------------------------------------------------------
1 | #include "Pods/Target Support Files/Pods-Runner/Pods-Runner.debug.xcconfig"
2 | #include "Generated.xcconfig"
3 |
--------------------------------------------------------------------------------
/ios/Flutter/Flutter.podspec:
--------------------------------------------------------------------------------
1 | #
2 | # NOTE: This podspec is NOT to be published. It is only used as a local source!
3 | #
4 |
5 | Pod::Spec.new do |s|
6 | s.name = 'Flutter'
7 | s.version = '1.0.0'
8 | s.summary = 'High-performance, high-fidelity mobile apps.'
9 | s.description = <<-DESC
10 | Flutter provides an easy and productive way to build and deploy high-performance mobile apps for Android and iOS.
11 | DESC
12 | s.homepage = 'https://flutter.io'
13 | s.license = { :type => 'MIT' }
14 | s.author = { 'Flutter Dev Team' => 'flutter-dev@googlegroups.com' }
15 | s.source = { :git => 'https://github.com/flutter/engine', :tag => s.version.to_s }
16 | s.ios.deployment_target = '8.0'
17 | s.vendored_frameworks = 'Flutter.framework'
18 | end
19 |
--------------------------------------------------------------------------------
/ios/Flutter/Release.xcconfig:
--------------------------------------------------------------------------------
1 | #include "Pods/Target Support Files/Pods-Runner/Pods-Runner.release.xcconfig"
2 | #include "Generated.xcconfig"
3 |
--------------------------------------------------------------------------------
/ios/Flutter/flutter_export_environment.sh:
--------------------------------------------------------------------------------
1 | #!/bin/sh
2 | # This is a generated file; do not edit or check into version control.
3 | export "FLUTTER_ROOT=/Users/lizhuoyuan/Development/flutter"
4 | export "FLUTTER_APPLICATION_PATH=/Users/lizhuoyuan/Development/Project/flutter_study"
5 | export "FLUTTER_TARGET=lib/main.dart"
6 | export "FLUTTER_BUILD_DIR=build"
7 | export "SYMROOT=${SOURCE_ROOT}/../build/ios"
8 | export "FLUTTER_FRAMEWORK_DIR=/Users/lizhuoyuan/Development/flutter/bin/cache/artifacts/engine/ios"
9 | export "FLUTTER_BUILD_NAME=1.0.0"
10 | export "FLUTTER_BUILD_NUMBER=1"
11 |
--------------------------------------------------------------------------------
/ios/Podfile:
--------------------------------------------------------------------------------
1 | # Uncomment this line to define a global platform for your project
2 | platform :ios, '9.0'
3 |
4 | # CocoaPods analytics sends network stats synchronously affecting flutter build latency.
5 | ENV['COCOAPODS_DISABLE_STATS'] = 'true'
6 |
7 | project 'Runner', {
8 | 'Debug' => :debug,
9 | 'Profile' => :release,
10 | 'Release' => :release,
11 | }
12 |
13 | def parse_KV_file(file, separator='=')
14 | file_abs_path = File.expand_path(file)
15 | if !File.exists? file_abs_path
16 | return [];
17 | end
18 | generated_key_values = {}
19 | skip_line_start_symbols = ["#", "/"]
20 | File.foreach(file_abs_path) do |line|
21 | next if skip_line_start_symbols.any? { |symbol| line =~ /^\s*#{symbol}/ }
22 | plugin = line.split(pattern=separator)
23 | if plugin.length == 2
24 | podname = plugin[0].strip()
25 | path = plugin[1].strip()
26 | podpath = File.expand_path("#{path}", file_abs_path)
27 | generated_key_values[podname] = podpath
28 | else
29 | puts "Invalid plugin specification: #{line}"
30 | end
31 | end
32 | generated_key_values
33 | end
34 |
35 | target 'Runner' do
36 | # Flutter Pod
37 |
38 | copied_flutter_dir = File.join(__dir__, 'Flutter')
39 | copied_framework_path = File.join(copied_flutter_dir, 'Flutter.framework')
40 | copied_podspec_path = File.join(copied_flutter_dir, 'Flutter.podspec')
41 | unless File.exist?(copied_framework_path) && File.exist?(copied_podspec_path)
42 | # Copy Flutter.framework and Flutter.podspec to Flutter/ to have something to link against if the xcode backend script has not run yet.
43 | # That script will copy the correct debug/profile/release version of the framework based on the currently selected Xcode configuration.
44 | # CocoaPods will not embed the framework on pod install (before any build phases can generate) if the dylib does not exist.
45 |
46 | generated_xcode_build_settings_path = File.join(copied_flutter_dir, 'Generated.xcconfig')
47 | unless File.exist?(generated_xcode_build_settings_path)
48 | raise "Generated.xcconfig must exist. If you're running pod install manually, make sure flutter pub get is executed first"
49 | end
50 | generated_xcode_build_settings = parse_KV_file(generated_xcode_build_settings_path)
51 | cached_framework_dir = generated_xcode_build_settings['FLUTTER_FRAMEWORK_DIR'];
52 |
53 | unless File.exist?(copied_framework_path)
54 | FileUtils.cp_r(File.join(cached_framework_dir, 'Flutter.framework'), copied_flutter_dir)
55 | end
56 | unless File.exist?(copied_podspec_path)
57 | FileUtils.cp(File.join(cached_framework_dir, 'Flutter.podspec'), copied_flutter_dir)
58 | end
59 | end
60 |
61 | # Keep pod path relative so it can be checked into Podfile.lock.
62 | pod 'Flutter', :path => 'Flutter'
63 |
64 | # Plugin Pods
65 |
66 | # Prepare symlinks folder. We use symlinks to avoid having Podfile.lock
67 | # referring to absolute paths on developers' machines.
68 | system('rm -rf .symlinks')
69 | system('mkdir -p .symlinks/plugins')
70 | plugin_pods = parse_KV_file('../.flutter-plugins')
71 | plugin_pods.each do |name, path|
72 | symlink = File.join('.symlinks', 'plugins', name)
73 | File.symlink(path, symlink)
74 | pod name, :path => File.join(symlink, 'ios')
75 | end
76 | end
77 |
78 | # Prevent Cocoapods from embedding a second Flutter framework and causing an error with the new Xcode build system.
79 | install! 'cocoapods', :disable_input_output_paths => true
80 |
81 | post_install do |installer|
82 | installer.pods_project.targets.each do |target|
83 | target.build_configurations.each do |config|
84 | config.build_settings['ENABLE_BITCODE'] = 'NO'
85 | end
86 | end
87 | end
88 |
--------------------------------------------------------------------------------
/ios/Runner.xcodeproj/project.xcworkspace/contents.xcworkspacedata:
--------------------------------------------------------------------------------
1 |
2 |
4 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/ios/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme:
--------------------------------------------------------------------------------
1 |
2 |
5 |
8 |
9 |
15 |
21 |
22 |
23 |
24 |
25 |
31 |
32 |
33 |
34 |
40 |
41 |
42 |
43 |
44 |
45 |
56 |
58 |
64 |
65 |
66 |
67 |
68 |
69 |
75 |
77 |
83 |
84 |
85 |
86 |
88 |
89 |
92 |
93 |
94 |
--------------------------------------------------------------------------------
/ios/Runner.xcworkspace/contents.xcworkspacedata:
--------------------------------------------------------------------------------
1 |
2 |
4 |
6 |
7 |
9 |
10 |
11 |
--------------------------------------------------------------------------------
/ios/Runner/AppDelegate.h:
--------------------------------------------------------------------------------
1 | #import
2 | #import
3 |
4 | @interface AppDelegate : FlutterAppDelegate
5 |
6 | @end
7 |
--------------------------------------------------------------------------------
/ios/Runner/AppDelegate.m:
--------------------------------------------------------------------------------
1 | #include "AppDelegate.h"
2 | #include "GeneratedPluginRegistrant.h"
3 |
4 | @implementation AppDelegate
5 |
6 | - (BOOL)application:(UIApplication *)application
7 | didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
8 | [GeneratedPluginRegistrant registerWithRegistry:self];
9 | // Override point for customization after application launch.
10 | return [super application:application didFinishLaunchingWithOptions:launchOptions];
11 | }
12 |
13 | @end
14 |
--------------------------------------------------------------------------------
/ios/Runner/Assets.xcassets/AppIcon.appiconset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "size" : "20x20",
5 | "idiom" : "iphone",
6 | "filename" : "Icon-App-20x20@2x.png",
7 | "scale" : "2x"
8 | },
9 | {
10 | "size" : "20x20",
11 | "idiom" : "iphone",
12 | "filename" : "Icon-App-20x20@3x.png",
13 | "scale" : "3x"
14 | },
15 | {
16 | "size" : "29x29",
17 | "idiom" : "iphone",
18 | "filename" : "Icon-App-29x29@1x.png",
19 | "scale" : "1x"
20 | },
21 | {
22 | "size" : "29x29",
23 | "idiom" : "iphone",
24 | "filename" : "Icon-App-29x29@2x.png",
25 | "scale" : "2x"
26 | },
27 | {
28 | "size" : "29x29",
29 | "idiom" : "iphone",
30 | "filename" : "Icon-App-29x29@3x.png",
31 | "scale" : "3x"
32 | },
33 | {
34 | "size" : "40x40",
35 | "idiom" : "iphone",
36 | "filename" : "Icon-App-40x40@2x.png",
37 | "scale" : "2x"
38 | },
39 | {
40 | "size" : "40x40",
41 | "idiom" : "iphone",
42 | "filename" : "Icon-App-40x40@3x.png",
43 | "scale" : "3x"
44 | },
45 | {
46 | "size" : "60x60",
47 | "idiom" : "iphone",
48 | "filename" : "Icon-App-60x60@2x.png",
49 | "scale" : "2x"
50 | },
51 | {
52 | "size" : "60x60",
53 | "idiom" : "iphone",
54 | "filename" : "Icon-App-60x60@3x.png",
55 | "scale" : "3x"
56 | },
57 | {
58 | "size" : "20x20",
59 | "idiom" : "ipad",
60 | "filename" : "Icon-App-20x20@1x.png",
61 | "scale" : "1x"
62 | },
63 | {
64 | "size" : "20x20",
65 | "idiom" : "ipad",
66 | "filename" : "Icon-App-20x20@2x.png",
67 | "scale" : "2x"
68 | },
69 | {
70 | "size" : "29x29",
71 | "idiom" : "ipad",
72 | "filename" : "Icon-App-29x29@1x.png",
73 | "scale" : "1x"
74 | },
75 | {
76 | "size" : "29x29",
77 | "idiom" : "ipad",
78 | "filename" : "Icon-App-29x29@2x.png",
79 | "scale" : "2x"
80 | },
81 | {
82 | "size" : "40x40",
83 | "idiom" : "ipad",
84 | "filename" : "Icon-App-40x40@1x.png",
85 | "scale" : "1x"
86 | },
87 | {
88 | "size" : "40x40",
89 | "idiom" : "ipad",
90 | "filename" : "Icon-App-40x40@2x.png",
91 | "scale" : "2x"
92 | },
93 | {
94 | "size" : "76x76",
95 | "idiom" : "ipad",
96 | "filename" : "Icon-App-76x76@1x.png",
97 | "scale" : "1x"
98 | },
99 | {
100 | "size" : "76x76",
101 | "idiom" : "ipad",
102 | "filename" : "Icon-App-76x76@2x.png",
103 | "scale" : "2x"
104 | },
105 | {
106 | "size" : "83.5x83.5",
107 | "idiom" : "ipad",
108 | "filename" : "Icon-App-83.5x83.5@2x.png",
109 | "scale" : "2x"
110 | },
111 | {
112 | "size" : "1024x1024",
113 | "idiom" : "ios-marketing",
114 | "filename" : "Icon-App-1024x1024@1x.png",
115 | "scale" : "1x"
116 | }
117 | ],
118 | "info" : {
119 | "version" : 1,
120 | "author" : "xcode"
121 | }
122 | }
123 |
--------------------------------------------------------------------------------
/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-1024x1024@1x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/lizhuoyuan/flutter_study/1dd31f1267d37c11c56a6af3e998026543968b9c/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-1024x1024@1x.png
--------------------------------------------------------------------------------
/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@1x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/lizhuoyuan/flutter_study/1dd31f1267d37c11c56a6af3e998026543968b9c/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@1x.png
--------------------------------------------------------------------------------
/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/lizhuoyuan/flutter_study/1dd31f1267d37c11c56a6af3e998026543968b9c/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@2x.png
--------------------------------------------------------------------------------
/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@3x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/lizhuoyuan/flutter_study/1dd31f1267d37c11c56a6af3e998026543968b9c/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@3x.png
--------------------------------------------------------------------------------
/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@1x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/lizhuoyuan/flutter_study/1dd31f1267d37c11c56a6af3e998026543968b9c/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@1x.png
--------------------------------------------------------------------------------
/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/lizhuoyuan/flutter_study/1dd31f1267d37c11c56a6af3e998026543968b9c/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@2x.png
--------------------------------------------------------------------------------
/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@3x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/lizhuoyuan/flutter_study/1dd31f1267d37c11c56a6af3e998026543968b9c/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@3x.png
--------------------------------------------------------------------------------
/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@1x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/lizhuoyuan/flutter_study/1dd31f1267d37c11c56a6af3e998026543968b9c/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@1x.png
--------------------------------------------------------------------------------
/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/lizhuoyuan/flutter_study/1dd31f1267d37c11c56a6af3e998026543968b9c/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@2x.png
--------------------------------------------------------------------------------
/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@3x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/lizhuoyuan/flutter_study/1dd31f1267d37c11c56a6af3e998026543968b9c/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@3x.png
--------------------------------------------------------------------------------
/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/lizhuoyuan/flutter_study/1dd31f1267d37c11c56a6af3e998026543968b9c/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@2x.png
--------------------------------------------------------------------------------
/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@3x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/lizhuoyuan/flutter_study/1dd31f1267d37c11c56a6af3e998026543968b9c/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@3x.png
--------------------------------------------------------------------------------
/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@1x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/lizhuoyuan/flutter_study/1dd31f1267d37c11c56a6af3e998026543968b9c/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@1x.png
--------------------------------------------------------------------------------
/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/lizhuoyuan/flutter_study/1dd31f1267d37c11c56a6af3e998026543968b9c/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@2x.png
--------------------------------------------------------------------------------
/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-83.5x83.5@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/lizhuoyuan/flutter_study/1dd31f1267d37c11c56a6af3e998026543968b9c/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-83.5x83.5@2x.png
--------------------------------------------------------------------------------
/ios/Runner/Assets.xcassets/LaunchImage.imageset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "idiom" : "universal",
5 | "filename" : "LaunchImage.png",
6 | "scale" : "1x"
7 | },
8 | {
9 | "idiom" : "universal",
10 | "filename" : "LaunchImage@2x.png",
11 | "scale" : "2x"
12 | },
13 | {
14 | "idiom" : "universal",
15 | "filename" : "LaunchImage@3x.png",
16 | "scale" : "3x"
17 | }
18 | ],
19 | "info" : {
20 | "version" : 1,
21 | "author" : "xcode"
22 | }
23 | }
24 |
--------------------------------------------------------------------------------
/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/lizhuoyuan/flutter_study/1dd31f1267d37c11c56a6af3e998026543968b9c/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage.png
--------------------------------------------------------------------------------
/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/lizhuoyuan/flutter_study/1dd31f1267d37c11c56a6af3e998026543968b9c/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@2x.png
--------------------------------------------------------------------------------
/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@3x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/lizhuoyuan/flutter_study/1dd31f1267d37c11c56a6af3e998026543968b9c/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@3x.png
--------------------------------------------------------------------------------
/ios/Runner/Assets.xcassets/LaunchImage.imageset/README.md:
--------------------------------------------------------------------------------
1 | # Launch Screen Assets
2 |
3 | You can customize the launch screen with your own desired assets by replacing the image files in this directory.
4 |
5 | You can also do it by opening your Flutter project's Xcode project with `open ios/Runner.xcworkspace`, selecting `Runner/Assets.xcassets` in the Project Navigator and dropping in the desired images.
--------------------------------------------------------------------------------
/ios/Runner/Base.lproj/LaunchScreen.storyboard:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
--------------------------------------------------------------------------------
/ios/Runner/Base.lproj/Main.storyboard:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
--------------------------------------------------------------------------------
/ios/Runner/Info.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | CFBundleDevelopmentRegion
6 | en
7 | CFBundleExecutable
8 | $(EXECUTABLE_NAME)
9 | CFBundleIdentifier
10 | $(PRODUCT_BUNDLE_IDENTIFIER)
11 | CFBundleInfoDictionaryVersion
12 | 6.0
13 | CFBundleName
14 | flutter_app
15 | CFBundlePackageType
16 | APPL
17 | CFBundleShortVersionString
18 | 1.0
19 | CFBundleSignature
20 | ????
21 | CFBundleVersion
22 | 1
23 | LSRequiresIPhoneOS
24 |
25 | UILaunchStoryboardName
26 | LaunchScreen
27 | UIMainStoryboardFile
28 | Main
29 | UISupportedInterfaceOrientations
30 |
31 | UIInterfaceOrientationPortrait
32 | UIInterfaceOrientationLandscapeLeft
33 | UIInterfaceOrientationLandscapeRight
34 |
35 | UISupportedInterfaceOrientations~ipad
36 |
37 | UIInterfaceOrientationPortrait
38 | UIInterfaceOrientationPortraitUpsideDown
39 | UIInterfaceOrientationLandscapeLeft
40 | UIInterfaceOrientationLandscapeRight
41 |
42 | UIViewControllerBasedStatusBarAppearance
43 |
44 |
45 |
46 |
--------------------------------------------------------------------------------
/ios/Runner/main.m:
--------------------------------------------------------------------------------
1 | #import
2 | #import
3 | #import "AppDelegate.h"
4 |
5 | int main(int argc, char* argv[]) {
6 | @autoreleasepool {
7 | return UIApplicationMain(argc, argv, nil, NSStringFromClass([AppDelegate class]));
8 | }
9 | }
10 |
--------------------------------------------------------------------------------
/lib/bean/number_attribution.dart:
--------------------------------------------------------------------------------
1 | /*
2 | * author: Created by 李卓原 on 2018/11/19.
3 | * email: zhuoyuan93@gmail.com
4 | * 号码归属地信息的实体类
5 | */
6 |
7 | class NumberAttribution {
8 | String province;
9 | String city;
10 | String areacode;
11 | String zip;
12 | String company;
13 | String card;
14 |
15 | NumberAttribution(
16 | {this.province,
17 | this.city,
18 | this.areacode,
19 | this.zip,
20 | this.company,
21 | this.card});
22 |
23 | NumberAttribution.fromJson(Map json) {
24 | province = json['province'];
25 | city = json['city'];
26 | areacode = json['areacode'];
27 | zip = json['zip'];
28 | company = json['company'];
29 | card = json['card'];
30 | }
31 |
32 | Map toJson() {
33 | final Map data = new Map();
34 | data['province'] = this.province;
35 | data['city'] = this.city;
36 | data['areacode'] = this.areacode;
37 | data['zip'] = this.zip;
38 | data['company'] = this.company;
39 | data['card'] = this.card;
40 | return data;
41 | }
42 | }
43 |
--------------------------------------------------------------------------------
/lib/bean/picker_data.dart:
--------------------------------------------------------------------------------
1 | const PickerData = '''
2 | [
3 | {
4 | "a": [
5 | {
6 | "a1": [
7 | 1,
8 | 2,
9 | 3,
10 | 4
11 | ]
12 | },
13 | {
14 | "a2": [
15 | 5,
16 | 6,
17 | 7,
18 | 8,
19 | 555,
20 | 666,
21 | 999
22 | ]
23 | },
24 | {
25 | "a3": [
26 | 9,
27 | 10,
28 | 11,
29 | 12
30 | ]
31 | }
32 | ]
33 | },
34 | {
35 | "b": [
36 | {
37 | "b1": [
38 | 11,
39 | 22,
40 | 33,
41 | 44
42 | ]
43 | },
44 | {
45 | "b2": [
46 | 55,
47 | 66,
48 | 77,
49 | 88,
50 | 99,
51 | 1010,
52 | 1111,
53 | 1212,
54 | 1313,
55 | 1414,
56 | 1515,
57 | 1616
58 | ]
59 | },
60 | {
61 | "b3": [
62 | 1010,
63 | 1111,
64 | 1212,
65 | 1313,
66 | 1414,
67 | 1515,
68 | 1616
69 | ]
70 | }
71 | ]
72 | },
73 | {
74 | "c": [
75 | {
76 | "c1": [
77 | "a",
78 | "b",
79 | "c"
80 | ]
81 | },
82 | {
83 | "c2": [
84 | "aa",
85 | "bb",
86 | "cc"
87 | ]
88 | },
89 | {
90 | "c3": [
91 | "aaa",
92 | "bbb",
93 | "ccc"
94 | ]
95 | },
96 | {
97 | "c4": [
98 | "a1",
99 | "b1",
100 | "c1",
101 | "d1"
102 | ]
103 | }
104 | ]
105 | }
106 | ]
107 | ''';
108 |
109 | const PickerData2 = '''
110 | [
111 | [
112 | 1,
113 | 2,
114 | 3,
115 | 4
116 | ],
117 | [
118 | 11,
119 | 22,
120 | 33,
121 | 44
122 | ],
123 | [
124 | "aaa",
125 | "bbb",
126 | "ccc"
127 | ]
128 | ]
129 | ''';
--------------------------------------------------------------------------------
/lib/common/constant.dart:
--------------------------------------------------------------------------------
1 | const PLACES_API_KEY = 'AIzaSyA17XB_P_TwEdg_MWQFZvKuyWYmaQunmdY';
2 |
--------------------------------------------------------------------------------
/lib/locale/i18n_en.json:
--------------------------------------------------------------------------------
1 | {
2 | "app_title": "My Application Title",
3 | "main_title": "My Main Title",
4 | "homePage":"Home Page"
5 | }
6 |
--------------------------------------------------------------------------------
/lib/locale/i18n_zh.json:
--------------------------------------------------------------------------------
1 | {
2 | "app_title": "我的应用标题",
3 | "main_title": "我的主要标题",
4 | "homePage":"主页面"
5 |
6 | }
7 |
--------------------------------------------------------------------------------
/lib/locale/translations_delegate.dart:
--------------------------------------------------------------------------------
1 | /*
2 | * author: Created by 李卓原 on 2018/11/22.
3 | * email: zhuoyuan93@gmail.com
4 | *
5 | */
6 |
7 | import 'dart:convert';
8 | import 'dart:async';
9 |
10 | import 'package:flutter/material.dart';
11 | import 'package:flutter/services.dart';
12 |
13 | class Translations {
14 | Locale locale;
15 | static Map _localizedValues;
16 |
17 | Translations(Locale locale) {
18 | this.locale = locale;
19 | _localizedValues = null;
20 | }
21 |
22 | static Translations of(BuildContext context) =>
23 | Localizations.of(context, Translations);
24 |
25 | String get(String key) => _localizedValues[key] ?? '** $key not found';
26 |
27 | static Future load(Locale locale) async {
28 | Translations translations = new Translations(locale);
29 | String jsonContent =
30 | await rootBundle.loadString('lib/locale/i18n_${locale.languageCode}.json');
31 | _localizedValues = json.decode(jsonContent);
32 | return translations;
33 | }
34 |
35 | get currentLanguage => locale.languageCode;
36 | }
37 |
38 | class TranslationsDelegate extends LocalizationsDelegate {
39 | const TranslationsDelegate();
40 |
41 | ///验证支持的语言
42 | @override
43 | bool isSupported(Locale locale) => ['en', 'zh'].contains(locale.languageCode);
44 |
45 | @override
46 | Future load(Locale locale) => Translations.load(locale);
47 |
48 | @override
49 | bool shouldReload(LocalizationsDelegate old) => false;
50 | }
51 |
--------------------------------------------------------------------------------
/lib/main.dart:
--------------------------------------------------------------------------------
1 | import 'dart:async';
2 |
3 | import 'package:flutter/material.dart';
4 | import 'package:flutter_app/locale/translations_delegate.dart';
5 | import 'package:flutter_app/routes.dart';
6 | import 'package:flutter_app/rxdart/bloc_provider.dart';
7 | import 'package:flutter_app/theme/app_theme.dart';
8 | import 'package:flutter_localizations/flutter_localizations.dart';
9 | import 'package:flutter_screenutil/flutter_screenutil.dart';
10 |
11 | bool get isInDebugMode {
12 | bool inDebugMode = false;
13 | assert(inDebugMode = true);
14 | return inDebugMode;
15 | }
16 |
17 | /// Reports [error] along with its [stackTrace] to Sentry.io.
18 | Future _reportError(dynamic error, dynamic stackTrace) async {
19 | print('-Caught error: $error');
20 |
21 | // Errors thrown in development mode are unlikely to be interesting. You can
22 | // check if you are running in dev mode using an assertion and omit sending
23 | // the report.
24 | if (isInDebugMode) {
25 | print(stackTrace);
26 | print('In dev mode. Not sending report to Sentry.io.');
27 | return;
28 | }
29 |
30 | print('Reporting to Sentry.io...');
31 |
32 | print('Success! Event ID: ');
33 | }
34 |
35 | Future main() async {
36 | WidgetsFlutterBinding.ensureInitialized();
37 |
38 | // This captures errors reported by the Flutter framework.
39 | FlutterError.onError = (FlutterErrorDetails details) async {
40 | if (isInDebugMode) {
41 | // In development mode simply print to console.
42 | FlutterError.dumpErrorToConsole(details);
43 | } else {
44 | // In production mode report to the application zone to report to
45 | // Sentry.
46 | Zone.current.handleUncaughtError(details.exception, details.stack);
47 | }
48 | };
49 | runApp(BlocProvider(child: const MyApp()));
50 | //
51 | // runZonedGuarded>(() async {
52 | // runApp(BlocProvider(child: const MyApp()));
53 | // }, (error, stackTrace) async {
54 | // await _reportError(error, stackTrace);
55 | // });
56 | }
57 |
58 | class MyApp extends StatelessWidget {
59 | const MyApp();
60 |
61 | @override
62 | Widget build(BuildContext context) {
63 | //AppModel appModel = AppModel();
64 | final themeSelect = BlocProvider.of(context);
65 | return StreamBuilder(
66 | builder: _builder,
67 | stream: themeSelect.value,
68 | initialData: false,
69 | );
70 | }
71 |
72 | Widget _builder(BuildContext context, AsyncSnapshot snapshot) {
73 | return ScreenUtilInit(
74 | allowFontScaling: false,
75 | designSize: Size(360, 720),
76 | child: MaterialApp(
77 | title: 'Welcome to Flutter_study',
78 | theme: snapshot.data ? AppTheme().darkTheme : AppTheme().lightTheme,
79 | localizationsDelegates: [
80 | const TranslationsDelegate(),
81 | GlobalMaterialLocalizations.delegate,
82 | GlobalWidgetsLocalizations.delegate,
83 | ],
84 | supportedLocales: [Locale("zh"), Locale("en")],
85 | initialRoute: '/',
86 | routes: routes,
87 | onGenerateRoute: onGenerateRoute,
88 | navigatorObservers: [
89 | Ob1(),
90 | ],
91 | ));
92 | }
93 | }
94 |
95 | class Ob1 extends NavigatorObserver {
96 | @override
97 | void didPush(Route route, Route previousRoute) {
98 | super.didPush(route, previousRoute);
99 | print('从${previousRoute?.settings?.name}到${route?.settings?.name}');
100 | }
101 | }
102 |
--------------------------------------------------------------------------------
/lib/model/AppModel.dart:
--------------------------------------------------------------------------------
1 | /*
2 | * Created by 李卓原 on 2018/10/8.
3 | * email: zhuoyuan93@gmail.com
4 | *
5 | */
6 |
7 | import 'package:flutter/material.dart';
8 | import 'package:scoped_model/scoped_model.dart';
9 |
10 | class AppModel extends Model {
11 | bool _isNight = false;
12 | ThemeData _darkTheme = ThemeData(
13 | backgroundColor: Colors.black,
14 | primaryColor: Colors.black,
15 | brightness: Brightness.dark);
16 |
17 | ThemeData _lightTheme = ThemeData(
18 | backgroundColor: Colors.white,
19 | primaryColor: Colors.green,
20 | primarySwatch: Colors.blue,
21 | brightness: Brightness.light);
22 |
23 | get theme => _isNight ? _darkTheme : _lightTheme;
24 |
25 | get isNight => _isNight;
26 |
27 | ///true为夜间模式
28 | void changeTheme(bool value) {
29 | _isNight = value;
30 | notifyListeners();
31 | }
32 |
33 | static AppModel of(BuildContext context) => ScopedModel.of(context);
34 | }
35 |
--------------------------------------------------------------------------------
/lib/model/note.dart:
--------------------------------------------------------------------------------
1 | /*
2 | * author: Created by 李卓原 on 2019/3/12.
3 | * email: zhuoyuan93@gmail.com
4 | *
5 | */
6 |
7 | class Note {
8 | int _pointID;
9 | String _image;
10 | int _contractId;
11 | int _publicationId;
12 | double _pointLng;
13 | double _pointLat;
14 |
15 | Note(this._pointID, this._image, this._contractId, this._publicationId,
16 | this._pointLng, this._pointLat);
17 |
18 | int get pointID => _pointID;
19 |
20 | String get image => _image;
21 |
22 | int get contractId => _contractId;
23 |
24 | int get publicationId => _publicationId;
25 |
26 | double get pointLng => _pointLng;
27 |
28 | double get pointLat => _pointLat;
29 |
30 | Map toMap() {
31 | var map = new Map();
32 | map['pointid'] = _pointID;
33 | map['image'] = _image;
34 | map['contractId'] = _contractId;
35 | map['publicationId'] = _publicationId;
36 | map['pointLng'] = _pointLng;
37 | map['pointLat'] = _pointLat;
38 | return map;
39 | }
40 |
41 | Note.fromMap(Map map) {
42 | this._publicationId = map['publicationId'];
43 | this._pointID = map['pointid'];
44 | this._image = map['image'];
45 | this._contractId = map['contractId'];
46 | this._pointLng = map['pointLng'];
47 | this._pointLat = map['pointLat'];
48 | }
49 | }
50 |
--------------------------------------------------------------------------------
/lib/page/ChipPage.dart:
--------------------------------------------------------------------------------
1 | /*
2 | * Created by 李卓原 on 2018/10/9.
3 | * email: zhuoyuan93@gmail.com
4 | *
5 | */
6 |
7 | import 'package:flutter/material.dart';
8 | import 'package:flutter_app/bean/number_attribution.dart';
9 |
10 | class ChipPage extends StatefulWidget {
11 | @override
12 | State createState() => ChipState();
13 | }
14 |
15 | class ChipState extends State {
16 | List list = List.generate(10, (index) => 'index:$index');
17 |
18 | @override
19 | Widget build(BuildContext context) {
20 | formatJson();
21 | return Scaffold(
22 | appBar: AppBar(
23 | title: Text('chip'),
24 | actions: [
25 | const RightTopIconButton(),
26 | ],
27 | ),
28 | body: Wrap(
29 | spacing: 10.0,
30 | children: list
31 | .map((i) => Chip(
32 | label: Text(i.toString()),
33 | onDeleted: () {
34 | setState(() {
35 | list.remove(i);
36 | });
37 | },
38 | avatar: Icon(
39 | Icons.hourglass_full,
40 | color: Colors.red,
41 | ),
42 | ))
43 | .toList(),
44 | ),
45 | );
46 | }
47 |
48 | void formatJson() {
49 | var jsons = {
50 | "province": "浙江",
51 | "city": "杭州",
52 | "areacode": "0571",
53 | "zip": "310000",
54 | "company": "中国移动",
55 | "card": ""
56 | };
57 | NumberAttribution numberAttribution = NumberAttribution.fromJson(jsons);
58 | var toJ = numberAttribution.toJson();
59 | print(toJ);
60 | }
61 | }
62 |
63 | class RightTopIconButton extends StatelessWidget {
64 | const RightTopIconButton();
65 |
66 | @override
67 | Widget build(BuildContext context) {
68 | print('buildIconButton');
69 | return IconButton(
70 | icon: Icon(Icons.add),
71 | onPressed: null,
72 | /*onPressed: () {
73 | setState(() {
74 | list.add('index:${list.length}');
75 | });
76 | }*/
77 | );
78 | }
79 | }
80 |
--------------------------------------------------------------------------------
/lib/page/ExpansionTilePage.dart:
--------------------------------------------------------------------------------
1 | /*
2 | * Created by 李卓原 on 2018/10/9.
3 | * email: zhuoyuan93@gmail.com
4 | *
5 | */
6 |
7 | import 'package:flutter/material.dart';
8 |
9 | class ExpansionTilePage extends StatefulWidget {
10 | @override
11 | State createState() => ExpandsionState();
12 | }
13 |
14 | class ExpandsionState extends State
15 | with SingleTickerProviderStateMixin {
16 | Animation animation;
17 | AnimationController animationController;
18 |
19 | var _iconColor;
20 |
21 | List list = [
22 | {'index': 1, 'opened': true},
23 | {'index': 2, 'opened': false},
24 | {'index': 3, 'opened': false},
25 | ];
26 |
27 | @override
28 | void initState() {
29 | super.initState();
30 | animationController =
31 | AnimationController(vsync: this, duration: Duration(milliseconds: 200));
32 | animation = Tween(begin: 0.0, end: 0.125).animate(animationController);
33 | }
34 |
35 | @override
36 | Widget build(BuildContext context) {
37 | return Scaffold(
38 | appBar: AppBar(
39 | title: Text('ExpansionTile'),
40 | ),
41 | body: ListView(children: [
42 | ExpansionTile(
43 | title: Text('title'),
44 | leading: Icon(Icons.title),
45 | trailing: RotationTransition(
46 | turns: animation,
47 | child: Icon(
48 | Icons.add,
49 | color: _iconColor,
50 | ),
51 | ),
52 | onExpansionChanged: (bool value) {
53 | print(value);
54 | setState(() {
55 | if (value) {
56 | animationController.forward();
57 | _iconColor = Colors.red;
58 | } else {
59 | animationController.reverse();
60 | _iconColor = Colors.green;
61 | }
62 | });
63 | },
64 | children: [
65 | ListTile(
66 | title: Text('1'),
67 | leading: Icon(Icons.map),
68 | )
69 | ],
70 | ),
71 | ExpansionPanelList.radio(
72 | expansionCallback: (int i, bool opened) {
73 | print(i);
74 | print(opened);
75 | setState(() {
76 | list[i]['opened'] = !opened;
77 | });
78 | },
79 | children: list
80 | .map((item) => ExpansionPanelRadio(
81 | value: item,
82 | headerBuilder: (context, opened) {
83 | return ListTile(
84 | title: Text("更多内容+${item['index']}"),
85 | );
86 | },
87 | body: Text('aa${item['index']}')))
88 | .toList(),
89 | )
90 | ]));
91 | }
92 | }
93 |
--------------------------------------------------------------------------------
/lib/page/FavoriteWidget.dart:
--------------------------------------------------------------------------------
1 | import 'package:flutter/material.dart';
2 |
3 | class FavoriteWidget extends StatefulWidget {
4 | @override
5 | State createState() => FavoriteWidgetState();
6 | }
7 |
8 | class FavoriteWidgetState extends State {
9 | bool _isFavorited = true;
10 | int _favoriteCount = 41;
11 |
12 | void _toggleFavorite() {
13 | setState(() {
14 | // If the lake is currently favorited, unfavorite it.
15 | if (_isFavorited) {
16 | _favoriteCount -= 1;
17 | _isFavorited = false;
18 | // Otherwise, favorite it.
19 | } else {
20 | _favoriteCount += 1;
21 | _isFavorited = true;
22 | }
23 | });
24 | }
25 |
26 | @override
27 | Widget build(BuildContext context) {
28 | return Row(
29 | mainAxisSize: MainAxisSize.min,
30 | children: [
31 | Container(
32 | child: IconButton(
33 | icon: _isFavorited ? Icon(Icons.star) : Icon(Icons.star_border),
34 | color: Colors.green,
35 | onPressed: _toggleFavorite),
36 | ),
37 | SizedBox(
38 | width: 20.0,
39 | child: new Container(
40 | child: new Text('$_favoriteCount'),
41 | ),
42 | ),
43 | ],
44 | );
45 | }
46 | }
47 |
--------------------------------------------------------------------------------
/lib/page/FutureBuilderPage.dart:
--------------------------------------------------------------------------------
1 | /*
2 | * Created by 李卓原 on 2018/9/30.
3 | * email: zhuoyuan93@gmail.com
4 | * 关于状态改变引起的不必要的页面刷新:
5 | * https://github.com/flutter/flutter/issues/11426#issuecomment-414047398
6 | *
7 | * 2019/8/8 豆瓣api已挂...择日更新代码
8 | */
9 |
10 | import 'dart:async';
11 |
12 | import 'package:async/async.dart';
13 | import 'package:flutter/material.dart';
14 | import 'package:flutter_app/utils/HttpUtil.dart';
15 |
16 | class FutureBuilderPage extends StatefulWidget {
17 | @override
18 | State createState() => FutureBuilderState();
19 | }
20 |
21 | class FutureBuilderState extends State {
22 | String title = 'FutureBuilder使用';
23 | AsyncMemoizer _memoizer = AsyncMemoizer();
24 |
25 | _gerData() {
26 | return _memoizer.runOnce(() async {
27 | return await HttpUtil()
28 | .get('http://rap2api.taobao.org/app/mock/162762/skill/dragoon');
29 | });
30 | }
31 |
32 | Future _refreshData() async {
33 | setState(() {
34 | _memoizer = AsyncMemoizer();
35 | });
36 | }
37 |
38 | /* @override
39 | void initState() {
40 | super.initState();
41 | _testGet();
42 | }
43 |
44 | Future _testGet() async {
45 | var response = await HttpUtil().get('https://www.apiopen.top/novelApi');
46 |
47 | print(response['data']);
48 | }*/
49 |
50 | @override
51 | Widget build(BuildContext context) {
52 | return Scaffold(
53 | appBar: AppBar(
54 | title: Text(title),
55 | ),
56 | floatingActionButton: FloatingActionButton(
57 | onPressed: () {
58 | setState(() {
59 | title = title + '.';
60 | });
61 | },
62 | child: Icon(Icons.title),
63 | ),
64 | body: RefreshIndicator(
65 | onRefresh: _refreshData,
66 | child: FutureBuilder(
67 | builder: _buildFuture,
68 | future: _gerData(), // 用户定义的需要异步执行的代码,类型为Future或者null的变量或函数
69 | ),
70 | ),
71 | );
72 | }
73 |
74 | ///snapshot就是_calculation在时间轴上执行过程的状态快照
75 | Widget _buildFuture(BuildContext context, AsyncSnapshot snapshot) {
76 | switch (snapshot.connectionState) {
77 | case ConnectionState.none:
78 | print('还没有开始网络请求');
79 | return Text('还没有开始网络请求');
80 | case ConnectionState.active:
81 | print('active');
82 | return Text('ConnectionState.active');
83 | case ConnectionState.waiting:
84 | print('waiting');
85 | return Center(
86 | child: CircularProgressIndicator(),
87 | );
88 | case ConnectionState.done:
89 | print('done');
90 | if (snapshot.hasError) return Text('Error: ${snapshot.error}');
91 | return _createListView(context, snapshot);
92 | default:
93 | return Text('还没有开始网络请求');
94 | }
95 | }
96 |
97 | Widget _createListView(BuildContext context, AsyncSnapshot snapshot) {
98 | List movies = snapshot.data['data'];
99 | return ListView.builder(
100 | itemBuilder: (context, index) => _itemBuilder(context, index, movies),
101 | itemCount: movies.length * 2,
102 | );
103 | }
104 |
105 | Widget _itemBuilder(BuildContext context, int index, skills) {
106 | if (index.isOdd) {
107 | return Divider();
108 | }
109 | index = index ~/ 2;
110 | return ListTile(
111 | title: Text(skills[index]['name']),
112 | leading: Text(skills[index]['type']),
113 | trailing: Text(skills[index]['slv']),
114 | );
115 | }
116 | }
117 |
--------------------------------------------------------------------------------
/lib/page/GridViewPage.dart:
--------------------------------------------------------------------------------
1 | import 'package:flutter/material.dart';
2 | import 'package:flutter_app/page/MyHomePage.dart';
3 | import 'package:flutter_appavailability/flutter_appavailability.dart';
4 | import 'package:url_launcher/url_launcher.dart';
5 |
6 | class GridViewPage extends StatefulWidget {
7 | @override
8 | State createState() {
9 | return GridViewState();
10 | }
11 | }
12 |
13 | class GridViewState extends State {
14 | final List listData = [];
15 |
16 | @override
17 | void initState() {
18 | super.initState();
19 | for (int i = 0; i < 20; i++) {
20 | listData.add(new ListItem("我是测试标题$i", Icons.cake));
21 | }
22 | }
23 |
24 | @override
25 | Widget build(BuildContext context) {
26 | return Scaffold(
27 | appBar: AppBar(
28 | title: Text('GridView'),
29 | ),
30 | body: GridView.builder(
31 | gridDelegate: SliverGridDelegateWithFixedCrossAxisCount(
32 | crossAxisCount: 2, //每行2个
33 | mainAxisSpacing: 10.0, //主轴(竖直)方向间距
34 | crossAxisSpacing: 10.0, //纵轴(水平)方向间距
35 | childAspectRatio: 1.0 //纵轴缩放比例
36 | ),
37 | itemCount: listData.length,
38 | itemBuilder: (BuildContext context, int index) {
39 | return ListItemWidget(listData[index], index);
40 | },
41 | ),
42 | );
43 | }
44 | }
45 |
46 | class ListItem {
47 | final String title;
48 | final IconData iconData;
49 |
50 | ListItem(this.title, this.iconData);
51 | }
52 |
53 | class ListItemWidget extends StatelessWidget {
54 | final ListItem listItem;
55 | final int index;
56 |
57 | ListItemWidget(this.listItem, this.index);
58 |
59 | @override
60 | Widget build(BuildContext context) {
61 | return GestureDetector(
62 | child: Container(
63 | color: Colors.green,
64 | child: Column(
65 | mainAxisAlignment: MainAxisAlignment.center,
66 | children: [
67 | Hero(
68 | tag: listItem.title,
69 | child: Image(
70 | image: AssetImage(index == 5 ? 'images/jay.jpg' : 'images/pic3.jpg'),
71 | width: 150.0,
72 | height: 150.0,
73 | fit: BoxFit.fill,
74 | /*listItem.iconData,
75 | size: 50.0,
76 | color: Colors.white,*/
77 | )),
78 | Text(
79 | listItem.title,
80 | style: TextStyle(color: Colors.white),
81 | )
82 | ],
83 | ),
84 | ),
85 | onTap: () async {
86 | /*Scaffold.of(context).showSnackBar(new SnackBar(
87 | content: new Text(listItem.title),
88 | ));*/
89 | /*Navigator.of(context).push(PageRouteBuilder(pageBuilder:
90 | (BuildContext context, Animation animation,
91 | Animation secondaryAnimation) {
92 | return MyHomePage(tag: listItem.title);
93 | }));*/
94 |
95 | print(await AppAvailability.checkAvailability("com.whatsapp"));
96 |
97 | print(await AppAvailability.checkAvailability("com.facebook.katana"));
98 | print(await AppAvailability.checkAvailability("com.twitter.android"));
99 | print(await AppAvailability.checkAvailability("com.instagram.android"));
100 |
101 | // print(await canLaunch(FB_PAGE));
102 |
103 | // const url = "https://wa.me/?text=Your Message here";
104 |
105 | var url = 'https://www.instagram.com/juno.horoscopes/';
106 |
107 | if (await canLaunch(url)) {
108 | await launch(url);
109 | } else {
110 | throw 'There was a problem to open the url: $url';
111 | }
112 | // print(await canLaunch(encoded));
113 | },
114 | );
115 | }
116 | static const String FACEBOOK_URL =
117 | 'https://www.facebook.com/%E6%B5%8B%E6%B5%8B%E5%9B%BD%E9%99%85%E7%89%88-617960732190357';
118 | static const String FB_PAGE = 'fb://page/617960732190357';
119 | }
120 |
--------------------------------------------------------------------------------
/lib/page/ImagePage.dart:
--------------------------------------------------------------------------------
1 | import 'dart:async';
2 | import 'package:flutter/material.dart';
3 | import 'package:dio/dio.dart';
4 |
5 | class ImagePage extends StatefulWidget {
6 | @override
7 | createState() => ImageState();
8 | }
9 |
10 | class ImageState extends State {
11 | var image = "images/beauty.jpg";
12 |
13 | @override
14 | Widget build(BuildContext context) {
15 | return Scaffold(
16 | appBar: AppBar(
17 | title: Text('Image使用示例'),
18 | ),
19 | body: ListView(
20 | children: [
21 | Image.asset(
22 | "images/beauty.jpg",
23 | width: 200.0,
24 | height: 200.0,
25 | fit: BoxFit.contain,
26 | color: Colors.greenAccent,
27 | colorBlendMode: BlendMode.colorBurn,
28 | alignment: Alignment.bottomRight,
29 | ),
30 | //资源图片
31 |
32 | new Directionality(
33 | textDirection: TextDirection.ltr,
34 | child: Image.asset(
35 | image,
36 | width: 200.0,
37 | height: 200.0,
38 | fit: BoxFit.contain,
39 | ),
40 | ),
41 |
42 | InkWell(
43 | child: Text(
44 | '点击切换图片',
45 | textAlign: TextAlign.center,
46 | style: TextStyle(fontWeight: FontWeight.bold),
47 | ),
48 | onTap: () {
49 | setState(() {
50 | if (image == 'images/beauty.jpg')
51 | image = "images/jay.jpg";
52 | else
53 | image = 'images/beauty.jpg';
54 | });
55 | },
56 | ),
57 | RaisedButton(
58 | onPressed: _getData,
59 | child: Text(
60 | 'getdata',
61 | style: TextStyle(color: Colors.white),
62 | ),
63 | color: Colors.green,
64 | ),
65 | ],
66 | ),
67 | );
68 | }
69 |
70 | Future _getData() async {
71 | print('开始请求');
72 | Dio dio = new Dio();
73 | //Response response = await dio.get("http://api.douban.com/v2/movie/top250");
74 | Response response = await dio
75 | .post("http://test.hadoop.network/loan/get_supported_operators");
76 | var data = response.data;
77 | print(data);
78 | print(data['data']);
79 |
80 | print('请求结束');
81 | }
82 | }
83 |
--------------------------------------------------------------------------------
/lib/page/KeepAlivePage.dart:
--------------------------------------------------------------------------------
1 | /*
2 | * Created by 李卓原 on 2018/9/19.
3 | * email: zhuoyuan93@gmail.com
4 | *
5 | */
6 |
7 | import 'package:flutter/material.dart';
8 | import 'package:flutter_app/page/alive_home_page.dart';
9 |
10 | class KeepAliveDemo extends StatefulWidget {
11 | @override
12 | _KeepAliveDemoState createState() => _KeepAliveDemoState();
13 | }
14 |
15 | class _KeepAliveDemoState extends State
16 | with SingleTickerProviderStateMixin {
17 | TabController _controller;
18 |
19 | @override
20 | void initState() {
21 | // TODO: implement initState
22 | super.initState();
23 | _controller = TabController(length: 3, vsync: this);
24 | }
25 |
26 | @override
27 | void dispose() {
28 | print('dispose');
29 | _controller.dispose();
30 | super.dispose();
31 | }
32 |
33 | @override
34 | Widget build(BuildContext context) {
35 | return Scaffold(
36 | appBar: AppBar(
37 | bottom: TabBar(
38 | controller: _controller,
39 | tabs: [
40 | Tab(icon: Icon(Icons.directions_car)),
41 | Tab(icon: Icon(Icons.directions_transit)),
42 | Tab(icon: Icon(Icons.directions_bike)),
43 | ],
44 | ),
45 | title: Text('Keep Alive Demo'),
46 | ),
47 | body: TabBarView(
48 | controller: _controller,
49 | children: [
50 | AliveHomePage(
51 | title: 'Keep Alive demo',
52 | ),
53 | AliveHomePage(
54 | title: 'Keep Alive demo',
55 | ),
56 | AliveHomePage(
57 | title: 'Keep Alive demo',
58 | ),
59 | ],
60 | ),
61 | );
62 | }
63 | }
64 |
--------------------------------------------------------------------------------
/lib/page/MyHomePage.dart:
--------------------------------------------------------------------------------
1 | import 'package:flutter/material.dart';
2 |
3 | import 'FavoriteWidget.dart';
4 |
5 | class MyHomePage extends StatelessWidget {
6 | final String tag;
7 |
8 | MyHomePage({this.tag, Key key}) : super(key: key);
9 |
10 | @override
11 | Widget build(BuildContext context) {
12 |
13 | Widget titleSection = Container(
14 | padding: const EdgeInsets.all(32.0),
15 | child: Row(
16 | children: [
17 | Expanded(
18 | child: new Column(
19 | crossAxisAlignment: CrossAxisAlignment.start,
20 | children: [
21 | Container(
22 | padding: const EdgeInsets.only(bottom: 8.0),
23 | child: Text(
24 | 'Oeschinen Lake Campground',
25 | style: TextStyle(fontWeight: FontWeight.bold),
26 | ),
27 | ),
28 | Text(
29 | 'Kandersteg, Switzerland',
30 | style: TextStyle(color: Colors.grey[500]),
31 | )
32 | ],
33 | ),
34 | ),
35 | FavoriteWidget()
36 | ],
37 | ),
38 | );
39 |
40 | Column buildButtonColumn(IconData icon, String label) {
41 | Color color = Theme.of(context).primaryColor;
42 | return new Column(
43 | mainAxisSize: MainAxisSize.min,
44 | mainAxisAlignment: MainAxisAlignment.center,
45 | children: [
46 | new Icon(icon, color: color),
47 | new Container(
48 | margin: const EdgeInsets.only(top: 8.0),
49 | child: new Text(
50 | label,
51 | style: new TextStyle(
52 | fontSize: 12.0,
53 | fontWeight: FontWeight.w400,
54 | color: color,
55 | ),
56 | ),
57 | ),
58 | ],
59 | );
60 | }
61 |
62 | Widget buttonSection = Container(
63 | child: Row(
64 | mainAxisAlignment: MainAxisAlignment.spaceEvenly,
65 | children: [
66 | buildButtonColumn(Icons.call, 'CALL'),
67 | buildButtonColumn(Icons.near_me, 'ROUTE'),
68 | buildButtonColumn(Icons.share, 'SHARE'),
69 | ],
70 | ),
71 | );
72 | Widget textSection = new Container(
73 | padding: const EdgeInsets.symmetric(vertical: 22.0, horizontal: 32.0),
74 | child: new Text(
75 | '''
76 | Lake1 Oeschinen lies at the foot of the Blüemlisalp in the Bernese Alps. Situated 1,578 meters above sea level, it is one of the larger Alpine Lakes. A gondola ride from Kandersteg, followed by a half-hour walk through pastures and pine forest, leads you to the lake, which warms to 20 degrees Celsius in the summer.
77 | ''',
78 | softWrap: true,
79 | ),
80 | );
81 |
82 | FloatingActionButton floatBtn = FloatingActionButton(
83 | foregroundColor: Colors.red,
84 | onPressed: _floatOnPress,
85 | tooltip: '长按显示',
86 | child: Icon(Icons.favorite),
87 | backgroundColor: Colors.transparent,
88 | );
89 |
90 | RaisedButton btn = new RaisedButton(
91 | onPressed: () {
92 | Navigator.of(context).pushNamed('Pavlova');
93 | },
94 | color: Colors.green,
95 | child: new Text('go to Pavlova',
96 | style: new TextStyle(color: Colors.white)));
97 | return Scaffold(
98 | appBar:
99 | AppBar(title: Text('Startup Name Generator'), actions: []),
100 | body: ListView(
101 | children: [
102 | Hero(
103 | tag: tag ?? 'hero',
104 | child: Image.asset(
105 | 'images/jay.jpg',
106 | width: 600.0,
107 | height: 240.0,
108 | fit: BoxFit.cover,
109 | ),
110 | ),
111 | titleSection,
112 | buttonSection,
113 | textSection,
114 | Container(
115 | padding: EdgeInsets.symmetric(horizontal: 32.0),
116 | child: btn,
117 | )
118 | ],
119 | ),
120 | floatingActionButton: floatBtn,
121 | );
122 | }
123 |
124 | void _floatOnPress() {
125 | print('add asda');
126 | //routes['asda'] = (_) => AliveHomePage();
127 | }
128 | }
129 |
--------------------------------------------------------------------------------
/lib/page/PavlovaPage.dart:
--------------------------------------------------------------------------------
1 | import 'package:flutter/cupertino.dart';
2 | import 'package:flutter/material.dart';
3 | import 'package:flutter_app/locale/translations_delegate.dart';
4 |
5 | class PavlovaPage extends StatefulWidget {
6 | @override
7 | State createState() {
8 | return PavlovaState();
9 | }
10 | }
11 |
12 | class PavlovaState extends State {
13 | @override
14 | Widget build(BuildContext context) {
15 | Container ratings = Container(
16 | decoration: BoxDecoration(
17 | color: Colors.white70,
18 | border: Border.all(width: 1.0, color: Colors.red),
19 | borderRadius: BorderRadius.all(Radius.circular(20.0)),
20 | ),
21 | padding: EdgeInsets.all(20.0),
22 | child: Row(mainAxisAlignment: MainAxisAlignment.spaceEvenly, children: [
23 | Row(
24 | mainAxisSize: MainAxisSize.min,
25 | children: [
26 | Icon(Icons.star, color: Colors.green[500]),
27 | Icon(Icons.star, color: Colors.green[500]),
28 | Icon(Icons.star, color: Colors.green[500]),
29 | Icon(Icons.star, color: Colors.grey),
30 | Icon(Icons.star, color: Colors.grey),
31 | ],
32 | ),
33 | Text('170 Reviews',
34 | style: TextStyle(
35 | color: Colors.black,
36 | fontWeight: FontWeight.w800,
37 | fontFamily: 'Roboto',
38 | letterSpacing: 0.5,
39 | fontSize: 20.0,
40 | ))
41 | ]));
42 |
43 | var descTextStyle = new TextStyle(
44 | color: Colors.black,
45 | fontWeight: FontWeight.w800,
46 | fontFamily: 'Roboto',
47 | letterSpacing: 0.5,
48 | fontSize: 18.0,
49 | height: 2.0,
50 | );
51 |
52 | var threeColumn = DefaultTextStyle.merge(
53 | style: descTextStyle,
54 | child: Container(
55 | padding: new EdgeInsets.all(20.0),
56 | child: Row(
57 | mainAxisAlignment: MainAxisAlignment.spaceEvenly,
58 | children: [
59 | Column(
60 | crossAxisAlignment: CrossAxisAlignment.center,
61 | children: [
62 | Icon(
63 | Icons.kitchen,
64 | color: Colors.green,
65 | ),
66 | Text('PREP'),
67 | Text('25 min'),
68 | ],
69 | ),
70 | Column(
71 | children: [
72 | Icon(
73 | Icons.timer,
74 | color: Colors.green,
75 | ),
76 | Text('COOK'),
77 | Text('1 hr'),
78 | ],
79 | ),
80 | Column(
81 | children: [
82 | Icon(
83 | Icons.restaurant,
84 | color: Colors.green,
85 | ),
86 | Text('FEEDS'),
87 | Text('4 - 6'),
88 | ],
89 | )
90 | ],
91 | ),
92 | ));
93 |
94 | var titleText =
95 | Text('ADSAD SA;DKJJ AS;KDA', style: TextStyle(fontSize: 22.0));
96 | var subTitle = Container(
97 | padding: EdgeInsets.symmetric(vertical: 20.0),
98 | child: Text(
99 | 'aaaaaaaaaaadsa ;kasdlka;sda sdaljdh ljahd ashd kahs dkaj hsld hasljd hals hdah '),
100 | );
101 | var ratIcon = Container(
102 | padding: new EdgeInsets.fromLTRB(20.0, 30.0, 20.0, 20.0),
103 | child: Column(
104 | children: [titleText, subTitle, ratings, threeColumn],
105 | ));
106 | return Scaffold(
107 | appBar: AppBar(title: Text('Pavlova')),
108 | body: Container(
109 | child: Column(
110 | children: [
111 | ratIcon,
112 | Hero(
113 | tag: '${Translations.of(context).get('homePage')}',
114 | child: Image.network(
115 | 'http://h.hiphotos.baidu.com/zhidao/wh%3D450%2C600/sign=0d023672312ac65c67506e77cec29e27/9f2f070828381f30dea167bbad014c086e06f06c.jpg',
116 | height: 230.0,
117 | width: double.infinity),
118 | ),
119 |
120 | /* Image.asset(
121 | 'images/beauty.jpg',
122 | height: 230.0,
123 | width: double.infinity,
124 | )*/
125 | ],
126 | ),
127 | ));
128 | }
129 | }
130 |
--------------------------------------------------------------------------------
/lib/page/RandomWords.dart:
--------------------------------------------------------------------------------
1 | import 'package:english_words/english_words.dart';
2 | import 'package:flutter/material.dart';
3 | import 'package:flutter_screenutil/flutter_screenutil.dart';
4 |
5 | class RandomWords extends StatefulWidget {
6 | @override
7 | createState() => RandomWordsState();
8 | }
9 |
10 | class RandomWordsState extends State {
11 | final _suggestions = [];
12 | final _biggerFont = const TextStyle(fontSize: 18.0);
13 | final _saved = new Set();
14 |
15 | @override
16 | Widget build(BuildContext context) {
17 | return Scaffold(
18 | appBar: AppBar(title: Text('Startup Name Generator'), actions: [
19 | IconButton(
20 | icon: Icon(Icons.list),
21 | onPressed: _pushSaved,
22 | )
23 | ]),
24 | body: _buildSuggestions(),
25 | );
26 | }
27 |
28 | Widget _buildSuggestions() {
29 | return ListView.builder(
30 | itemBuilder: (context, i) {
31 | if (i.isOdd) return Divider();
32 | final index = i ~/ 2;
33 | if (index >= _suggestions.length) {
34 | _suggestions.addAll(generateWordPairs().take(10));
35 | }
36 | return _buildRow(_suggestions[index], i);
37 | },
38 | padding: const EdgeInsets.all(16.0),
39 | );
40 | }
41 |
42 | Widget _buildRow(WordPair pair, int i) {
43 | final alreadySaved = _saved.contains(pair);
44 |
45 | return ListTile(
46 | title: Text(pair.asPascalCase, style: _biggerFont),
47 | trailing: Icon(
48 | alreadySaved ? Icons.favorite : Icons.favorite_border,
49 | color: alreadySaved ? Colors.red : null,
50 | ),
51 | onTap: () {
52 | print(i);
53 | setState(() {
54 | if (alreadySaved) {
55 | _saved.remove(pair);
56 | } else {
57 | _saved.add(pair);
58 | }
59 | });
60 | },
61 | );
62 | }
63 |
64 | void _pushSaved() {
65 | Navigator.of(context).push(MaterialPageRoute(builder: (context) {
66 | final tiles = _saved.map((pair) {
67 | return ListTile(
68 | title: Text(pair.asPascalCase, style: _biggerFont),
69 | );
70 | });
71 | final divided =
72 | ListTile.divideTiles(tiles: tiles, context: context).toList();
73 | return Scaffold(
74 | appBar: AppBar(
75 | title: Text('Saved Suggestions'),
76 | ),
77 | body: ListView(children: divided),
78 | );
79 | }));
80 | }
81 | }
82 |
--------------------------------------------------------------------------------
/lib/page/ScreenUtilTest.dart:
--------------------------------------------------------------------------------
1 | /*
2 | * Created by 李卓原 on 2018/9/29.
3 | * email: zhuoyuan93@gmail.com
4 | *
5 | */
6 |
7 | import 'package:flutter/material.dart';
8 | import 'package:flutter_screenutil/flutter_screenutil.dart';
9 |
10 | class ScreenUtilTest extends StatefulWidget {
11 | final String title;
12 |
13 | const ScreenUtilTest({Key key, this.title}) : super(key: key);
14 |
15 | @override
16 | _MyHomePageState createState() => new _MyHomePageState();
17 | }
18 |
19 | class _MyHomePageState extends State {
20 | @override
21 | Widget build(BuildContext context) {
22 | printScreenInformation();
23 | return Scaffold(
24 | appBar: AppBar(
25 | title: Text(widget.title),
26 | ),
27 | body: SingleChildScrollView(
28 | child: Column(
29 | crossAxisAlignment: CrossAxisAlignment.center,
30 | children: [
31 | Row(
32 | children: [
33 | Container(
34 | padding: EdgeInsets.all(ScreenUtil().setWidth(10)),
35 | width: 180.w,
36 | height: 200.h,
37 | color: Colors.red,
38 | child: Text(
39 | '我的实际宽度:${0.5.sw}dp \n'
40 | '我的实际高度:${ScreenUtil().setHeight(200)}dp',
41 | style: TextStyle(color: Colors.white, fontSize: ScreenUtil().setSp(12)),
42 | ),
43 | ),
44 | Container(
45 | padding: EdgeInsets.all(ScreenUtil().setWidth(10)),
46 | width: ScreenUtil().setWidth(180),
47 | height: ScreenUtil().setHeight(200),
48 | color: Colors.blue,
49 | child: Text(
50 | '我的设计稿宽度: 180dp \n'
51 | '我的设计稿高度: 200dp',
52 | style: TextStyle(color: Colors.white, fontSize: ScreenUtil().setSp(12))),
53 | ),
54 | ],
55 | ),
56 | Container(
57 | padding: EdgeInsets.all(ScreenUtil().setWidth(10)),
58 | width: 100.r,
59 | height: 100.r,
60 | color: Colors.green,
61 | child: Text(
62 | '我是正方形,边长是100',
63 | style: TextStyle(
64 | color: Colors.white,
65 | fontSize: ScreenUtil().setSp(12),
66 | ),
67 | ),
68 | ),
69 | Text('设备宽度:${ScreenUtil().screenWidth}dp'),
70 | Text('设备高度:${ScreenUtil().screenHeight}dp'),
71 | Text('设备的像素密度:${ScreenUtil().pixelRatio}'),
72 | Text('底部安全区距离:${ScreenUtil().bottomBarHeight}dp'),
73 | Text('状态栏高度:${ScreenUtil().statusBarHeight}dp'),
74 | Text(
75 | '实际宽度与设计稿的比例:${ScreenUtil().scaleWidth}',
76 | textAlign: TextAlign.center,
77 | ),
78 | Text(
79 | '实际高度与设计稿的比例:${ScreenUtil().scaleHeight}',
80 | textAlign: TextAlign.center,
81 | ),
82 | SizedBox(
83 | height: 50.h,
84 | ),
85 | Text('系统的字体缩放比例:${ScreenUtil().textScaleFactor}'),
86 | Column(
87 | crossAxisAlignment: CrossAxisAlignment.start,
88 | children: [
89 | Text(
90 | '我的文字大小在设计稿上是16dp,不会随着系统的文字缩放比例变化',
91 | style: TextStyle(
92 | color: Colors.black,
93 | fontSize: 16.sp,
94 | ),
95 | ),
96 | Text(
97 | '我的文字大小在设计稿上是16dp,会随着系统的文字缩放比例变化',
98 | style: TextStyle(
99 | color: Colors.black,
100 | fontSize: 16.ssp,
101 | ),
102 | ),
103 | ],
104 | )
105 | ],
106 | ),
107 | ),
108 | );
109 | }
110 |
111 | void printScreenInformation() {
112 | print('设备宽度:${1.sw}dp');
113 | print('设备高度:${1.sh}dp');
114 | print('设备的像素密度:${ScreenUtil().pixelRatio}');
115 | print('底部安全区距离:${ScreenUtil().bottomBarHeight}dp');
116 | print('状态栏高度:${ScreenUtil().statusBarHeight}dp');
117 | print('实际宽度的dp与设计稿px的比例:${ScreenUtil().scaleWidth}');
118 | print('实际高度的dp与设计稿px的比例:${ScreenUtil().scaleHeight}');
119 | print('宽度和字体相对于设计稿放大的比例:${ScreenUtil().scaleWidth * ScreenUtil().pixelRatio}');
120 | print('高度相对于设计稿放大的比例:${ScreenUtil().scaleHeight * ScreenUtil().pixelRatio}');
121 | print('系统的字体缩放比例:${ScreenUtil().textScaleFactor}');
122 | print('屏幕宽度的0.5:${0.5.sw}dp');
123 | print('屏幕高度的0.5:${0.5.sh}dp');
124 | }
125 | }
126 |
--------------------------------------------------------------------------------
/lib/page/StateWidgetPage.dart:
--------------------------------------------------------------------------------
1 | /*
2 | 父组件管理子组件状态(控制背景色和文字)
3 | 子组件控制自己的状态(按下和抬起的边框高亮)
4 | */
5 |
6 | import 'dart:io';
7 |
8 | import 'package:flutter/material.dart';
9 |
10 | class StateWidgetPage extends StatefulWidget {
11 | @override
12 | State createState() {
13 | return StateWidgetState();
14 | }
15 | }
16 |
17 | class StateWidgetState extends State {
18 | bool _active = false;
19 |
20 | @override
21 | Widget build(BuildContext context) {
22 | return Scaffold(
23 | appBar: AppBar(
24 | title: Text('state'),
25 | ),
26 | body: Container(
27 | child: TabBox(active: _active, onClick: _onclick),
28 | ),
29 | );
30 | }
31 |
32 | _onclick() {
33 | setState(() {
34 | _active = !_active;
35 | });
36 | }
37 | }
38 |
39 | class TabBox extends StatefulWidget {
40 | TabBox({Key key, this.active: false, @required this.onClick})
41 | : super(key: key);
42 | final bool active;
43 | final onClick;
44 |
45 | @override
46 | State createState() {
47 | return TabBoxState();
48 | }
49 | }
50 |
51 | class TabBoxState extends State {
52 | bool _highlight = false;
53 |
54 | Widget build(BuildContext context) {
55 | return GestureDetector(
56 | onTapDown: _handleTapDown,
57 | // Handle the tap events in the order that
58 | onTapUp: _handleTapUp,
59 | // they occur: down, up, tap, cancel
60 | onTap: _handleTap,
61 | onTapCancel: _handleTapCancel,
62 |
63 | child: Container(
64 | child: Center(
65 | child: Text(
66 | widget.active ? 'Active' : 'Inactive',
67 | style: TextStyle(
68 | fontSize: 32.0,
69 | color: Colors.white,
70 | decorationColor: Colors.yellow),
71 | ),
72 | ),
73 | width: 200.0,
74 | height: 200.0,
75 | decoration: BoxDecoration(
76 | color: widget.active ? Colors.lightGreen[700] : Colors.grey[600],
77 | border: _highlight
78 | ? Border.all(
79 | color: Colors.yellow[700],
80 | width: 10.0,
81 | )
82 | : null,
83 | ),
84 | ),
85 | );
86 | }
87 |
88 | void _handleTapDown(TapDownDetails details) {
89 | setState(() {
90 | _highlight = true;
91 | });
92 | }
93 |
94 | void _handleTapUp(TapUpDetails details) {
95 | _highlight = false;
96 | }
97 |
98 | void _handleTap() {
99 | widget.onClick();
100 | }
101 |
102 | void _handleTapCancel() {
103 | _highlight = false;
104 | }
105 | }
106 |
--------------------------------------------------------------------------------
/lib/page/SwiperPage.dart:
--------------------------------------------------------------------------------
1 | /*
2 | * Created by 李卓原 on 2018/9/19.
3 | * email: zhuoyuan93@gmail.com
4 | *
5 | */
6 |
7 | import 'package:flutter/material.dart';
8 | import 'package:flutter_swiper/flutter_swiper.dart';
9 | import 'package:url_launcher/url_launcher.dart';
10 |
11 | class SwiperPage extends StatefulWidget {
12 | @override
13 | SwiperPageState createState() {
14 | return SwiperPageState();
15 | }
16 | }
17 |
18 | class SwiperPageState extends State {
19 | @override
20 | Widget build(BuildContext context) {
21 | return Scaffold(
22 | appBar: AppBar(
23 | title: Text('轮播组件'),
24 | ),
25 | body: Container(
26 | width: MediaQuery.of(context).size.width,
27 | height: 200.0,
28 | child: Swiper(
29 | itemBuilder: _swiperBuilder,
30 | itemCount: 3,
31 | pagination: new SwiperPagination(
32 | builder: DotSwiperPaginationBuilder(
33 | color: Colors.black54,
34 | activeColor: Colors.white,
35 | )),
36 | control: new SwiperControl(),
37 | scrollDirection: Axis.horizontal,
38 | autoplay: true,
39 | onTap: _goOtherApp,
40 | )),
41 | );
42 | }
43 |
44 | Widget _swiperBuilder(BuildContext context, int index) {
45 | return (Image.network(
46 | "http://via.placeholder.com/350x150",
47 | fit: BoxFit.fill,
48 | ));
49 | }
50 |
51 | void _goOtherApp(int index) async {
52 | const url = 'flutter://li.zhuoyuan'; //这个url就是由scheme和host组成的 :scheme://host
53 | if (await canLaunch(url)) {
54 | await launch(url);
55 | } else {
56 | throw 'Could not launch $url';
57 | }
58 | }
59 | }
60 |
--------------------------------------------------------------------------------
/lib/page/alive_home_page.dart:
--------------------------------------------------------------------------------
1 | /*
2 | * Created by 李卓原 on 2018/9/19.
3 | * email: zhuoyuan93@gmail.com
4 | * 实现原理,使用AutomaticKeepAliveClientMixin,并重写wantKeepAlive方法,让状态不被回收掉。
5 | */
6 |
7 | import 'package:flutter/material.dart';
8 | import 'package:url_launcher/url_launcher.dart';
9 |
10 | class AliveHomePage extends StatefulWidget {
11 | AliveHomePage({Key key, this.title}) : super(key: key);
12 | final String title;
13 |
14 | @override
15 | _MyHomePageState createState() => new _MyHomePageState();
16 | }
17 |
18 | class _MyHomePageState extends State with AutomaticKeepAliveClientMixin {
19 | int _counter = 0;
20 | static const String OFFICIAL_WEBSITE = 'https://www.junohoro.com/';
21 |
22 | @override
23 | bool get wantKeepAlive => true;
24 |
25 | void _incrementCounter() async {
26 | const text = 'Juno:您身邊的星座專家,占星、塔羅、合盤全都有!$OFFICIAL_WEBSITE';
27 |
28 | String url = "whatsapp://send?text=$text";
29 | if (await canLaunch(url)) {
30 | await launch(url);
31 | } else {
32 | print('Could not launch $url');
33 | }
34 | }
35 |
36 | @override
37 | Widget build(BuildContext context) {
38 | super.build(context);
39 | return new Scaffold(
40 | body: new Center(
41 | child: new Column(
42 | mainAxisAlignment: MainAxisAlignment.center,
43 | children: [
44 | new Text(
45 | 'You have pushed the button this many times:',
46 | ),
47 | new Text(
48 | '$_counter',
49 | style: Theme.of(context).textTheme.button,
50 | ),
51 | ],
52 | ),
53 | ),
54 | floatingActionButton: new FloatingActionButton(
55 | onPressed: _incrementCounter,
56 | tooltip: 'Increment',
57 | child: Icon(Icons.add),
58 | ),
59 | );
60 | }
61 | }
62 |
--------------------------------------------------------------------------------
/lib/page/animation_page.dart:
--------------------------------------------------------------------------------
1 | /*
2 | * Created by 李卓原 on 2018/9/27.
3 | * email: zhuoyuan93@gmail.com
4 | *
5 | */
6 |
7 | import 'package:flutter/material.dart';
8 | import 'package:flutter_app/widget/transform_animation_widget.dart';
9 |
10 | class AnimationPage extends StatefulWidget {
11 | @override
12 | State createState() => AnimationState();
13 | }
14 |
15 | class AnimationState extends State
16 | with SingleTickerProviderStateMixin {
17 | AnimationController imageAnimationController;
18 | Animation animation;
19 |
20 | IconData _icon = Icons.done;
21 |
22 | @override
23 | void initState() {
24 | super.initState();
25 |
26 | imageAnimationController = AnimationController(
27 | vsync: this,
28 | duration: Duration(seconds: 2),
29 | );
30 |
31 | animation = Tween(begin: 0.0, end: 200.0).animate(imageAnimationController)
32 | ..addStatusListener(_imageAnimationStatusListener);
33 | /*animation =
34 | CurvedAnimation(parent: imageAnimationController, curve: Curves.easeIn)
35 | ..addStatusListener(_imageAnimationStatusListener);*/
36 | }
37 |
38 | @override
39 | Widget build(BuildContext context) {
40 | return Scaffold(
41 | appBar: AppBar(
42 | title: Text('动画'),
43 | actions: [
44 | AnimatedSwitcher(
45 | transitionBuilder: (Widget child, Animation animation) {
46 | return ScaleTransition(scale: animation, child: child);
47 | },
48 | duration: Duration(milliseconds: 200),
49 | child: IconButton(
50 | key: ValueKey(_icon),
51 | icon: Icon(_icon),
52 | onPressed: () {
53 | setState(() {
54 | _icon =
55 | _icon == Icons.done ? Icons.delete_forever : Icons.done;
56 | });
57 | },
58 | ),
59 | )
60 | ],
61 | ),
62 | floatingActionButton: FloatingActionButton(
63 | onPressed: _startAnimation,
64 | child: Icon(Icons.play_arrow),
65 | ),
66 | body: Column(
67 | mainAxisSize: MainAxisSize.max,
68 | crossAxisAlignment: CrossAxisAlignment.center,
69 | children: [
70 | TransformAnimationWidget(animation: animation),
71 | /* GrowTransition(
72 | animation: animation,
73 | child: Image.asset(
74 | 'images/pic3.jpg',
75 | fit: BoxFit.fill,
76 | ),
77 | ),*/
78 | SizedBox(
79 | height: 50.0,
80 | width: MediaQuery.of(context).size.width,
81 | ),
82 | AnimationImage(
83 | animation: animation,
84 | )
85 | ],
86 | ));
87 | }
88 |
89 | @override
90 | void dispose() {
91 | imageAnimationController.dispose();
92 | super.dispose();
93 | }
94 |
95 | void _startAnimation() {
96 | imageAnimationController.forward();
97 | }
98 |
99 | void _imageAnimationStatusListener(AnimationStatus status) {
100 | switch (status) {
101 | case AnimationStatus.dismissed:
102 | // 动画反向运行结束
103 | print('动画结束');
104 | //动画恢复到初始状态后执行正向动画
105 | imageAnimationController.forward();
106 | break;
107 | case AnimationStatus.forward:
108 | print('动画正向运行');
109 | break;
110 | case AnimationStatus.reverse:
111 | print('动画反向运行');
112 | break;
113 | case AnimationStatus.completed:
114 | //动画完成
115 | print('动画完成');
116 | //动画结束之后执行反向动画
117 | imageAnimationController.reverse();
118 |
119 | break;
120 | }
121 | }
122 | }
123 |
124 | class AnimationImage extends AnimatedWidget {
125 | /*static final _sizeAnimation = Tween(begin: 0.0, end: 200.0);
126 | static final _opacityAni = Tween(begin: 0.0, end: 1.0);*/
127 |
128 | AnimationImage({
129 | Key key,
130 | Animation animation,
131 | }) : super(key: key, listenable: animation);
132 |
133 | @override
134 | Widget build(BuildContext context) {
135 | final Animation animation = listenable;
136 | return Opacity(
137 | opacity: animation.value / 200,
138 | child: Image.asset(
139 | 'images/pic3.jpg',
140 | width: animation.value,
141 | height: animation.value,
142 | fit: BoxFit.fill,
143 | ),
144 | );
145 | }
146 | }
147 |
148 | class GrowTransition extends StatelessWidget {
149 | final Widget child;
150 | final Animation animation;
151 |
152 | GrowTransition({this.child, this.animation});
153 |
154 | @override
155 | Widget build(BuildContext context) {
156 | return Center(
157 | child: AnimatedBuilder(
158 | animation: animation,
159 | builder: _animatedBuilder,
160 | child: child,
161 | ),
162 | );
163 | }
164 |
165 | Widget _animatedBuilder(BuildContext context, Widget child) {
166 | return Opacity(
167 | child: Container(
168 | child: child,
169 | height: animation.value,
170 | width: animation.value,
171 | ),
172 | opacity: animation.value / 200,
173 | );
174 | }
175 | }
176 |
--------------------------------------------------------------------------------
/lib/page/cupertino_action_sheet_page.dart:
--------------------------------------------------------------------------------
1 | import 'package:flutter/cupertino.dart';
2 | import 'package:flutter/material.dart';
3 | import 'package:fluttertoast/fluttertoast.dart';
4 |
5 | class CupertinoActionSheetPage extends StatefulWidget {
6 | @override
7 | _CupertinoActionSheetPAGEState createState() =>
8 | _CupertinoActionSheetPAGEState();
9 | }
10 |
11 | class _CupertinoActionSheetPAGEState extends State {
12 | ScrollController scrollController;
13 |
14 | @override
15 | Widget build(BuildContext context) {
16 | scrollController = ScrollController();
17 | return Scaffold(
18 | appBar: AppBar(
19 | title: Text('CupertinoActionSheet'),
20 | ),
21 | body: Container(
22 | child: RaisedButton(
23 | onPressed: _showCupertinoActionSheet,
24 | child: Text('show'),
25 | ),
26 | ),
27 | );
28 | }
29 |
30 | void _showCupertinoActionSheet() async {
31 | var result = await showCupertinoModalPopup(
32 | context: context,
33 | builder: (BuildContext context) {
34 | return CupertinoActionSheet(
35 | messageScrollController: scrollController,
36 | title: Text('兄弟 '),
37 | message: Text('不能删啊'),
38 | actions: [
39 | CupertinoActionSheetAction(
40 | isDestructiveAction: true,
41 | onPressed: () {
42 | Fluttertoast.showToast(msg: '删除了');
43 |
44 | Navigator.of(context).pop('删除');
45 | },
46 | child: Text('删除'),
47 | ),
48 | ],
49 | cancelButton: CupertinoActionSheetAction(
50 | onPressed: () {
51 | Navigator.of(context).pop('cancel');
52 | },
53 | child: Text('取消'),
54 | ),
55 | );
56 | });
57 | print(result.toString());
58 | }
59 | }
60 |
--------------------------------------------------------------------------------
/lib/page/custom_scrollview_page.dart:
--------------------------------------------------------------------------------
1 | import 'package:flutter/material.dart';
2 |
3 | class CustomScrollViewPage extends StatefulWidget {
4 | @override
5 | _CustomScrollViewPageState createState() => _CustomScrollViewPageState();
6 | }
7 |
8 | class _CustomScrollViewPageState extends State
9 | with SingleTickerProviderStateMixin {
10 | var tabController;
11 |
12 | @override
13 | void initState() {
14 | // TODO: implement initState
15 | super.initState();
16 | tabController = TabController(length: 2, vsync: this);
17 | }
18 |
19 | @override
20 | Widget build(BuildContext context) {
21 | return SafeArea(
22 | child: Scaffold(
23 | body: CustomScrollView(
24 | slivers: [
25 | SliverToBoxAdapter(
26 | child: Container(color: Colors.green, height: 100, child: Text('我的可滚动列表上面的一些文')),
27 | ),
28 | SliverAppBar(
29 | //标题居中
30 | centerTitle: true,
31 | //展开高度200
32 | expandedHeight: 200.0,
33 | //不随着滑动隐藏标题
34 | floating: false,
35 | //固定在顶部
36 | pinned: true,
37 | flexibleSpace: FlexibleSpaceBar(
38 | centerTitle: true,
39 | title: Container(
40 | child: Column(
41 | children: [
42 |
43 | Text('我是一个FlexibleSpaceBar')
44 | ],
45 | ),
46 | ),
47 | background: Image.network(
48 | "https://timgsa.baidu.com/timg?image&quality=80&size=b9999_10000&sec=1531798262708&di=53d278a8427f482c5b836fa0e057f4ea&imgtype=0&src=http%3A%2F%2Fh.hiphotos.baidu.com%2Fimage%2Fpic%2Fitem%2F342ac65c103853434cc02dda9f13b07eca80883a.jpg",
49 | fit: BoxFit.cover,
50 | ),
51 | ),
52 | ),
53 | SliverPersistentHeader(
54 | pinned: true,
55 | delegate: StickyTabBarDelegate(
56 | child: TabBar(
57 | controller: tabController,
58 | labelColor: Colors.black,
59 | tabs: [
60 | Tab(text: '资讯'),
61 | Tab(text: '技术'),
62 | ],
63 | ),
64 | ),
65 | ),
66 | SliverToBoxAdapter(
67 | child: Text('我的可滚动列表上面的一些文'),
68 | ),
69 | SliverList(delegate: SliverChildBuilderDelegate(itemBuilder, childCount: 10)),
70 | SliverFixedExtentList(
71 | itemExtent: 50.0,
72 | delegate: SliverChildBuilderDelegate((BuildContext context, int index) {
73 | return Container(
74 | alignment: Alignment.center,
75 | color: Colors.lightBlue[100 * (index % 9)],
76 | child: Text('List Item $index'),
77 | );
78 | }, childCount: 10),
79 | ),
80 | ],
81 | ),
82 | ),
83 | );
84 | }
85 |
86 | Widget itemBuilder(BuildContext context, int index) {
87 | return Container(
88 | color: Colors.green.withOpacity(index / 10),
89 | height: 200,
90 | );
91 | }
92 | }
93 |
94 | class StickyTabBarDelegate extends SliverPersistentHeaderDelegate {
95 | final TabBar child;
96 |
97 | StickyTabBarDelegate({@required this.child});
98 |
99 | @override
100 | Widget build(BuildContext context, double shrinkOffset, bool overlapsContent) {
101 | return Container(
102 | color: Theme.of(context).backgroundColor,
103 | child: this.child,
104 | );
105 | }
106 |
107 | @override
108 | double get maxExtent => this.child.preferredSize.height;
109 |
110 | @override
111 | double get minExtent => this.child.preferredSize.height;
112 |
113 | @override
114 | bool shouldRebuild(SliverPersistentHeaderDelegate oldDelegate) {
115 | return true;
116 | }
117 | }
118 |
--------------------------------------------------------------------------------
/lib/page/draggable_dragtargets.dart:
--------------------------------------------------------------------------------
1 | /*
2 | * @Author: zhuoyuan93@gmail.com
3 | * @Date: 2018-11-20 10:43:49
4 | * @LastEditors: zhuoyuan93@gmail.com
5 | * @LastEditTime: 2018-11-20 12:09:21
6 | * @Description:
7 | */
8 |
9 | import 'package:flutter/material.dart';
10 |
11 | class DraggableDragtargets extends StatefulWidget {
12 | @override
13 | DraggableDragtargetsState createState() {
14 | return new DraggableDragtargetsState();
15 | }
16 | }
17 |
18 | class DraggableDragtargetsState extends State
19 | with TickerProviderStateMixin {
20 |
21 | bool accept = true;
22 | bool accept2 = false;
23 |
24 | Widget _dragGableWidget() {
25 | return Draggable(
26 | child: _moveWidget('卓'),
27 | feedback: _moveWidget('卓'),
28 | childWhenDragging: _moveWidget(''),
29 | onDragStarted: () {
30 | print('drag start');
31 | },
32 | data: '卓',
33 | );
34 | }
35 |
36 | @override
37 | Widget build(BuildContext context) {
38 | // TODO: implement build
39 | return Scaffold(
40 | appBar: AppBar(
41 | title: Text('可拖动的组件'),
42 | ),
43 | body: Column(
44 | crossAxisAlignment: CrossAxisAlignment.center,
45 | children: [
46 | DragTarget(
47 | builder: (BuildContext context, List candidateData,
48 | List rejectedData) {
49 | return accept ? _dragGableWidget() : _moveWidget('');
50 | },
51 | onWillAccept: (data) {
52 | print('right will accept : $data');
53 | if (data != '卓') return false;
54 | return true;
55 | },
56 | onAccept: (data) {
57 | setState(() {
58 | accept = true;
59 | accept2 = false;
60 | });
61 | print('accept : $data');
62 | },
63 | ),
64 | SizedBox(
65 | height: 150.0,
66 | ),
67 | Row(
68 | mainAxisAlignment: MainAxisAlignment.spaceEvenly,
69 | children: [
70 | DragTarget(
71 | builder: (BuildContext context, List candidateData,
72 | List rejectedData) {
73 | return _moveWidget('Left Target');
74 | },
75 | onWillAccept: (data) {
76 | print('left will accept : $data');
77 | if (data == '卓') return false;
78 | return true;
79 | },
80 | onAccept: (data) {
81 | print('accept : $data');
82 | },
83 | ),
84 | DragTarget(
85 | builder: (BuildContext context, List candidateData,
86 | List rejectedData) {
87 | return accept2 ? _dragGableWidget() : _moveWidget('');
88 | },
89 | onWillAccept: (data) {
90 | print('right will accept : $data');
91 | if (data != '卓') return false;
92 | return true;
93 | },
94 | onAccept: (data) {
95 | setState(() {
96 | accept2 = true;
97 | accept = false;
98 | });
99 | print('accept : $data');
100 | },
101 | )
102 | ],
103 | )
104 | ],
105 | ),
106 | );
107 | }
108 |
109 | Widget _moveWidget(string) {
110 | return Container(
111 | height: 100.0,
112 | width: 100.0,
113 | color: Colors.blue,
114 | alignment: Alignment.center,
115 | child: Text(
116 | string,
117 | style: TextStyle(fontSize: 24.0, color: Colors.white),
118 | textAlign: TextAlign.center,
119 | ),
120 | );
121 | }
122 | }
123 |
--------------------------------------------------------------------------------
/lib/page/draggable_scrollable_sheet_page.dart:
--------------------------------------------------------------------------------
1 | import 'package:flutter/material.dart';
2 |
3 | class DraggableScrollableSheetPage extends StatefulWidget {
4 | @override
5 | _DraggableScrollableSheetPageState createState() =>
6 | _DraggableScrollableSheetPageState();
7 | }
8 |
9 | class _DraggableScrollableSheetPageState
10 | extends State {
11 | @override
12 | Widget build(BuildContext context) {
13 | return Scaffold(
14 | appBar: AppBar(
15 | title: Text('DraggableScrollableSheet'),
16 | ),
17 | body: Stack(
18 | children: [
19 | Align(
20 | alignment: Alignment.topCenter,
21 | child: Image.asset(
22 | 'images/beauty.jpg',
23 | width: 200,
24 | height: 100,
25 | fit: BoxFit.fill,
26 | ),
27 | ),
28 | DraggableScrollableSheet(
29 | initialChildSize: 0.5,
30 | minChildSize: 0.2,
31 | maxChildSize: 0.8,
32 | builder: (BuildContext context, ScrollController scrollController) {
33 | return Container(
34 | decoration: BoxDecoration(
35 | color: Colors.grey,
36 | borderRadius: BorderRadius.horizontal(
37 | left: Radius.circular(10), right: Radius.circular(10)),
38 | ),
39 | child: ListView(
40 | controller: scrollController,
41 | children: [
42 | SizedBox(
43 | height: 20,
44 | ),
45 | Text('嘤嘤嘤'),
46 | Image.asset(
47 | 'images/jay.jpg',
48 | width: 200,
49 | height: 200,
50 | ),
51 | SizedBox(height: 300),
52 | Text('llll'),
53 | ],
54 | ),
55 | );
56 | },
57 | ),
58 | ],
59 | ),
60 | );
61 | }
62 | }
63 |
--------------------------------------------------------------------------------
/lib/page/extension_page.dart:
--------------------------------------------------------------------------------
1 | import 'dart:ui';
2 |
3 | import 'package:flutter/material.dart';
4 | import 'package:flutter_screenutil/flutter_screenutil.dart';
5 |
6 | class ExtensionPage extends StatefulWidget {
7 | @override
8 | _ExtensionPagState createState() => _ExtensionPagState();
9 | }
10 |
11 | class _ExtensionPagState extends State {
12 | bool isShowBlur = true;
13 |
14 | @override
15 | Widget build(BuildContext context) {
16 | return Scaffold(
17 | appBar: AppBar(
18 | title: Text('扩展函数'),
19 | actions: [
20 | Padding(
21 | padding: EdgeInsets.only(right: 20),
22 | child: InkWell(
23 | onTap: () => setState(() {
24 | isShowBlur = !isShowBlur;
25 | }),
26 | child: Container(
27 | alignment: Alignment.center,
28 | child: Text(
29 | '模糊',
30 | style: TextStyle(
31 | color: Colors.white,
32 | fontSize: 20,
33 | ),
34 | )),
35 | ),
36 | )
37 | ],
38 | ),
39 | body: Stack(
40 | children: [
41 | Image.asset(
42 | 'images/pavlova.png',
43 | width: ScreenUtil().screenWidth,
44 | height: ScreenUtil().screenHeight,
45 | ),
46 | if (isShowBlur)
47 | BackdropFilter(
48 | filter: ImageFilter.blur(sigmaX: 5, sigmaY: 5),
49 | child: Center(
50 | child: InkWell(
51 | onTap: _onTap,
52 | child: Container(
53 | color: Colors.blue,
54 | child: Text(
55 | '显示',
56 | style: TextStyle(
57 | color: Colors.white,
58 | fontSize: 20,
59 | ),
60 | ),
61 | ),
62 | ).click(() {
63 | print('extension');
64 | setState(() {
65 | isShowBlur = !isShowBlur;
66 | });
67 | }),
68 | ),
69 | ),
70 | ],
71 | ));
72 | }
73 |
74 | void _onTap() {
75 | print('on tap');
76 | }
77 | }
78 |
79 | extension Ink on InkWell {
80 | InkWell click(Function f) {
81 | return InkWell(
82 | child: child,
83 | onTap: () {
84 | f();
85 | },
86 | );
87 | }
88 | }
89 |
--------------------------------------------------------------------------------
/lib/page/flutter_native_web.dart:
--------------------------------------------------------------------------------
1 | /*
2 | * author: Created by 李卓原 on 2019/3/6.
3 | * email: zhuoyuan93@gmail.com
4 | *
5 | */
6 |
7 | import 'dart:async';
8 |
9 | import 'package:flutter/material.dart';
10 | import 'package:flutter_screenutil/flutter_screenutil.dart';
11 | import 'package:webview_flutter/webview_flutter.dart';
12 |
13 | class FlutterNativeWebPage extends StatefulWidget {
14 | @override
15 | _FlutterNativeWebPageState createState() => _FlutterNativeWebPageState();
16 | }
17 |
18 | class _FlutterNativeWebPageState extends State {
19 | final Completer _controller =
20 | Completer();
21 |
22 | @override
23 | Widget build(BuildContext context) {
24 | return Scaffold(
25 | appBar: AppBar(
26 | title: Text('flutterwebview'),
27 | ),
28 | body: Container(
29 | height:300,
30 | width: ScreenUtil().screenWidth,
31 | child: WebView(
32 | initialUrl: 'https://www.youtube.com/watch?v=GWqwOOg6IUE',
33 | javascriptMode: JavascriptMode.unrestricted,
34 | onWebViewCreated: (WebViewController webViewController) {
35 | _controller.complete(webViewController);
36 | },
37 | // Remove this when collection literals makes it to stable.
38 | // ignore: prefer_collection_literals
39 | javascriptChannels: [
40 | _toasterJavascriptChannel(context),
41 | ].toSet(),
42 | )),
43 | );
44 | }
45 |
46 | JavascriptChannel _toasterJavascriptChannel(BuildContext context) {
47 | return JavascriptChannel(
48 | name: 'Toaster',
49 | onMessageReceived: (JavascriptMessage message) {
50 | Scaffold.of(context).showSnackBar(
51 | SnackBar(content: Text(message.message)),
52 | );
53 | });
54 | }
55 | }
56 |
--------------------------------------------------------------------------------
/lib/page/flutter_picker_page.dart:
--------------------------------------------------------------------------------
1 | import 'dart:convert';
2 |
3 | import 'package:flutter/material.dart';
4 | import 'package:flutter_app/bean/picker_data.dart';
5 | import 'package:flutter_picker/flutter_picker.dart';
6 |
7 | class PickerPage extends StatefulWidget {
8 | @override
9 | _PickerPageState createState() => _PickerPageState();
10 | }
11 |
12 | class _PickerPageState extends State {
13 | final double listSpec = 4.0;
14 | final GlobalKey _scaffoldKey = GlobalKey();
15 | String stateText;
16 |
17 | @override
18 | Widget build(BuildContext context) {
19 | return Scaffold(
20 | key: _scaffoldKey,
21 | appBar: AppBar(
22 | title: Text('Picker'),
23 | ),
24 | body: Container(
25 | padding: EdgeInsets.all(10.0),
26 | alignment: Alignment.topCenter,
27 | child: ListView(
28 | children: [
29 | (stateText != null) ? Text(stateText) : Container(),
30 | SizedBox(height: listSpec),
31 | RaisedButton(
32 | child: Text('Picker Show Modal'),
33 | onPressed: showPickerModal,
34 | ),
35 | SizedBox(height: listSpec),
36 | RaisedButton(
37 | child: Text('Picker Show Datetime (Round background)'),
38 | onPressed: showPickerDateTimeRoundBg,
39 | ),
40 | SizedBox(height: listSpec),
41 | ],
42 | ),
43 | ),
44 | );
45 | }
46 |
47 | showPickerModal() {
48 | Picker(
49 | adapter: PickerDataAdapter(pickerdata: JsonDecoder().convert(PickerData)),
50 | changeToFirst: true,
51 | hideHeader: false,
52 | selectedTextStyle: TextStyle(color: Colors.blue),
53 | onConfirm: (Picker picker, List value) {
54 | print(value.toString());
55 | print(picker.adapter.text);
56 | }).showModal(context); //_scaffoldKey.currentState);
57 | }
58 |
59 | Widget timePicker({ThemeData themeData, bool isModal = false}) {
60 | return Picker(
61 | height: 300,
62 | backgroundColor: Colors.transparent,
63 | headerDecoration:
64 | BoxDecoration(border: Border(bottom: BorderSide(color: Colors.black12, width: 0.5))),
65 | adapter: DateTimePickerAdapter(
66 | type: PickerDateTimeType.kYMDHM,
67 | isNumberMonth: false,
68 | ),
69 | title: Text("选择时间"),
70 | onConfirm: (Picker picker, List value) {
71 | print('confirm:${picker.adapter.text}');
72 | this.setState(() {
73 | stateText = picker.adapter.toString();
74 | });
75 | },
76 | onSelect: (Picker picker, int index, List selecteds) {
77 | print('onSelect:${picker.adapter.text}');
78 | }).makePicker(themeData, isModal);
79 | }
80 |
81 | /// 圆角背景
82 | showPickerDateTimeRoundBg() {
83 | showModalBottomSheet(
84 | context: context,
85 | backgroundColor: Colors.transparent,
86 | builder: (context) {
87 | return Material(
88 | color: Colors.white,
89 | borderRadius: BorderRadius.vertical(top: Radius.circular(10)),
90 | child: timePicker(isModal: true),
91 | );
92 | });
93 | }
94 | }
95 |
--------------------------------------------------------------------------------
/lib/page/fractionally_sized_box_page.dart:
--------------------------------------------------------------------------------
1 | import 'package:flutter/material.dart';
2 |
3 | class FractionallySizedBoxPage extends StatelessWidget {
4 | @override
5 | Widget build(BuildContext context) {
6 | return Scaffold(
7 | appBar: AppBar(
8 | title: Text('FractionallySizedBox:按比例设置widget尺寸'),
9 | ),
10 | body: Column(
11 | children: [
12 | Container(
13 | width: 300,
14 | height: 300,
15 | color: Colors.grey,
16 | child: FractionallySizedBox(
17 | alignment: Alignment.bottomRight,
18 | heightFactor: 0.5,
19 | widthFactor: 0.5,
20 | child: RaisedButton(
21 | onPressed: () {
22 | print('hhh');
23 | },
24 | child: Text('button'),
25 | )),
26 | ),
27 | Flexible(
28 | child: FractionallySizedBox(
29 | heightFactor: 0.1,
30 | ),
31 | ),
32 | Container(
33 | color: Colors.blue,
34 | child: Row(
35 | children: [
36 | Flexible(
37 | child: FractionallySizedBox(
38 | widthFactor: 0.5,
39 | ),
40 | ),
41 | Image.asset(
42 | 'images/jay.jpg',
43 | width: 50,
44 | ),
45 | SizedBox(width: 10),
46 | Text('文字'),
47 | ],
48 | ),
49 | )
50 | ],
51 | ),
52 | );
53 | }
54 | }
55 |
--------------------------------------------------------------------------------
/lib/page/map_search_page.dart:
--------------------------------------------------------------------------------
1 | import 'package:dio/dio.dart';
2 | import 'package:flutter/material.dart';
3 | import 'package:flutter_app/common/constant.dart';
4 | import 'package:flutter_app/utils/HttpUtil.dart';
5 | import 'package:mapbox_search/mapbox_search.dart';
6 |
7 | class MapSearchPage extends StatefulWidget {
8 | @override
9 | _MapSearchPageState createState() => _MapSearchPageState();
10 | }
11 |
12 | class _MapSearchPageState extends State {
13 | static const String key =
14 | 'pk.eyJ1Ijoiemh1b3l1YW45OSIsImEiOiJja2VwcXducjUya291MnFucDNlMmZmeDAzIn0.JoxtgAjdqfpZZz-dUJLykQ';
15 |
16 | TextEditingController controller = TextEditingController();
17 |
18 | List addressList = [];
19 |
20 | var placesSearch = PlacesSearch(
21 | apiKey: key,
22 | limit: 8,
23 | );
24 |
25 | var selectAddress;
26 | var loadingText = '';
27 |
28 | @override
29 | Widget build(BuildContext context) {
30 | return Scaffold(
31 | floatingActionButton: FloatingActionButton(
32 | onPressed: baiduSearch,
33 | ),
34 | appBar: AppBar(
35 | title: Text(loadingText),
36 | ),
37 | body: GestureDetector(
38 | onTap: () {
39 | FocusScope.of(context).requestFocus(FocusNode());
40 | },
41 | child: ListView(
42 | children: [
43 | Text('选择的地址:$selectAddress'),
44 | TextField(
45 | onChanged: (text) async {
46 | setState(() {
47 | loadingText = '正在搜寻位置';
48 | });
49 | getGooglePlaces(text);
50 | var places = await getPlaces(text);
51 |
52 | setState(() {
53 | loadingText = '搜索完成';
54 | addressList = places;
55 | });
56 | },
57 | decoration: InputDecoration(
58 | hintText: '输入地址',
59 | ),
60 | ),
61 | ListView.builder(
62 | shrinkWrap: true,
63 | itemBuilder: _itemBuilder,
64 | itemCount: addressList.length,
65 | )
66 | ],
67 | ),
68 | ),
69 | );
70 | }
71 |
72 | Future> getPlaces(String place) =>
73 | placesSearch.getPlaces(place);
74 |
75 | Future getGooglePlaces(String place) async {
76 | String googleBaseUrl =
77 | 'https://maps.googleapis.com/maps/api/place/autocomplete/json';
78 |
79 | Response response = await HttpUtil().get(googleBaseUrl,
80 | data: {'key': PLACES_API_KEY, 'input': place, 'type': 'regions'});
81 | print(response);
82 | }
83 |
84 | Future baiduSearch() async {
85 | String baiduBaseUrl = 'http://api.map.baidu.com/place_abroad/v1/search';
86 |
87 | var response = await HttpUtil().get(baiduBaseUrl, data: {
88 | 'ak': 'o7BxXRdG5GEZ8qbA03GGvA1Xix7UcG0P',
89 | 'output': 'json',
90 | 'region': '全国',
91 | 'query': 'newyor',
92 | });
93 | }
94 |
95 | Widget _itemBuilder(BuildContext context, int index) {
96 | return ListTile(
97 | onTap: () {
98 | _onTap(addressList[index]);
99 | },
100 | leading: Icon(Icons.location_city),
101 | title: Text('${addressList[index].text}'),
102 | );
103 | }
104 |
105 | void _onTap(address) {
106 | print('click $address');
107 | setState(() {
108 | selectAddress = address;
109 | addressList?.clear();
110 | });
111 | }
112 | }
113 |
--------------------------------------------------------------------------------
/lib/page/modal_page.dart:
--------------------------------------------------------------------------------
1 | import 'package:flutter/material.dart';
2 |
3 | class ModalPage extends StatefulWidget {
4 | @override
5 | _ModalPageState createState() => _ModalPageState();
6 | }
7 |
8 | class _ModalPageState extends State {
9 | String fileContent;
10 |
11 | String timeZone;
12 |
13 | @override
14 | Widget build(BuildContext context) {
15 | return Scaffold(
16 | appBar: AppBar(
17 | title: Text('弹窗'),
18 | ),
19 | body: Column(
20 | children: [
21 | RaisedButton(
22 | child: Text('show bottom sheet'),
23 | onPressed: _showBottom,
24 | )
25 | ],
26 | ),
27 | );
28 | }
29 |
30 | Future _showBottom() async {
31 | var res = await showModalBottomSheet(
32 | context: context,
33 | isScrollControlled: true,
34 | shape: RoundedRectangleBorder(
35 | borderRadius: BorderRadius.circular(15),
36 | side: BorderSide(
37 | color: Colors.blue,
38 | width: 5
39 | ),
40 | ),
41 | builder: (context) => Container(
42 | height: 400,
43 | child: Column(
44 | children: [
45 | Text('top'),
46 | RaisedButton(
47 | child: Text('pop pop'),
48 | onPressed: () {
49 | Navigator.of(context).pop('pop');
50 | },
51 | ),
52 | SizedBox(
53 | height: 300,
54 | ),
55 | Text('bottom')
56 | ],
57 | ),
58 | ),
59 | );
60 | tt(res, (result, index) => {print(result)});
61 | }
62 |
63 | void tt(String s, MyFun f) {
64 | f(s, 1);
65 | }
66 | }
67 |
68 | typedef MyFun = Function(String result, int index);
69 |
--------------------------------------------------------------------------------
/lib/page/repaint_boundary_page.dart:
--------------------------------------------------------------------------------
1 | import 'dart:io';
2 | import 'dart:typed_data';
3 | import 'dart:ui' as ui;
4 | import 'dart:ui';
5 |
6 | import 'package:flutter/material.dart';
7 | import 'package:flutter/rendering.dart';
8 | import 'package:flutter_share_me/flutter_share_me.dart';
9 | import 'package:fluttertoast/fluttertoast.dart';
10 | import 'package:path_provider/path_provider.dart';
11 |
12 | class RepaintBoundaryPage extends StatefulWidget {
13 | @override
14 | _RepaintBoundaryPageState createState() => _RepaintBoundaryPageState();
15 | }
16 |
17 | class _RepaintBoundaryPageState extends State {
18 | GlobalKey _globalKey = GlobalKey();
19 | Uint8List uint8list;
20 | File file;
21 |
22 | @override
23 | void initState() {
24 | super.initState();
25 | //getFile();
26 | }
27 |
28 | @override
29 | Widget build(BuildContext context) {
30 | return Scaffold(
31 | floatingActionButton: FloatingActionButton(
32 | child: Icon(Icons.delete_forever),
33 | onPressed: deleteFile,
34 | ),
35 | appBar: AppBar(
36 | title: Text('屏幕/组件截图'),
37 | actions: [
38 | IconButton(
39 | icon: Icon(Icons.share),
40 | onPressed: share,
41 | )
42 | ],
43 | ),
44 | body: Container(
45 | color: Colors.grey,
46 | alignment: Alignment.center,
47 | child: Column(
48 | crossAxisAlignment: CrossAxisAlignment.center,
49 | mainAxisAlignment: MainAxisAlignment.spaceEvenly,
50 | children: [
51 | ElevatedButton(
52 | child: Text('以下的东西会截图'),
53 | onPressed: _screenShot,
54 | ),
55 | RepaintBoundary(
56 | key: _globalKey,
57 | child: Row(
58 | mainAxisAlignment: MainAxisAlignment.center,
59 | children: [
60 | Text(
61 | '图里的文字',
62 | style: TextStyle(color: Colors.blue, fontSize: 20),
63 | ),
64 | Icon(
65 | Icons.accessibility,
66 | color: Colors.red,
67 | ),
68 | ],
69 | ),
70 | ),
71 | Text('↓以下为截图的内容↓'),
72 | if (uint8list != null) Image.memory(uint8list),
73 | Text('↓下面的图片为本地保存的图片文件↓'),
74 | if (file?.existsSync() == true) Image.file(file),
75 | ],
76 | ),
77 | ));
78 | }
79 |
80 | Future deleteFile() async {
81 | bool fileIsExist = await file.exists();
82 | if (fileIsExist) {
83 | file.deleteSync();
84 | setState(() {});
85 | print('删除图片成功:${file.existsSync()}');
86 | }
87 | }
88 |
89 | Future _screenShot() async {
90 | RenderRepaintBoundary boundary = _globalKey.currentContext.findRenderObject();
91 | ui.Image image = await boundary.toImage();
92 | ByteData byteData = await image.toByteData(format: ImageByteFormat.png);
93 | Uint8List pngBytes = byteData.buffer.asUint8List();
94 |
95 | setState(() {
96 | uint8list = pngBytes;
97 | });
98 |
99 | byte2File(pngBytes);
100 | }
101 |
102 | /// 把图片ByteData写入File
103 | Future byte2File(Uint8List pngBytes) async {
104 | await getFile();
105 | if (!file.existsSync()) {
106 | file.createSync();
107 | print('生成图片文件:$file');
108 | }
109 | file.writeAsBytesSync(pngBytes);
110 | if (file.existsSync()) {
111 | print('图片保存成功');
112 | Fluttertoast.showToast(msg: '图片保存成功');
113 | }
114 | }
115 |
116 | Future getFile() async {
117 | Directory tempDir = await getTemporaryDirectory();
118 | file = File('${tempDir.path}/img${DateTime.now()}.png');
119 |
120 | setState(() {});
121 | }
122 |
123 | void share() {
124 | FlutterShareMe().shareToWhatsApp(imagePath: file.path, msg: 'ssss');
125 | }
126 | }
127 |
--------------------------------------------------------------------------------
/lib/page/route_page.dart:
--------------------------------------------------------------------------------
1 | import 'package:flutter/material.dart';
2 | import 'package:flutter_screenutil/flutter_screenutil.dart';
3 |
4 | class RoutePage extends StatelessWidget {
5 | final List listData = [];
6 |
7 | void initData(BuildContext context) {
8 | listData.clear();
9 |
10 | listData.add(ListItem("Home Page", "Home", Icons.home));
11 | listData.add(ListItem("Pavlova示例", "Pavlova", Icons.panorama_vertical));
12 | listData.add(ListItem("randomWords示例", "randomWords", Icons.book));
13 | listData.add(ListItem("图片", "Image", Icons.image));
14 | listData.add(ListItem("GridView", "GridView", Icons.grid_on));
15 | listData.add(ListItem("StateWidget", "StateWidget", Icons.widgets));
16 | listData.add(ListItem("TextField", "TextField", Icons.text_fields));
17 | listData.add(ListItem("KeepAlive", "KeepAlive", Icons.live_tv));
18 | listData.add(ListItem("Swiper", "Swiper", Icons.landscape));
19 | listData.add(ListItem("流式布局", "Wrap", Icons.landscape));
20 | listData.add(ListItem("动画", "Animation", Icons.landscape));
21 | listData.add(ListItem('动画2', 'AnimationTwo', Icons.android));
22 | listData.add(ListItem("屏幕适配示例", "ScreenUtilPage", Icons.landscape));
23 | listData.add(ListItem("futureBuilder", "FutureBuilderPage", Icons.hourglass_full));
24 | listData.add(ListItem("主题", "ThemePage", Icons.landscape));
25 | listData.add(ListItem("Chip", "ChipPage", Icons.landscape));
26 | listData.add(ListItem("ExpansionTile", "ExpansionTilePage", Icons.landscape));
27 | listData.add(ListItem("Transform 3D效果", "TransformPage", Icons.landscape));
28 | listData.add(ListItem("登录页", "LoginPage", Icons.landscape));
29 | listData.add(ListItem("WebView", "WebViewPage", Icons.web));
30 | listData.add(ListItem("自定义View", "CustomViewPage", Icons.view_quilt));
31 | listData.add(ListItem("Tab的使用", "TabPae", Icons.view_quilt));
32 | listData.add(ListItem("backdropPage", "backdropPage", Icons.view_quilt));
33 | listData.add(ListItem('可拖动组件', 'Draggable', Icons.drag_handle));
34 | listData.add(ListItem('分享', 'SharePage', Icons.share));
35 | listData.add(ListItem('搜索', 'SearchPage', Icons.search));
36 | listData.add(ListItem('mp4视频播放', 'VideoPlayerPage', Icons.video_library));
37 | listData.add(ListItem('Youtube视频播放', 'FlutterYoutubePage', Icons.video_library));
38 | listData.add(ListItem('FlutterNativeWeb插件的使用', 'FlutterNativeWeb', Icons.web));
39 | listData.add(ListItem('sqflite的使用', 'SqfLitePage', Icons.crop_square));
40 | listData.add(ListItem('步骤条Stepper ', 'StepperPage', Icons.short_text));
41 | listData.add(ListItem('类似于qq列表的组件树', 'TreePage', Icons.people));
42 | listData.add(ListItem('Sliver', 'Sliver', Icons.list));
43 | listData
44 | .add(ListItem('CupertinoActionSheet', 'CupertinoActionSheetPage', Icons.call_to_action));
45 | listData.add(ListItem('按比例设置尺寸', 'FractionallySizedBoxPage', Icons.crop_din));
46 | listData.add(ListItem('屏幕/组件截图', 'RepaintBoundaryPage', Icons.screen_lock_landscape));
47 | listData.add(ListItem('高斯模糊&扩展函数', 'ExtensionPage', Icons.extension));
48 | listData.add(ListItem('搜索地理位置', 'MapSearchPage', Icons.location_city));
49 | listData.add(
50 | ListItem('DraggableScrollableSheetPage', 'DraggableScrollableSheet', Icons.location_city));
51 | listData.add(ListItem('弹窗', 'ModalPage', Icons.airplanemode_active));
52 | listData.add(ListItem('日期选择器,多级联动', 'PickerPage', Icons.airplanemode_active));
53 |
54 | listData.add(ListItem('复杂的CustomScrollView', 'CustomScrollViewPage', Icons.crop_rotate));
55 | }
56 |
57 | @override
58 | Widget build(BuildContext context) {
59 | initData(context);
60 |
61 | //设置适配尺寸 (填入设计稿中设备的屏幕尺寸) 假如设计稿是按iPhone6的尺寸设计的(iPhone6 750*1334)
62 | return Scaffold(
63 | appBar: AppBar(
64 | title: Text('列表'),
65 | centerTitle: true,
66 | ),
67 | body: ListView.builder(
68 | itemBuilder: (BuildContext context, int index) {
69 | return ListItemWidget(listData[index]);
70 | },
71 | itemCount: listData.length,
72 | ),
73 | );
74 | }
75 | }
76 |
77 | class ListItem {
78 | final String title;
79 | final String routeName;
80 | final IconData iconData;
81 |
82 | ListItem(this.title, this.routeName, this.iconData);
83 | }
84 |
85 | class ListItemWidget extends StatelessWidget {
86 | final ListItem listItem;
87 |
88 | ListItemWidget(this.listItem);
89 |
90 | @override
91 | Widget build(BuildContext context) {
92 | return ListTile(
93 | title: Text(listItem.title),
94 | leading: Icon(listItem.iconData),
95 | trailing: Icon(Icons.arrow_forward),
96 | onTap: () {
97 | Navigator.pushNamed(context, listItem.routeName, arguments: listItem.title);
98 | });
99 | }
100 | }
101 |
--------------------------------------------------------------------------------
/lib/page/search_page.dart:
--------------------------------------------------------------------------------
1 | /*
2 | * author: Created by 李卓原 on 2019/2/19.
3 | * email: zhuoyuan93@gmail.com
4 | *
5 | */
6 |
7 | import 'package:flutter/material.dart';
8 | import 'package:flutter_app/widget/searchbar_delegate.dart';
9 |
10 | class SearchPage extends StatelessWidget {
11 | @override
12 | Widget build(BuildContext context) {
13 | return Scaffold(
14 | appBar: AppBar(
15 | title: Text('搜索'),
16 | ),
17 | body: Container(
18 | child: RaisedButton(
19 | onPressed: () {
20 | showSearch(context: context, delegate: SearchBarDelegate());
21 | },
22 | child: Text('去搜索')),
23 | ),
24 | );
25 | }
26 | }
27 |
--------------------------------------------------------------------------------
/lib/page/sliver_page.dart:
--------------------------------------------------------------------------------
1 | /*
2 | * author: Created by 李卓原 on 2020/7/5
3 | * email: zhuoyuan93@gmail.com
4 | *
5 | */
6 | import 'package:flutter/material.dart';
7 |
8 | class SliverPage extends StatefulWidget {
9 | @override
10 | _SliverPageState createState() => _SliverPageState();
11 | }
12 |
13 | class _SliverPageState extends State {
14 | List list = [1, 2, 3, 4, 5];
15 |
16 | @override
17 | Widget build(BuildContext context) {
18 | return Scaffold(
19 | body: CustomScrollView(
20 | slivers: [
21 | SliverAppBar(
22 | automaticallyImplyLeading: false,
23 | elevation: 5,
24 | forceElevated: true,
25 | expandedHeight: 200,
26 | floating: true,
27 | snap: false,
28 | pinned: true,
29 | stretch: true,
30 | flexibleSpace: FlexibleSpaceBar(
31 | title: Text('SliverAppBar'),
32 | background: Image.asset(
33 | 'images/pic1.jpg',
34 | fit: BoxFit.fill,
35 | ),
36 | //标题是否居中
37 | centerTitle: false,
38 | //标题间距
39 | //titlePadding: EdgeInsetsDirectional.only(start: 0, bottom: 16),
40 | collapseMode: CollapseMode.parallax,
41 | )),
42 | SliverList(
43 | delegate: SliverChildBuilderDelegate(
44 | _reportBuilder,
45 | childCount: list.length + 1,
46 | ),
47 | ),
48 | SliverToBoxAdapter(
49 | child: Text('Title'),
50 | ),
51 | SliverGrid(
52 | gridDelegate: SliverGridDelegateWithMaxCrossAxisExtent(
53 | maxCrossAxisExtent: 400),
54 | delegate: SliverChildBuilderDelegate(
55 | _reportBuilder,
56 | childCount: list.length + 1,
57 | ),
58 | )
59 | ],
60 | ),
61 | );
62 | }
63 |
64 | Widget _reportBuilder(BuildContext context, int index) {
65 | const header = Text('I am title');
66 |
67 | if (index <= 0) {
68 | return header;
69 | } else {
70 | int listIndex = index - 1;
71 | print(listIndex);
72 | return Container(
73 | color: Colors.blue,
74 | height: 200,
75 | child: Text('${list[listIndex]}'),
76 | );
77 | }
78 | }
79 | }
80 |
--------------------------------------------------------------------------------
/lib/page/sqflite_page.dart:
--------------------------------------------------------------------------------
1 | /*
2 | * author: Created by 李卓原 on 2019/3/12.
3 | * email: zhuoyuan93@gmail.com
4 | *
5 | */
6 |
7 | import 'package:flutter/material.dart';
8 | import 'package:flutter_app/model/note.dart';
9 | import 'package:flutter_app/utils/dbHelper.dart';
10 |
11 | class SqfLite extends StatefulWidget {
12 | @override
13 | _SqfLiteState createState() => _SqfLiteState();
14 | }
15 |
16 | class _SqfLiteState extends State {
17 | List notes = [];
18 | int i = 0;
19 |
20 | @override
21 | Widget build(BuildContext context) {
22 | return Scaffold(
23 | appBar: AppBar(
24 | title: Text('Sqflite的使用'),
25 | centerTitle: true,
26 | ),
27 | body: Container(
28 | child: Column(
29 | children: [
30 | ButtonBar(
31 | children: [
32 | RaisedButton(
33 | onPressed: _insertData,
34 | child: Text('存储数据'),
35 | ),
36 | RaisedButton(
37 | onPressed: getNotes,
38 | child: Text('点一次取2条数据'),
39 | ),
40 | ],
41 | ),
42 | Expanded(
43 | child: ListView.builder(
44 | itemBuilder: _itemBuilder,
45 | shrinkWrap: true,
46 | itemCount: notes.length,
47 | ),
48 | )
49 | ],
50 | ),
51 | ),
52 | );
53 | }
54 |
55 | void _insertData() async {
56 | var db = DatabaseHelper();
57 | Note todo = new Note(DateTime.now().millisecondsSinceEpoch, 'imarge', i, i,
58 | 0.1 * i, 0.1 * i);
59 | i++;
60 | await db.saveNote(todo);
61 |
62 | getNotes();
63 | }
64 |
65 | void getNotes() async {
66 | var db = DatabaseHelper();
67 | var res = await db.getAllNotes(limit: 2, offset: notes.length);
68 | setState(() {
69 | notes.addAll(res);
70 | });
71 | }
72 |
73 | Widget _itemBuilder(BuildContext context, int index) {
74 | return Text('${notes[index]}');
75 | }
76 | }
77 |
--------------------------------------------------------------------------------
/lib/page/stepper_page.dart:
--------------------------------------------------------------------------------
1 | /*
2 | * author: Created by 李卓原 on 2019/8/5.
3 | * email: zhuoyuan93@gmail.com
4 | *
5 | */
6 |
7 | import 'package:flutter/material.dart';
8 |
9 | class StepperPage extends StatefulWidget {
10 | @override
11 | _StepperPageState createState() => _StepperPageState();
12 | }
13 |
14 | class _StepperPageState extends State {
15 | int _currentStep;
16 | List _list;
17 |
18 | @override
19 | void initState() {
20 | super.initState();
21 | _currentStep = 0;
22 | _list = [];
23 | for (int i = 0; i < 5; i++) {
24 | _list.add('title:$i');
25 | }
26 | }
27 |
28 | @override
29 | Widget build(BuildContext context) {
30 | return Scaffold(
31 | appBar: AppBar(
32 | title: Text('Stepper(步骤条)'),
33 | ),
34 | body: Container(
35 | child: Stepper(
36 | steps: _list
37 | .map((item) => Step(
38 | title: Text(item),
39 | content: SizedBox(),
40 | isActive: _currentStep == _list.indexOf(item)))
41 | .toList(),
42 | type: StepperType.vertical,
43 | currentStep: _currentStep,
44 | onStepCancel: stepCancel,
45 | onStepContinue: stepContinue,
46 | onStepTapped: stepTapped,
47 | controlsBuilder: (BuildContext context,
48 | {VoidCallback onStepContinue, VoidCallback onStepCancel}) {
49 | return Container(
50 | /*width: double.infinity,
51 | color: Colors.blue,
52 | child: RaisedButton(
53 | child: Text('next'),
54 | onPressed: onStepContinue,
55 | ),*/
56 | );
57 | },
58 | )),
59 | );
60 | }
61 |
62 | void stepCancel() {
63 | setState(() {
64 | _currentStep = 0;
65 | });
66 | }
67 |
68 | void stepContinue() {
69 | if (_currentStep < _list.length - 1)
70 | setState(() {
71 | _currentStep++;
72 | });
73 | }
74 |
75 | void stepTapped(int i) {
76 | setState(() {
77 | _currentStep = i;
78 | });
79 | }
80 | }
81 |
--------------------------------------------------------------------------------
/lib/page/tab_page.dart:
--------------------------------------------------------------------------------
1 | /*
2 | * author: Created by 李卓原 on 2018/10/18.
3 | * email: zhuoyuan93@gmail.com
4 | *
5 | */
6 | import 'package:flutter/material.dart';
7 | import 'package:flutter_screenutil/flutter_screenutil.dart';
8 |
9 | class TabPage extends StatefulWidget {
10 | @override
11 | _TabPageState createState() => _TabPageState();
12 | }
13 |
14 | class _TabPageState extends State with SingleTickerProviderStateMixin {
15 | TabController _mysTabController;
16 | Color _color;
17 | final List _colors = [
18 | Colors.blue,
19 | Colors.green,
20 | Colors.pink,
21 | Colors.yellow,
22 | Colors.red,
23 | Colors.purple,
24 | Colors.grey,
25 | ];
26 | final List myTabs = [
27 | Tab(text: '明教'),
28 | Tab(text: '霸刀'),
29 | Tab(text: '天策'),
30 | Tab(text: '纯阳'),
31 | Tab(text: '少林'),
32 | Tab(text: '藏剑'),
33 | Tab(text: '五毒'),
34 | ];
35 |
36 | final List myTabBarViews = [
37 | Tab(text: '喵喵喵喵喵喵喵喵喵喵'),
38 | Tab(text: '叨叨叨叨叨叨叨叨叨叨'),
39 | Tab(text: '汪汪汪汪汪汪汪汪汪汪'),
40 | Tab(text: '咩咩咩咩咩咩咩咩咩咩'),
41 | Tab(text: '观自在菩萨,行深般若波罗蜜多时'),
42 | Tab(text: '君子如风,藏剑西湖'),
43 | Tab(text: '情之所依,心之所系。代君受命,保君平安。'),
44 | ];
45 |
46 | @override
47 | void initState() {
48 | _color ??= _colors[0]; //设置一个颜色的初始值
49 | _mysTabController = TabController(vsync: this, length: myTabs.length);
50 | super.initState();
51 | _mysTabController.animation.addListener(() {
52 | setState(() {
53 | _color = _colors[_mysTabController.index];
54 |
55 | //当Tab向右滑动时
56 | if (_mysTabController.offset > 0) {
57 | final ColorTween myscolor = ColorTween(
58 | begin: _colors[_mysTabController.index],
59 | end: _colors[_mysTabController.index + 1],
60 | );
61 | _color = myscolor.lerp(_mysTabController.offset);
62 | } else if (_mysTabController.offset < 0) {
63 | //当Tab向左滑动时
64 | final ColorTween myscolor = ColorTween(
65 | begin: _colors[_mysTabController.index],
66 | end: _colors[_mysTabController.index - 1],
67 | );
68 | _color = myscolor.lerp(-_mysTabController.offset);
69 | }
70 | print(_mysTabController.offset);
71 | });
72 | });
73 | }
74 |
75 | @override
76 | void dispose() {
77 | _mysTabController.dispose();
78 | super.dispose();
79 | }
80 |
81 | @override
82 | Widget build(BuildContext context) {
83 | return Scaffold(
84 | backgroundColor: _color,
85 | body: Column(
86 | children: [
87 | Container(
88 | color: _color,
89 | height: ScreenUtil().statusBarHeight,
90 | ),
91 | CustomScrollView(
92 | shrinkWrap: true,
93 | slivers: [
94 | SliverToBoxAdapter(
95 | child: Text('asda'),
96 | ),
97 | SliverToBoxAdapter(
98 | child: Container(
99 | child: TabBar(
100 | controller: _mysTabController,
101 | labelColor: Colors.black,
102 | tabs: [...myTabs],
103 | isScrollable: true,
104 | ),
105 | ),
106 | ),
107 | SliverToBoxAdapter(
108 | child: SizedBox(
109 | height: 500,
110 | child: TabBarView(
111 | controller: _mysTabController,
112 | children: myTabBarViews
113 | .map((Tab tab) => Container(
114 | alignment: Alignment.center,
115 | // color: _color,
116 | child: Text(
117 | tab.text,
118 | style: TextStyle(color: Colors.white),
119 | ),
120 | ))
121 | .toList()),
122 | ),
123 | ),
124 | SliverToBoxAdapter(
125 | child: Container(
126 | height: 20,
127 | color: Colors.blue,
128 | ),
129 | )
130 | ],
131 | ),
132 | ],
133 | ),
134 | );
135 | }
136 | }
137 |
--------------------------------------------------------------------------------
/lib/page/theme_page.dart:
--------------------------------------------------------------------------------
1 | /*
2 | * Created by 李卓原 on 2018/10/8.
3 | * email: zhuoyuan93@gmail.com
4 | *
5 | */
6 |
7 | import 'package:flutter/material.dart';
8 | import 'package:flutter_app/model/AppModel.dart';
9 | import 'package:flutter_app/rxdart/bloc_provider.dart';
10 | import 'package:flutter_app/rxdart/theme_select.dart';
11 |
12 | import 'package:scoped_model/scoped_model.dart';
13 |
14 | class ThemePage extends StatefulWidget {
15 | @override
16 | State createState() => ThemeState();
17 | }
18 |
19 | class ThemeState extends State {
20 | ThemeSelect themeSelect;
21 |
22 | @override
23 | Widget build(BuildContext context) {
24 | themeSelect = BlocProvider.of(context);
25 | return Scaffold(
26 | appBar: AppBar(
27 | title: Text('夜间模式'),
28 | ),
29 | body: StreamBuilder(
30 | builder: _builder,
31 | stream: themeSelect.value,
32 | initialData: false,
33 | ),
34 | );
35 | }
36 |
37 | Widget _builder(BuildContext context, AsyncSnapshot snapshot) {
38 | return Row(
39 | children: [
40 | Text('夜间模式'),
41 | Switch(
42 | value: snapshot.data,
43 | onChanged: (bool value) {
44 | print('value:$value');
45 | themeSelect.changeTheme(value);
46 | })
47 | ],
48 | );
49 | }
50 | }
51 |
--------------------------------------------------------------------------------
/lib/page/tree_page.dart:
--------------------------------------------------------------------------------
1 | import 'package:flutter/material.dart';
2 | import 'package:flutter_app/widget/node.dart';
3 |
4 | ///类似于qq列表的组件树
5 | class TreePage extends StatefulWidget {
6 | @override
7 | _TreePageState createState() => _TreePageState();
8 | }
9 |
10 | class _TreePageState extends State {
11 | List goodFriends2 = ['刘亦菲', '李一桐', '信'];
12 | List goodFriends = ['陈浩', '胡歌', '周杰伦', '田馥甄'];
13 | List sb = ['罗永浩', '陈年', '特朗普', '安倍晋三'];
14 |
15 | @override
16 | Widget build(BuildContext context) {
17 | print(goodFriends.length);
18 | return Scaffold(
19 | appBar: AppBar(
20 | title: Text("类似于qq列表的组件树"),
21 | ),
22 | body: NodeWidget(
23 | node: Node(me: Text('我的好友'), children: [
24 | Node(
25 | me: NodeWidget(
26 | node: Node(
27 | me: Text('好友1'),
28 | children:
29 | goodFriends.map((f) => Node(me: Text(f))).toList()))),
30 | Node(
31 | me: NodeWidget(
32 | node: Node(me: Text('家人'), children: [
33 | ...goodFriends2.map((item) => Node(me: Text(item)))
34 | ]),
35 | )),
36 | Node(
37 | me: NodeWidget(
38 | node: Node(
39 | children: [...sb.map((item) => Node(me: Text(item)))],
40 | me: Text('MDZZ')),
41 | ),
42 | )
43 | ]),
44 | ),
45 | );
46 | }
47 | }
48 |
--------------------------------------------------------------------------------
/lib/page/video_player.dart:
--------------------------------------------------------------------------------
1 | /*
2 | * author: Created by 李卓原 on 2019/2/22.
3 | * email: zhuoyuan93@gmail.com
4 | *
5 | */
6 |
7 | import 'package:flutter/material.dart';
8 |
9 | class VideoPlayerPage extends StatefulWidget {
10 | @override
11 | _VideoPlayerPageState createState() => _VideoPlayerPageState();
12 | }
13 |
14 | class _VideoPlayerPageState extends State {
15 | // VideoPlayerController _videoPlayerController;
16 | String videoUrl =
17 | 'https:\/\/r2---sn-t0a7ln7d.googlevideo.com\/videoplayback?pcm2=no&id=o-AGhjJTNX-_rpxrF-lQPBebK-cqFnodGNEMsSZ1RlZPHM&key=yt6&mn=sn-t0a7ln7d%2Csn-vgqsknlz&mm=31%2C26&expire=1551100886&ms=au%2Conr&requiressl=yes&ei=dZdzXI2sOeHP8gTiuahA&fvip=2&pl=24&mv=u&ipbits=0&ip=54.80.95.108&ratebypass=yes&txp=5531432&sparams=dur%2Cei%2Cid%2Cip%2Cipbits%2Citag%2Clmt%2Cmime%2Cmm%2Cmn%2Cms%2Cmv%2Cpcm2%2Cpl%2Cratebypass%2Crequiressl%2Csource%2Cexpire&signature=246C48A87B1DE26DACF4558F02F14836F986F125.2058F1D1395A987D10183B01486A5BE7384FB482&lmt=1542774011565518&dur=552.588&itag=22&mime=video%2Fmp4&source=youtube&mt=1551078639';
18 |
19 | @override
20 | void initState() {
21 | super.initState();
22 |
23 | }
24 |
25 | @override
26 | Widget build(BuildContext context) {
27 | return Scaffold(
28 | appBar: AppBar(
29 | title: Text('播放视频'),
30 | ),
31 |
32 | );
33 | }
34 |
35 | @override
36 | void dispose() {
37 | super.dispose();
38 | }
39 | }
40 |
--------------------------------------------------------------------------------
/lib/page/wrap_page.dart:
--------------------------------------------------------------------------------
1 | /*
2 | * Created by 李卓原 on 2018/9/27.
3 | * email: zhuoyuan93@gmail.com
4 | *
5 | */
6 |
7 | import 'package:flutter/material.dart';
8 |
9 | import 'package:fluttertoast/fluttertoast.dart';
10 |
11 | class WrapPage extends StatelessWidget {
12 | final List list = [
13 | '斗破苍穹',
14 | '遮天',
15 | '斗罗大陆',
16 | '大主宰',
17 | '凡人修仙传',
18 | '盗墓笔记',
19 | '校花的贴身高手',
20 | '诛仙'
21 | ];
22 |
23 | List _childList(BuildContext context) {
24 | List childs = [];
25 | /*for (int i = 0; i < list.length; i++) {
26 | childs.add(Text(list[i]));
27 | }*/
28 | childs.addAll(
29 | list.map((item) => Container(
30 | child: Row(
31 | mainAxisSize: MainAxisSize.min,
32 | children: [
33 | Container(
34 | color: Colors.red,
35 | child: Text(
36 | '#',
37 | style: TextStyle(color: Colors.white),
38 | ),
39 | ),
40 | Text(item),
41 | ],
42 | ),
43 | padding: EdgeInsets.all(8),
44 | color: Colors.blue)),
45 | );
46 | // list.forEach((item) => childs.add(Text(item)));
47 | return childs;
48 | }
49 |
50 | @override
51 | Widget build(BuildContext context) {
52 | return Scaffold(
53 | appBar: AppBar(
54 | title: Text('流式布局'),
55 | ),
56 | body: Container(
57 | padding: EdgeInsets.all(10.0),
58 | child: Wrap(
59 | alignment: WrapAlignment.start,
60 | children: _childList(context),
61 | spacing: 10.0,
62 | runSpacing: 10.0,
63 | direction: Axis.horizontal,
64 | //children: list.map((item) => (Text(item))).toList(),
65 | ),
66 | ),
67 | );
68 | }
69 | }
70 |
71 | class Textbook extends StatelessWidget {
72 | final item;
73 |
74 | Textbook(this.item);
75 |
76 | @override
77 | Widget build(BuildContext context) {
78 | return GestureDetector(
79 | onTap: () {
80 | Fluttertoast.showToast(msg: item);
81 | /* Scaffold.of(context).showSnackBar(SnackBar(
82 | content: Text(item),
83 | action: new SnackBarAction(
84 | label: "撤回",
85 | onPressed: () {},
86 | ),
87 | ));*/
88 | },
89 | child: Container(
90 | padding: EdgeInsets.all(5.0),
91 | decoration: BoxDecoration(
92 | border: Border.all(
93 | color: Colors.blue, width: 2.0, style: BorderStyle.solid),
94 | borderRadius: new BorderRadius.all(new Radius.circular(2.0)),
95 | ),
96 | child: Text(
97 | item,
98 | style: TextStyle(fontSize: 18.0),
99 | ),
100 | ));
101 | }
102 | }
103 |
--------------------------------------------------------------------------------
/lib/routes.dart:
--------------------------------------------------------------------------------
1 | import 'package:flutter/material.dart';
2 | import 'package:flutter_app/page/ChipPage.dart';
3 | import 'package:flutter_app/page/ExpansionTilePage.dart';
4 | import 'package:flutter_app/page/FutureBuilderPage.dart';
5 | import 'package:flutter_app/page/GridViewPage.dart';
6 | import 'package:flutter_app/page/ImagePage.dart';
7 | import 'package:flutter_app/page/KeepAlivePage.dart';
8 | import 'package:flutter_app/page/MyHomePage.dart';
9 | import 'package:flutter_app/page/PavlovaPage.dart';
10 | import 'package:flutter_app/page/RandomWords.dart';
11 | import 'package:flutter_app/page/cupertino_action_sheet_page.dart';
12 | import 'package:flutter_app/page/custom_scrollview_page.dart';
13 | import 'package:flutter_app/page/draggable_scrollable_sheet_page.dart';
14 | import 'package:flutter_app/page/flutter_picker_page.dart';
15 | import 'package:flutter_app/page/fractionally_sized_box_page.dart';
16 | import 'package:flutter_app/page/map_search_page.dart';
17 | import 'package:flutter_app/page/modal_page.dart';
18 | import 'package:flutter_app/page/repaint_boundary_page.dart';
19 | import 'package:flutter_app/page/extension_page.dart';
20 | import 'package:flutter_app/page/route_page.dart';
21 | import 'package:flutter_app/page/ScreenUtilTest.dart';
22 | import 'package:flutter_app/page/StateWidgetPage.dart';
23 | import 'package:flutter_app/page/SwiperPage.dart';
24 | import 'package:flutter_app/page/theme_page.dart';
25 | import 'package:flutter_app/page/Transform3D.dart';
26 | import 'package:flutter_app/page/wrap_page.dart';
27 | import 'package:flutter_app/page/animation_page.dart';
28 | import 'package:flutter_app/page/animation_two.dart';
29 | import 'package:flutter_app/page/backdrop_page.dart';
30 | import 'package:flutter_app/page/custom_animation_page.dart';
31 | import 'package:flutter_app/page/draggable_dragtargets.dart';
32 | import 'package:flutter_app/page/flutter_native_web.dart';
33 | import 'package:flutter_app/page/login_page.dart';
34 | import 'package:flutter_app/page/search_page.dart';
35 | import 'package:flutter_app/page/share_page.dart';
36 | import 'package:flutter_app/page/sliver_page.dart';
37 | import 'package:flutter_app/page/sqflite_page.dart';
38 | import 'package:flutter_app/page/tab_page.dart';
39 | import 'package:flutter_app/page/textField.dart';
40 | import 'package:flutter_app/page/tree_page.dart';
41 | import 'package:flutter_app/page/video_player.dart';
42 |
43 | import 'page/stepper_page.dart';
44 |
45 | final routes = {
46 | //静态路由,无法传参
47 | '/': (_) => RoutePage(),
48 | 'randomWords': (_) => RandomWords(),
49 | 'Home': (context) => MyHomePage(tag: ModalRoute.of(context).settings.arguments),
50 | 'Pavlova': (_) => PavlovaPage(),
51 | 'Image': (_) => ImagePage(),
52 | 'GridView': (_) => GridViewPage(),
53 | 'StateWidget': (_) => StateWidgetPage(),
54 | 'TextField': (_) => TextFieldAndCheckPage(),
55 | 'KeepAlive': (_) => KeepAliveDemo(),
56 | 'Swiper': (_) => SwiperPage(),
57 | 'Wrap': (_) => WrapPage(),
58 | 'Animation': (_) => AnimationPage(),
59 | 'ScreenUtilPage': (_) => ScreenUtilTest(title: 'ScreenUtil测试'),
60 | 'FutureBuilderPage': (_) => FutureBuilderPage(),
61 | 'ThemePage': (_) => ThemePage(),
62 | 'ChipPage': (_) => ChipPage(),
63 | 'ExpansionTilePage': (_) => ExpansionTilePage(),
64 | 'TransformPage': (_) => Transform3D(),
65 | 'LoginPage': (_) => LoginPage(),
66 | 'CustomViewPage': (_) => CustomAnimationPage(),
67 | 'TabPae': (_) => TabPage(),
68 | 'backdropPage': (_) => BackdropPage(),
69 | 'Draggable': (_) => DraggableDragtargets(),
70 | 'SharePage': (_) => SharePage(),
71 | 'AnimationTwo': (_) => AnimationTwo(),
72 | 'SearchPage': (_) => SearchPage(),
73 | 'VideoPlayerPage': (_) => VideoPlayerPage(),
74 | 'Sliver': (_) => SliverPage(),
75 | 'FlutterNativeWeb': (_) => FlutterNativeWebPage(),
76 | 'SqfLitePage': (_) => SqfLite(),
77 | 'StepperPage': (_) => StepperPage(),
78 | 'TreePage': (_) => TreePage(),
79 | 'CupertinoActionSheetPage': (_) => CupertinoActionSheetPage(),
80 | 'FractionallySizedBoxPage': (_) => FractionallySizedBoxPage(),
81 | 'RepaintBoundaryPage': (_) => RepaintBoundaryPage(),
82 | 'ExtensionPage': (_) => ExtensionPage(),
83 | 'MapSearchPage': (_) => MapSearchPage(),
84 | 'DraggableScrollableSheet': (_) => DraggableScrollableSheetPage(),
85 | 'ModalPage': (_) => ModalPage(),
86 | 'PickerPage': (_) => PickerPage(),
87 | 'CustomScrollViewPage': (_) => CustomScrollViewPage(),
88 | };
89 |
90 | ///当通过Navigation.of(context).pushNamed跳转路由时,在routes查找不到时,会调用该方法
91 | Route onGenerateRoute(RouteSettings settings) {
92 | return MaterialPageRoute(builder: (BuildContext context) {
93 | String routeName = settings.name;
94 | print('----route name : $routeName');
95 |
96 | return Scaffold(
97 | appBar: AppBar(
98 | title: Text('$routeName'),
99 | ),
100 | body: Text('找不到$routeName'),
101 | );
102 | });
103 | }
104 |
--------------------------------------------------------------------------------
/lib/rxdart/bloc_provider.dart:
--------------------------------------------------------------------------------
1 | /*
2 | * author: Created by 李卓原 on 2018/10/30.
3 | * email: zhuoyuan93@gmail.com
4 | *
5 | */
6 |
7 | import 'package:flutter/material.dart';
8 | import 'package:flutter_app/rxdart/theme_select.dart';
9 |
10 | class BlocProvider extends InheritedWidget {
11 | final ThemeSelect themeSelect = ThemeSelect();
12 |
13 | BlocProvider({Key key, Widget child}) : super(key: key, child: child);
14 |
15 | @override
16 | bool updateShouldNotify(_) => true;
17 |
18 | static ThemeSelect of(BuildContext context) =>
19 | (context.inheritFromWidgetOfExactType(BlocProvider) as BlocProvider)
20 | .themeSelect;
21 | }
22 |
--------------------------------------------------------------------------------
/lib/rxdart/theme_select.dart:
--------------------------------------------------------------------------------
1 | /*
2 | * author: Created by 李卓原 on 2018/10/30.
3 | * email: zhuoyuan93@gmail.com
4 | * rxdart 实现 主题切换
5 | */
6 | import 'dart:async';
7 |
8 | import 'package:rxdart/rxdart.dart';
9 | import 'package:shared_preferences/shared_preferences.dart';
10 |
11 | class ThemeSelect {
12 | ThemeSelect() {
13 | print("theme select cons");
14 |
15 | initTheme();
16 | }
17 |
18 | var _subject = BehaviorSubject();
19 |
20 | Stream get value => _subject.stream;
21 |
22 | void changeTheme(bool value) async {
23 | SharedPreferences preferences = await SharedPreferences.getInstance();
24 | preferences.setBool("isNight", value);
25 | _subject.add(value);
26 | }
27 |
28 | void dispose() {
29 | _subject.close();
30 | }
31 |
32 | void initTheme() async {
33 | SharedPreferences preferences = await SharedPreferences.getInstance();
34 | bool isNight = preferences.getBool("isNight") ?? false;
35 | preferences.setBool("isNight", isNight);
36 | _subject.add(isNight);
37 | }
38 | }
39 |
--------------------------------------------------------------------------------
/lib/theme/app_theme.dart:
--------------------------------------------------------------------------------
1 | /*
2 | * author: Created by 李卓原 on 2018/10/30.
3 | * email: zhuoyuan93@gmail.com
4 | *
5 | */
6 | import 'package:flutter/material.dart';
7 |
8 | class AppTheme {
9 | final darkTheme = ThemeData(
10 | backgroundColor: Colors.black,
11 | primaryColor: Colors.black,
12 | brightness: Brightness.dark);
13 |
14 | final lightTheme = ThemeData(
15 | backgroundColor: Colors.white,
16 | primaryColor: Colors.green,
17 | primarySwatch: Colors.blue,
18 | brightness: Brightness.light);
19 | }
20 |
--------------------------------------------------------------------------------
/lib/utils/HttpUtil.dart:
--------------------------------------------------------------------------------
1 | /*
2 | * Created by 李卓原 on 2018/9/15.
3 | * email: zhuoyuan93@gmail.com
4 | * 网络请求封装
5 | */
6 |
7 | import 'package:dio/dio.dart';
8 |
9 | class HttpUtil {
10 | static HttpUtil instance;
11 | Dio dio;
12 | Options options;
13 |
14 | static HttpUtil getInstance() {
15 | print('getInstance');
16 | if (instance == null) {
17 | instance = new HttpUtil();
18 | }
19 | return instance;
20 | }
21 |
22 | HttpUtil() {
23 | print('dio赋值');
24 | // 或者通过传递一个 `options`来创建dio实例
25 | options = Options(
26 | // 请求基地址,可以包含子路径,如: "https://www.google.com/api/".
27 | baseUrl: "https://www.xx.com/api",
28 | //连接服务器超时时间,单位是毫秒.
29 | connectTimeout: 10000,
30 |
31 | /// 响应流上前后两次接受到数据的间隔,单位为毫秒。如果两次间隔超过[receiveTimeout],
32 | /// [Dio] 将会抛出一个[DioErrorType.RECEIVE_TIMEOUT]的异常.
33 | /// 注意: 这并不是接收数据的总时限.
34 | receiveTimeout: 3000,
35 | headers: {},
36 | );
37 | dio = new Dio(options);
38 | }
39 |
40 | get(url, {data, options, cancelToken}) async {
41 | print('get请求启动! url:$url ,body: $data');
42 | Response response;
43 | try {
44 | response = await dio.get(
45 | url,
46 | data: data,
47 | cancelToken: cancelToken,
48 | );
49 | print('get请求成功!response.data:${response.data}');
50 | } on DioError catch (e) {
51 | if (CancelToken.isCancel(e)) {
52 | print('get请求取消! ' + e.message);
53 | }
54 | print('get请求发生错误:$e');
55 | }
56 | return response.data;
57 | }
58 |
59 | post(url, {data, options, cancelToken}) async {
60 | print('post请求启动! url:$url ,body: $data');
61 | Response response;
62 | try {
63 | response = await dio.post(
64 | url,
65 | data: data,
66 | cancelToken: cancelToken,
67 | );
68 | print('post请求成功!response.data:${response.data}');
69 | } on DioError catch (e) {
70 | if (CancelToken.isCancel(e)) {
71 | print('post请求取消! ' + e.message);
72 | }
73 | print('post请求发生错误:$e');
74 | }
75 | return response.data;
76 | }
77 | }
78 |
--------------------------------------------------------------------------------
/lib/utils/dbHelper.dart:
--------------------------------------------------------------------------------
1 | /*
2 | * author: Created by 李卓原 on 2019/3/12.
3 | * email: zhuoyuan93@gmail.com
4 | *
5 | */
6 |
7 | import 'dart:async';
8 |
9 | import 'package:flutter_app/model/note.dart';
10 | import 'package:path/path.dart';
11 | import 'package:sqflite/sqflite.dart';
12 |
13 | class DatabaseHelper {
14 | static final DatabaseHelper _instance = new DatabaseHelper.internal();
15 |
16 | factory DatabaseHelper() => _instance;
17 |
18 | final String tableNote = 'note11Table';
19 | final String pointID = 'pointid';
20 | final String image = 'image';
21 | final String contractId = 'contractId';
22 | final String publicationId = 'publicationId';
23 | final String pointLat = 'pointLat';
24 | final String pointLng = 'pointLng';
25 |
26 | static Database _db;
27 |
28 | DatabaseHelper.internal();
29 |
30 | Future get db async {
31 | if (_db != null) {
32 | return _db;
33 | }
34 | _db = await initDb();
35 |
36 | return _db;
37 | }
38 |
39 | initDb() async {
40 | String databasesPath = await getDatabasesPath();
41 | String path = join(databasesPath, 'notes11.db');
42 |
43 | var db = await openDatabase(path, version: 1, onCreate: _onCreate);
44 | return db;
45 | }
46 |
47 | void _onCreate(Database db, int newVersion) async {
48 | await db.execute(
49 | 'CREATE TABLE $tableNote($pointID TEXT PRIMARY KEY, $image TEXT, $contractId TEXT, $publicationId TEXT, $pointLng TEXT, $pointLat TEXT)');
50 | }
51 |
52 | Future saveNote(Note note) async {
53 | var dbClient = await db;
54 | var result = await dbClient.insert(tableNote, note.toMap());
55 |
56 | return result;
57 | }
58 |
59 | Future getAllNotes({int limit, int offset}) async {
60 | var dbClient = await db;
61 | var result = await dbClient.query(
62 | tableNote,
63 | columns: [pointID, image, contractId, publicationId, pointLng, pointLat],
64 | limit: limit,
65 | offset: offset,
66 | );
67 |
68 | return result.toList();
69 | }
70 |
71 | Future getCount() async {
72 | var dbClient = await db;
73 | return Sqflite.firstIntValue(
74 | await dbClient.rawQuery('SELECT COUNT(*) FROM $tableNote'));
75 | }
76 |
77 | Future getNote(int id) async {
78 | var dbClient = await db;
79 | List