├── .DS_Store ├── .flutter-plugins ├── .gitignore ├── .vscode └── launch.json ├── LICENSE ├── README.md ├── android ├── .gitignore ├── app │ ├── build.gradle │ └── src │ │ ├── debug │ │ └── AndroidManifest.xml │ │ ├── main │ │ ├── AndroidManifest.xml │ │ ├── java │ │ │ └── com │ │ │ │ └── example │ │ │ │ └── fluttertest01 │ │ │ │ └── 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 │ │ │ └── styles.xml │ │ └── profile │ │ └── AndroidManifest.xml ├── build.gradle ├── fluttertest01_android.iml ├── gradle.properties ├── gradle │ └── wrapper │ │ └── gradle-wrapper.properties └── settings.gradle ├── d.png ├── f.png ├── flutterExample.iml ├── fonts ├── Merriweather-Black.ttf ├── Merriweather-Light.ttf ├── MoultiPass2.ttf ├── Pangolin-Regular.ttf └── TTGODMB1.TTF ├── img ├── 1.jpeg ├── 2.png ├── 3.5.1-1.png ├── 7.2.1-2.png ├── demo.gif ├── fl.png ├── get_all.gif └── get_guanxi.png ├── ios ├── .gitignore ├── .ruby-version ├── Flutter │ ├── .last_build_id │ ├── AppFrameworkInfo.plist │ ├── Debug.xcconfig │ └── Release.xcconfig ├── Podfile ├── Podfile.lock ├── Runner.xcodeproj │ ├── project.pbxproj │ ├── project.xcworkspace │ │ ├── contents.xcworkspacedata │ │ └── xcshareddata │ │ │ ├── IDEWorkspaceChecks.plist │ │ │ └── WorkspaceSettings.xcsettings │ └── xcshareddata │ │ └── xcschemes │ │ └── Runner.xcscheme ├── Runner.xcworkspace │ ├── contents.xcworkspacedata │ └── xcshareddata │ │ ├── IDEWorkspaceChecks.plist │ │ └── WorkspaceSettings.xcsettings └── Runner │ ├── AppDelegate.swift │ ├── Assets.xcassets │ ├── .DS_Store │ ├── 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 │ ├── Contents.json │ ├── Image.imageset │ │ ├── Contents.json │ │ └── 画板.png │ └── LaunchImage2.imageset │ │ ├── Contents.json │ │ ├── README.md │ │ ├── icon 2.png │ │ ├── icon 2@2x.png │ │ └── icon 2@3x.png │ ├── Base.lproj │ ├── LaunchScreen.storyboard │ └── Main.storyboard │ ├── Info.plist │ └── Runner-Bridging-Header.h ├── lib ├── animation │ ├── base_animaiton.dart │ ├── base_animation_diy.dart │ ├── base_animation_switch.dart │ ├── base_hreo.dart │ ├── base_pageRoute.dart │ └── base_tagger_animation.dart ├── baseWidget │ ├── animation_text_kit.dart │ ├── baseButtons.dart │ ├── baseIndicator.dart │ ├── baseState.dart │ ├── baseSwitch.dart │ ├── baseText.dart │ ├── baseTextField.dart │ ├── base_page_view.dart │ ├── base_page_view_page.dart │ ├── base_rotation.dart │ ├── base_slider.dart │ ├── dialog.dart │ └── imgAndIcon.dart ├── comment │ └── config.dart ├── container │ ├── base_bars.dart │ ├── base_clip.dart │ ├── base_constraints.dart │ ├── base_container.dart │ ├── base_decorateBox.dart │ ├── base_padding.dart │ └── base_transform.dart ├── counter.dart ├── custom_animation │ └── base_custom_animation.dart ├── features │ ├── base_color_and_theme.dart │ ├── base_eventbus.dart │ ├── base_future_stream.dart │ ├── base_gesturedetetor.dart │ ├── base_notification.dart │ ├── base_touch_handle.dart │ ├── base_will_pop.dart │ └── share_data.dart ├── file_and_http │ ├── fileAction.dart │ ├── http_client.dart │ ├── http_dio.dart │ ├── http_socket.dart │ ├── json_to_model.dart │ └── model │ │ ├── git_model.dart │ │ ├── user.dart │ │ └── user_entity.dart ├── generated │ └── json │ │ ├── base │ │ ├── json_convert_content.dart │ │ └── json_filed.dart │ │ ├── git_model_helper.dart │ │ └── user_entity_helper.dart ├── layout │ ├── baseFlex.dart │ ├── base_align.dart │ ├── base_flow_and_wrap.dart │ ├── base_row_and_column.dart │ └── base_stack.dart ├── main.dart ├── main2 ├── main3.dart ├── mainUtil.dart ├── page_view │ ├── page_view.dart │ └── page_view_custom.dart ├── scrollview │ ├── baseCustomScrollview.dart │ ├── baseGridView.dart │ ├── baseListView.dart │ ├── baseListenScrollViewOffset.dart │ ├── baseSingleChildScrollView.dart │ ├── scrollview.dart │ └── swich_page.dart ├── secondPage.dart ├── server │ └── basic_writer_server.dart ├── test.dart ├── tips │ ├── .DS_Store │ ├── Tabbar.dart │ ├── asyn_and_isolate.dart │ ├── async_and_async*.dart │ ├── base_ visibility_detector.dart │ ├── base_bloc.dart │ ├── base_connect.dart │ ├── base_interactive_viewer.dart │ ├── base_key.dart │ ├── base_qrcode.dart │ ├── base_record.dart │ ├── base_render_tree.dart │ ├── base_slider.dart │ ├── base_tabbar.dart │ ├── bloc │ │ ├── base_bloc_list.dart │ │ ├── base_login_cubit.dart │ │ ├── list_cubit │ │ │ ├── bloc │ │ │ │ └── list_bloc.dart │ │ │ ├── list_events │ │ │ │ └── list_event.dart │ │ │ ├── list_status │ │ │ │ └── list_state.dart │ │ │ ├── model │ │ │ │ └── list_data.dart │ │ │ ├── obs │ │ │ │ └── post_obs.dart │ │ │ └── page │ │ │ │ └── list_bloc_route.dart │ │ ├── login_bloc │ │ │ ├── bloc │ │ │ │ ├── login_bloc.dart │ │ │ │ ├── login_blocs.dart │ │ │ │ ├── login_event.dart │ │ │ │ └── login_state.dart │ │ │ ├── login_bloc_page.dart │ │ │ ├── model │ │ │ │ ├── login2_model.dart │ │ │ │ └── login_models.dart │ │ │ └── view │ │ │ │ └── login2_view.dart │ │ └── login_cubit │ │ │ ├── bloc_observer │ │ │ └── bloc_observer.dart │ │ │ ├── cubit │ │ │ ├── base_login_cubit.dart │ │ │ └── cubit.dart │ │ │ ├── model │ │ │ ├── base_login_model.dart │ │ │ └── login_cubit_models.dart │ │ │ ├── page │ │ │ ├── base_login_page.dart │ │ │ └── login_pages.dart │ │ │ └── view │ │ │ ├── base_login_view.dart │ │ │ └── login_views.dart │ ├── channel │ │ └── base_channel.dart │ ├── fish_redux_page.dart │ ├── get │ │ ├── README.md │ │ ├── get_example.dart │ │ ├── get_increment_page.dart │ │ ├── get_list_page.dart │ │ ├── get_login_page.dart │ │ ├── get_route.dart │ │ └── get_store.dart │ ├── hive │ │ ├── base_hive.dart │ │ └── hive_person.dart │ ├── img │ │ └── base_img.dart │ ├── keepStateAlive.dart │ ├── layout │ │ └── base_layout.dart │ ├── page_view.dart │ ├── page_view_tabbar.dart │ ├── provider │ │ ├── base_provider.dart │ │ ├── base_provider_pan_zan.dart │ │ └── base_stream_pge.dart │ ├── redux_page.dart │ ├── revierpod │ │ ├── base_river_pod.dart │ │ └── base_river_pod_list.dart │ ├── rx_dart │ │ └── base_rxDart.dart │ ├── scoped_page.dart │ ├── touch │ │ └── base_touch_handle.dart │ └── wechat_view.dart ├── u3d │ └── u3d_page.dart ├── util.dart └── video │ ├── base_download_file_page.dart │ ├── base_video_ijk_page.dart │ └── base_video_page.dart ├── pubspec.lock ├── pubspec.yaml └── test └── widget_test.dart /.DS_Store: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ifgyong/flutter-example/58679c0bef0de656605e3e2bd5daf7b241ea1baf/.DS_Store -------------------------------------------------------------------------------- /.flutter-plugins: -------------------------------------------------------------------------------- 1 | # This is a generated file; do not edit or check into version control. 2 | audioplayer=/Users/fanguangyong450/.fvm/versions/2.2.1-stable/.pub-cache/hosted/nest.hellobike.cn/audioplayer-0.8.1/ 3 | connectivity=/Users/fanguangyong450/.fvm/versions/2.2.1-stable/.pub-cache/hosted/nest.hellobike.cn/connectivity-3.0.6/ 4 | connectivity_for_web=/Users/fanguangyong450/.fvm/versions/2.2.1-stable/.pub-cache/hosted/nest.hellobike.cn/connectivity_for_web-0.4.0/ 5 | connectivity_macos=/Users/fanguangyong450/.fvm/versions/2.2.1-stable/.pub-cache/hosted/nest.hellobike.cn/connectivity_macos-0.2.0/ 6 | flutter_boost=/Users/fanguangyong450/.fvm/versions/2.2.1-stable/.pub-cache/hosted/nest.hellobike.cn/flutter_boost-1.33.4/ 7 | flutter_ijkplayer=/Users/fanguangyong450/.fvm/versions/2.2.1-stable/.pub-cache/hosted/nest.hellobike.cn/flutter_ijkplayer-0.3.5+1/ 8 | flutter_inappwebview=/Users/fanguangyong450/.fvm/versions/2.2.1-stable/.pub-cache/hosted/nest.hellobike.cn/flutter_inappwebview-5.3.2/ 9 | flutter_vlc_player=/Users/fanguangyong450/.fvm/versions/2.2.1-stable/.pub-cache/hosted/nest.hellobike.cn/flutter_vlc_player-5.0.5/ 10 | fluttertoast=/Users/fanguangyong450/.fvm/versions/2.2.1-stable/.pub-cache/hosted/nest.hellobike.cn/fluttertoast-3.1.3/ 11 | path_provider=/Users/fanguangyong450/.fvm/versions/2.2.1-stable/.pub-cache/hosted/nest.hellobike.cn/path_provider-1.6.24/ 12 | path_provider_linux=/Users/fanguangyong450/.fvm/versions/2.2.1-stable/.pub-cache/hosted/nest.hellobike.cn/path_provider_linux-0.0.1+2/ 13 | path_provider_macos=/Users/fanguangyong450/.fvm/versions/2.2.1-stable/.pub-cache/hosted/nest.hellobike.cn/path_provider_macos-0.0.4+8/ 14 | path_provider_windows=/Users/fanguangyong450/.fvm/versions/2.2.1-stable/.pub-cache/hosted/nest.hellobike.cn/path_provider_windows-0.0.5/ 15 | permission_handler=/Users/fanguangyong450/.fvm/versions/2.2.1-stable/.pub-cache/hosted/nest.hellobike.cn/permission_handler-5.0.1+x/ 16 | qr_code_scanner=/Users/fanguangyong450/.fvm/versions/2.2.1-stable/.pub-cache/hosted/nest.hellobike.cn/qr_code_scanner-0.5.2/ 17 | record_mp3=/Users/fanguangyong450/.fvm/versions/2.2.1-stable/.pub-cache/hosted/nest.hellobike.cn/record_mp3-2.1.0/ 18 | url_launcher=/Users/fanguangyong450/.fvm/versions/2.2.1-stable/.pub-cache/hosted/nest.hellobike.cn/url_launcher-5.5.0/ 19 | url_launcher_linux=/Users/fanguangyong450/.fvm/versions/2.2.1-stable/.pub-cache/hosted/nest.hellobike.cn/url_launcher_linux-0.0.1+4/ 20 | url_launcher_macos=/Users/fanguangyong450/.fvm/versions/2.2.1-stable/.pub-cache/hosted/nest.hellobike.cn/url_launcher_macos-0.0.1+9/ 21 | url_launcher_web=/Users/fanguangyong450/.fvm/versions/2.2.1-stable/.pub-cache/hosted/nest.hellobike.cn/url_launcher_web-0.1.4+1/ 22 | video_player=/Users/fanguangyong450/.fvm/versions/2.2.1-stable/.pub-cache/hosted/nest.hellobike.cn/video_player-2.1.12/ 23 | video_player_web=/Users/fanguangyong450/.fvm/versions/2.2.1-stable/.pub-cache/hosted/nest.hellobike.cn/video_player_web-2.0.2/ 24 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | build/ 2 | .dart_tool/ 3 | .idea/ 4 | .packages 5 | .flutter-plugins-dependencies 6 | -------------------------------------------------------------------------------- /.vscode/launch.json: -------------------------------------------------------------------------------- 1 | { 2 | // Use IntelliSense to learn about possible attributes. 3 | // Hover to view descriptions of existing attributes. 4 | // For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387 5 | "version": "0.2.0", 6 | "configurations": [ 7 | { 8 | "name": "Flutter", 9 | "request": "launch", 10 | "type": "dart" 11 | } 12 | ] 13 | } -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2020 FanGuangYong 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /android/.gitignore: -------------------------------------------------------------------------------- 1 | gradle-wrapper.jar 2 | /.gradle 3 | /captures/ 4 | /gradlew 5 | /gradlew.bat 6 | /local.properties 7 | GeneratedPluginRegistrant.java 8 | -------------------------------------------------------------------------------- /android/app/build.gradle: -------------------------------------------------------------------------------- 1 | def localProperties = new Properties() 2 | def localPropertiesFile = rootProject.file('local.properties') 3 | if (localPropertiesFile.exists()) { 4 | localPropertiesFile.withReader('UTF-8') { reader -> 5 | localProperties.load(reader) 6 | } 7 | } 8 | 9 | def flutterRoot = localProperties.getProperty('flutter.sdk') 10 | if (flutterRoot == null) { 11 | throw new GradleException("Flutter SDK not found. Define location with flutter.sdk in the local.properties file.") 12 | } 13 | 14 | def flutterVersionCode = localProperties.getProperty('flutter.versionCode') 15 | if (flutterVersionCode == null) { 16 | flutterVersionCode = '1' 17 | } 18 | 19 | def flutterVersionName = localProperties.getProperty('flutter.versionName') 20 | if (flutterVersionName == null) { 21 | flutterVersionName = '1.0' 22 | } 23 | 24 | apply plugin: 'com.android.application' 25 | apply from: "$flutterRoot/packages/flutter_tools/gradle/flutter.gradle" 26 | 27 | android { 28 | compileSdkVersion 28 29 | 30 | lintOptions { 31 | disable 'InvalidPackage' 32 | } 33 | 34 | defaultConfig { 35 | // TODO: Specify your own unique Application ID (https://developer.android.com/studio/build/application-id.html). 36 | applicationId "com.example.fluttertest01" 37 | minSdkVersion 16 38 | targetSdkVersion 28 39 | versionCode flutterVersionCode.toInteger() 40 | versionName flutterVersionName 41 | } 42 | 43 | buildTypes { 44 | release { 45 | // TODO: Add your own signing config for the release build. 46 | // Signing with the debug keys for now, so `flutter run --release` works. 47 | signingConfig signingConfigs.debug 48 | } 49 | } 50 | } 51 | 52 | flutter { 53 | source '../..' 54 | } 55 | -------------------------------------------------------------------------------- /android/app/src/debug/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 3 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /android/app/src/main/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 3 | 8 | 12 | 19 | 23 | 27 | 32 | 36 | 37 | 38 | 39 | 40 | 41 | 43 | 46 | 47 | 48 | -------------------------------------------------------------------------------- /android/app/src/main/java/com/example/fluttertest01/MainActivity.java: -------------------------------------------------------------------------------- 1 | package com.example.fluttertest01; 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/ifgyong/flutter-example/58679c0bef0de656605e3e2bd5daf7b241ea1baf/android/app/src/main/res/mipmap-hdpi/ic_launcher.png -------------------------------------------------------------------------------- /android/app/src/main/res/mipmap-mdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ifgyong/flutter-example/58679c0bef0de656605e3e2bd5daf7b241ea1baf/android/app/src/main/res/mipmap-mdpi/ic_launcher.png -------------------------------------------------------------------------------- /android/app/src/main/res/mipmap-xhdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ifgyong/flutter-example/58679c0bef0de656605e3e2bd5daf7b241ea1baf/android/app/src/main/res/mipmap-xhdpi/ic_launcher.png -------------------------------------------------------------------------------- /android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ifgyong/flutter-example/58679c0bef0de656605e3e2bd5daf7b241ea1baf/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png -------------------------------------------------------------------------------- /android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ifgyong/flutter-example/58679c0bef0de656605e3e2bd5daf7b241ea1baf/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png -------------------------------------------------------------------------------- /android/app/src/main/res/values/styles.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 9 | 15 | 18 | 19 | -------------------------------------------------------------------------------- /android/app/src/profile/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 3 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /android/build.gradle: -------------------------------------------------------------------------------- 1 | buildscript { 2 | repositories { 3 | google() 4 | jcenter() 5 | } 6 | 7 | dependencies { 8 | classpath 'com.android.tools.build:gradle:3.5.0' 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/fluttertest01_android.iml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | -------------------------------------------------------------------------------- /android/gradle.properties: -------------------------------------------------------------------------------- 1 | org.gradle.jvmargs=-Xmx1536M 2 | android.enableR8=true 3 | android.useAndroidX=true 4 | android.enableJetifier=true 5 | -------------------------------------------------------------------------------- /android/gradle/wrapper/gradle-wrapper.properties: -------------------------------------------------------------------------------- 1 | #Fri Jun 23 08:50:38 CEST 2017 2 | distributionBase=GRADLE_USER_HOME 3 | distributionPath=wrapper/dists 4 | zipStoreBase=GRADLE_USER_HOME 5 | zipStorePath=wrapper/dists 6 | distributionUrl=https\://services.gradle.org/distributions/gradle-5.6.2-all.zip 7 | -------------------------------------------------------------------------------- /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 | -------------------------------------------------------------------------------- /d.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ifgyong/flutter-example/58679c0bef0de656605e3e2bd5daf7b241ea1baf/d.png -------------------------------------------------------------------------------- /f.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ifgyong/flutter-example/58679c0bef0de656605e3e2bd5daf7b241ea1baf/f.png -------------------------------------------------------------------------------- /flutterExample.iml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | -------------------------------------------------------------------------------- /fonts/Merriweather-Black.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ifgyong/flutter-example/58679c0bef0de656605e3e2bd5daf7b241ea1baf/fonts/Merriweather-Black.ttf -------------------------------------------------------------------------------- /fonts/Merriweather-Light.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ifgyong/flutter-example/58679c0bef0de656605e3e2bd5daf7b241ea1baf/fonts/Merriweather-Light.ttf -------------------------------------------------------------------------------- /fonts/MoultiPass2.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ifgyong/flutter-example/58679c0bef0de656605e3e2bd5daf7b241ea1baf/fonts/MoultiPass2.ttf -------------------------------------------------------------------------------- /fonts/Pangolin-Regular.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ifgyong/flutter-example/58679c0bef0de656605e3e2bd5daf7b241ea1baf/fonts/Pangolin-Regular.ttf -------------------------------------------------------------------------------- /fonts/TTGODMB1.TTF: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ifgyong/flutter-example/58679c0bef0de656605e3e2bd5daf7b241ea1baf/fonts/TTGODMB1.TTF -------------------------------------------------------------------------------- /img/1.jpeg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ifgyong/flutter-example/58679c0bef0de656605e3e2bd5daf7b241ea1baf/img/1.jpeg -------------------------------------------------------------------------------- /img/2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ifgyong/flutter-example/58679c0bef0de656605e3e2bd5daf7b241ea1baf/img/2.png -------------------------------------------------------------------------------- /img/3.5.1-1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ifgyong/flutter-example/58679c0bef0de656605e3e2bd5daf7b241ea1baf/img/3.5.1-1.png -------------------------------------------------------------------------------- /img/7.2.1-2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ifgyong/flutter-example/58679c0bef0de656605e3e2bd5daf7b241ea1baf/img/7.2.1-2.png -------------------------------------------------------------------------------- /img/demo.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ifgyong/flutter-example/58679c0bef0de656605e3e2bd5daf7b241ea1baf/img/demo.gif -------------------------------------------------------------------------------- /img/fl.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ifgyong/flutter-example/58679c0bef0de656605e3e2bd5daf7b241ea1baf/img/fl.png -------------------------------------------------------------------------------- /img/get_all.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ifgyong/flutter-example/58679c0bef0de656605e3e2bd5daf7b241ea1baf/img/get_all.gif -------------------------------------------------------------------------------- /img/get_guanxi.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ifgyong/flutter-example/58679c0bef0de656605e3e2bd5daf7b241ea1baf/img/get_guanxi.png -------------------------------------------------------------------------------- /ios/.gitignore: -------------------------------------------------------------------------------- 1 | *.mode1v3 2 | *.mode2v3 3 | *.moved-aside 4 | *.pbxuser 5 | *.perspectivev3 6 | **/*sync/ 7 | .sconsign.dblite 8 | .tags* 9 | **/.vagrant/ 10 | **/DerivedData/ 11 | Icon? 12 | **/Pods/ 13 | **/.symlinks/ 14 | profile 15 | xcuserdata 16 | **/.generated/ 17 | Flutter/App.framework 18 | Flutter/Flutter.framework 19 | Flutter/Flutter.podspec 20 | Flutter/Generated.xcconfig 21 | Flutter/app.flx 22 | Flutter/app.zip 23 | Flutter/flutter_assets/ 24 | Flutter/flutter_export_environment.sh 25 | ServiceDefinitions.json 26 | Runner/GeneratedPluginRegistrant.* 27 | 28 | # Exceptions to above rules. 29 | !default.mode1v3 30 | !default.mode2v3 31 | !default.pbxuser 32 | !default.perspectivev3 33 | -------------------------------------------------------------------------------- /ios/.ruby-version: -------------------------------------------------------------------------------- 1 | 2.7.3 2 | -------------------------------------------------------------------------------- /ios/Flutter/.last_build_id: -------------------------------------------------------------------------------- 1 | 1b6b09cea91d89a2f74b90f380a02a80 -------------------------------------------------------------------------------- /ios/Flutter/AppFrameworkInfo.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | $(DEVELOPMENT_LANGUAGE) 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/Release.xcconfig: -------------------------------------------------------------------------------- 1 | #include "Pods/Target Support Files/Pods-Runner/Pods-Runner.release.xcconfig" 2 | #include "Generated.xcconfig" 3 | -------------------------------------------------------------------------------- /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 flutter_root 14 | generated_xcode_build_settings_path = File.expand_path(File.join('..', 'Flutter', 'Generated.xcconfig'), __FILE__) 15 | unless File.exist?(generated_xcode_build_settings_path) 16 | raise "#{generated_xcode_build_settings_path} must exist. If you're running pod install manually, make sure flutter pub get is executed first" 17 | end 18 | 19 | File.foreach(generated_xcode_build_settings_path) do |line| 20 | matches = line.match(/FLUTTER_ROOT\=(.*)/) 21 | return matches[1].strip if matches 22 | end 23 | raise "FLUTTER_ROOT not found in #{generated_xcode_build_settings_path}. Try deleting Generated.xcconfig, then run flutter pub get" 24 | end 25 | 26 | require File.expand_path(File.join('packages', 'flutter_tools', 'bin', 'podhelper'), flutter_root) 27 | 28 | flutter_ios_podfile_setup 29 | 30 | target 'Runner' do 31 | use_frameworks! 32 | use_modular_headers! 33 | 34 | flutter_install_all_ios_pods File.dirname(File.realpath(__FILE__)) 35 | end 36 | 37 | post_install do |installer| 38 | installer.pods_project.targets.each do |target| 39 | flutter_additional_ios_build_settings(target) 40 | end 41 | end 42 | -------------------------------------------------------------------------------- /ios/Runner.xcodeproj/project.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /ios/Runner.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | IDEDidComputeMac32BitWarning 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /ios/Runner.xcodeproj/project.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | PreviewsEnabled 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /ios/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme: -------------------------------------------------------------------------------- 1 | 2 | 5 | 8 | 9 | 15 | 21 | 22 | 23 | 24 | 25 | 30 | 31 | 32 | 33 | 39 | 40 | 41 | 42 | 43 | 44 | 54 | 56 | 62 | 63 | 64 | 65 | 66 | 67 | 73 | 75 | 81 | 82 | 83 | 84 | 86 | 87 | 90 | 91 | 92 | -------------------------------------------------------------------------------- /ios/Runner.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 9 | 10 | 11 | -------------------------------------------------------------------------------- /ios/Runner.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | IDEDidComputeMac32BitWarning 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /ios/Runner.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | PreviewsEnabled 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /ios/Runner/AppDelegate.swift: -------------------------------------------------------------------------------- 1 | import UIKit 2 | import Flutter 3 | 4 | @UIApplicationMain 5 | @objc class AppDelegate: FlutterAppDelegate { 6 | override func application( 7 | _ application: UIApplication, 8 | didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]? 9 | ) -> Bool { 10 | GeneratedPluginRegistrant.register(with: self) 11 | let root = self.window.rootViewController as! FlutterViewController 12 | let 13 | channel = FlutterMethodChannel.init(name: "samples.flutter.io/battery", binaryMessenger: root as! FlutterBinaryMessenger) 14 | 15 | channel.setMethodCallHandler { (call: FlutterMethodCall, retult: FlutterResult) in 16 | 17 | if call.method=="getBatteryLevel"{ 18 | let ret = self.getBattery() 19 | 20 | if ret == -1{ 21 | retult(FlutterError.init(code: "-1", message: "无法获取电池用量", details: nil)) 22 | }else{ 23 | retult(Int(ret*100)) 24 | } 25 | }else{ 26 | retult(FlutterMethodNotImplemented) 27 | } 28 | } 29 | 30 | return super.application(application, didFinishLaunchingWithOptions: launchOptions) 31 | } 32 | func getBattery() -> Float { 33 | let device = UIDevice.current 34 | device.isBatteryMonitoringEnabled=true 35 | if UIDevice.current.batteryState == UIDevice.BatteryState.unknown 36 | { 37 | return -1 38 | } 39 | return UIDevice.current.batteryLevel; 40 | 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /ios/Runner/Assets.xcassets/.DS_Store: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ifgyong/flutter-example/58679c0bef0de656605e3e2bd5daf7b241ea1baf/ios/Runner/Assets.xcassets/.DS_Store -------------------------------------------------------------------------------- /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/ifgyong/flutter-example/58679c0bef0de656605e3e2bd5daf7b241ea1baf/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/ifgyong/flutter-example/58679c0bef0de656605e3e2bd5daf7b241ea1baf/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/ifgyong/flutter-example/58679c0bef0de656605e3e2bd5daf7b241ea1baf/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/ifgyong/flutter-example/58679c0bef0de656605e3e2bd5daf7b241ea1baf/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/ifgyong/flutter-example/58679c0bef0de656605e3e2bd5daf7b241ea1baf/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/ifgyong/flutter-example/58679c0bef0de656605e3e2bd5daf7b241ea1baf/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/ifgyong/flutter-example/58679c0bef0de656605e3e2bd5daf7b241ea1baf/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/ifgyong/flutter-example/58679c0bef0de656605e3e2bd5daf7b241ea1baf/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/ifgyong/flutter-example/58679c0bef0de656605e3e2bd5daf7b241ea1baf/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/ifgyong/flutter-example/58679c0bef0de656605e3e2bd5daf7b241ea1baf/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/ifgyong/flutter-example/58679c0bef0de656605e3e2bd5daf7b241ea1baf/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/ifgyong/flutter-example/58679c0bef0de656605e3e2bd5daf7b241ea1baf/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/ifgyong/flutter-example/58679c0bef0de656605e3e2bd5daf7b241ea1baf/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/ifgyong/flutter-example/58679c0bef0de656605e3e2bd5daf7b241ea1baf/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/ifgyong/flutter-example/58679c0bef0de656605e3e2bd5daf7b241ea1baf/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-83.5x83.5@2x.png -------------------------------------------------------------------------------- /ios/Runner/Assets.xcassets/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "info" : { 3 | "author" : "xcode", 4 | "version" : 1 5 | } 6 | } 7 | -------------------------------------------------------------------------------- /ios/Runner/Assets.xcassets/Image.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "scale" : "1x" 6 | }, 7 | { 8 | "filename" : "画板.png", 9 | "idiom" : "universal", 10 | "scale" : "2x" 11 | }, 12 | { 13 | "idiom" : "universal", 14 | "scale" : "3x" 15 | } 16 | ], 17 | "info" : { 18 | "author" : "xcode", 19 | "version" : 1 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /ios/Runner/Assets.xcassets/Image.imageset/画板.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ifgyong/flutter-example/58679c0bef0de656605e3e2bd5daf7b241ea1baf/ios/Runner/Assets.xcassets/Image.imageset/画板.png -------------------------------------------------------------------------------- /ios/Runner/Assets.xcassets/LaunchImage2.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "compression-type" : "automatic", 5 | "filename" : "icon 2.png", 6 | "idiom" : "universal", 7 | "scale" : "1x" 8 | }, 9 | { 10 | "filename" : "icon 2@2x.png", 11 | "idiom" : "universal", 12 | "scale" : "2x" 13 | }, 14 | { 15 | "filename" : "icon 2@3x.png", 16 | "idiom" : "universal", 17 | "scale" : "3x" 18 | } 19 | ], 20 | "info" : { 21 | "author" : "xcode", 22 | "version" : 1 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /ios/Runner/Assets.xcassets/LaunchImage2.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/Assets.xcassets/LaunchImage2.imageset/icon 2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ifgyong/flutter-example/58679c0bef0de656605e3e2bd5daf7b241ea1baf/ios/Runner/Assets.xcassets/LaunchImage2.imageset/icon 2.png -------------------------------------------------------------------------------- /ios/Runner/Assets.xcassets/LaunchImage2.imageset/icon 2@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ifgyong/flutter-example/58679c0bef0de656605e3e2bd5daf7b241ea1baf/ios/Runner/Assets.xcassets/LaunchImage2.imageset/icon 2@2x.png -------------------------------------------------------------------------------- /ios/Runner/Assets.xcassets/LaunchImage2.imageset/icon 2@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ifgyong/flutter-example/58679c0bef0de656605e3e2bd5daf7b241ea1baf/ios/Runner/Assets.xcassets/LaunchImage2.imageset/icon 2@3x.png -------------------------------------------------------------------------------- /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 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | -------------------------------------------------------------------------------- /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 | $(DEVELOPMENT_LANGUAGE) 7 | NSAppTransportSecurity 8 | 9 | NSAllowsArbitraryLoads 10 | 11 | 12 | CFBundleExecutable 13 | $(EXECUTABLE_NAME) 14 | CFBundleIdentifier 15 | $(PRODUCT_BUNDLE_IDENTIFIER) 16 | CFBundleInfoDictionaryVersion 17 | 6.0 18 | CFBundleName 19 | fluttertest01 20 | CFBundlePackageType 21 | APPL 22 | CFBundleShortVersionString 23 | $(FLUTTER_BUILD_NAME) 24 | CFBundleSignature 25 | ???? 26 | CFBundleVersion 27 | $(FLUTTER_BUILD_NUMBER) 28 | LSRequiresIPhoneOS 29 | 30 | io.flutter.embedded_views_preview 31 | 32 | UILaunchStoryboardName 33 | LaunchScreen 34 | UIMainStoryboardFile 35 | Main 36 | UISupportedInterfaceOrientations 37 | 38 | UIInterfaceOrientationPortrait 39 | UIInterfaceOrientationLandscapeLeft 40 | UIInterfaceOrientationLandscapeRight 41 | 42 | UISupportedInterfaceOrientations~ipad 43 | 44 | UIInterfaceOrientationPortrait 45 | UIInterfaceOrientationPortraitUpsideDown 46 | UIInterfaceOrientationLandscapeLeft 47 | UIInterfaceOrientationLandscapeRight 48 | 49 | UIViewControllerBasedStatusBarAppearance 50 | 51 | 52 | 53 | -------------------------------------------------------------------------------- /ios/Runner/Runner-Bridging-Header.h: -------------------------------------------------------------------------------- 1 | #import "GeneratedPluginRegistrant.h" 2 | -------------------------------------------------------------------------------- /lib/animation/base_hreo.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/cupertino.dart'; 2 | import 'package:flutter/material.dart'; 3 | 4 | /// 5 | /// Created by fgyong on 2020/7/21. 6 | /// 7 | 8 | class BaseHreo extends StatefulWidget { 9 | final String heroKey; 10 | BaseHreo({Key key, this.heroKey}) : super(key: key); 11 | 12 | @override 13 | _BaseHreoState createState() => _BaseHreoState(); 14 | } 15 | 16 | class _BaseHreoState extends State { 17 | @override 18 | Widget build(BuildContext context) { 19 | return Scaffold( 20 | appBar: AppBar( 21 | title: Text('Hero 动画'), 22 | ), 23 | body: _body(), 24 | ); 25 | } 26 | 27 | Widget _body() { 28 | return Center( 29 | child: Column( 30 | children: [ 31 | Hero( 32 | child: Container( 33 | width: 100, 34 | height: 100, 35 | child: Image.asset('img/2.png'), 36 | ), 37 | tag: 'key', 38 | ), 39 | OutlineButton( 40 | child: Text('push'), 41 | onPressed: () { 42 | Navigator.push( 43 | context, 44 | MaterialPageRoute( 45 | builder: (ctx) => _BaseHreo( 46 | heroKey: 'key', 47 | ))); 48 | }, 49 | ) 50 | ], 51 | ), 52 | ); 53 | } 54 | } 55 | 56 | class _BaseHreo extends StatelessWidget { 57 | final String heroKey; 58 | _BaseHreo({Key key, this.heroKey}) : super(key: key); 59 | @override 60 | Widget build(BuildContext context) { 61 | return Scaffold( 62 | appBar: AppBar( 63 | title: Text('hero 动画'), 64 | ), 65 | body: _body(), 66 | ); 67 | } 68 | 69 | Widget _body() { 70 | return Align( 71 | alignment: Alignment.bottomCenter, 72 | child: Hero( 73 | child: ClipRRect( 74 | child: Container( 75 | width: 300, 76 | height: 300, 77 | child: Image.asset( 78 | 'img/2.png', 79 | fit: BoxFit.fill, 80 | ), 81 | ), 82 | borderRadius: BorderRadius.all(Radius.circular(150)), 83 | ), 84 | tag: heroKey ?? 'key', 85 | ), 86 | ); 87 | } 88 | } 89 | -------------------------------------------------------------------------------- /lib/animation/base_tagger_animation.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/cupertino.dart'; 2 | import 'package:flutter/material.dart'; 3 | 4 | /// 5 | /// Created by fgyong on 2020/7/21. 6 | 7 | /// 8 | 9 | class BaseTaggerAnimation extends StatefulWidget { 10 | BaseTaggerAnimation({Key key}) : super(key: key); 11 | 12 | @override 13 | _BaseTaggerAnimationState createState() => _BaseTaggerAnimationState(); 14 | } 15 | 16 | class _BaseTaggerAnimationState extends State 17 | with SingleTickerProviderStateMixin { 18 | AnimationController _animationController; 19 | Animation _radius; 20 | Animation _height; 21 | @override 22 | void initState() { 23 | _animationController = 24 | AnimationController(vsync: this, duration: Duration(milliseconds: 4000)) 25 | ..repeat(); 26 | _radius = Tween(begin: 0, end: 100).animate(CurvedAnimation( 27 | parent: _animationController, 28 | curve: Interval(0, 0.5, curve: Curves.easeIn))); 29 | _height = Tween(begin: 1, end: 0.5).animate(CurvedAnimation( 30 | parent: _animationController, 31 | curve: Interval(0.5, 1.0, curve: Curves.bounceOut), 32 | )); 33 | 34 | super.initState(); 35 | } 36 | 37 | @override 38 | Widget build(BuildContext context) { 39 | return Scaffold( 40 | appBar: AppBar( 41 | title: Text('交织动画'), 42 | ), 43 | body: _body(), 44 | ); 45 | } 46 | 47 | Widget _body() { 48 | double height = 200; 49 | return AnimatedBuilder( 50 | animation: _animationController, 51 | builder: (ctx, child) { 52 | return Center( 53 | child: ClipRRect( 54 | borderRadius: BorderRadius.all(Radius.circular(_radius.value)), 55 | child: Container( 56 | width: height * _height.value, 57 | height: height * _height.value, 58 | color: Colors.orange, 59 | ), 60 | ), 61 | ); 62 | }, 63 | ); 64 | } 65 | 66 | @override 67 | void dispose() { 68 | _animationController.dispose(); 69 | super.dispose(); 70 | } 71 | } 72 | -------------------------------------------------------------------------------- /lib/baseWidget/animation_text_kit.dart: -------------------------------------------------------------------------------- 1 | import 'package:animated_text_kit/animated_text_kit.dart'; 2 | import 'package:flutter/cupertino.dart'; 3 | import 'package:flutter/material.dart'; 4 | 5 | class AnimationTextKitPage extends StatefulWidget { 6 | @override 7 | State createState() => _AnimationTextKitState(); 8 | static String get routeName => '/AnimationTextKitPage'; 9 | } 10 | 11 | class _AnimationTextKitState extends State { 12 | @override 13 | Widget build(BuildContext context) { 14 | return Scaffold( 15 | appBar: AppBar( 16 | title: Text('AnimationTextKit'), 17 | ), 18 | body: Column( 19 | children: [ 20 | _item(TypewriterAnimatedText( 21 | 'Hello world!', 22 | textStyle: const TextStyle( 23 | fontSize: 32.0, 24 | fontWeight: FontWeight.bold, 25 | ), 26 | speed: const Duration(milliseconds: 200), 27 | )), 28 | _item(ColorizeAnimatedText('ColorizeAnimatedText ', 29 | textStyle: const TextStyle( 30 | fontSize: 32.0, 31 | fontWeight: FontWeight.bold, 32 | ), 33 | colors: [Colors.red, Colors.blueAccent])), 34 | _item(FadeAnimatedText('FadeAnimatedText')), 35 | _item(FlickerAnimatedText('FadeAnimatedText')), 36 | _item(RotateAnimatedText('RotateAnimatedText')), 37 | _item(ScaleAnimatedText('ScaleAnimatedText')), 38 | TextLiquidFill(text: 'TextLiquidFill'), 39 | _item(TyperAnimatedText('TyperAnimatedText ', 40 | speed: Duration(milliseconds: 400))), 41 | ], 42 | ), 43 | ); 44 | } 45 | 46 | Widget _item(AnimatedText text) { 47 | return AnimatedTextKit( 48 | animatedTexts: [text], 49 | totalRepeatCount: 4, 50 | pause: const Duration(milliseconds: 500), 51 | displayFullTextOnTap: true, 52 | stopPauseOnTap: true, 53 | ); 54 | } 55 | } 56 | -------------------------------------------------------------------------------- /lib/baseWidget/base_page_view_page.dart: -------------------------------------------------------------------------------- 1 | import 'dart:async'; 2 | 3 | import 'package:flutter/cupertino.dart'; 4 | import 'package:flutter/material.dart'; 5 | import 'package:fluttertest01/baseWidget/base_page_view.dart'; 6 | 7 | class BasePageViewPage extends StatefulWidget { 8 | @override 9 | State createState() { 10 | return _BaseSliderPageState(); 11 | } 12 | 13 | static String get routeName => '/BasePageViewPage'; 14 | } 15 | 16 | class _BaseSliderPageState extends State { 17 | @override 18 | void initState() { 19 | super.initState(); 20 | _height = 100; 21 | } 22 | 23 | double _height; 24 | 25 | @override 26 | Widget build(BuildContext context) { 27 | return Scaffold( 28 | appBar: AppBar( 29 | title: Text('BaseSliderPageState'), 30 | ), 31 | body: Center( 32 | child: Column( 33 | mainAxisAlignment: MainAxisAlignment.center, 34 | children: [ 35 | Container( 36 | child: Text('滑动渐变pageView'), 37 | ), 38 | Container( 39 | alignment: Alignment.center, 40 | child: HotelPageView( 41 | widgetHeights: [100, 200, 150], 42 | pageCount: 3, 43 | initPage: 0, 44 | freshWidget: (fn) { 45 | if (mounted) { 46 | setState(fn); 47 | } 48 | }, 49 | freshHeightCallBack: (height) { 50 | scheduleMicrotask(() { 51 | if (mounted) { 52 | setState(() { 53 | _height = height; 54 | }); 55 | } 56 | }); 57 | }, 58 | itemBuilder: (ctx, index) { 59 | double height = [100.0, 200.0, 160.0][index]; 60 | 61 | return Container( 62 | height: height, 63 | child: Container( 64 | color: 65 | Colors.accents[(index + 1) % Colors.accents.length], 66 | height: height, 67 | ), 68 | color: Colors.accents[index % Colors.accents.length], 69 | ); 70 | }, 71 | ), 72 | height: _height, 73 | width: 200, 74 | ) 75 | ], 76 | ), 77 | ), 78 | ); 79 | } 80 | } 81 | -------------------------------------------------------------------------------- /lib/baseWidget/base_rotation.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/cupertino.dart'; 2 | import 'package:flutter/material.dart'; 3 | 4 | class BaseRotationBoxPage extends StatefulWidget { 5 | @override 6 | State createState() { 7 | return _BaseSliderPageState(); 8 | } 9 | 10 | static String get routeName => '/BaseRotationBoxPage'; 11 | } 12 | 13 | class _BaseSliderPageState extends State { 14 | @override 15 | void initState() { 16 | super.initState(); 17 | } 18 | 19 | int value = 1; 20 | 21 | @override 22 | Widget build(BuildContext context) { 23 | return Scaffold( 24 | appBar: AppBar( 25 | title: Text('BaseSliderPageState'), 26 | ), 27 | body: Center( 28 | child: Column( 29 | mainAxisAlignment: MainAxisAlignment.center, 30 | children: [ 31 | Text('点击蓝色文字 看见旋转效果 \n RotatedBox会影响布局,而transform不会影响布局,只会影响绘制。'), 32 | SizedBox( 33 | height: 50, 34 | ), 35 | Row( 36 | mainAxisAlignment: MainAxisAlignment.center, 37 | children: [ 38 | TextButton( 39 | child: RotatedBox( 40 | quarterTurns: value, 41 | child: Container( 42 | padding: EdgeInsets.all(20), 43 | decoration: BoxDecoration( 44 | color: Colors.blue, 45 | borderRadius: BorderRadius.all(Radius.circular(10))), 46 | child: Text( 47 | '点我旋转', 48 | style: TextStyle( 49 | fontSize: 20, 50 | fontWeight: FontWeight.bold, 51 | color: Colors.white), 52 | ), 53 | ), 54 | ), 55 | onPressed: () { 56 | setState(() { 57 | value += 1; 58 | value %= 4; 59 | print(value); 60 | }); 61 | }, 62 | ), 63 | Text('点击左侧按钮 我会移动的'), 64 | ], 65 | ) 66 | ], 67 | ), 68 | ), 69 | ); 70 | } 71 | } 72 | -------------------------------------------------------------------------------- /lib/baseWidget/base_slider.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/cupertino.dart'; 2 | import 'package:flutter/material.dart'; 3 | 4 | class BaseSliderRangPage extends StatefulWidget { 5 | @override 6 | State createState() { 7 | return _BaseSliderPageState(); 8 | } 9 | 10 | static String get routeName => '/BaseSliderRangPage'; 11 | } 12 | 13 | class _BaseSliderPageState extends State { 14 | double value; 15 | RangeValues rangeValues; 16 | @override 17 | void initState() { 18 | super.initState(); 19 | value = 0.5; 20 | rangeValues = RangeValues(1, 10); 21 | } 22 | 23 | @override 24 | Widget build(BuildContext context) { 25 | return Scaffold( 26 | appBar: AppBar( 27 | title: Text('BaseSliderPageState'), 28 | ), 29 | body: Center( 30 | child: Column( 31 | mainAxisAlignment: MainAxisAlignment.center, 32 | children: [ 33 | Text('拖动下方slider查看效果'), 34 | SizedBox( 35 | height: 50, 36 | ), 37 | Slider( 38 | value: value, 39 | onChanged: (v) { 40 | setState(() { 41 | value = v; 42 | }); 43 | }, 44 | label: '$value', 45 | divisions: 100, 46 | activeColor: Colors.redAccent, 47 | ), 48 | RangeSlider( 49 | values: rangeValues, 50 | max: 100, 51 | min: 0, 52 | onChanged: (v) { 53 | setState(() { 54 | rangeValues = v; 55 | }); 56 | }, 57 | labels: RangeLabels('${rangeValues.start}', '${rangeValues.end}'), 58 | divisions: 100, 59 | activeColor: Colors.redAccent, 60 | ), 61 | ], 62 | ), 63 | ), 64 | ); 65 | } 66 | } 67 | -------------------------------------------------------------------------------- /lib/comment/config.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/cupertino.dart'; 2 | import 'package:flutter/material.dart'; 3 | 4 | class ThemeYo { 5 | static TextStyle get textStyle { 6 | return TextStyle(color: Colors.black, fontSize: 25); 7 | } 8 | 9 | static TextStyle get subTileTextStyle { 10 | return TextStyle(color: Colors.black54, fontSize: 15); 11 | } 12 | 13 | static TextStyle get itemTextStyle { 14 | return TextStyle(color: Colors.black45, fontSize: 15); 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /lib/container/base_clip.dart: -------------------------------------------------------------------------------- 1 | import 'dart:math'; 2 | 3 | import 'package:flutter/material.dart'; 4 | 5 | class BaseClip extends StatelessWidget { 6 | @override 7 | Widget build(BuildContext context) { 8 | return Scaffold( 9 | appBar: AppBar( 10 | title: Text('裁剪部件'), 11 | ), 12 | body: Center( 13 | child: _body2(), 14 | ), 15 | ); 16 | } 17 | 18 | Widget _body() { 19 | Widget avator = Container( 20 | width: 100, 21 | height: 100, 22 | color: Colors.blue, 23 | ); 24 | return Column( 25 | mainAxisAlignment: MainAxisAlignment.center, 26 | children: [ 27 | Text('ClipOval 剪切圆形'), 28 | ClipOval( 29 | child: avator, 30 | ), 31 | Text('ClipOval 圆角'), 32 | ClipRRect( 33 | borderRadius: BorderRadius.all(Radius.circular(10)), 34 | child: avator, 35 | ), 36 | Text('ClipOval 剪切为原来的1/4'), 37 | ClipRect( 38 | child: Align( 39 | alignment: Alignment.topRight, 40 | widthFactor: 0.5, 41 | heightFactor: 0.5, 42 | child: avator, 43 | ), 44 | ) 45 | ], 46 | ); 47 | } 48 | 49 | Widget _body2() { 50 | Widget avator = Container(height: 200,width: 200,child: Image.asset('img/1.jpeg',),); 51 | return Column( 52 | mainAxisAlignment: MainAxisAlignment.center, 53 | children: [ 54 | ClipPath( 55 | child: avator, 56 | clipper: BaseCustomPath(), 57 | ) 58 | ], 59 | ); 60 | } 61 | } 62 | 63 | class BaseCustomPath extends CustomClipper { 64 | @override 65 | Path getClip(Size size) { 66 | Path path = Path(); 67 | path.moveTo(size.width / 2, 40); 68 | path.lineTo(size.width - 15, size.height - 15); 69 | path.lineTo(15, size.height - 15); 70 | 71 | double p1 = 1 * pi; 72 | path.addArc(Rect.fromLTWH(30,30,30,30), 73 | p1, p1 + 2 * pi); 74 | path.lineTo(15, size.height - 15); 75 | path.addArc( 76 | Rect.fromLTWH(size.width - 30,30,30,30), 77 | p1, 78 | p1 + 2 * pi); 79 | path.lineTo(0, 0); 80 | return path; 81 | } 82 | 83 | @override 84 | bool shouldReclip(CustomClipper oldClipper) { 85 | return this != oldClipper; 86 | } 87 | } 88 | -------------------------------------------------------------------------------- /lib/container/base_constraints.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/material.dart'; 2 | 3 | class BaseConstraints extends StatelessWidget { 4 | @override 5 | Widget build(BuildContext context) { 6 | return Scaffold( 7 | appBar: AppBar( 8 | title: Text('尺寸限制类容器'), 9 | ), 10 | body: _widget(), 11 | ); 12 | } 13 | 14 | Widget _redBox() { 15 | return ConstrainedBox( 16 | constraints: BoxConstraints(minHeight: 50, minWidth: 50), 17 | child: Container( 18 | color: Colors.red, 19 | ), 20 | ); 21 | } 22 | 23 | Widget _widget() { 24 | return Container( 25 | color: Colors.black12, 26 | constraints: BoxConstraints( 27 | minHeight: 100, minWidth: 100, maxWidth: 200, maxHeight: 200), 28 | child: UnconstrainedBox( 29 | child: _redBox(), 30 | ), 31 | ); 32 | } 33 | 34 | Widget _bd() { 35 | return Column( 36 | children: [ 37 | Container( 38 | constraints: BoxConstraints( 39 | minWidth: 50, minHeight: 50, maxHeight: 200, maxWidth: 100), 40 | color: Colors.red, 41 | child: Container( 42 | constraints: BoxConstraints( 43 | minWidth: 30, minHeight: 30, maxHeight: 50, maxWidth: 100), 44 | // width: 30, 45 | // height: 30, 46 | color: Colors.blue, 47 | ), 48 | ), 49 | _redBox(), 50 | SizedBox( 51 | height: 10, 52 | ), 53 | // SizedBox(width: 100.0, height: 100.0, child: _redBox()), 54 | Container( 55 | width: 200, 56 | height: 200, 57 | child: ConstrainedBox( 58 | constraints: BoxConstraints( 59 | minHeight: 100, 60 | minWidth: 100, 61 | ), 62 | // color: Colors.black12, 63 | child: _redBox(), 64 | ), 65 | ), 66 | ], 67 | ); 68 | } 69 | } 70 | -------------------------------------------------------------------------------- /lib/container/base_container.dart: -------------------------------------------------------------------------------- 1 | import 'dart:math'; 2 | 3 | import 'package:flutter/cupertino.dart'; 4 | import 'package:flutter/material.dart'; 5 | 6 | class BaseContainer extends StatefulWidget { 7 | @override 8 | _BaseContainerState createState() => _BaseContainerState(); 9 | } 10 | 11 | class _BaseContainerState extends State { 12 | @override 13 | Widget build(BuildContext context) { 14 | return Scaffold( 15 | appBar: AppBar( 16 | title: Text('Container容器'), 17 | ), 18 | body: _body(), 19 | ); 20 | } 21 | 22 | Widget _body() { 23 | return Center( 24 | child: Column( 25 | mainAxisAlignment: MainAxisAlignment.center, 26 | crossAxisAlignment: CrossAxisAlignment.center, 27 | children: [ 28 | Container( 29 | clipBehavior: Clip.none, 30 | width: 200, 31 | height: 100, 32 | decoration: BoxDecoration( 33 | borderRadius: BorderRadius.all(Radius.circular(10)), 34 | gradient: 35 | LinearGradient(colors: [Colors.orange, Colors.deepOrange])), 36 | transform: Matrix4.identity()..rotateZ(pi / 10), 37 | child: Text( 38 | 'www.flutter.fgyong.cn', 39 | style: TextStyle(fontSize: 18, color: Colors.white), 40 | ), 41 | alignment: Alignment.center, 42 | ) 43 | ], 44 | ), 45 | ); 46 | } 47 | } 48 | -------------------------------------------------------------------------------- /lib/container/base_padding.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/material.dart'; 2 | 3 | class BasePadding extends StatelessWidget { 4 | @override 5 | Widget build(BuildContext context) { 6 | return Scaffold( 7 | appBar: AppBar( 8 | title: Text('Padding'), 9 | ), 10 | body: _body(), 11 | ); 12 | } 13 | 14 | Widget _body() { 15 | return Center( 16 | child: Column( 17 | mainAxisAlignment: MainAxisAlignment.center, 18 | children: [ 19 | Container( 20 | color: Colors.black12, 21 | child: Padding( 22 | /// 设置上下左右各10像素 颜色是父级颜色 23 | 24 | padding: EdgeInsets.all(10), 25 | child: Container( 26 | color: Colors.red, 27 | child: Text('设置上下左右各10像素 颜色是父级颜色'), 28 | ), 29 | ), 30 | ), 31 | Container( 32 | color: Colors.black12, 33 | child: Padding( 34 | /// 设置上下20像素 颜色是父级颜色 35 | 36 | padding: EdgeInsets.symmetric(vertical: 20), 37 | child: Container( 38 | color: Colors.blue, 39 | child: Text('设置上下20像素 颜色是父级颜色'), 40 | ), 41 | ), 42 | ), 43 | Container( 44 | color: Colors.black12, 45 | child: Padding( 46 | /// 设置上下左右各30像素 颜色是父级颜色 47 | padding: 48 | EdgeInsets.only(left: 30, top: 30, right: 30, bottom: 30), 49 | child: Container( 50 | color: Colors.orange, 51 | child: Text('设置上下左右各30像素 颜色是父级颜色'), 52 | ), 53 | ), 54 | ) 55 | ], 56 | ), 57 | ); 58 | } 59 | } 60 | -------------------------------------------------------------------------------- /lib/counter.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/cupertino.dart'; 2 | 3 | class Counter extends ChangeNotifier { 4 | int index = 0; 5 | void add() { 6 | index += 1; 7 | notifyListeners(); 8 | } 9 | 10 | void changeValue(int index) { 11 | this.index = index; 12 | notifyListeners(); 13 | } 14 | } 15 | 16 | class CounterValue extends ChangeNotifier { 17 | int _index = 0; 18 | int get value => _index; 19 | void add() { 20 | _index += 2; 21 | notifyListeners(); 22 | } 23 | } 24 | 25 | class CounterValue2 extends ChangeNotifier { 26 | int _index = 0; 27 | int get value => _index; 28 | void add() { 29 | _index += 2; 30 | notifyListeners(); 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /lib/custom_animation/base_custom_animation.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/cupertino.dart'; 2 | import 'package:flutter/material.dart'; 3 | 4 | /// 5 | /// Created by fgyong on 2020/8/31. 6 | /// 7 | 8 | class BaseCustomListAnimationPage extends StatelessWidget { 9 | static String get routeName => '/BaseCustomListAnimationPage'; 10 | @override 11 | Widget build(BuildContext context) { 12 | return Scaffold( 13 | appBar: AppBar( 14 | title: Text(''), 15 | ), 16 | body: _body(), 17 | ); 18 | } 19 | 20 | Widget _body() { 21 | return NestedScrollView( 22 | headerSliverBuilder: _listView, 23 | body: ListView.builder( 24 | itemBuilder: (context, index) { 25 | return ListTile( 26 | title: Text('$index'), 27 | ); 28 | }, 29 | itemCount: 10, 30 | )); 31 | } 32 | 33 | List _listView(BuildContext context, bool innerBoxIsScrolled) { 34 | return [ 35 | SliverAppBar( 36 | title: Text('123'), 37 | floating: false, 38 | ) 39 | ]; 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /lib/features/base_color_and_theme.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/cupertino.dart'; 2 | import 'package:flutter/material.dart'; 3 | 4 | /// 5 | /// Created by fgyong on 2020/7/8. 6 | /// 7 | 8 | class BaseColorAndTheme extends StatefulWidget { 9 | @override 10 | _BaseColorAndThemeState createState() => _BaseColorAndThemeState(); 11 | } 12 | 13 | class _BaseColorAndThemeState extends State { 14 | Color _color; 15 | @override 16 | Widget build(BuildContext context) { 17 | ThemeData themeData = Theme.of(context); 18 | 19 | return Theme( 20 | child: Scaffold( 21 | appBar: AppBar( 22 | title: Text('颜色和主题'), 23 | ), 24 | body: _body(), 25 | ), 26 | data: ThemeData( 27 | primarySwatch: _color, 28 | iconTheme: IconThemeData(color: _color), 29 | textTheme: TextTheme(button: TextStyle(backgroundColor: _color))), 30 | ); 31 | } 32 | 33 | Widget _body() { 34 | return Center( 35 | child: Column( 36 | children: [ 37 | FlatButton( 38 | child: Text('切换颜色'), 39 | color: Theme.of(context).buttonColor, 40 | onPressed: () { 41 | setState(() { 42 | // _iconColor = Colors.orange; 43 | _color = _color == Colors.orange ? Colors.green : Colors.orange; 44 | }); 45 | // Navigator.of(context) 46 | // .push(MaterialPageRoute(builder: (ctx) => _BaseRoutePage())); 47 | }, 48 | ), 49 | Row( 50 | children: [ 51 | Icon( 52 | Icons.add, 53 | size: 50, 54 | ), 55 | Text('颜色跟随主题') 56 | ], 57 | ), 58 | Theme( 59 | child: Row( 60 | children: [ 61 | Icon( 62 | Icons.add, 63 | size: 50, 64 | ), 65 | Text('颜色固定') 66 | ], 67 | ), 68 | data: ThemeData( 69 | iconTheme: IconThemeData(color: Colors.red), 70 | ), 71 | ) 72 | ], 73 | ), 74 | ); 75 | } 76 | 77 | @override 78 | void initState() { 79 | _color = Colors.teal; 80 | 81 | super.initState(); 82 | } 83 | } 84 | -------------------------------------------------------------------------------- /lib/features/base_eventbus.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/cupertino.dart'; 2 | import 'package:flutter/material.dart'; 3 | 4 | /// 5 | /// Created by fgyong on 2020/7/9. 6 | /// 7 | 8 | class BaseEventBus extends StatefulWidget { 9 | @override 10 | _BaseEventBusState createState() => _BaseEventBusState(); 11 | } 12 | 13 | class _BaseEventBusState extends State { 14 | @override 15 | Widget build(BuildContext context) { 16 | return Scaffold( 17 | appBar: AppBar( 18 | title: Text('事件总线'), 19 | ), 20 | body: _body(), 21 | ); 22 | } 23 | 24 | Widget _body() { 25 | return Center( 26 | child: Column( 27 | children: [ 28 | Text(_str), 29 | OutlineButton( 30 | onPressed: () { 31 | // _bus.fire('test', '全局调用了一次哦'); 32 | 33 | Navigator.of(context) 34 | .push(MaterialPageRoute(builder: (c) => _Page2())); 35 | }, 36 | child: Text('点我push new page'), 37 | ) 38 | ], 39 | ), 40 | ); 41 | } 42 | 43 | String _str = ''; 44 | FYEventBus _bus; 45 | @override 46 | void initState() { 47 | _bus = FYEventBus() 48 | ..on('test', (string) { 49 | setState(() { 50 | _str += string; 51 | }); 52 | }); 53 | super.initState(); 54 | } 55 | 56 | @override 57 | void dispose() { 58 | _bus.off('test', null); 59 | super.dispose(); 60 | } 61 | } 62 | 63 | class _Page2 extends StatelessWidget { 64 | @override 65 | Widget build(BuildContext context) { 66 | return Scaffold( 67 | appBar: AppBar( 68 | title: Text('过来传值了'), 69 | ), 70 | body: _body(), 71 | ); 72 | } 73 | 74 | FYEventBus _bus = FYEventBus(); 75 | Widget _body() { 76 | return Center( 77 | child: Column( 78 | children: [ 79 | OutlineButton( 80 | onPressed: () { 81 | _bus.fire('test', '\n点我发送请求A'); 82 | }, 83 | child: Text('点我发送请求A'), 84 | ), 85 | OutlineButton( 86 | onPressed: () { 87 | _bus.fire('test', '\n点我发送请求B'); 88 | }, 89 | child: Text('点我发送请求B'), 90 | ) 91 | ], 92 | ), 93 | ); 94 | } 95 | } 96 | 97 | typedef EventBusCallback = void Function(Object object); 98 | 99 | class FYEventBus { 100 | static FYEventBus _bus = new FYEventBus._(); 101 | FYEventBus._(); 102 | 103 | /// 工厂构造 单例模式 104 | factory FYEventBus() => _bus; 105 | 106 | //保存全局 107 | var _emap = new Map>(); 108 | 109 | /// 监听回调 110 | void on(eventName, EventBusCallback callback) { 111 | if (eventName == null || callback == null) return; 112 | _emap[eventName] ??= new List(); 113 | if (_emap[eventName].contains(callback) == false) { 114 | _emap[eventName].add(callback); 115 | } 116 | } 117 | 118 | /// 删除回调 119 | void off(eventName, EventBusCallback callback) { 120 | if (eventName == null || callback == null) return; 121 | if (callback == null) { 122 | _emap[eventName] = null; 123 | } else { 124 | _emap[eventName].remove(callback); 125 | } 126 | } 127 | 128 | /// 发送回调 129 | void fire(eventName, [arg]) { 130 | if (eventName == null) return; 131 | var list = _emap[eventName]; 132 | if (list == null) return; 133 | for (var j = list.length - 1; j >= 0; --j) { 134 | var o = list[j]; 135 | o(arg); 136 | } 137 | } 138 | } 139 | -------------------------------------------------------------------------------- /lib/features/base_future_stream.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/cupertino.dart'; 2 | import 'package:flutter/material.dart'; 3 | 4 | /// 5 | /// Created by fgyong on 2020/7/8. 6 | /// 7 | 8 | class BaseFutureStream extends StatefulWidget { 9 | @override 10 | _BaseFutureStreamState createState() => _BaseFutureStreamState(); 11 | } 12 | 13 | class _BaseFutureStreamState extends State { 14 | @override 15 | Widget build(BuildContext context) { 16 | return Scaffold( 17 | appBar: AppBar( 18 | title: Text('异步更新 Future Stream'), 19 | ), 20 | body: _bd(), 21 | ); 22 | } 23 | 24 | Widget _bd2() { 25 | return FutureBuilder( 26 | future: _getData(), 27 | builder: (BuildContext context, AsyncSnapshot snapshot) { 28 | if (snapshot.connectionState == ConnectionState.done) { 29 | if (snapshot.hasError) { 30 | return Center( 31 | child: Text('error:${snapshot.error}'), 32 | ); 33 | } else { 34 | return Center( 35 | child: Text('data:${snapshot.data}'), 36 | ); 37 | } 38 | } else { 39 | return Center( 40 | child: CircularProgressIndicator(), 41 | ); 42 | } 43 | }, 44 | ); 45 | } 46 | 47 | Future _getData() async { 48 | return Future.delayed(Duration(seconds: 2), () => "我是从互联网上获取的数据"); 49 | } 50 | 51 | Widget _bd() { 52 | return Center( 53 | child: StreamBuilder( 54 | stream: _counter(), 55 | builder: (BuildContext context, AsyncSnapshot snapshot) { 56 | if (snapshot.connectionState == ConnectionState.done) { 57 | if (snapshot.hasError) { 58 | return Center( 59 | child: Text('error:${snapshot.error}'), 60 | ); 61 | } else { 62 | return Center( 63 | child: Text('data:${snapshot.data}'), 64 | ); 65 | } 66 | } else { 67 | return Center( 68 | child: Text( 69 | 'state:${snapshot.connectionState},count:${snapshot.data}'), 70 | ); 71 | } 72 | }, 73 | ), 74 | ); 75 | } 76 | 77 | Stream _counter() { 78 | return Stream.periodic(Duration(milliseconds: 500), (i) { 79 | return i; 80 | }); 81 | } 82 | 83 | @override 84 | void initState() { 85 | super.initState(); 86 | } 87 | } 88 | -------------------------------------------------------------------------------- /lib/features/base_gesturedetetor.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/cupertino.dart'; 2 | import 'package:flutter/gestures.dart'; 3 | import 'package:flutter/material.dart'; 4 | 5 | /// 6 | /// Created by fgyong on 2020/7/9. 7 | /// 8 | 9 | class BaseGesuredetetor extends StatefulWidget { 10 | @override 11 | _BaseGesuredetetorState createState() => _BaseGesuredetetorState(); 12 | } 13 | 14 | class _BaseGesuredetetorState extends State { 15 | @override 16 | Widget build(BuildContext context) { 17 | return Scaffold( 18 | appBar: AppBar( 19 | title: Text('手势识别'), 20 | ), 21 | body: _body3(), 22 | ); 23 | } 24 | 25 | String _string; 26 | double _left = 0, _top = 0; 27 | Offset _offset = Offset(0, 0); 28 | double _width = 300, _height = 300; 29 | Widget _body() { 30 | return Stack( 31 | children: [ 32 | GestureDetector( 33 | child: Container( 34 | width: _width, 35 | height: _height, 36 | margin: EdgeInsets.only( 37 | left: _left > 0 ? _left : 0, top: _top < 0 ? 0 : _top), 38 | child: Text(_string == null ? '点击我识别手势' : _string), 39 | color: Colors.orange, 40 | ), 41 | onScaleUpdate: (ScaleUpdateDetails detail) { 42 | setState(() { 43 | _width = 200 * detail.scale.clamp(0.5, 2); 44 | _height = _width; 45 | }); 46 | }, 47 | ), 48 | ], 49 | ); 50 | } 51 | 52 | bool _selected = false; 53 | Widget _body2() { 54 | return Center( 55 | child: Text.rich( 56 | TextSpan(text: '你好,', children: [ 57 | TextSpan( 58 | text: 'Flutter', 59 | recognizer: _gestureRecognizer(), 60 | style: TextStyle( 61 | color: _selected ? Colors.blue : Colors.orange, 62 | fontSize: _selected ? 30 : 20)) 63 | ]), 64 | ), 65 | ); 66 | } 67 | 68 | GestureRecognizer _gestureRecognizer() { 69 | return TapGestureRecognizer() 70 | ..onTap = () { 71 | setState(() { 72 | _selected = !_selected; 73 | }); 74 | }; 75 | } 76 | 77 | String _moveDetail = ''; 78 | Widget _body3() { 79 | return Stack( 80 | children: [ 81 | GestureDetector( 82 | child: Container( 83 | width: _width, 84 | height: _height, 85 | margin: EdgeInsets.only( 86 | left: _left > 0 ? _left : 0, top: _top < 0 ? 0 : _top), 87 | child: Text( 88 | (_string == null ? '点击我识别手势' : _string) + _moveDetail ?? ''), 89 | color: Colors.orange, 90 | ), 91 | onTap: () { 92 | setState(() { 93 | _string += '点击手势'; 94 | }); 95 | }, 96 | onTapUp: (TapUpDetails detail) { 97 | setState(() { 98 | _string += 'up:' + detail.toString(); 99 | }); 100 | }, 101 | onHorizontalDragUpdate: (DragUpdateDetails detail) { 102 | setState(() { 103 | _moveDetail = detail.toString(); 104 | }); 105 | }, 106 | ), 107 | ], 108 | ); 109 | } 110 | } 111 | -------------------------------------------------------------------------------- /lib/features/base_notification.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/cupertino.dart'; 2 | import 'package:flutter/material.dart'; 3 | 4 | /// 5 | /// Created by fgyong on 2020/7/9. 6 | /// 7 | 8 | class BaseNotificationPage extends StatefulWidget { 9 | @override 10 | _BaseNotificationPageState createState() => _BaseNotificationPageState(); 11 | } 12 | 13 | class _BaseNotificationPageState extends State { 14 | @override 15 | Widget build(BuildContext context) { 16 | return Scaffold( 17 | appBar: AppBar( 18 | title: Text('通知'), 19 | ), 20 | body: _body2(), 21 | ); 22 | } 23 | 24 | Widget _body() { 25 | return NotificationListener( 26 | onNotification: (notification) { 27 | switch (notification.runtimeType) { 28 | case ScrollStartNotification: 29 | print("开始滚动"); 30 | break; 31 | case ScrollUpdateNotification: 32 | print("正在滚动"); 33 | break; 34 | case ScrollEndNotification: 35 | print("滚动停止"); 36 | break; 37 | case OverscrollNotification: 38 | print("滚动到边界"); 39 | break; 40 | } 41 | return true; 42 | }, 43 | child: CupertinoScrollbar( 44 | child: SingleChildScrollView( 45 | child: Container( 46 | height: 2000, 47 | width: 400, 48 | color: Colors.orange, 49 | ), 50 | ), 51 | ), 52 | ); 53 | } 54 | 55 | int _code = 0; 56 | Widget _body2() { 57 | return NotificationListener( 58 | onNotification: (notification) { 59 | print('我是外层监听'); 60 | return false; 61 | }, 62 | child: NotificationListener( 63 | onNotification: (FyNotification notification) { 64 | setState(() { 65 | _code = notification.code; 66 | }); 67 | print('我是内层监听'); 68 | return false; 69 | }, 70 | child: Center( 71 | child: Column( 72 | children: [ 73 | Builder( 74 | builder: (context) { 75 | return OutlineButton( 76 | child: Text('发送通知'), 77 | onPressed: () { 78 | FyNotification(code: 200).dispatch(context); 79 | }, 80 | ); 81 | }, 82 | ), 83 | Text('$_code'), 84 | ], 85 | ), 86 | ), 87 | ), 88 | ); 89 | } 90 | } 91 | 92 | class FyNotification extends Notification { 93 | int code; 94 | FyNotification({this.code}); 95 | } 96 | -------------------------------------------------------------------------------- /lib/features/base_touch_handle.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/cupertino.dart'; 2 | import 'package:flutter/material.dart'; 3 | 4 | /// 5 | /// Created by fgyong on 2020/7/8. 6 | /// 7 | 8 | class BaseTouchHandle extends StatefulWidget { 9 | @override 10 | _BaseTouchHandleState createState() => _BaseTouchHandleState(); 11 | } 12 | 13 | class _BaseTouchHandleState extends State { 14 | @override 15 | Widget build(BuildContext context) { 16 | return Scaffold( 17 | appBar: AppBar( 18 | title: Text('原始手势处理'), 19 | ), 20 | body: _body2(), 21 | ); 22 | } 23 | 24 | //定义一个状态,保存当前指针位置 25 | PointerEvent _event; 26 | String _eventState = ''; 27 | Widget _body() { 28 | return Center( 29 | child: Listener( 30 | child: Center( 31 | child: Column( 32 | children: [ 33 | IgnorePointer( 34 | child: Listener( 35 | child: SizedBox( 36 | height: 50, 37 | child: Container( 38 | color: Colors.red, 39 | height: 50, 40 | width: 100, 41 | child: Text(_eventState), 42 | ), 43 | ), 44 | onPointerDown: (PointerDownEvent ev) { 45 | setState(() { 46 | _event = ev; 47 | _eventState = '子树 -> 手势按下'; 48 | }); 49 | }, 50 | ), 51 | ) 52 | ], 53 | ), 54 | ), 55 | onPointerUp: (PointerUpEvent ev) { 56 | setState(() { 57 | _event = ev; 58 | _eventState = '抬起手势'; 59 | }); 60 | }, 61 | ), 62 | ); 63 | } 64 | 65 | Widget _body2() { 66 | return Center( 67 | child: Listener( 68 | child: Center( 69 | child: Container( 70 | color: Colors.red, 71 | height: 200, 72 | width: 100, 73 | child: Stack( 74 | children: [ 75 | Listener( 76 | child: ConstrainedBox( 77 | child: DecoratedBox( 78 | decoration: BoxDecoration(color: Colors.blue), 79 | child: Text(_eventState), 80 | ), 81 | constraints: BoxConstraints.tight(Size(100.0, 100.0)), 82 | ), 83 | onPointerDown: (PointerDownEvent ev) { 84 | setState(() { 85 | _eventState = '点击 蓝色'; 86 | }); 87 | }, 88 | ), 89 | Listener( 90 | child: ConstrainedBox( 91 | child: DecoratedBox( 92 | decoration: BoxDecoration(color: Colors.orange), 93 | child: Text(_eventState), 94 | ), 95 | constraints: BoxConstraints.tight(Size(100.0, 50.0)), 96 | ), 97 | onPointerDown: (PointerDownEvent ev) { 98 | setState(() { 99 | _eventState = '点击橘黄色区域'; 100 | }); 101 | }, 102 | ), 103 | ], 104 | ), 105 | ), 106 | ), 107 | behavior: HitTestBehavior.deferToChild, 108 | onPointerUp: (PointerUpEvent ev) { 109 | setState(() { 110 | _event = ev; 111 | _eventState = '抬起手势'; 112 | }); 113 | }, 114 | ), 115 | ); 116 | } 117 | } 118 | -------------------------------------------------------------------------------- /lib/features/base_will_pop.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/cupertino.dart'; 2 | import 'package:flutter/material.dart'; 3 | 4 | /// 5 | /// Created by fgyong on 2020/7/3. 6 | /// 7 | class BaseWillPop extends StatefulWidget { 8 | @override 9 | _BaseWillPopState createState() => _BaseWillPopState(); 10 | } 11 | 12 | class _BaseWillPopState extends State { 13 | @override 14 | Widget build(BuildContext context) { 15 | return Scaffold( 16 | appBar: AppBar( 17 | title: Text('BaseWillPop'), 18 | ), 19 | body: WillPopScope( 20 | child: _body(), 21 | onWillPop: () async { 22 | //code 23 | showDialog( 24 | context: context, 25 | builder: (ctx) => CupertinoAlertDialog( 26 | title: Text('提示'), 27 | content: Text('真的退出吗?'), 28 | actions: [ 29 | FlatButton( 30 | child: Text('真的 退出了'), 31 | onPressed: () { 32 | Navigator.of(context).popUntil((route) { 33 | return route.isFirst; 34 | }); 35 | }, 36 | ), 37 | FlatButton( 38 | child: Text('暂不退出了'), 39 | onPressed: () { 40 | Navigator.maybePop(context); 41 | }, 42 | ), 43 | ], 44 | )); 45 | return false; 46 | }), 47 | ); 48 | } 49 | 50 | Widget _body() { 51 | return Container(); 52 | } 53 | } 54 | -------------------------------------------------------------------------------- /lib/features/share_data.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/cupertino.dart'; 2 | import 'package:flutter/material.dart'; 3 | 4 | /// 5 | /// Created by fgyong on 2020/7/3. 6 | /// 7 | class ShareData extends InheritedWidget { 8 | int count; 9 | ShareData({Key key, this.count, @required Widget child}) 10 | : super(key: key, child: child); 11 | @override 12 | bool updateShouldNotify(InheritedWidget oldWidget) { 13 | return this != oldWidget; 14 | } 15 | 16 | static ShareData of(BuildContext context) { 17 | return context.dependOnInheritedWidgetOfExactType(); 18 | } 19 | 20 | static ShareData ofNoRefresh(BuildContext context) { 21 | return context.getElementForInheritedWidgetOfExactType().widget; 22 | } 23 | } 24 | 25 | class BaseShareData extends StatefulWidget { 26 | @override 27 | _BaseShareDataState createState() => _BaseShareDataState(); 28 | } 29 | 30 | class _BaseShareDataState extends State { 31 | @override 32 | Widget build(BuildContext context) { 33 | return Scaffold( 34 | appBar: AppBar( 35 | title: Text('共享数据'), 36 | ), 37 | body: _body(), 38 | floatingActionButton: FloatingActionButton( 39 | child: Icon(Icons.add), 40 | onPressed: () { 41 | setState(() { 42 | _count += 1; 43 | }); 44 | }, 45 | ), 46 | ); 47 | } 48 | 49 | int _count = 0; 50 | Widget _body() { 51 | return ShareData( 52 | count: _count, 53 | child: Column( 54 | children: [ 55 | BaseShareData2( 56 | have: true, 57 | child: Row( 58 | children: [ 59 | BaseShareData2( 60 | have: false, 61 | ), 62 | BaseShareData2( 63 | have: false, 64 | ) 65 | ], 66 | ), 67 | ), 68 | BaseShareData2( 69 | have: false, 70 | child: Row( 71 | children: [ 72 | BaseShareData2( 73 | have: true, 74 | ), 75 | BaseShareData2( 76 | have: false, 77 | ) 78 | ], 79 | ), 80 | ) 81 | ], 82 | ), 83 | ); 84 | } 85 | } 86 | 87 | class BaseShareData2 extends StatefulWidget { 88 | final bool have; 89 | final Widget child; 90 | BaseShareData2({this.have, this.child}); 91 | @override 92 | _BaseShareData2State createState() => _BaseShareData2State(); 93 | } 94 | 95 | class _BaseShareData2State extends State { 96 | @override 97 | Widget build(BuildContext context) { 98 | print('build ${widget.have}'); 99 | 100 | List list = new List(); 101 | list.add(Text( 102 | widget.have == false 103 | ? widget.have.toString() 104 | : ShareData.of(context).count.toString(), 105 | style: TextStyle(fontSize: 20), 106 | )); 107 | if (widget.child != null) { 108 | list.add(widget.child); 109 | } 110 | return Container( 111 | child: Column( 112 | children: list, 113 | ), 114 | alignment: Alignment.center, 115 | ); 116 | } 117 | 118 | @override 119 | void didChangeDependencies() { 120 | print('didChangeDependencies'); 121 | super.didChangeDependencies(); 122 | } 123 | } 124 | -------------------------------------------------------------------------------- /lib/file_and_http/http_client.dart: -------------------------------------------------------------------------------- 1 | import 'dart:io'; 2 | 3 | import 'package:flutter/cupertino.dart'; 4 | import 'package:flutter/material.dart'; 5 | 6 | /// 7 | /// Created by fgyong on 2020/7/27. 8 | /// 9 | 10 | class BaseHttpClientRoute extends StatefulWidget { 11 | BaseHttpClientRoute({Key key}) : super(key: key); 12 | 13 | @override 14 | _BaseHttpClientRouteState createState() => _BaseHttpClientRouteState(); 15 | } 16 | 17 | class _BaseHttpClientRouteState extends State { 18 | @override 19 | Widget build(BuildContext context) { 20 | return Scaffold( 21 | appBar: AppBar( 22 | title: Text('HttpClient'), 23 | ), 24 | body: _body(), 25 | ); 26 | } 27 | 28 | Widget _body() { 29 | return Center( 30 | child: Column( 31 | children: [], 32 | ), 33 | ); 34 | } 35 | 36 | void _send() async { 37 | HttpClient httpClient = new HttpClient(); 38 | Uri uri = Uri( 39 | scheme: 'https', 40 | host: 'flutterchine.club', 41 | queryParameters: {'a': '1', 'b': '2'}); 42 | HttpClientRequest request = await httpClient.getUrl(uri); 43 | } 44 | } 45 | -------------------------------------------------------------------------------- /lib/file_and_http/http_dio.dart: -------------------------------------------------------------------------------- 1 | import 'dart:convert'; 2 | 3 | import 'package:dio/adapter.dart'; 4 | import 'package:dio/dio.dart'; 5 | import 'package:flutter/cupertino.dart'; 6 | import 'package:flutter/material.dart'; 7 | import 'dart:convert' as convert; 8 | 9 | import 'package:flutter_easyhub/flutter_easy_hub.dart'; 10 | import 'package:fluttertest01/file_and_http/model/git_model.dart'; 11 | import 'package:fluttertest01/generated/json/base/json_convert_content.dart'; 12 | 13 | /// 14 | /// Created by fgyong on 2020/7/27. 15 | /// 16 | 17 | class BaseHttpDioRoute extends StatefulWidget { 18 | BaseHttpDioRoute({Key key}) : super(key: key); 19 | 20 | @override 21 | _BaseHttpDioRouteState createState() => _BaseHttpDioRouteState(); 22 | } 23 | 24 | class _BaseHttpDioRouteState extends State { 25 | @override 26 | Widget build(BuildContext context) { 27 | return Scaffold( 28 | appBar: AppBar( 29 | title: Text('Dio'), 30 | ), 31 | body: _body(), 32 | ); 33 | } 34 | 35 | Dio _dio = new Dio(); 36 | String _string; 37 | Widget _body() { 38 | return Center( 39 | child: FlutterEasyHub( 40 | child: SingleChildScrollView( 41 | child: Row( 42 | children: [ 43 | Expanded( 44 | child: Text(_string ?? ''), 45 | ) 46 | ], 47 | ), 48 | ), 49 | ), 50 | ); 51 | } 52 | 53 | @override 54 | void initState() { 55 | super.initState(); 56 | WidgetsBinding.instance.addPostFrameCallback((timeStamp) { 57 | _getData(); 58 | }); 59 | } 60 | 61 | void _getData() async { 62 | EasyHub.showHub(); 63 | (_dio.httpClientAdapter as DefaultHttpClientAdapter).onHttpClientCreate = 64 | (client) { 65 | // config the http client 66 | client.findProxy = (uri) { 67 | return "PROXY localhost:1088"; 68 | }; 69 | // you can also create a HttpClient to dio 70 | // return HttpClient(); 71 | }; 72 | Response res = await _dio.get('https://api.github.com/users/ifgyong/repos'); 73 | List list = res.data; 74 | List gitList = []; 75 | if (res.data is List) { 76 | (res.data as List).forEach((element) { 77 | GitModel modl = JsonConvert.fromJsonAsT(element); 78 | gitList.add(modl); 79 | }); 80 | print('${gitList.length}'); 81 | } 82 | 83 | // Map mapret = convert.jsonDecode(res.data); 84 | setState(() { 85 | _string = res.data.toString(); 86 | }); 87 | EasyHub.dismiss(); 88 | print('res.data${list.toString()}'); 89 | } 90 | } 91 | -------------------------------------------------------------------------------- /lib/file_and_http/http_socket.dart: -------------------------------------------------------------------------------- 1 | import 'dart:io'; 2 | 3 | import 'package:flutter/cupertino.dart'; 4 | import 'package:flutter/material.dart'; 5 | 6 | /// 7 | /// Created by fgyong on 2020/7/27. 8 | /// 9 | 10 | import 'dart:convert'; 11 | 12 | import 'package:dio/dio.dart'; 13 | 14 | import 'package:flutter_easyhub/flutter_easy_hub.dart'; 15 | 16 | /// 17 | /// Created by fgyong on 2020/7/27. 18 | /// 19 | 20 | class BaseSocketRoute extends StatefulWidget { 21 | BaseSocketRoute({Key key}) : super(key: key); 22 | 23 | @override 24 | _BaseHttpDioRouteState createState() => _BaseHttpDioRouteState(); 25 | } 26 | 27 | class _BaseHttpDioRouteState extends State { 28 | @override 29 | Widget build(BuildContext context) { 30 | return Scaffold( 31 | appBar: AppBar( 32 | title: Text('Socket'), 33 | ), 34 | body: _body(), 35 | ); 36 | } 37 | 38 | String _string = ''; 39 | Widget _body() { 40 | return Center( 41 | child: FlutterEasyHub( 42 | child: SingleChildScrollView( 43 | child: Row( 44 | children: [ 45 | Expanded( 46 | child: Text(_string ?? ''), 47 | ) 48 | ], 49 | ), 50 | ), 51 | ), 52 | ); 53 | } 54 | 55 | @override 56 | void initState() { 57 | super.initState(); 58 | WidgetsBinding.instance.addPostFrameCallback((timeStamp) { 59 | _getData(); 60 | }); 61 | } 62 | 63 | void _getData() async { 64 | var socket = await Socket.connect('github.com', 80); 65 | socket.write('GET / HTTP:/1.1'); 66 | socket.write('Host:github.com'); 67 | socket.write('Connection:close'); 68 | socket.writeln(); 69 | 70 | utf8.decoder.bind(socket).listen((event) { 71 | print(event); 72 | _string += event; 73 | setState(() {}); 74 | }); 75 | 76 | socket.flush(); 77 | 78 | await socket.close(); //关闭 79 | } 80 | } 81 | -------------------------------------------------------------------------------- /lib/file_and_http/json_to_model.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/cupertino.dart'; 2 | import 'package:flutter/material.dart'; 3 | import 'dart:convert'; 4 | 5 | import 'package:fluttertest01/file_and_http/model/user.dart'; 6 | import 'package:fluttertest01/file_and_http/model/user_entity.dart'; 7 | import 'package:fluttertest01/generated/json/base/json_convert_content.dart'; 8 | 9 | /// 10 | /// Created by fgyong on 2020/7/27. 11 | /// 12 | 13 | class BaseJsonToModelRoute extends StatefulWidget { 14 | BaseJsonToModelRoute({Key key}) : super(key: key); 15 | 16 | @override 17 | _BaseJsonToModelRouteState createState() => _BaseJsonToModelRouteState(); 18 | } 19 | 20 | class _BaseJsonToModelRouteState extends State { 21 | String jsonStr = '{"list":[{"name":"Jack Ma"},{"name":"QiangDong liu"}]}'; 22 | @override 23 | void initState() { 24 | // List items = json.decode(jsonStr); 25 | // 26 | // print(items[0]['name']); 27 | super.initState(); 28 | } 29 | 30 | String _string = '姓名:\n'; 31 | void _toModel() { 32 | UserEntity list = JsonConvert.fromJsonAsT(json.decode(jsonStr)); 33 | list.xList.forEach((element) { 34 | _string += element.name; 35 | _string += '\n'; 36 | print(element.name); 37 | }); 38 | } 39 | 40 | @override 41 | Widget build(BuildContext context) { 42 | _toModel(); 43 | return Scaffold( 44 | appBar: AppBar( 45 | title: Text('json to model'), 46 | ), 47 | body: _body(), 48 | ); 49 | } 50 | 51 | Widget _body() { 52 | return Center( 53 | child: Column( 54 | children: [Text(_string)], 55 | ), 56 | ); 57 | } 58 | } 59 | -------------------------------------------------------------------------------- /lib/file_and_http/model/user.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/cupertino.dart'; 2 | import 'package:flutter/material.dart'; 3 | import 'package:json_annotation/json_annotation.dart'; 4 | 5 | /// 6 | /// Created by fgyong on 2020/7/28. 7 | /// 8 | //@JsonSerializable() 9 | //class UserModel { 10 | // String name; 11 | // String age; 12 | // UserModel({this.name, this.age}); 13 | // factory UserModel.fromJson(Map js) => 14 | // _$UserModelFromJson(js); 15 | //} 16 | // 17 | //@JsonSerializable() 18 | //class UserList { 19 | // List list; 20 | // UserList({this.list}); 21 | // factory UserList.fromJson(Map ll) => _$UserListFromJson(ll); 22 | //} 23 | 24 | class UserModel { 25 | List list; 26 | 27 | UserModel({this.list}); 28 | 29 | factory UserModel.fromJson(Map json) { 30 | return UserModel( 31 | list: json['list'] != null 32 | ? (json['list'] as List).map((i) => X.fromJson(i)).toList() 33 | : null, 34 | ); 35 | } 36 | 37 | Map toJson() { 38 | final Map data = new Map(); 39 | if (this.list != null) { 40 | data['list'] = this.list.map((v) => v.toJson()).toList(); 41 | } 42 | return data; 43 | } 44 | } 45 | 46 | class X { 47 | String name; 48 | 49 | X({this.name}); 50 | 51 | factory X.fromJson(Map json) { 52 | return X( 53 | name: json['name'], 54 | ); 55 | } 56 | 57 | Map toJson() { 58 | final Map data = new Map(); 59 | data['name'] = this.name; 60 | return data; 61 | } 62 | } 63 | -------------------------------------------------------------------------------- /lib/file_and_http/model/user_entity.dart: -------------------------------------------------------------------------------- 1 | import 'package:fluttertest01/generated/json/base/json_convert_content.dart'; 2 | import 'package:fluttertest01/generated/json/base/json_filed.dart'; 3 | 4 | class UserEntity with JsonConvert { 5 | @JSONField(name: "list") 6 | List xList; 7 | } 8 | 9 | class UserList with JsonConvert { 10 | String name; 11 | } 12 | -------------------------------------------------------------------------------- /lib/generated/json/base/json_convert_content.dart: -------------------------------------------------------------------------------- 1 | // ignore_for_file: non_constant_identifier_names 2 | // ignore_for_file: camel_case_types 3 | // ignore_for_file: prefer_single_quotes 4 | 5 | // This file is automatically generated. DO NOT EDIT, all your changes would be lost. 6 | import 'package:fluttertest01/file_and_http/model/user_entity.dart'; 7 | import 'package:fluttertest01/generated/json/user_entity_helper.dart'; 8 | import 'package:fluttertest01/file_and_http/model/git_model.dart'; 9 | import 'package:fluttertest01/generated/json/git_model_helper.dart'; 10 | 11 | class JsonConvert { 12 | T fromJson(Map json) { 13 | return _getFromJson(runtimeType, this, json); 14 | } 15 | 16 | Map toJson() { 17 | return _getToJson(runtimeType, this); 18 | } 19 | 20 | static _getFromJson(Type type, data, json) { 21 | switch (type) { 22 | case UserEntity: 23 | return userEntityFromJson(data as UserEntity, json) as T; 24 | case UserList: 25 | return userListFromJson(data as UserList, json) as T; 26 | case GitModel: 27 | return gitModelFromJson(data as GitModel, json) as T; 28 | case GitOwner: 29 | return gitOwnerFromJson(data as GitOwner, json) as T; 30 | case GitLicense: 31 | return gitLicenseFromJson(data as GitLicense, json) as T; 32 | } 33 | return data as T; 34 | } 35 | 36 | static _getToJson(Type type, data) { 37 | switch (type) { 38 | case UserEntity: 39 | return userEntityToJson(data as UserEntity); 40 | case UserList: 41 | return userListToJson(data as UserList); 42 | case GitModel: 43 | return gitModelToJson(data as GitModel); 44 | case GitOwner: 45 | return gitOwnerToJson(data as GitOwner); 46 | case GitLicense: 47 | return gitLicenseToJson(data as GitLicense); 48 | } 49 | return data as T; 50 | } 51 | 52 | //Go back to a single instance by type 53 | static _fromJsonSingle(String type, json) { 54 | switch (type) { 55 | case 'UserEntity': 56 | return UserEntity().fromJson(json); 57 | case 'UserList': 58 | return UserList().fromJson(json); 59 | case 'GitModel': 60 | return GitModel().fromJson(json); 61 | case 'GitOwner': 62 | return GitOwner().fromJson(json); 63 | case 'GitLicense': 64 | return GitLicense().fromJson(json); 65 | } 66 | return null; 67 | } 68 | 69 | //empty list is returned by type 70 | static _getListFromType(String type) { 71 | switch (type) { 72 | case 'UserEntity': 73 | return List(); 74 | case 'UserList': 75 | return List(); 76 | case 'GitModel': 77 | return List(); 78 | case 'GitOwner': 79 | return List(); 80 | case 'GitLicense': 81 | return List(); 82 | } 83 | return null; 84 | } 85 | 86 | static M fromJsonAsT(json) { 87 | String type = M.toString(); 88 | if (json is List && type.contains("List<")) { 89 | String itemType = type.substring(5, type.length - 1); 90 | List tempList = _getListFromType(itemType); 91 | json.forEach((itemJson) { 92 | tempList 93 | .add(_fromJsonSingle(type.substring(5, type.length - 1), itemJson)); 94 | }); 95 | return tempList as M; 96 | } else { 97 | return _fromJsonSingle(M.toString(), json) as M; 98 | } 99 | } 100 | } 101 | -------------------------------------------------------------------------------- /lib/generated/json/base/json_filed.dart: -------------------------------------------------------------------------------- 1 | // ignore_for_file: non_constant_identifier_names 2 | // ignore_for_file: camel_case_types 3 | // ignore_for_file: prefer_single_quotes 4 | 5 | // This file is automatically generated. DO NOT EDIT, all your changes would be lost. 6 | 7 | class JSONField { 8 | //Specify the parse field name 9 | final String name; 10 | 11 | //Specify the time resolution format 12 | final String format; 13 | 14 | //Whether to participate in toJson 15 | final bool serialize; 16 | 17 | //Whether to participate in fromMap 18 | final bool deserialize; 19 | 20 | const JSONField({this.name, this.format, this.serialize, this.deserialize}); 21 | } 22 | -------------------------------------------------------------------------------- /lib/generated/json/user_entity_helper.dart: -------------------------------------------------------------------------------- 1 | import 'package:fluttertest01/file_and_http/model/user_entity.dart'; 2 | 3 | userEntityFromJson(UserEntity data, Map json) { 4 | if (json['list'] != null) { 5 | data.xList = new List(); 6 | (json['list'] as List).forEach((v) { 7 | data.xList.add(new UserList().fromJson(v)); 8 | }); 9 | } 10 | return data; 11 | } 12 | 13 | Map userEntityToJson(UserEntity entity) { 14 | final Map data = new Map(); 15 | if (entity.xList != null) { 16 | data['list'] = entity.xList.map((v) => v.toJson()).toList(); 17 | } 18 | return data; 19 | } 20 | 21 | userListFromJson(UserList data, Map json) { 22 | if (json['name'] != null) { 23 | data.name = json['name']?.toString(); 24 | } 25 | return data; 26 | } 27 | 28 | Map userListToJson(UserList entity) { 29 | final Map data = new Map(); 30 | data['name'] = entity.name; 31 | return data; 32 | } 33 | -------------------------------------------------------------------------------- /lib/layout/base_align.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/material.dart'; 2 | 3 | class BaseAlign extends StatefulWidget { 4 | BaseAlign({Key key}) : super(key: key); 5 | 6 | @override 7 | _BaseAlignState createState() => _BaseAlignState(); 8 | } 9 | 10 | class _BaseAlignState extends State { 11 | @override 12 | Widget build(BuildContext context) { 13 | return Scaffold( 14 | appBar: AppBar( 15 | title: Text('相对位置'), 16 | ), 17 | body: _body(), 18 | ); 19 | } 20 | 21 | Widget _body() { 22 | return Center( 23 | child: Column( 24 | mainAxisAlignment: MainAxisAlignment.center, 25 | crossAxisAlignment: CrossAxisAlignment.center, 26 | children: [ 27 | Container( 28 | width: 200, 29 | height: 200, 30 | color: Colors.blue[50], 31 | child: Align( 32 | child: FlutterLogo( 33 | size: 30, 34 | )), 35 | ), 36 | DecoratedBox( 37 | decoration: BoxDecoration(color: Colors.blue), 38 | child: Center( 39 | child: Text('center2'), 40 | ), 41 | ), 42 | SizedBox( 43 | height: 20, 44 | ), 45 | DecoratedBox( 46 | decoration: BoxDecoration(color: Colors.blue), 47 | child: Center( 48 | widthFactor: 1, 49 | heightFactor: 1, 50 | child: Text('center2'), 51 | ), 52 | ) 53 | ], 54 | ), 55 | ); 56 | } 57 | } 58 | -------------------------------------------------------------------------------- /lib/layout/base_flow_and_wrap.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/material.dart'; 2 | 3 | class BaseFlowAndWrap extends StatelessWidget { 4 | @override 5 | Widget build(BuildContext context) { 6 | return Scaffold( 7 | appBar: AppBar( 8 | title: Text('流式布局'), 9 | ), 10 | body: Column( 11 | children: [ 12 | Container( 13 | child: _body(), 14 | color: Colors.black12, 15 | ), 16 | Container( 17 | margin: EdgeInsets.only(top: 20), 18 | child: _bd2(), 19 | color: Colors.black12, 20 | ) 21 | ], 22 | ), 23 | ); 24 | } 25 | 26 | Widget _body() { 27 | return Wrap( 28 | runAlignment: WrapAlignment.start, 29 | alignment: WrapAlignment.center, 30 | spacing: 20.0, 31 | runSpacing: 30, 32 | direction: Axis.horizontal, 33 | children: [ 34 | _item('Are you ok ?', 'A'), 35 | _item('I am ok ', 'B'), 36 | _item('马什么?', 'C'), 37 | _item('什么梅?', 'D'), 38 | _item('马东什么?', 'E'), 39 | ], 40 | ); 41 | } 42 | 43 | Widget _item(String title, String subavator) { 44 | return Chip( 45 | avatar: new CircleAvatar( 46 | backgroundColor: Colors.blue, 47 | child: Text(subavator), 48 | ), 49 | label: Text(title), 50 | ); 51 | return OutlineButton.icon( 52 | onPressed: null, icon: Icon(Icons.mail), label: Text(title)); 53 | } 54 | 55 | Widget _bd2() { 56 | return Flow.unwrapped( 57 | delegate: BaseFlowDelegate(margin: EdgeInsets.all(20)), 58 | children: _list(), 59 | ); 60 | } 61 | 62 | List _list() { 63 | return [ 64 | _item('Are you ok ?', 'A'), 65 | _item('I am ok ', 'B'), 66 | _item('马什么?', 'C'), 67 | _item('什么梅?', 'D'), 68 | _item('马东什么?', 'E'), 69 | ]; 70 | } 71 | } 72 | 73 | class BaseFlowDelegate extends FlowDelegate { 74 | EdgeInsets margin; 75 | BaseFlowDelegate({this.margin = EdgeInsets.zero}); 76 | @override 77 | void paintChildren(FlowPaintingContext context) { 78 | var x = margin.left; 79 | var y = margin.top; 80 | //计算每一个子widget的位置 81 | for (int i = 0; i < context.childCount; i++) { 82 | var w = context.getChildSize(i).width + x + margin.right; 83 | if (w <= context.size.width) { 84 | context.paintChild(i, 85 | transform: new Matrix4.translationValues(x, y, 0.0)); 86 | x = w + margin.left; 87 | } else { 88 | x = margin.left; 89 | y += context.getChildSize(i).height + margin.top + margin.bottom; 90 | //绘制子widget(有优化) 91 | context.paintChild(i, 92 | transform: new Matrix4.translationValues(x, y, 0.0)); 93 | x += context.getChildSize(i).width + margin.left + margin.right; 94 | } 95 | } 96 | } 97 | 98 | @override 99 | getSize(BoxConstraints constraints) { 100 | //指定Flow的大小 101 | return Size(double.infinity, 300); 102 | } 103 | 104 | @override 105 | bool shouldRepaint(FlowDelegate oldDelegate) { 106 | return oldDelegate != this; 107 | } 108 | } 109 | -------------------------------------------------------------------------------- /lib/layout/base_stack.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/material.dart'; 2 | import 'package:flutter/rendering.dart'; 3 | 4 | class BaseStack extends StatelessWidget { 5 | @override 6 | Widget build(BuildContext context) { 7 | return Scaffold( 8 | appBar: AppBar( 9 | title: Text('相对位置'), 10 | ), 11 | body: Center( 12 | child: Column( 13 | children: [ 14 | Container( 15 | margin: EdgeInsets.only(top: 20), 16 | child: _body(), 17 | constraints: BoxConstraints.loose(Size(100, 100)), 18 | ), 19 | Container( 20 | margin: EdgeInsets.only(top: 20), 21 | child: _body2(), 22 | color: Colors.black12, 23 | constraints: BoxConstraints.expand(width: 200, height: 200), 24 | ), 25 | Container( 26 | margin: EdgeInsets.only(top: 20), 27 | child: _body3(), 28 | color: Colors.black12, 29 | constraints: BoxConstraints.expand(width: 200, height: 200), 30 | ) 31 | ], 32 | ), 33 | ), 34 | ); 35 | } 36 | 37 | Widget _body() { 38 | return Stack( 39 | fit: StackFit.loose, 40 | alignment: Alignment.bottomRight, 41 | children: [ 42 | Positioned.fill( 43 | child: Container( 44 | color: Colors.red, 45 | )), 46 | Positioned.fill( 47 | left: 20, 48 | right: 20, 49 | bottom: 20, 50 | top: 20, 51 | child: Container( 52 | color: Colors.deepOrangeAccent, 53 | )), 54 | Positioned.fill( 55 | left: 40, 56 | right: 40, 57 | bottom: 40, 58 | top: 40, 59 | child: Container( 60 | color: Colors.orange, 61 | )), 62 | ], 63 | ); 64 | } 65 | 66 | Widget _body2() { 67 | return Stack( 68 | fit: StackFit.expand, 69 | alignment: Alignment.center, 70 | children: [ 71 | Container( 72 | child: Text("Hello world", style: TextStyle(color: Colors.white)), 73 | color: Colors.red, 74 | ), 75 | Positioned( 76 | top: 20.0, 77 | child: Container( 78 | child: Text("Are you OK?"), 79 | color: Colors.blue, 80 | ), 81 | ), 82 | Positioned( 83 | left: 18.0, 84 | child: Container( 85 | child: Text("I am Jack"), 86 | color: Colors.blue, 87 | )), 88 | ], 89 | ); 90 | } 91 | 92 | Widget _body3() { 93 | return Stack( 94 | fit: StackFit.loose, 95 | alignment: Alignment.bottomRight, 96 | children: [ 97 | Positioned( 98 | left: 0, 99 | right: 0, 100 | height: 50, 101 | child: Container( 102 | color: Colors.red, 103 | alignment: Alignment.center, 104 | child: Text('Are you OK?'), 105 | ), 106 | ), 107 | Positioned( 108 | right: 0, 109 | height: 50, 110 | width: 50, 111 | top: 0, 112 | child: Container( 113 | color: Colors.red, 114 | alignment: Alignment.center, 115 | child: Text('I ma Jack!'), 116 | ), 117 | ), 118 | Positioned( 119 | height: 40, 120 | width: 60, 121 | child: Container( 122 | color: Colors.blue, 123 | alignment: Alignment.center, 124 | child: Text('hello'), 125 | ), 126 | ), 127 | ], 128 | ); 129 | } 130 | } 131 | -------------------------------------------------------------------------------- /lib/main3.dart: -------------------------------------------------------------------------------- 1 | import 'dart:isolate'; 2 | 3 | import 'package:flutter/cupertino.dart'; 4 | import 'package:flutter/material.dart'; 5 | 6 | /// 7 | /// Created by fgyong on 2020/7/29. 8 | /// 9 | main() async { 10 | runApp(HomeRoute()); 11 | } 12 | 13 | class HomeRoute extends StatelessWidget { 14 | @override 15 | Widget build(BuildContext context) { 16 | return Center( 17 | child: Text('Hello world'), 18 | ); 19 | } 20 | } 21 | 22 | class HomeViewModel extends ChangeNotifier {} 23 | 24 | /// 创建并管理 多线程 25 | void m() async { 26 | var ourFirstReceivePort = new ReceivePort(); 27 | 28 | await Isolate.spawn(echo, ourFirstReceivePort.sendPort); 29 | 30 | var echoPort = await ourFirstReceivePort.first; 31 | 32 | // if you try to use our first receive port, you’ll get this error: 33 | // “Bad state: Stream has already been listened to.” 34 | // so it seems like you always need a new port to communicate with 35 | // an isolate (actor). 36 | var ourSecondReceivePort = ReceivePort(); 37 | echoPort.send(['message 1', ourSecondReceivePort.sendPort]); 38 | var msg = await ourSecondReceivePort.first; 39 | print('main received "$msg"'); 40 | 41 | // instead of 'await', use 'then' as a different way of receiving 42 | // a reply from 'echo' (handle it asynchronously, rather than 43 | // waiting for the reply) 44 | var port3 = ReceivePort(); 45 | echoPort.send(['message 2', port3.sendPort]); 46 | port3.first.then((msg) { 47 | print('main received "$msg"'); 48 | }); 49 | 50 | // use 'then' one more time 51 | var port4 = ReceivePort(); 52 | echoPort.send(['port 4', port4.sendPort]); 53 | port4.first.then((msg) { 54 | print('main received "$msg"'); 55 | }); 56 | 57 | print('end of main'); 58 | } 59 | 60 | echo(SendPort sendPort) async { 61 | var ourReceivePort = ReceivePort(); 62 | 63 | sendPort.send(ourReceivePort.sendPort); 64 | 65 | await for (var msg in ourReceivePort) { 66 | var data = msg[0]; // the 1st element we receive should be their message 67 | print('echo received "$data"'); 68 | SendPort replyToPort = msg[1]; // the 2nd element should be their port 69 | 70 | Future.delayed(const Duration(milliseconds: 100), () { 71 | replyToPort.send('echo said: ' + data); 72 | }); 73 | 74 | if (data == "bye") ourReceivePort.close(); 75 | } 76 | } 77 | -------------------------------------------------------------------------------- /lib/mainUtil.dart: -------------------------------------------------------------------------------- 1 | export './Features/base_will_pop.dart'; 2 | export './animation/base_animaiton.dart'; 3 | export './animation/base_animation_diy.dart'; 4 | export './animation/base_animation_switch.dart'; 5 | export './animation/base_hreo.dart'; 6 | export './animation/base_pageRoute.dart'; 7 | export './animation/base_tagger_animation.dart'; 8 | export './baseWidget/baseButtons.dart'; 9 | export './baseWidget/baseIndicator.dart'; 10 | export './baseWidget/baseState.dart'; 11 | export './baseWidget/baseSwitch.dart'; 12 | export './baseWidget/baseText.dart'; 13 | export './baseWidget/baseTextField.dart'; 14 | export './baseWidget/dialog.dart'; 15 | export './baseWidget/imgAndIcon.dart'; 16 | export './comment/config.dart'; 17 | export './container/base_bars.dart'; 18 | export './container/base_container.dart'; 19 | export './container/base_decorateBox.dart'; 20 | export './container/base_clip.dart'; 21 | export './container/base_constraints.dart'; 22 | export './container/base_padding.dart'; 23 | export './container/base_transform.dart'; 24 | export './features/base_color_and_theme.dart'; 25 | export './features/base_eventbus.dart'; 26 | export './features/base_future_stream.dart'; 27 | export './features/base_gesturedetetor.dart'; 28 | export './features/base_notification.dart'; 29 | export './features/base_touch_handle.dart'; 30 | export './features/share_data.dart'; 31 | export './file_and_http/fileAction.dart'; 32 | export './file_and_http/http_client.dart'; 33 | export './file_and_http/http_dio.dart'; 34 | export './file_and_http/http_socket.dart'; 35 | export './file_and_http/json_to_model.dart'; 36 | export './layout/baseFlex.dart'; 37 | export './layout/base_align.dart'; 38 | export './layout/base_flow_and_wrap.dart'; 39 | export './layout/base_row_and_column.dart'; 40 | export './layout/base_stack.dart'; 41 | export './scrollview/scrollview.dart'; 42 | export './scrollview/baseCustomScrollview.dart'; 43 | export './scrollview/baseGridView.dart'; 44 | export './scrollview/baseListView.dart'; 45 | export './scrollview/baseListenScrollViewOffset.dart'; 46 | export './scrollview/baseSingleChildScrollView.dart'; 47 | export './tips/asyn_and_isolate.dart'; 48 | export './tips/async_and_async*.dart'; 49 | export './tips/base_bloc.dart'; 50 | export './tips/base_key.dart'; 51 | export './tips/layout/base_layout.dart'; 52 | export './tips/provider/base_provider.dart'; 53 | export './tips/base_record.dart'; 54 | export './tips/bloc/base_login_cubit.dart'; 55 | export './tips/fish_redux_page.dart'; 56 | export './tips/keepStateAlive.dart'; 57 | export './tips/page_view.dart'; 58 | export './tips/page_view_tabbar.dart'; 59 | export './tips/redux_page.dart'; 60 | export './tips/rx_dart/base_rxDart.dart'; 61 | export './tips/scoped_page.dart'; 62 | export './tips/wechat_view.dart'; 63 | export './tips/base_render_tree.dart'; 64 | export './custom_animation/base_custom_animation.dart'; 65 | export './tips/img/base_img.dart'; 66 | export './tips/channel/base_channel.dart'; 67 | export './tips/touch/base_touch_handle.dart'; 68 | 69 | /// 70 | /// Created by fgyong on 2020/8/26. 71 | /// 72 | -------------------------------------------------------------------------------- /lib/page_view/page_view.dart: -------------------------------------------------------------------------------- 1 | import 'dart:math'; 2 | 3 | import 'package:flutter/cupertino.dart'; 4 | import 'package:flutter/material.dart'; 5 | import 'package:fluttertest01/page_view/page_view_custom.dart'; 6 | 7 | class CustomPageViewPage extends StatefulWidget { 8 | List widgetHeights; 9 | int initPage; 10 | int pageCount; 11 | 12 | @override 13 | State createState() => _CustomPageViewState(); 14 | static String get routeName => '/page_view'; 15 | } 16 | 17 | class _CustomPageViewState extends State { 18 | @override 19 | Widget build(BuildContext context) { 20 | return Scaffold( 21 | body: Container( 22 | alignment: Alignment.center, 23 | color: Colors.white, 24 | child: CustomScrollView( 25 | slivers: [ 26 | SliverToBoxAdapter( 27 | child: Container( 28 | child: Text('我是第1行'), 29 | height: 200, 30 | ), 31 | ), 32 | SliverToBoxAdapter( 33 | child: Container( 34 | height: _pageViewHeight, 35 | width: double.maxFinite, 36 | alignment: Alignment.center, 37 | child: CustomPageView( 38 | widgetHeights: [100, 200, 300], 39 | initPage: 1, 40 | pageCount: 3, 41 | itemBuilder: (ctx, index) { 42 | return _item(index); 43 | }, 44 | freshWidget: (fn) { 45 | if (mounted) setState(fn); 46 | }, 47 | freshHeightCallBack: (height) { 48 | _pageViewHeight = height; 49 | }, 50 | ), 51 | ), 52 | ), 53 | SliverToBoxAdapter( 54 | child: Text('我是第二行'), 55 | ), 56 | ], 57 | ), 58 | ), 59 | appBar: AppBar( 60 | title: Text('pageView' 61 | ''), 62 | ), 63 | ); 64 | } 65 | 66 | Widget _item(int index) { 67 | print('build $index'); 68 | index += 1; 69 | return Opacity( 70 | opacity: 1, 71 | child: Container( 72 | color: Colors.accents[index % Colors.accents.length], 73 | height: (index * 100).toDouble(), 74 | alignment: Alignment.center, 75 | child: Text('$index'), 76 | ), 77 | ); 78 | } 79 | 80 | double _pageViewHeight; 81 | @override 82 | void initState() { 83 | super.initState(); 84 | 85 | _pageViewHeight = 200; 86 | } 87 | 88 | @override 89 | void dispose() { 90 | super.dispose(); 91 | } 92 | } 93 | -------------------------------------------------------------------------------- /lib/scrollview/baseGridView.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/cupertino.dart'; 2 | import 'package:flutter/material.dart'; 3 | import 'package:fluttertest01/scrollview/baseListView.dart'; 4 | 5 | /// 6 | /// Created by fgyong on 2020/7/3. 7 | /// 8 | 9 | class BaseGridView extends StatefulWidget { 10 | @override 11 | _BaseGridViewState createState() => _BaseGridViewState(); 12 | } 13 | 14 | class _BaseGridViewState extends State { 15 | @override 16 | Widget build(BuildContext context) { 17 | return Scaffold( 18 | appBar: AppBar( 19 | title: Text('GridView'), 20 | ), 21 | body: _body(), 22 | ); 23 | } 24 | 25 | Widget _body() { 26 | // List list = new List(); 27 | // for (int i = 0; i < 10; i++) { 28 | // list.add(Container( 29 | // height: 80, 30 | // color: Colors.primaries[i % Colors.primaries.length], 31 | // alignment: Alignment.center, 32 | // child: TestContainer( 33 | // title: DateTime.now().toString(), 34 | // ))); 35 | // } 36 | 37 | return GridView.builder( 38 | gridDelegate: SliverGridDelegateWithMaxCrossAxisExtent( 39 | // crossAxisCount: 4, 40 | maxCrossAxisExtent: MediaQuery.of(context).size.width / 4 + 10.0, 41 | mainAxisSpacing: 10, 42 | crossAxisSpacing: 10, 43 | childAspectRatio: 2), 44 | itemBuilder: _buildCell, 45 | itemCount: _list.length, 46 | semanticChildCount: 13, 47 | ); 48 | } 49 | 50 | List _list; 51 | 52 | Widget _buildCell(BuildContext context, int index) { 53 | if (index < _list.length - 1) { 54 | return Container( 55 | height: 80, alignment: Alignment.center, child: _list[index]); 56 | } else if (_list.length < 100) { 57 | _getData(); 58 | return Container( 59 | alignment: Alignment.center, 60 | child: RefreshProgressIndicator(), 61 | ); 62 | } else { 63 | return Container( 64 | height: 80, alignment: Alignment.center, child: _list[index]); 65 | } 66 | } 67 | 68 | @override 69 | void initState() { 70 | _list = new List(); 71 | _getData(); 72 | super.initState(); 73 | } 74 | 75 | void _getData() async { 76 | await Future.delayed(Duration(milliseconds: 1500)); 77 | _list.addAll([ 78 | Icon(Icons.directions), 79 | Icon(Icons.title), 80 | Icon(Icons.refresh), 81 | Icon(Icons.dehaze), 82 | Icon(Icons.ac_unit), 83 | ]); 84 | setState(() {}); 85 | } 86 | } 87 | -------------------------------------------------------------------------------- /lib/scrollview/baseListenScrollViewOffset.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/cupertino.dart'; 2 | import 'package:flutter/material.dart'; 3 | 4 | /// 5 | /// Created by fgyong on 2020/7/3. 6 | /// 7 | 8 | class BaseListenScrollView extends StatefulWidget { 9 | @override 10 | _BaseListenScrollViewState createState() => _BaseListenScrollViewState(); 11 | } 12 | 13 | class _BaseListenScrollViewState extends State { 14 | @override 15 | Widget build(BuildContext context) { 16 | return Scaffold( 17 | appBar: AppBar( 18 | title: Text('监听滚动'), 19 | ), 20 | body: _body(), 21 | ); 22 | } 23 | 24 | Widget _body() { 25 | return Stack( 26 | alignment: Alignment.center, 27 | children: [ 28 | CupertinoScrollbar( 29 | // isAlwaysShown: false, 30 | child: NotificationListener( 31 | onNotification: (ScrollNotification no) { 32 | var v = no.metrics.pixels / no.metrics.maxScrollExtent; 33 | setState(() { 34 | _value = v * 100; 35 | }); 36 | return true; 37 | }, 38 | child: ListView.builder( 39 | itemBuilder: _child, 40 | controller: _controller, 41 | itemCount: 50, 42 | ), 43 | ), 44 | ), 45 | CircleAvatar( 46 | radius: 40, 47 | child: Container( 48 | child: Text('${_value.toStringAsFixed(2)}%'), 49 | ), 50 | ) 51 | ], 52 | ); 53 | } 54 | 55 | Widget _child(ctx, int index) { 56 | return Container( 57 | height: 80, 58 | color: Colors.primaries[index % Colors.primaries.length], 59 | ); 60 | } 61 | 62 | ScrollController _controller; 63 | double _value = 0; 64 | @override 65 | void initState() { 66 | _controller = new ScrollController() 67 | ..addListener(() { 68 | print('${_controller.offset}'); 69 | }); 70 | super.initState(); 71 | } 72 | } 73 | -------------------------------------------------------------------------------- /lib/scrollview/baseSingleChildScrollView.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/cupertino.dart'; 2 | import 'package:flutter/material.dart'; 3 | 4 | /// 5 | /// Created by fgyong on 2020/7/2. 6 | /// 7 | class BaseSingleChildScrollView extends StatefulWidget { 8 | @override 9 | _BaseSingleChildScrollViewState createState() => 10 | _BaseSingleChildScrollViewState(); 11 | } 12 | 13 | class _BaseSingleChildScrollViewState extends State { 14 | @override 15 | Widget build(BuildContext context) { 16 | return Scaffold( 17 | appBar: AppBar( 18 | title: Text('SingleChildScrollView'), 19 | ), 20 | body: _body(), 21 | ); 22 | } 23 | 24 | Widget _body() { 25 | List list = new List(); 26 | for (int i = 0; i < 30; i++) { 27 | list.add(Card( 28 | child: Container( 29 | height: 140, 30 | width: MediaQuery.of(context).size.width, 31 | alignment: Alignment.center, 32 | child: Text('$i'), 33 | ), 34 | )); 35 | } 36 | return CupertinoScrollbar( 37 | child: SingleChildScrollView( 38 | reverse: true, 39 | physics: BouncingScrollPhysics(), 40 | scrollDirection: Axis.vertical, 41 | child: Column( 42 | children: list, 43 | ), 44 | ), 45 | ); 46 | } 47 | } 48 | -------------------------------------------------------------------------------- /lib/scrollview/scrollview.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/cupertino.dart'; 2 | import 'package:flutter/material.dart'; 3 | import 'package:flutter/widgets.dart'; 4 | 5 | class BaseScrollViewWheel extends StatefulWidget { 6 | BaseScrollViewWheelState createState() => BaseScrollViewWheelState(); 7 | } 8 | 9 | class BaseScrollViewWheelState extends State { 10 | @override 11 | Widget build(BuildContext context) { 12 | return Scaffold( 13 | appBar: AppBar( 14 | title: Text('ListWheelScrollView'), 15 | ), 16 | body: Stack( 17 | children: [ 18 | Positioned.fill(child: _body()), 19 | Positioned.fill( 20 | child: _bottom(), 21 | bottom: 0, 22 | ), 23 | ], 24 | ), 25 | ); 26 | } 27 | 28 | Widget _body() { 29 | List list = new List(); 30 | 31 | for (int i = 0; i < 100; i++) { 32 | Widget widget = Container( 33 | width: 300, 34 | height: 100, 35 | color: Colors.primaries[i % Colors.primaries.length], 36 | ); 37 | list.add(widget); 38 | } 39 | return ListWheelScrollView( 40 | itemExtent: 100, 41 | children: list, 42 | offAxisFraction: value, //左右偏移量 43 | /// 固定中间选中的的放大或者缩小操作 44 | magnification: value3 + 1, 45 | useMagnifier: true, 46 | 47 | /// list 弯曲度 [0,0.01] 48 | 49 | perspective: value2 / 100.0 == 0 ? 0.00000000001 : value2 / 100.0); 50 | } 51 | 52 | Widget _bottom() { 53 | return Column( 54 | children: [ 55 | Row( 56 | mainAxisAlignment: MainAxisAlignment.center, 57 | children: [ 58 | Text('offAxisFraction'), 59 | CupertinoSlider( 60 | value: value, 61 | onChanged: (v) { 62 | setState(() { 63 | value = v; 64 | }); 65 | print(v); 66 | }), 67 | ], 68 | ), 69 | Row( 70 | mainAxisAlignment: MainAxisAlignment.center, 71 | children: [ 72 | Text('perspective'), 73 | CupertinoSlider( 74 | value: value2, 75 | onChanged: (v) { 76 | setState(() { 77 | value2 = v; 78 | }); 79 | print(v); 80 | }), 81 | ], 82 | ), 83 | Row( 84 | mainAxisAlignment: MainAxisAlignment.center, 85 | children: [ 86 | Text('magnification'), 87 | CupertinoSlider( 88 | value: value3, 89 | onChanged: (v) { 90 | setState(() { 91 | value3 = v; 92 | }); 93 | print(v); 94 | }), 95 | ], 96 | ) 97 | ], 98 | ); 99 | } 100 | 101 | double value = 0; 102 | double value2 = 0; 103 | double value3 = 0; 104 | } 105 | -------------------------------------------------------------------------------- /lib/scrollview/swich_page.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/cupertino.dart'; 2 | import 'package:flutter/material.dart'; 3 | import 'package:fluttertest01/util.dart'; 4 | 5 | /// 6 | /// Created by fgyong on 7/19/21. 7 | /// 8 | 9 | class BaseSwitchListTitlePage extends StatefulWidget { 10 | const BaseSwitchListTitlePage({Key key}) : super(key: key); 11 | 12 | @override 13 | _BaseSwitchListTitlePageState createState() => 14 | _BaseSwitchListTitlePageState(); 15 | static String get routeName => '/BaseSwitchListTitlePage'; 16 | } 17 | 18 | T tryCatch({ 19 | T Function() bodyFunc, 20 | T Function() errorSummaryFunc, 21 | T Function() noSuchMethodFunc, 22 | T Function() rangeErrorFunc, 23 | T Function() outOfMemoryErrorFunc, 24 | T Function() typeErrorFunc, 25 | T Function() stateErrorFunc, 26 | T Function() otherFunc, 27 | void Function() finallyFunc, 28 | }) { 29 | try { 30 | if (bodyFunc != null) return bodyFunc(); 31 | } on ErrorSummary catch (e) { 32 | Util.v('$e', tag: 'ErrorSummary'); 33 | if (errorSummaryFunc != null) return errorSummaryFunc(); 34 | } on NoSuchMethodError catch (e) { 35 | Util.v('$e', tag: 'NoSuchMethodError'); 36 | if (noSuchMethodFunc != null) return noSuchMethodFunc(); 37 | } on RangeError catch (e) { 38 | Util.v('$e', tag: 'RangeError'); 39 | if (rangeErrorFunc != null) return rangeErrorFunc(); 40 | } on OutOfMemoryError catch (e) { 41 | Util.v('$e', tag: 'OutOfMemoryError'); 42 | if (outOfMemoryErrorFunc != null) return outOfMemoryErrorFunc(); 43 | } on TypeError catch (e) { 44 | Util.v('$e', tag: 'TypeError'); 45 | if (typeErrorFunc != null) return typeErrorFunc(); 46 | } on StateError catch (e) { 47 | Util.v('$e', tag: 'StateError'); 48 | if (stateErrorFunc != null) return stateErrorFunc(); 49 | } catch (e) { 50 | Util.v('$e', tag: 'Error:${e.runtimeType}'); 51 | if (otherFunc != null) return otherFunc(); 52 | } finally { 53 | Util.v('finally'); 54 | if (finallyFunc != null) finallyFunc(); 55 | } 56 | } 57 | 58 | class _BaseSwitchListTitlePageState extends State { 59 | bool _isOpen = true; 60 | bool _isOpen2 = true; 61 | @override 62 | Widget build(BuildContext context) { 63 | return Scaffold( 64 | appBar: AppBar( 65 | title: Text('切换开关'), 66 | ), 67 | body: Container( 68 | child: Column( 69 | children: [ 70 | SwitchListTile( 71 | value: _isOpen, 72 | onChanged: (s) { 73 | setState(() { 74 | _isOpen = s; 75 | tryCatch( 76 | bodyFunc: () {}, 77 | noSuchMethodFunc: () { 78 | Util.v('noSuchMethodFunc'); 79 | }, 80 | ); 81 | }); 82 | }, 83 | title: Text('开关上边'), 84 | subtitle: Text('二级开关下边'), 85 | secondary: Icon(Icons.forward), 86 | ), 87 | SwitchListTile( 88 | value: _isOpen2, 89 | onChanged: (s) { 90 | tryCatch(bodyFunc: () { 91 | setState(() { 92 | _isOpen2 = s; 93 | }); 94 | }); 95 | }, 96 | title: Text('开关'), 97 | subtitle: Text('二级开关'), 98 | secondary: Icon(Icons.add), 99 | ), 100 | ], 101 | ), 102 | ), 103 | ); 104 | } 105 | } 106 | -------------------------------------------------------------------------------- /lib/secondPage.dart: -------------------------------------------------------------------------------- 1 | import 'dart:developer'; 2 | 3 | import 'package:flutter/cupertino.dart'; 4 | import 'package:flutter/material.dart'; 5 | import 'package:provider/provider.dart'; 6 | import 'package:fluttertest01/counter.dart'; 7 | 8 | class SecondPage extends StatelessWidget { 9 | @override 10 | Widget build(BuildContext context) { 11 | return Scaffold( 12 | appBar: AppBar( 13 | title: Text('second'), 14 | ), 15 | body: Hero( 16 | tag: 'null', 17 | child: Container( 18 | height: 100, 19 | color: Colors.lightBlueAccent, 20 | width: 200, 21 | child: FlatButton( 22 | onPressed: () { 23 | context.read().changeValue(2); 24 | // Navigator.of(context) 25 | // .push(MaterialPageRoute(builder: (ctx) => SecondPage())); 26 | }, 27 | child: Text('2')), 28 | ), 29 | ), 30 | // floatingActionButton: FloatingActionButton( 31 | // onPressed: () { 32 | // Navigator.of(context).pop(); 33 | // }, 34 | // tooltip: 'Increment', 35 | // child: Icon(Icons.add), 36 | // ), // This trailing comma makes auto-formatting nicer for build methods. 37 | ); 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /lib/server/basic_writer_server.dart: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2014, the Dart project authors. Please see the AUTHORS file 2 | // for details. All rights reserved. Use of this source code is governed by a 3 | // BSD-style license that can be found in the LICENSE file. 4 | 5 | // Server to basic_writer_client.dart. 6 | // Receives JSON encoded data in a POST request and writes it to 7 | // the file specified in the URI. 8 | 9 | // import 'package:mysql1/mysql1.dart'; 10 | 11 | // String _host = InternetAddress.loopbackIPv4.host; 12 | 13 | // Future main() async { 14 | // var server = await HttpServer.bind(_host, 4049); 15 | // HttpServer.listenOn(server); 16 | // print('Listening on http://${server.address.address}:${server.port}/'); 17 | // await for (var req in server) { 18 | // handle(req); 19 | // } 20 | // } 21 | 22 | // void handle(HttpRequest req) async { 23 | // final response = req.response; 24 | // if (uris.containsKey(req.uri.path)) { 25 | // uris[req.uri.path](req); 26 | // } 27 | // await response.close(); 28 | // } 29 | // 30 | // void getList(HttpRequest req) async { 31 | // final response = req.response; 32 | // // req.method == 'POST' && 33 | // // contentType?.mimeType == 'application/json' 34 | // 35 | // try { 36 | // var data = req.uri.queryParametersAll; 37 | // // data['ex'] = req.requestedUri.query; 38 | // 39 | // // final content = await utf8.decoder.bind(req).join(); /*2*/ 40 | // // final conn = await MySqlConnection.connect(ConnectionSettings( 41 | // // host: '127.0.0.1', 42 | // // port: 3306, 43 | // // user: 'root', 44 | // // db: 'testDB', 45 | // // password: '12345678')); 46 | // 47 | // // final ret = await conn.query('select * from user'); 48 | // req.response 49 | // ..statusCode = HttpStatus.ok 50 | // ..write('Wrote data for ${data} ${req.requestedUri.path} .'); 51 | // } catch (e) { 52 | // response 53 | // ..statusCode = HttpStatus.internalServerError 54 | // ..write('Exception during file I/O: $e.') 55 | // ..close(); 56 | // } 57 | // } 58 | // 59 | // typedef f = Function(HttpRequest req); 60 | // Map uris = {'/get': getList}; 61 | -------------------------------------------------------------------------------- /lib/test.dart: -------------------------------------------------------------------------------- 1 | void runTest() { 2 | t2(); 3 | } 4 | 5 | void test1() { 6 | var items = ['Salad', 'Popcorn', 'T']; 7 | 8 | if (items.any((element) => element.contains('a'))) { 9 | print('At least one element contains "a"'); 10 | } 11 | if (items.any((element) => element.contains('T'))) { 12 | print('at lease one el contains T'); 13 | } 14 | 15 | if (items.every((element) => element.length >= 5)) { 16 | print('All elements have length >= 5'); 17 | } 18 | } 19 | 20 | t2() { 21 | var numbers = [1, 3, -2, 0, 4, 5]; 22 | 23 | var numbersUntilZero = numbers.takeWhile((number) => number != 0); 24 | print('Numbers until 0: $numbersUntilZero'); 25 | 26 | var numbersAfterZero = numbers.skipWhile((number) => number != 0); 27 | print('Numbers after 0: $numbersAfterZero'); 28 | 29 | Iterable iterable = numbers.map((e) { 30 | return e + 1; 31 | }); 32 | print(iterable.toString()); 33 | } 34 | -------------------------------------------------------------------------------- /lib/tips/.DS_Store: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ifgyong/flutter-example/58679c0bef0de656605e3e2bd5daf7b241ea1baf/lib/tips/.DS_Store -------------------------------------------------------------------------------- /lib/tips/async_and_async*.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/cupertino.dart'; 2 | import 'package:flutter/material.dart'; 3 | import 'dart:io'; 4 | 5 | /// 6 | /// Created by fgyong on 2020/7/29. 7 | /// 8 | 9 | class BaseAsync extends StatefulWidget { 10 | BaseAsync({Key key}) : super(key: key); 11 | 12 | @override 13 | _BaseAsyncState createState() => _BaseAsyncState(); 14 | } 15 | 16 | class _BaseAsyncState extends State { 17 | @override 18 | Widget build(BuildContext context) { 19 | return Scaffold( 20 | appBar: AppBar( 21 | title: Text('异步与同步数据流'), 22 | ), 23 | body: _body(), 24 | ); 25 | } 26 | 27 | Widget _body() { 28 | return Center( 29 | child: Column( 30 | mainAxisAlignment: MainAxisAlignment.center, 31 | children: [ 32 | Expanded( 33 | child: Text('${stringBuffer.toString()}'), 34 | ) 35 | ], 36 | ), 37 | ); 38 | } 39 | 40 | int _count = 0; 41 | 42 | Future _toString() async { 43 | var s = await _stream().map((event) => event.toString()).join('|'); 44 | return s; 45 | } 46 | 47 | Future _toList() async { 48 | var s = await _stream().toList(); 49 | return s; 50 | } 51 | 52 | Stream _getDataFromServer() { 53 | return null; 54 | } 55 | 56 | /// 异步数据流 57 | Stream _stream() async* { 58 | if (_count < 10) { 59 | yield _count++; 60 | 61 | await Future.delayed(Duration(seconds: 1)); 62 | sleep(Duration(seconds: 1)); 63 | yield* _getDataFromServer(); 64 | } 65 | } 66 | 67 | StringBuffer stringBuffer; 68 | 69 | /// 同步获取数据 70 | Iterable _streamIterable() sync* { 71 | if (_count < 20) { 72 | yield _count; 73 | yield* _streamIterable(); 74 | } 75 | } 76 | 77 | @override 78 | void initState() { 79 | stringBuffer = StringBuffer(); 80 | setState(() { 81 | _toString().then((value) { 82 | stringBuffer.write(value); 83 | }); 84 | }); 85 | // _stream().listen((event) { 86 | //// stringBuffer.write(event); 87 | ////// stringBuffer.writeln(event) 88 | //// setState(() {}); 89 | //// print(event); 90 | // }); 91 | super.initState(); 92 | } 93 | } 94 | -------------------------------------------------------------------------------- /lib/tips/base_ visibility_detector.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/cupertino.dart'; 2 | import 'package:flutter/material.dart'; 3 | import 'package:visibility_detector/visibility_detector.dart'; 4 | 5 | class BaseVisibilityDetector extends StatefulWidget { 6 | @override 7 | State createState() => _BaseVisibilityDetectorState(); 8 | static String get routeName => '/BaseVisibilityDetector'; 9 | } 10 | 11 | class _BaseVisibilityDetectorState extends State { 12 | @override 13 | Widget build(BuildContext context) { 14 | return Scaffold( 15 | appBar: AppBar( 16 | title: Text('BaseVisibilityDetector'), 17 | ), 18 | body: CustomScrollView( 19 | slivers: [ 20 | _item('0'), 21 | _item('1'), 22 | _item('2'), 23 | _item('3'), 24 | _item('4'), 25 | _item('5'), 26 | _item('6'), 27 | _item2('6'), 28 | _item('7'), 29 | _item('8'), 30 | _item('9'), 31 | _item('10'), 32 | ], 33 | ), 34 | ); 35 | } 36 | 37 | SliverToBoxAdapter _item(String index) { 38 | return SliverToBoxAdapter( 39 | child: VisibilityDetector( 40 | key: ValueKey('key_$index'), 41 | child: Container( 42 | height: 100, 43 | child: Text('key_$index'), 44 | ), 45 | onVisibilityChanged: (show) { 46 | print('$index ${show.visibleFraction * 100}'); 47 | }, 48 | ), 49 | ); 50 | } 51 | 52 | SliverToBoxAdapter _item2(String index) { 53 | return SliverToBoxAdapter( 54 | child: VisibilityDetector( 55 | key: ValueKey('key2_$index'), 56 | child: SizedBox( 57 | height: 100, 58 | child: TextField(), 59 | ), 60 | onVisibilityChanged: (show) { 61 | print('$index ${show.visibleFraction * 100}'); 62 | }, 63 | ), 64 | ); 65 | } 66 | } 67 | -------------------------------------------------------------------------------- /lib/tips/base_connect.dart: -------------------------------------------------------------------------------- 1 | import 'package:connectivity/connectivity.dart'; 2 | import 'package:flutter/cupertino.dart'; 3 | import 'package:flutter/material.dart'; 4 | 5 | class BaseNetWorkConnect extends StatefulWidget { 6 | @override 7 | State createState() => _BaseNetWorkConnectState(); 8 | static String get routeName => '/_BaseNetWorkConnectState'; 9 | } 10 | 11 | class _BaseNetWorkConnectState extends State { 12 | @override 13 | Widget build(BuildContext context) { 14 | return Scaffold( 15 | appBar: AppBar( 16 | title: Text('BaseNetWorkConnect'), 17 | ), 18 | body: _body(), 19 | ); 20 | } 21 | 22 | String ret = ''; 23 | 24 | Widget _body() { 25 | return Center( 26 | child: Column( 27 | mainAxisAlignment: MainAxisAlignment.center, 28 | crossAxisAlignment: CrossAxisAlignment.center, 29 | children: [TextButton(onPressed: check, child: Text('刷新 $ret'))], 30 | ), 31 | ); 32 | } 33 | 34 | Connectivity connect; 35 | @override 36 | void initState() { 37 | super.initState(); 38 | connect = Connectivity(); 39 | check(); 40 | connect.onConnectivityChanged.listen((event) { 41 | statusToStr(event); 42 | if (mounted) setState(() {}); 43 | }, onDone: () { 44 | print('done'); 45 | }, onError: (error) { 46 | print(error); 47 | }); 48 | } 49 | 50 | void check() async { 51 | connect.checkConnectivity().then((event) { 52 | statusToStr(event); 53 | if (mounted) setState(() {}); 54 | }); 55 | } 56 | 57 | String statusToStr(ConnectivityResult event) { 58 | switch (event) { 59 | case ConnectivityResult.none: 60 | ret = 'none'; 61 | break; 62 | case ConnectivityResult.wifi: 63 | ret = 'wifi'; 64 | break; 65 | case ConnectivityResult.mobile: 66 | ret = 'mobile'; 67 | break; 68 | } 69 | return ret; 70 | } 71 | } 72 | -------------------------------------------------------------------------------- /lib/tips/base_interactive_viewer.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/cupertino.dart'; 2 | import 'package:flutter/material.dart'; 3 | 4 | /// 5 | /// Created by fgyong on 2020/11/9. 6 | /// 7 | 8 | class BaseInteractiveViewer extends StatefulWidget { 9 | BaseInteractiveViewer({Key key}) : super(key: key); 10 | 11 | @override 12 | _BaseInteractiveViewerState createState() => _BaseInteractiveViewerState(); 13 | 14 | static String get routeName => "interactiveViewer"; 15 | } 16 | 17 | class _BaseInteractiveViewerState extends State { 18 | @override 19 | Widget build(BuildContext context) { 20 | return Scaffold( 21 | appBar: AppBar( 22 | title: Text('interactiveViewer'), 23 | ), 24 | body: _body(), 25 | ); 26 | } 27 | 28 | Widget _body() { 29 | return Center( 30 | child: InteractiveViewer( 31 | boundaryMargin: EdgeInsets.all(20.0), 32 | minScale: 0.1, 33 | maxScale: 1.6, 34 | child: Container( 35 | child: Image.asset('img/2.png'), 36 | // decoration: BoxDecoration( 37 | // gradient: LinearGradient( 38 | // begin: Alignment.topCenter, 39 | // end: Alignment.bottomCenter, 40 | // colors: [Colors.orange, Colors.red], 41 | // stops: [0.0, 1.0], 42 | // ), 43 | // ), 44 | ), 45 | ), 46 | ); 47 | } 48 | } 49 | -------------------------------------------------------------------------------- /lib/tips/base_key.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/cupertino.dart'; 2 | import 'package:flutter/material.dart'; 3 | 4 | /// 5 | /// Created by fgyong on 2020/8/21. 6 | /// 7 | 8 | class BaseKeyPage extends StatefulWidget { 9 | BaseKeyPage({Key key}) : super(key: key); 10 | 11 | @override 12 | _BaseKeyPageState createState() => _BaseKeyPageState(); 13 | static String get routeName => '/BaseKeyPage'; 14 | } 15 | 16 | class _BaseKeyPageState extends State { 17 | @override 18 | Widget build(BuildContext context) { 19 | return Scaffold( 20 | appBar: AppBar( 21 | title: Text('key'), 22 | ), 23 | body: _body(), 24 | floatingActionButton: FloatingActionButton( 25 | child: Icon(Icons.refresh), 26 | onPressed: () { 27 | setState(() { 28 | count += 1; 29 | }); 30 | }, 31 | ), 32 | ); 33 | } 34 | 35 | Student _student; 36 | int count = 0; 37 | Widget _body() { 38 | _student = Student('老王'); 39 | return Column( 40 | children: [ 41 | Text('ValueKey 包含的值相等就判定为相等'), 42 | TextField( 43 | key: ValueKey(Student('老王1')), 44 | ), 45 | TextField( 46 | key: ValueKey(Student('老王2')), 47 | ), 48 | Text( 49 | 'objetKey 必须引用相同地址才判断为相等\n' 50 | '每次new 就生成不同地址的对象', 51 | textAlign: TextAlign.center, 52 | ), 53 | TextField( 54 | key: ObjectKey(Student('老王')), 55 | ), 56 | TextField( 57 | key: ObjectKey(Student('老王')), 58 | ), 59 | TextField( 60 | key: UniqueKey(), 61 | ), 62 | TextField( 63 | key: UniqueKey(), 64 | ), 65 | AnimatedSwitcher( 66 | duration: Duration(milliseconds: 1000), 67 | child: Container( 68 | key: UniqueKey(), 69 | height: 100, 70 | width: 100, 71 | color: Colors.primaries[count % Colors.primaries.length], 72 | ), 73 | ), 74 | SizedBox( 75 | height: 20, 76 | ), 77 | _Container(_key), 78 | OutlineButton( 79 | child: Text('global key 刷新'), 80 | onPressed: () { 81 | _key.currentState.setState(() {}); 82 | }, 83 | ) 84 | ], 85 | ); 86 | } 87 | 88 | GlobalKey _key = GlobalKey(); 89 | } 90 | 91 | class _Container extends StatefulWidget { 92 | /// 使用[StatefulWidget] 的[key]来获取[state] 93 | _Container(Key key) : super(key: key); 94 | @override 95 | State createState() { 96 | return __ContainerState(); 97 | } 98 | } 99 | 100 | class __ContainerState extends State<_Container> { 101 | int count = 0; 102 | @override 103 | Widget build(BuildContext context) { 104 | count += 1; 105 | 106 | /// 每次build 都更换颜色 107 | return Container( 108 | height: 100, 109 | width: 100, 110 | color: Colors.primaries[count % Colors.primaries.length], 111 | ); 112 | } 113 | } 114 | 115 | class Student { 116 | final String name; 117 | 118 | Student(this.name); 119 | 120 | @override 121 | int get hashCode => name.hashCode; 122 | 123 | @override 124 | bool operator ==(Object other) => 125 | identical(this, other) || 126 | other is Student && 127 | runtimeType == other.runtimeType && 128 | name == other.name; 129 | } 130 | -------------------------------------------------------------------------------- /lib/tips/base_record.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/cupertino.dart'; 2 | import 'package:flutter/material.dart'; 3 | import 'package:flutter_simple_record_and_player/fluttersimplerecordandplayer.dart'; 4 | import 'package:path_provider/path_provider.dart'; 5 | 6 | /// 7 | /// Created by fgyong on 2020/7/30. 8 | /// 9 | 10 | class BaseRecordRoute extends StatefulWidget { 11 | BaseRecordRoute({Key key}) : super(key: key); 12 | 13 | @override 14 | _BaseRecordRouteState createState() => _BaseRecordRouteState(); 15 | } 16 | 17 | class _BaseRecordRouteState extends State { 18 | @override 19 | Widget build(BuildContext context) { 20 | return Scaffold( 21 | appBar: AppBar( 22 | title: Text('录音测试'), 23 | ), 24 | body: _body(), 25 | ); 26 | } 27 | 28 | Widget _body() { 29 | return Center( 30 | child: Column( 31 | children: [ 32 | Text('录音需在真机上测试'), 33 | OutlineButton( 34 | child: Text('录音开始'), 35 | onPressed: _start, 36 | ), 37 | OutlineButton( 38 | child: Text('录音结束'), 39 | onPressed: _end, 40 | ), 41 | OutlineButton( 42 | child: Text('录音播放'), 43 | onPressed: _play, 44 | ), 45 | OutlineButton( 46 | child: Text('播放停止'), 47 | onPressed: () { 48 | _andPlayer.stopPlay(); 49 | }, 50 | ), 51 | Text('文件地址:$_path'), 52 | ], 53 | ), 54 | ); 55 | } 56 | 57 | String _path = ''; 58 | void _start() async { 59 | var p = await getTemporaryDirectory(); 60 | _path = '${p.path}/mp3/${DateTime.now()}.mp3'; 61 | _andPlayer.startRecord(null, (error) { 62 | print(error); 63 | }); 64 | } 65 | 66 | void _end() { 67 | _andPlayer.stopRecord; 68 | _path = _andPlayer.recordListPath.last.toString(); 69 | setState(() {}); 70 | print(_andPlayer.recordListPath.last.toString()); 71 | } 72 | 73 | void _play() { 74 | _andPlayer.play(_andPlayer.recordListPath.last, isLocal: true); 75 | } 76 | 77 | SimpleSoundRecordAndPlayer _andPlayer; 78 | @override 79 | void initState() { 80 | _andPlayer = SimpleSoundRecordAndPlayer(); 81 | super.initState(); 82 | } 83 | } 84 | -------------------------------------------------------------------------------- /lib/tips/base_render_tree.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/cupertino.dart'; 2 | import 'package:flutter/foundation.dart'; 3 | import 'package:flutter/material.dart'; 4 | 5 | /// 6 | /// Created by fgyong on 2020/8/26. 7 | /// 8 | 9 | class BaseRenderTree extends StatefulWidget { 10 | BaseRenderTree({Key key}) : super(key: key); 11 | 12 | @override 13 | _BaseRenderTreeState createState() => _BaseRenderTreeState(); 14 | static String get routeName => '/BaseRenderTree'; 15 | } 16 | 17 | class _BaseRenderTreeState extends State { 18 | @override 19 | Widget build(BuildContext context) { 20 | return Scaffold( 21 | appBar: AppBar( 22 | title: Text('3棵树'), 23 | ), 24 | body: _body(), 25 | floatingActionButton: FloatingActionButton( 26 | child: Icon(Icons.add), 27 | onPressed: _add, 28 | ), 29 | ); 30 | } 31 | 32 | void _add() { 33 | setState(() { 34 | _count += 1; 35 | }); 36 | } 37 | 38 | int _count = 0; 39 | Widget _body() { 40 | print('build'); 41 | return Center( 42 | child: Column( 43 | children: [ 44 | Text.rich( 45 | TextSpan( 46 | text: '每次刷新只', 47 | children: [ 48 | _widgetBold('改变Text文本,`renderobject` 不会重新创建'), 49 | _widget('只有当'), 50 | _widgetBold('`key`或者类型'), 51 | _widget('改变才会重新创建`renderobject`') 52 | ], 53 | ), 54 | ), 55 | Container( 56 | child: Text('$_count'), 57 | ), 58 | const _LessRoute(), 59 | ], 60 | ), 61 | ); 62 | } 63 | 64 | Widget _listView() { 65 | return CustomScrollView( 66 | slivers: [ 67 | SliverList( 68 | delegate: SliverChildBuilderDelegate((context, index) { 69 | return Text('$index'); 70 | }, childCount: 10), 71 | ), 72 | SliverGrid( 73 | gridDelegate: SliverGridDelegateWithFixedCrossAxisCount( 74 | crossAxisCount: 3, 75 | crossAxisSpacing: 10, 76 | mainAxisSpacing: 10, 77 | ), 78 | delegate: SliverChildBuilderDelegate((context, index) { 79 | return Text('$index'); 80 | }, childCount: 12), 81 | ) 82 | ], 83 | ); 84 | } 85 | 86 | Widget _widget2() { 87 | return Stack(); 88 | } 89 | 90 | TextSpan _widgetBold(String string) { 91 | return TextSpan( 92 | text: '$string', 93 | style: TextStyle( 94 | fontSize: 15, color: Colors.blueAccent, fontWeight: FontWeight.bold), 95 | ); 96 | } 97 | 98 | TextSpan _widget(String string) { 99 | return TextSpan( 100 | text: '$string', 101 | ); 102 | } 103 | } 104 | 105 | class _LessRoute extends StatelessWidget { 106 | @override 107 | Widget build(BuildContext context) { 108 | print('_LessRoute build'); 109 | return Container( 110 | child: Text('const 修饰的组件,父组件怎么刷新,子组件都不刷新'), 111 | ); 112 | } 113 | 114 | const _LessRoute(); 115 | } 116 | -------------------------------------------------------------------------------- /lib/tips/base_slider.dart: -------------------------------------------------------------------------------- 1 | import 'package:connectivity/connectivity.dart'; 2 | import 'package:flutter/cupertino.dart'; 3 | import 'package:flutter/material.dart'; 4 | import 'package:flutter_slidable/flutter_slidable.dart'; 5 | 6 | class BaseSliderPage extends StatefulWidget { 7 | @override 8 | State createState() => _BaseSliderPageState(); 9 | static String get routeName => '/BaseSliderPage'; 10 | } 11 | 12 | class _BaseSliderPageState extends State { 13 | @override 14 | Widget build(BuildContext context) { 15 | return Scaffold( 16 | appBar: AppBar( 17 | title: Text('BaseSliderPage'), 18 | ), 19 | body: _body(), 20 | ); 21 | } 22 | 23 | Widget _body() { 24 | return Column( 25 | children: [ 26 | _buildItem(), 27 | _buildItem(), 28 | _buildItem(), 29 | _buildItem(), 30 | _buildItem(), 31 | ], 32 | ); 33 | } 34 | 35 | Widget _buildItem() { 36 | return Slidable( 37 | actionPane: SlidableDrawerActionPane(), 38 | actionExtentRatio: 0.25, 39 | child: Container( 40 | color: Colors.white, 41 | child: ListTile( 42 | leading: CircleAvatar( 43 | backgroundColor: Colors.indigoAccent, 44 | child: Text('3'), 45 | foregroundColor: Colors.white, 46 | ), 47 | title: Text('Tile n°3'), 48 | subtitle: Text('SlidableDrawerDelegate'), 49 | ), 50 | ), 51 | actions: [ 52 | IconSlideAction( 53 | caption: 'Archive', 54 | color: Colors.blue, 55 | icon: Icons.archive, 56 | onTap: () => _showSnackBar('Archive'), 57 | ), 58 | IconSlideAction( 59 | caption: 'Share', 60 | color: Colors.indigo, 61 | icon: Icons.share, 62 | onTap: () => _showSnackBar('Share'), 63 | ), 64 | ], 65 | secondaryActions: [ 66 | IconSlideAction( 67 | caption: 'More', 68 | color: Colors.black45, 69 | icon: Icons.more_horiz, 70 | onTap: () => _showSnackBar('More'), 71 | ), 72 | IconSlideAction( 73 | caption: 'Delete', 74 | color: Colors.red, 75 | icon: Icons.delete, 76 | onTap: () => _showSnackBar('Delete'), 77 | ), 78 | ], 79 | ); 80 | } 81 | 82 | void _showSnackBar(String str) { 83 | ScaffoldMessenger.of(context).showSnackBar(SnackBar(content: Text(str))); 84 | } 85 | 86 | @override 87 | void initState() { 88 | super.initState(); 89 | } 90 | } 91 | -------------------------------------------------------------------------------- /lib/tips/bloc/base_bloc_list.dart: -------------------------------------------------------------------------------- 1 | import 'dart:html'; 2 | 3 | import 'package:flutter/cupertino.dart'; 4 | import 'package:flutter/material.dart'; 5 | import 'package:equatable/equatable.dart'; 6 | import 'package:flutter_bloc/flutter_bloc.dart'; 7 | 8 | /// 9 | /// Created by fgyong on 2020/8/19. 10 | /// 11 | 12 | class BaseBlocListRoute extends StatefulWidget { 13 | BaseBlocListRoute({Key key}) : super(key: key); 14 | 15 | @override 16 | _BaseBlocListRouteState createState() => _BaseBlocListRouteState(); 17 | } 18 | 19 | class _BaseBlocListRouteState extends State { 20 | @override 21 | Widget build(BuildContext context) { 22 | return Scaffold( 23 | appBar: AppBar( 24 | title: Text('下拉列表BLoC'), 25 | ), 26 | body: _body(), 27 | ); 28 | } 29 | 30 | Widget _body() {} 31 | } 32 | 33 | class ListCubit extends Cubit { 34 | ListCubit(Model state) : super(state); 35 | 36 | Future> request(int count) async { 37 | await Future.delayed(Duration(seconds: 1)); 38 | List<_Item> list = List(); 39 | for (int i = 0; i < count; i++) { 40 | list.add(_Item(title: 'title${list.length}', subTitle: 'subtitle')); 41 | } 42 | return list; 43 | } 44 | } 45 | 46 | enum ListState { 47 | success, 48 | faild, 49 | isLoading, 50 | } 51 | 52 | class Model extends Equatable { 53 | Model({this.list}) { 54 | this.list ??= List(); 55 | } 56 | List<_Item> list; 57 | ListState state; 58 | 59 | Model copyWith(List<_Item> list) { 60 | return Model(list: list); 61 | } 62 | 63 | @override 64 | List get props => [list]; 65 | } 66 | 67 | // ignore: unused_element 68 | class _Item extends Equatable { 69 | String title, subTitle; 70 | _Item({this.title, this.subTitle}); 71 | @override 72 | List get props => [title, subTitle]; 73 | } 74 | -------------------------------------------------------------------------------- /lib/tips/bloc/base_login_cubit.dart: -------------------------------------------------------------------------------- 1 | export 'login_cubit/cubit/cubit.dart'; 2 | export 'login_cubit/model/login_cubit_models.dart'; 3 | export 'login_cubit/view/login_views.dart'; 4 | export 'login_cubit/page/login_pages.dart'; 5 | 6 | /// 7 | /// Created by fgyong on 2020/8/20. 8 | /// 9 | -------------------------------------------------------------------------------- /lib/tips/bloc/list_cubit/bloc/list_bloc.dart: -------------------------------------------------------------------------------- 1 | import 'dart:convert'; 2 | 3 | import 'package:flutter_bloc/flutter_bloc.dart'; 4 | import 'package:fluttertest01/tips/bloc/list_cubit/list_events/list_event.dart'; 5 | import 'package:fluttertest01/tips/bloc/list_cubit/list_status/list_state.dart'; 6 | import 'package:fluttertest01/tips/bloc/list_cubit/model/list_data.dart'; 7 | import 'package:http/http.dart' as http; 8 | 9 | /// 10 | /// Created by fgyong on 2020/9/22. 11 | /// 12 | 13 | class PostBloc extends Bloc { 14 | PostBloc(initialState, this.httpClient) : super(initialState); 15 | final http.Client httpClient; 16 | 17 | @override 18 | Stream mapEventToState(PostEvent event) async* { 19 | final currentState = state; 20 | print('$event'); 21 | try { 22 | if (event is PostFetchedEvent && _hasReachMax(state) == false) { 23 | if (currentState is PostInitial) { 24 | final posts = await _fetchPosts(0, 20); 25 | yield PostSuccess(posts: posts, hasReachedMax: false); 26 | return; 27 | } else if (currentState is PostSuccess) { 28 | yield PostSuccessIsLoading( 29 | posts: currentState.posts, 30 | hasReachMax: currentState.hasReachedMax); 31 | final posts = await _fetchPosts((currentState).posts.length, 20); 32 | yield posts.isEmpty 33 | ? (currentState).copyWith(hasReachedMax: true) 34 | : PostSuccess( 35 | posts: (currentState).posts + posts, hasReachedMax: false); 36 | } 37 | } 38 | } catch (_) { 39 | yield PostFailure(); 40 | } 41 | } 42 | 43 | /// 是否有最大值 44 | bool _hasReachMax(PostState state) { 45 | return state is PostSuccess && (state).hasReachedMax == true; 46 | } 47 | 48 | /// 加载数据 49 | Future> _fetchPosts(int startIndex, int limit) async { 50 | await Future.delayed(Duration(seconds: 1)); 51 | 52 | List list = []; 53 | if (startIndex > 40) return list; 54 | for (int i = startIndex; i < startIndex + limit; i++) { 55 | list.add(Post( 56 | id: i, 57 | title: 'title $i', 58 | body: 'body 测试数据,body就是这么长', 59 | )); 60 | } 61 | return list; 62 | } 63 | } 64 | -------------------------------------------------------------------------------- /lib/tips/bloc/list_cubit/list_events/list_event.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/cupertino.dart'; 2 | import 'package:flutter/material.dart'; 3 | 4 | /// 5 | /// Created by fgyong on 2020/9/22. 6 | /// 7 | 8 | import 'package:equatable/equatable.dart'; 9 | 10 | abstract class PostEvent extends Equatable { 11 | @override 12 | List get props => []; 13 | } 14 | 15 | class PostFetchedEvent extends PostEvent {} 16 | -------------------------------------------------------------------------------- /lib/tips/bloc/list_cubit/list_status/list_state.dart: -------------------------------------------------------------------------------- 1 | /// 2 | /// Created by fgyong on 2020/9/22. 3 | /// 4 | 5 | import 'package:equatable/equatable.dart'; 6 | 7 | import '../model/list_data.dart'; 8 | 9 | abstract class PostState extends Equatable { 10 | const PostState(); 11 | 12 | @override 13 | List get props => []; 14 | } 15 | 16 | class PostInitial extends PostState {} 17 | 18 | class PostFailure extends PostState {} 19 | 20 | class PostSuccess extends PostState { 21 | final List posts; 22 | final bool hasReachedMax; 23 | 24 | const PostSuccess({ 25 | this.posts, 26 | this.hasReachedMax, 27 | }); 28 | 29 | PostSuccess copyWith({ 30 | List posts, 31 | bool hasReachedMax, 32 | }) { 33 | return PostSuccess( 34 | posts: posts ?? this.posts, 35 | hasReachedMax: hasReachedMax ?? this.hasReachedMax, 36 | ); 37 | } 38 | 39 | @override 40 | List get props => [posts, hasReachedMax]; 41 | 42 | @override 43 | String toString() => 44 | 'PostSuccess { posts: ${posts.length}, hasReachedMax: $hasReachedMax }'; 45 | } 46 | 47 | class PostSuccessIsLoading extends PostSuccess { 48 | PostSuccessIsLoading({List posts, bool hasReachMax}) 49 | : super(posts: posts, hasReachedMax: hasReachMax); 50 | } 51 | -------------------------------------------------------------------------------- /lib/tips/bloc/list_cubit/model/list_data.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/cupertino.dart'; 2 | import 'package:flutter/material.dart'; 3 | 4 | /// 5 | /// Created by fgyong on 2020/9/22. 6 | /// 7 | 8 | import 'package:equatable/equatable.dart'; 9 | 10 | class Post extends Equatable { 11 | final int id; 12 | final String title; 13 | final String body; 14 | 15 | const Post({this.id, this.title, this.body}); 16 | 17 | @override 18 | List get props => [id, title, body]; 19 | 20 | @override 21 | String toString() => 'Post { id: $id }'; 22 | } 23 | -------------------------------------------------------------------------------- /lib/tips/bloc/list_cubit/obs/post_obs.dart: -------------------------------------------------------------------------------- 1 | import 'package:bloc/bloc.dart'; 2 | import 'package:flutter/cupertino.dart'; 3 | import 'package:flutter/material.dart'; 4 | 5 | /// 6 | /// Created by fgyong on 2020/9/22. 7 | /// 8 | 9 | class PostOBs extends BlocObserver { 10 | @override 11 | void onChange(Cubit cubit, Change change) { 12 | print('$cubit $change'); 13 | super.onChange(cubit, change); 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /lib/tips/bloc/login_bloc/bloc/login_bloc.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter_bloc/flutter_bloc.dart'; 2 | import 'package:equatable/equatable.dart'; 3 | import '../model/login_models.dart'; 4 | part 'login_event.dart'; 5 | part 'login_state.dart'; 6 | 7 | /// 8 | /// Created by fgyong on 2020/8/19. 9 | /// 10 | 11 | class LoginBloc extends Bloc { 12 | LoginBloc(initialState) : super(initialState); 13 | 14 | @override 15 | Stream mapEventToState(event) async* { 16 | if (event is LoginChagneName) { 17 | yield _mapChangeUserNameToState(event, state); 18 | } else if (event is LoginChagnePassword) { 19 | yield _mapChangePasswordToState(event, state); 20 | } else if (event is LoginSubmitted) { 21 | yield* _mapSubmittedToState(event, state); 22 | } 23 | } 24 | 25 | /// 改变密码 26 | LoginState2 _mapChangePasswordToState( 27 | LoginChagnePassword event, LoginState2 state2) { 28 | return state2.copyWith(pwd: event.password ?? ''); 29 | } 30 | 31 | /// 改变名字 32 | LoginState2 _mapChangeUserNameToState( 33 | LoginChagneName event, LoginState2 state2) { 34 | return state2.copyWith(name: event.name ?? ''); 35 | } 36 | 37 | /// 提交 38 | Stream _mapSubmittedToState( 39 | LoginSubmitted event, LoginState2 state2) async* { 40 | try { 41 | if (state2.name.isNotEmpty && state2.password.isNotEmpty) { 42 | yield state2.copyWith(login2progress: Login2Progress.isRequesting); 43 | await Future.delayed(Duration(seconds: 2)); 44 | yield state2.copyWith(login2progress: Login2Progress.success); 45 | 46 | yield state2.copyWith(login2progress: Login2Progress.init); 47 | } 48 | } on Exception catch (e) { 49 | yield state2.copyWith(login2progress: Login2Progress.error); 50 | } 51 | } 52 | } 53 | -------------------------------------------------------------------------------- /lib/tips/bloc/login_bloc/bloc/login_blocs.dart: -------------------------------------------------------------------------------- 1 | export 'login_bloc.dart'; 2 | 3 | /// 4 | /// Created by fgyong on 2020/8/20. 5 | /// 6 | -------------------------------------------------------------------------------- /lib/tips/bloc/login_bloc/bloc/login_event.dart: -------------------------------------------------------------------------------- 1 | part of '../bloc/login_bloc.dart'; 2 | 3 | /// 4 | /// Created by fgyong on 2020/8/20. 5 | /// 6 | /// 登陆相关的事件 7 | abstract class LoginEvent extends Equatable { 8 | const LoginEvent(); 9 | @override 10 | List get props => []; 11 | } 12 | 13 | /// 修改密码 14 | class LoginChagnePassword extends LoginEvent { 15 | final String password; 16 | const LoginChagnePassword({this.password}); 17 | @override 18 | List get props => [password]; 19 | } 20 | 21 | /// 修改账户 22 | class LoginChagneName extends LoginEvent { 23 | final String name; 24 | const LoginChagneName({this.name}); 25 | @override 26 | List get props => [name]; 27 | } 28 | 29 | /// 提交事件 30 | class LoginSubmitted extends LoginEvent { 31 | const LoginSubmitted(); 32 | @override 33 | List get props => []; 34 | } 35 | -------------------------------------------------------------------------------- /lib/tips/bloc/login_bloc/bloc/login_state.dart: -------------------------------------------------------------------------------- 1 | part of 'login_bloc.dart'; 2 | 3 | /// 4 | /// Created by fgyong on 2020/8/19. 5 | /// 6 | /// 事件变更状态[正在请求,报错,登陆成功,初始化] 7 | enum Login2Progress { isRequesting, error, success, init } 8 | 9 | /// 存储数据的model 在[bloc]中称作[state] 10 | class LoginState2 extends Equatable { 11 | final String name; 12 | final String password; 13 | final Login2Progress progress; 14 | LoginState2({this.name, this.password, this.progress = Login2Progress.init}); 15 | @override 16 | List get props => [name, password, btnVisiable, progress]; 17 | LoginState2 copyWith( 18 | {String name, String pwd, Login2Progress login2progress}) { 19 | return LoginState2( 20 | name: name ?? this.name, 21 | password: pwd ?? this.password, 22 | progress: login2progress ?? this.progress); 23 | } 24 | 25 | /// 使用 [UserName] &&[UserPassword]来校验规则 26 | bool get btnVisiable => nameVisiable && passwordVisiable; 27 | bool get nameVisiable => UserName(name).visiable; 28 | bool get passwordVisiable => UserPassword(password).visiable; 29 | 30 | /// 是否展示名字错误信息 31 | 32 | bool get showNameErrorText { 33 | if (name?.isEmpty ?? true) return false; 34 | return nameVisiable == false; 35 | } 36 | 37 | /// 是否展示密码错误信息 38 | bool get showPasswordErrorText { 39 | if (password?.isEmpty ?? true) return false; 40 | return passwordVisiable == false; 41 | } 42 | 43 | @override 44 | String toString() { 45 | return '$props'; 46 | } 47 | } 48 | -------------------------------------------------------------------------------- /lib/tips/bloc/login_bloc/login_bloc_page.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/cupertino.dart'; 2 | import 'package:flutter/material.dart'; 3 | import 'package:flutter_bloc/flutter_bloc.dart'; 4 | import 'package:fluttertest01/tips/bloc/login_bloc/bloc/login_bloc.dart'; 5 | import 'package:fluttertest01/tips/bloc/login_bloc/view/login2_view.dart'; 6 | 7 | /// 8 | /// Created by fgyong on 2020/8/19. 9 | /// 10 | /// 使用[bloc]完成的登陆功能 11 | class LoginBlocRoute extends StatelessWidget { 12 | @override 13 | Widget build(BuildContext context) { 14 | return BlocProvider( 15 | child: BaseLogin2Page(), 16 | create: (_) => LoginBloc(LoginState2()), 17 | ); 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /lib/tips/bloc/login_bloc/model/login2_model.dart: -------------------------------------------------------------------------------- 1 | import 'package:equatable/equatable.dart'; 2 | 3 | /// 4 | /// Created by fgyong on 2020/8/19. 5 | /// 6 | abstract class UserAction { 7 | final String value; 8 | const UserAction(this.value); 9 | bool get visiable; 10 | } 11 | 12 | class UserName extends UserAction { 13 | UserName(String value) : super(value); 14 | 15 | /// 这里可以写校验规则 16 | @override 17 | bool get visiable { 18 | /// 名字长度大于3 符合要求 19 | 20 | return (value?.isNotEmpty ?? false) ? value.length > 3 : false; 21 | } 22 | } 23 | 24 | class UserPassword extends UserAction { 25 | UserPassword(String value) : super(value); 26 | 27 | /// 这里可以写校验规则 28 | @override 29 | bool get visiable { 30 | /// 密码长度大于3 符合要求 31 | 32 | return (value?.isNotEmpty ?? false) ? value.length > 1 : false; 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /lib/tips/bloc/login_bloc/model/login_models.dart: -------------------------------------------------------------------------------- 1 | export 'login2_model.dart'; 2 | 3 | /// 4 | /// Created by fgyong on 2020/8/20. 5 | /// 6 | -------------------------------------------------------------------------------- /lib/tips/bloc/login_cubit/bloc_observer/bloc_observer.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/cupertino.dart'; 2 | import 'package:flutter/foundation.dart'; 3 | import 'package:flutter/material.dart'; 4 | import 'package:flutter_bloc/flutter_bloc.dart'; 5 | 6 | /// 7 | /// Created by fgyong on 2020/8/19. 8 | /// 9 | 10 | class DefaultBlocObserver extends BlocObserver { 11 | @override 12 | void onChange(Cubit cubit, Change change) { 13 | if (kDebugMode) 14 | print( 15 | '${cubit.toString()} new:${change.toString()} old:${cubit.state.toString()}'); 16 | super.onChange(cubit, change); 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /lib/tips/bloc/login_cubit/cubit/base_login_cubit.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter_bloc/flutter_bloc.dart'; 2 | import 'package:fluttertest01/tips/bloc/login_cubit/model/base_login_model.dart'; 3 | import 'package:equatable/equatable.dart'; 4 | 5 | /// 6 | /// Created by fgyong on 2020/8/19. 7 | /// 8 | 9 | class LoginCubit extends Cubit { 10 | LoginCubit(state) : super(state); 11 | void login() async { 12 | emit(state.copyWith(loginState: LoginState.isLoading)); 13 | await Future.delayed(Duration(seconds: 2)); 14 | if (state.btnVisiable == true) 15 | emit(state.copyWith(loginState: LoginState.success)); 16 | emit(state.copyWith(loginState: LoginState.faild)); 17 | } 18 | 19 | void logOut() async { 20 | emit(state.copyWith( 21 | name: null, 22 | pwd: null, 23 | )); 24 | } 25 | 26 | void changeName({String name}) { 27 | emit(state.copyWith( 28 | name: name, pwd: state.password, loginState: state.state)); 29 | } 30 | 31 | void changePassword({String pwd}) { 32 | emit(state.copyWith(name: state.name, pwd: pwd, loginState: state.state)); 33 | } 34 | 35 | /// 36 | /// 把所有之间集中于一个函数,只用不同的class来区分事件 37 | /// 类似 mapToState 38 | void handleLoginEvents(LoginEvent event) { 39 | switch (event.runtimeType) { 40 | case LoginCubitChagneName: 41 | emit(state.copyWith(name: (event as LoginCubitChagneName).name)); 42 | break; 43 | case LoginCubitChagnePassword: 44 | emit(state.copyWith(pwd: (event as LoginCubitChagnePassword).password)); 45 | break; 46 | case LoginCubitSubmitted: 47 | emit(state.copyWith(loginState: LoginState.isLoading)); 48 | Future.delayed(Duration(seconds: 2)).then((_) { 49 | emit(state.copyWith( 50 | loginState: state.btnVisiable == true 51 | ? LoginState.success 52 | : LoginState.faild)); 53 | }); 54 | break; 55 | } 56 | } 57 | } 58 | 59 | /// 登陆相关的事件 60 | abstract class LoginEvent extends Equatable { 61 | const LoginEvent(); 62 | @override 63 | List get props => []; 64 | } 65 | 66 | /// 修改密码 67 | class LoginCubitChagnePassword extends LoginEvent { 68 | final String password; 69 | const LoginCubitChagnePassword({this.password}); 70 | @override 71 | List get props => [password]; 72 | } 73 | 74 | /// 修改账户 75 | class LoginCubitChagneName extends LoginEvent { 76 | final String name; 77 | const LoginCubitChagneName({this.name}); 78 | @override 79 | List get props => [name]; 80 | } 81 | 82 | /// 提交事件 83 | class LoginCubitSubmitted extends LoginEvent { 84 | const LoginCubitSubmitted(); 85 | @override 86 | List get props => []; 87 | } 88 | -------------------------------------------------------------------------------- /lib/tips/bloc/login_cubit/cubit/cubit.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/cupertino.dart'; 2 | import 'package:flutter/material.dart'; 3 | export 'base_login_cubit.dart'; 4 | 5 | /// 6 | /// Created by fgyong on 2020/8/20. 7 | /// 8 | -------------------------------------------------------------------------------- /lib/tips/bloc/login_cubit/model/base_login_model.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/cupertino.dart'; 2 | import 'package:flutter/material.dart'; 3 | import 'package:equatable/equatable.dart'; 4 | 5 | /// 6 | /// Created by fgyong on 2020/8/19. 7 | /// 8 | enum LoginState { 9 | success, 10 | faild, 11 | isLoading, 12 | } 13 | enum BtnState { available, unAvailable } 14 | 15 | class LoginModel extends Equatable { 16 | final String name; 17 | final String password; 18 | final LoginState state; 19 | LoginModel({this.name, this.password, this.state}); 20 | @override 21 | List get props => [name, password, state, btnVisiable]; 22 | LoginModel copyWith({String name, String pwd, LoginState loginState}) { 23 | return LoginModel( 24 | name: name ?? this.name, 25 | password: pwd ?? this.password, 26 | state: loginState ?? this.state); 27 | } 28 | 29 | bool get btnVisiable => 30 | (password?.isNotEmpty ?? false) && (name?.isNotEmpty ?? false); 31 | @override 32 | String toString() { 33 | return '$props'; 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /lib/tips/bloc/login_cubit/model/login_cubit_models.dart: -------------------------------------------------------------------------------- 1 | export 'base_login_model.dart'; 2 | 3 | /// 4 | /// Created by fgyong on 2020/8/20. 5 | /// 6 | -------------------------------------------------------------------------------- /lib/tips/bloc/login_cubit/page/base_login_page.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/cupertino.dart'; 2 | import 'package:flutter/material.dart'; 3 | import 'package:flutter_bloc/flutter_bloc.dart'; 4 | import '../../base_login_cubit.dart'; 5 | 6 | /// 7 | /// Created by fgyong on 2020/8/19. 8 | /// 9 | class BaseLoginPageRoute extends StatelessWidget { 10 | @override 11 | Widget build(BuildContext context) { 12 | return BlocProvider( 13 | create: (_) => LoginCubit(LoginModel()), 14 | child: BaseLoginPage(), 15 | ); 16 | } 17 | 18 | static String routeName = '/BaseLoginPageRoute'; 19 | MaterialPageRoute get route => 20 | MaterialPageRoute(builder: (_) => BaseLoginPageRoute()); 21 | } 22 | -------------------------------------------------------------------------------- /lib/tips/bloc/login_cubit/page/login_pages.dart: -------------------------------------------------------------------------------- 1 | export 'base_login_page.dart'; 2 | 3 | /// 4 | /// Created by fgyong on 2020/8/20. 5 | /// 6 | -------------------------------------------------------------------------------- /lib/tips/bloc/login_cubit/view/login_views.dart: -------------------------------------------------------------------------------- 1 | export 'base_login_view.dart'; 2 | 3 | /// 4 | /// Created by fgyong on 2020/8/20. 5 | /// 6 | -------------------------------------------------------------------------------- /lib/tips/channel/base_channel.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/cupertino.dart'; 2 | import 'package:flutter/material.dart'; 3 | import 'package:flutter/services.dart'; 4 | 5 | /// 6 | /// Created by fgyong on 2020/9/7. 7 | /// 8 | 9 | class BaseChannelRoute extends StatefulWidget { 10 | BaseChannelRoute({Key key}) : super(key: key); 11 | 12 | @override 13 | _BaseChannelRouteState createState() => _BaseChannelRouteState(); 14 | static String get routeName => 'BaseChannelRoute'; 15 | } 16 | 17 | class _BaseChannelRouteState extends State { 18 | static const platform = const MethodChannel('samples.flutter.io/battery'); 19 | @override 20 | Widget build(BuildContext context) { 21 | return Scaffold( 22 | appBar: AppBar( 23 | title: Text('获取电量'), 24 | ), 25 | body: _body(), 26 | ); 27 | } 28 | 29 | String _string = ''; 30 | Widget _body() { 31 | return Column( 32 | children: [ 33 | OutlineButton( 34 | child: Text('获取电量'), 35 | onPressed: _get, 36 | ), 37 | Text('$_string') 38 | ], 39 | ); 40 | } 41 | 42 | Future _get() async { 43 | try { 44 | final int result = await platform.invokeMethod('getBatteryLevel'); 45 | setState(() { 46 | _string = result.toString(); 47 | }); 48 | } on PlatformException catch (e) { 49 | print('$e'); 50 | } 51 | } 52 | } 53 | -------------------------------------------------------------------------------- /lib/tips/fish_redux_page.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/cupertino.dart'; 2 | import 'package:flutter/material.dart'; 3 | 4 | /// 5 | /// Created by fgyong on 2020/8/17. 6 | /// 7 | 8 | class BaseFishReduxPage extends StatefulWidget { 9 | BaseFishReduxPage({Key key}) : super(key: key); 10 | 11 | @override 12 | _BaseFishReduxPageState createState() => _BaseFishReduxPageState(); 13 | static String routeName = "/BaseFishReduxPage"; 14 | } 15 | 16 | class _BaseFishReduxPageState extends State { 17 | @override 18 | Widget build(BuildContext context) { 19 | return Scaffold( 20 | appBar: AppBar( 21 | title: Text('Fish'), 22 | ), 23 | body: _body(), 24 | ); 25 | } 26 | 27 | Widget _body() {} 28 | } 29 | -------------------------------------------------------------------------------- /lib/tips/get/get_increment_page.dart: -------------------------------------------------------------------------------- 1 | import 'dart:async'; 2 | 3 | import 'package:flutter/material.dart'; 4 | import 'package:get/get.dart'; 5 | 6 | class GetIncrementPage extends StatefulWidget { 7 | GetIncrementPage({Key key}) : super(key: key); 8 | 9 | @override 10 | _GetIncrementPageState createState() => _GetIncrementPageState(); 11 | } 12 | 13 | class _GetIncrementPageState extends State { 14 | @override 15 | Widget build(BuildContext context) { 16 | return Scaffold( 17 | appBar: AppBar( 18 | title: Text('get'), 19 | ), 20 | body: Container( 21 | alignment: Alignment.center, 22 | child: _body(), 23 | ), 24 | ); 25 | } 26 | 27 | Widget _body() { 28 | return Column( 29 | mainAxisAlignment: MainAxisAlignment.center, 30 | crossAxisAlignment: CrossAxisAlignment.center, 31 | children: [ 32 | Obx(() { 33 | var n = c.count.value.count.toString(); 34 | printInfo(info: '刷新了页面 get_数字变动了 $n'); 35 | return Text('当前值:$n'); 36 | }), 37 | OutlineButton( 38 | child: Text('get 数字加'), 39 | onPressed: c.increment, 40 | ), 41 | OutlineButton( 42 | child: Text('get 数字减'), 43 | onPressed: c.down, 44 | ), 45 | 46 | Obx(() { 47 | printInfo(info: '刷新了页面 get_obx_log1'); 48 | 49 | return Text('logObx:' + c.log.toString()); 50 | }), 51 | Obx(() { 52 | printInfo(info: '刷新了页面 get_obx_log2'); 53 | 54 | return Text(c.log2.toString()); 55 | }), 56 | OutlineButton( 57 | child: Text('get log 变化'), 58 | onPressed: c.change, 59 | ), 60 | 61 | // ObxValue((var value) => Text('${value.toString()}'), c), 62 | ], 63 | ); 64 | } 65 | 66 | @override 67 | void dispose() { 68 | Get.delete(); 69 | super.dispose(); 70 | } 71 | 72 | final Controller2 c = Get.put(Controller2()); 73 | } 74 | 75 | class Test extends StatefulWidget { 76 | @override 77 | State createState() => _Test(); 78 | } 79 | 80 | class _Test extends State { 81 | @override 82 | Widget build(BuildContext context) { 83 | return Container( 84 | child: Text('$value'), 85 | ); 86 | } 87 | 88 | var value; 89 | 90 | StreamController subject; 91 | StreamSubscription streamSubscription; 92 | @override 93 | void initState() { 94 | subject = StreamController.broadcast(); 95 | streamSubscription = subject.stream.listen((event) { 96 | setState(() {}); 97 | }); 98 | super.initState(); 99 | } 100 | 101 | @override 102 | void dispose() { 103 | subject.close(); 104 | streamSubscription.cancel(); 105 | super.dispose(); 106 | } 107 | 108 | var nu = 0; 109 | add() { 110 | nu++; 111 | value = 'event$nu'; 112 | subject.add(value); 113 | ''.obs.value = '123'; 114 | } 115 | } 116 | 117 | /// 118 | /// Created by fgyong on 2020/10/22. 119 | /// 120 | 121 | class Controller2 extends GetxController { 122 | var count = NumberCount().obs; 123 | var count2 = 0.obs; 124 | 125 | final log = ''.obs; 126 | final log2 = ''.obs; 127 | 128 | increment() { 129 | count.value.increment(); 130 | count.refresh(); 131 | } 132 | 133 | down() { 134 | count.value.down(); 135 | count.refresh(); 136 | } 137 | 138 | @override 139 | void onClose() { 140 | printInfo(info: 'Controller close'); 141 | super.onClose(); 142 | } 143 | 144 | void change() { 145 | log.value += ' ${log.value.length}'; 146 | } 147 | } 148 | 149 | class NumberCount { 150 | var count = 0.obs; 151 | increment() { 152 | count++; 153 | } 154 | 155 | down() { 156 | count--; 157 | } 158 | } 159 | -------------------------------------------------------------------------------- /lib/tips/get/get_route.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/material.dart'; 2 | import 'package:get/get.dart'; 3 | 4 | class GetRoute extends StatefulWidget { 5 | GetRoute({Key key}) : super(key: key); 6 | 7 | @override 8 | _GetRouteState createState() => _GetRouteState(); 9 | static String get routeName => "GetRoute"; 10 | } 11 | 12 | class _GetRouteState extends State { 13 | @override 14 | Widget build(BuildContext context) { 15 | return Scaffold( 16 | appBar: AppBar( 17 | title: Text('路由跳转'), 18 | ), 19 | body: Center( 20 | child: Column( 21 | children: [ 22 | OutlineButton( 23 | child: Text('to 下一个页面'), 24 | onPressed: _to, 25 | ), 26 | OutlineButton( 27 | child: Text('back 返回'), 28 | onPressed: _back, 29 | ), 30 | OutlineButton( 31 | child: Text('off 替换当前路由'), 32 | onPressed: _off, 33 | ), 34 | OutlineButton( 35 | child: Text('offAll 返回到顶部'), 36 | onPressed: _offAll, 37 | ), 38 | OutlineButton( 39 | child: Text('off Until 返回到符合条件的路由'), 40 | onPressed: _offUntil, 41 | ), 42 | ], 43 | ), 44 | ), 45 | ); 46 | } 47 | 48 | /// 新打开页面 49 | void _to() { 50 | Get.to(GetRoute(), 51 | preventDuplicates: false, transition: Transition.topLevel, duration: Duration(seconds: 1)); 52 | } 53 | 54 | /// 返回 55 | void _back() { 56 | Get.back(); 57 | } 58 | 59 | void _off() { 60 | Get.off(GetRoute(), preventDuplicates: false); 61 | } 62 | 63 | void _offAll() { 64 | Get.offAll(GetRoute()); 65 | } 66 | 67 | void _offUntil() { 68 | Get.offUntil(MaterialPageRoute(builder: (_) => GetRoute()), (route) => false); 69 | } 70 | } 71 | 72 | class GetRouteController extends GetxController {} 73 | -------------------------------------------------------------------------------- /lib/tips/hive/base_hive.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/cupertino.dart'; 2 | import 'package:flutter/material.dart'; 3 | import 'package:fluttertest01/tips/hive/hive_person.dart'; 4 | import 'package:hive/hive.dart'; 5 | import 'package:path_provider/path_provider.dart'; 6 | import 'dart:core'; 7 | 8 | /// 9 | /// Created by fgyong on 2020/10/10. 10 | /// 11 | class BaseHive extends StatefulWidget { 12 | @override 13 | State createState() { 14 | return _BaseHive(); 15 | } 16 | 17 | static String get routeName => '/BaseHive'; 18 | } 19 | 20 | class _BaseHive extends State { 21 | @override 22 | Widget build(BuildContext context) { 23 | return Scaffold( 24 | appBar: AppBar( 25 | title: Text('hive'), 26 | ), 27 | body: Center( 28 | child: Column( 29 | children: [ 30 | OutlineButton( 31 | child: Text('add'), 32 | onPressed: add, 33 | ), 34 | OutlineButton( 35 | child: Text('查询'), 36 | onPressed: _query, 37 | ), 38 | OutlineButton( 39 | child: Text('清空'), 40 | onPressed: _clear, 41 | ), 42 | ], 43 | ), 44 | ), 45 | ); 46 | } 47 | 48 | void _clear() async { 49 | // if (Hive.isBoxOpen('testBox') == false) { 50 | // await Hive.openBox('testBox', path: (await getTemporaryDirectory()).path); 51 | // } 52 | // var box = await Hive.box('testBox'); 53 | // await box.deleteFromDisk(); 54 | // Symbol lib = new Symbol('Person_lib'); 55 | // Symbol className = Symbol('Person'); 56 | } 57 | 58 | // void testSymbol(Symbol lib, Symbol className) {} 59 | 60 | void add() async { 61 | if (Hive.isAdapterRegistered(PersonAdapter().typeId) == false) { 62 | Hive.registerAdapter(PersonAdapter()); 63 | } 64 | if (Hive.isBoxOpen('testBox') == false) { 65 | await Hive.openBox('testBox', path: (await getTemporaryDirectory()).path); 66 | } 67 | var box = await Hive.box('testBox'); 68 | 69 | box.put('name', 'David'); 70 | box.add(Person('laowng')); 71 | 72 | box.add(Person('老李')); 73 | 74 | print('Name: ${box.get('name')}'); 75 | await box.close(); 76 | // printLog(); 77 | } 78 | 79 | void _query() async { 80 | if (Hive.isBoxOpen('testBox') == false) { 81 | await Hive.close(); 82 | await Hive.openBox('testBox', 83 | path: (await getTemporaryDirectory()).path); 84 | } 85 | 86 | var box = Hive.box('testBox'); 87 | 88 | box.values.forEach((element) { 89 | print('${element.toString()}'); 90 | }); 91 | } 92 | 93 | void printLog() async { 94 | var box = await Hive.openBox('testBox', 95 | path: (await getTemporaryDirectory()).path); 96 | print('${box.path}'); 97 | box.values.forEach((element) { 98 | print('${element.toString()}'); 99 | }); 100 | } 101 | 102 | @override 103 | void initState() { 104 | super.initState(); 105 | } 106 | } 107 | -------------------------------------------------------------------------------- /lib/tips/hive/hive_person.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/cupertino.dart'; 2 | import 'package:flutter/material.dart'; 3 | 4 | /// 5 | /// Created by fgyong on 2020/10/10. 6 | /// 7 | 8 | import 'package:hive/hive.dart'; 9 | import 'package:json_annotation/json_annotation.dart'; 10 | 11 | @HiveType(typeId: 1) 12 | @HiveType() 13 | class Person extends HiveObject { 14 | @HiveField(0) 15 | String name; 16 | 17 | Person(this.name); 18 | } 19 | 20 | class PersonAdapter extends TypeAdapter { 21 | @override 22 | Person read(BinaryReader reader) { 23 | return Person(reader.read()); 24 | } 25 | 26 | @override 27 | int get typeId => 2; 28 | 29 | @override 30 | void write(BinaryWriter writer, Person obj) { 31 | writer.write(obj.name); 32 | // writer.write(obj.age); 33 | // writer.write(obj.friends); 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /lib/tips/img/base_img.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/cupertino.dart'; 2 | import 'package:flutter/material.dart'; 3 | 4 | /// 5 | /// Created by fgyong on 2020/9/2. 6 | /// 7 | 8 | class BaseImagePage extends StatefulWidget { 9 | BaseImagePage({Key key}) : super(key: key); 10 | 11 | @override 12 | _BaseImagePageState createState() => _BaseImagePageState(); 13 | static String get routeName => '/BaseImagePage'; 14 | } 15 | 16 | class _BaseImagePageState extends State { 17 | @override 18 | Widget build(BuildContext context) { 19 | return Scaffold( 20 | appBar: AppBar( 21 | title: Text('图片加载'), 22 | ), 23 | body: _body(), 24 | ); 25 | } 26 | 27 | Widget _body() { 28 | Image widget = Image.asset('img/2.png'); 29 | print('${widget.width} ${widget.height}'); 30 | print('${widget.toString()}'); 31 | return Center( 32 | child: Image.asset('img/2.png'), 33 | ); 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /lib/tips/layout/base_layout.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/cupertino.dart'; 2 | import 'package:flutter/material.dart'; 3 | 4 | /// 5 | /// Created by fgyong on 2020/8/21. 6 | /// 7 | 8 | class BaseLayoutPage extends StatefulWidget { 9 | BaseLayoutPage({Key key}) : super(key: key); 10 | 11 | @override 12 | _BaseLayoutPageState createState() => _BaseLayoutPageState(); 13 | static String get routeName => '/_BaseLayoutPageState'; 14 | } 15 | 16 | class _BaseLayoutPageState extends State { 17 | @override 18 | Widget build(BuildContext context) { 19 | return Scaffold( 20 | appBar: AppBar( 21 | title: Text(''), 22 | ), 23 | body: _body(), 24 | ); 25 | } 26 | 27 | Widget _body() { 28 | return Column( 29 | children: [ 30 | Container( 31 | // width: 100, 32 | // height: 100, 33 | child: LayoutBuilder( 34 | builder: (BuildContext context, BoxConstraints constraints) { 35 | print('$constraints'); 36 | return Text('constraints'); 37 | }, 38 | ), 39 | ) 40 | ], 41 | ); 42 | } 43 | } 44 | -------------------------------------------------------------------------------- /lib/tips/page_view.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/cupertino.dart'; 2 | import 'package:flutter/material.dart'; 3 | import 'package:fluttertest01/tips/Tabbar.dart'; 4 | 5 | /// 6 | /// Created by fgyong on 2020/8/3. 7 | /// 8 | class BasePageViewRoute extends StatefulWidget { 9 | BasePageViewRoute({Key key}) : super(key: key); 10 | 11 | @override 12 | _BasePageViewRouteState createState() => _BasePageViewRouteState(); 13 | } 14 | 15 | class _BasePageViewRouteState extends State { 16 | @override 17 | Widget build(BuildContext context) { 18 | return Scaffold( 19 | appBar: AppBar( 20 | title: Text('pageView'), 21 | ), 22 | body: _body(), 23 | ); 24 | } 25 | 26 | int hightIndex = 0; 27 | Widget _body() { 28 | return TabbarViewTWO( 29 | callback: _changeIndex, 30 | hightIndex: hightIndex, 31 | child: PageView( 32 | pageSnapping: true, 33 | controller: _pageController, 34 | onPageChanged: (index) { 35 | _pageController.jumpToPage(index); 36 | }, 37 | children: [ 38 | Text('1'), 39 | Text('2'), 40 | ], 41 | ), 42 | leftTitle: 'left', 43 | rightTitle: 'right', 44 | leftNumber: 0, 45 | rightNumber: 0, 46 | ); 47 | } 48 | 49 | void _changeIndex(int index) { 50 | _pageController.jumpToPage(index); 51 | setState(() { 52 | hightIndex = index; 53 | }); 54 | } 55 | 56 | PageController _pageController; 57 | @override 58 | void initState() { 59 | _pageController = PageController(); 60 | super.initState(); 61 | } 62 | } 63 | -------------------------------------------------------------------------------- /lib/tips/provider/base_stream_pge.dart: -------------------------------------------------------------------------------- 1 | import 'dart:async'; 2 | 3 | import 'package:flutter/cupertino.dart'; 4 | import 'package:flutter/material.dart'; 5 | import 'package:provider/provider.dart'; 6 | 7 | /// 8 | /// Created by fgyong on 2020/8/20. 9 | /// 10 | 11 | class BaseProviderStreamRoute extends StatelessWidget { 12 | BaseProviderStreamRoute({Key key}) : super(key: key); 13 | 14 | static MaterialPageRoute get pageRoute => 15 | MaterialPageRoute(builder: (_) => _BaseProviderStreamRoute2()); 16 | @override 17 | Widget build(BuildContext context) { 18 | return ChangeNotifierProvider( 19 | create: (_) => _ModelStream(), 20 | lazy: false, 21 | builder: (context, child) { 22 | return _BaseProviderStreamRoute2(); 23 | }, 24 | ); 25 | } 26 | } 27 | 28 | class _BaseProviderStreamRoute2 extends StatelessWidget { 29 | @override 30 | Widget build(BuildContext context) { 31 | _ModelStream stream = context.read<_ModelStream>(); 32 | return StreamProvider.value( 33 | value: stream.firstStream, 34 | lazy: false, 35 | initialData: 0, 36 | child: _BaseProviderStreamRoute(), 37 | ); 38 | } 39 | } 40 | 41 | class _BaseProviderStreamRoute extends StatefulWidget { 42 | @override 43 | State createState() { 44 | return __BaseProviderStream(); 45 | } 46 | } 47 | 48 | class __BaseProviderStream extends State<_BaseProviderStreamRoute> { 49 | @override 50 | Widget build(BuildContext context) { 51 | return Scaffold( 52 | appBar: AppBar( 53 | title: Text('定时器'), 54 | ), 55 | body: Center( 56 | child: Column( 57 | mainAxisAlignment: MainAxisAlignment.center, 58 | children: [ 59 | Text('${context.select((value) => value.toString())}'), 60 | OutlineButton( 61 | child: Text('stop'), 62 | onPressed: () {}, 63 | ) 64 | ], 65 | ), 66 | ), 67 | ); 68 | } 69 | } 70 | 71 | class _ModelStream extends ChangeNotifier { 72 | StreamController _streamController; 73 | Timer _timer; 74 | int count = 0; 75 | _ModelStream() { 76 | _streamController = StreamController(); 77 | initTimer(); 78 | } 79 | void initTimer() { 80 | _timer = Timer.periodic(Duration(seconds: 1), (timer) { 81 | _streamController.add(count++); 82 | }); 83 | } 84 | 85 | Stream get firstStream => _streamController.stream; 86 | void add() { 87 | _streamController.add(1); 88 | } 89 | 90 | void reset() { 91 | count = 0; 92 | } 93 | 94 | @override 95 | void dispose() { 96 | _timer?.cancel(); 97 | _timer = null; 98 | super.dispose(); 99 | } 100 | } 101 | 102 | class _ValueModel { 103 | final int value; 104 | const _ValueModel({this.value}); 105 | 106 | @override 107 | bool operator ==(Object other) => 108 | identical(this, other) || 109 | other is _ValueModel && 110 | runtimeType == other.runtimeType && 111 | value == other.value; 112 | 113 | @override 114 | int get hashCode => value.hashCode; 115 | 116 | _ValueModel.name(this.value); 117 | } 118 | -------------------------------------------------------------------------------- /lib/tips/revierpod/base_river_pod_list.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/material.dart'; 2 | import 'package:flutter_hooks/flutter_hooks.dart'; 3 | 4 | class RiverPodListRoute extends HookWidget { 5 | @override 6 | Widget build(BuildContext context) { 7 | return Scaffold( 8 | appBar: AppBar( 9 | title: Text('list'), 10 | ), 11 | body: Center( 12 | child: Text('center'), 13 | ), 14 | ); 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /lib/tips/rx_dart/base_rxDart.dart: -------------------------------------------------------------------------------- 1 | import 'dart:async'; 2 | import 'dart:ffi'; 3 | 4 | import 'package:flutter/cupertino.dart'; 5 | import 'package:flutter/material.dart'; 6 | import 'package:rxdart/rxdart.dart'; 7 | 8 | /// 9 | /// Created by fgyong on 2020/8/24. 10 | /// 11 | 12 | class BaseDartPage extends StatefulWidget { 13 | BaseDartPage({Key key}) : super(key: key); 14 | 15 | @override 16 | _BaseDartPageState createState() => _BaseDartPageState(); 17 | static String get routeName => '/BaseDartPage'; 18 | } 19 | 20 | class _BaseDartPageState extends State { 21 | @override 22 | Widget build(BuildContext context) { 23 | return Scaffold( 24 | appBar: AppBar( 25 | title: Text('Stream'), 26 | ), 27 | body: _body(), 28 | ); 29 | } 30 | 31 | Widget _body() { 32 | return Center( 33 | child: Column( 34 | children: [ 35 | TextField( 36 | onChanged: (v) { 37 | _streamController.add(v); 38 | }, 39 | ) 40 | ], 41 | ), 42 | ); 43 | } 44 | 45 | StreamController _streamController; 46 | PublishSubject _subject; 47 | StreamSubscription _subscription; 48 | @override 49 | void initState() { 50 | _streamController = StreamController(); 51 | // _subscription =StreamSubscription() 52 | _streamController.stream.listen((event) {}); 53 | _streamController.add('data'); 54 | // _subject = PublishSubject(); 55 | // _subject.stream..where((event) => event.length < 5); 56 | // 57 | // _subject.add('str'); 58 | 59 | // Rx.repeat((repeatIndex) => Stream.value(repeatIndex)).listen((event) { 60 | // print(event); 61 | // }); 62 | // Rx.timer(0, Duration(seconds: 1)).listen((event) { 63 | // print(event); 64 | // }); 65 | print(Zone.root.toString()); 66 | super.initState(); 67 | } 68 | } 69 | -------------------------------------------------------------------------------- /lib/tips/scoped_page.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/cupertino.dart'; 2 | import 'package:flutter/material.dart'; 3 | import 'package:scoped_model/scoped_model.dart'; 4 | 5 | /// 6 | /// Created by fgyong on 2020/8/12. 7 | /// 8 | 9 | class BaseScopedPateRoute extends StatelessWidget { 10 | @override 11 | Widget build(BuildContext context) { 12 | return ScopedModel<_BaseModel>( 13 | model: _BaseModel(), 14 | child: ScopedModel<_BaseModel2>( 15 | model: _BaseModel2(), 16 | child: _body(), 17 | ), 18 | ); 19 | } 20 | 21 | static String get routeName => 'BaseScopedPate'; 22 | 23 | Widget _body() => BaseScopedPate(); 24 | } 25 | 26 | class BaseScopedPate extends StatefulWidget { 27 | BaseScopedPate({Key key}) : super(key: key); 28 | 29 | @override 30 | _BaseScopedPateState createState() => _BaseScopedPateState(); 31 | } 32 | 33 | class _BaseScopedPateState extends State { 34 | String _build = ''; 35 | @override 36 | Widget build(BuildContext context) { 37 | _build += 'p1 build \n'; 38 | return Scaffold( 39 | appBar: AppBar( 40 | title: Text('ScopedModel'), 41 | ), 42 | body: Center( 43 | child: Column( 44 | mainAxisAlignment: MainAxisAlignment.center, 45 | children: [ 46 | Text(_build), 47 | ScopedModelDescendant<_BaseModel>( 48 | builder: (context, child, model) { 49 | _build += 'b1 '; 50 | 51 | return Center( 52 | child: Text('${model.count}'), 53 | ); 54 | }, 55 | child: Text('外部小部件'), 56 | ), 57 | ScopedModelDescendant<_BaseModel2>( 58 | builder: (context, child, model) { 59 | _build += 'b2 '; 60 | 61 | return Center( 62 | child: Text('${model.count}'), 63 | ); 64 | }, 65 | child: Text('外部小部件'), 66 | ), 67 | OutlineButton( 68 | child: Icon(Icons.add), 69 | onPressed: () { 70 | ScopedModel.of<_BaseModel>(context).add(1); 71 | }, 72 | ), 73 | OutlineButton( 74 | child: Text('-'), 75 | onPressed: () { 76 | ScopedModel.of<_BaseModel2>(context).add(-1); 77 | }, 78 | ), 79 | Row( 80 | mainAxisAlignment: MainAxisAlignment.center, 81 | children: [ 82 | OutlineButton( 83 | child: Icon(Icons.refresh), 84 | onPressed: () { 85 | if (mounted) setState(() {}); 86 | }, 87 | ), 88 | OutlineButton( 89 | child: Icon(Icons.clear), 90 | onPressed: () { 91 | if (mounted) 92 | setState(() { 93 | _build = ''; 94 | }); 95 | }, 96 | ), 97 | ], 98 | ) 99 | ], 100 | ), 101 | )); 102 | } 103 | } 104 | 105 | class _BaseModel extends Model { 106 | int _count = 0; 107 | void add(int a) { 108 | _count += a; 109 | notifyListeners(); 110 | } 111 | 112 | int get count => _count; 113 | } 114 | 115 | class _BaseModel2 extends Model { 116 | int _count = 0; 117 | void add(int a) { 118 | _count += a; 119 | notifyListeners(); 120 | } 121 | 122 | int get count => _count; 123 | } 124 | -------------------------------------------------------------------------------- /lib/tips/touch/base_touch_handle.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/cupertino.dart'; 2 | import 'package:flutter/material.dart'; 3 | 4 | /// 5 | /// Created by fgyong on 2020/9/10. 6 | /// 7 | 8 | class BaseTouchHandlePage extends StatefulWidget { 9 | BaseTouchHandlePage({Key key}) : super(key: key); 10 | 11 | @override 12 | _BaseTouchHandlePageState createState() => _BaseTouchHandlePageState(); 13 | static String get routenName => "BaseTouchHandlePage"; 14 | } 15 | 16 | class _BaseTouchHandlePageState extends State { 17 | @override 18 | Widget build(BuildContext context) { 19 | return Scaffold( 20 | appBar: AppBar( 21 | title: Text('触摸事件流程探索'), 22 | ), 23 | body: _body(), 24 | ); 25 | } 26 | 27 | Widget _body() { 28 | return Center( 29 | child: GestureDetector( 30 | child: Container( 31 | child: Text('按压'), 32 | width: 100, 33 | height: 60, 34 | alignment: Alignment.center, 35 | color: Colors.orange, 36 | ), 37 | onTap: _onPress, 38 | ), 39 | ); 40 | } 41 | 42 | void _onPress() { 43 | print('object'); 44 | } 45 | } 46 | -------------------------------------------------------------------------------- /lib/u3d/u3d_page.dart: -------------------------------------------------------------------------------- 1 | /// 2 | /// Created by fgyong on 7/20/21. 3 | /// 4 | 5 | import 'package:flutter/cupertino.dart'; 6 | import 'package:flutter/material.dart'; 7 | 8 | class BaseU3DPage extends StatefulWidget { 9 | @override 10 | State createState() { 11 | return _BaseU3DPageState(); 12 | } 13 | 14 | static String get routeName => '/BaseU3DPage'; 15 | } 16 | 17 | class _BaseU3DPageState extends State { 18 | @override 19 | Widget build(BuildContext context) { 20 | return Scaffold( 21 | appBar: AppBar( 22 | title: Text('BaseU3DPage'), 23 | ), 24 | body: _body(), 25 | ); 26 | } 27 | 28 | Widget _body() { 29 | return Container( 30 | child: Text('123'), 31 | ); 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /lib/util.dart: -------------------------------------------------------------------------------- 1 | class Util { 2 | static int _maxLen = 128; 3 | static String _tagValue = ''; 4 | static void v(Object object, {String tag}) { 5 | log('$tag', ' e ', object); 6 | } 7 | 8 | static void log(String tag, String stag, Object object) { 9 | String da = object.toString(); 10 | tag = tag ?? _tagValue; 11 | if (da.length <= _maxLen) { 12 | print("$tag::$stag:: $da"); 13 | return; 14 | } 15 | print( 16 | '$tag::$stag ============================= log start ============================='); 17 | while (da.isNotEmpty) { 18 | if (da.length > _maxLen) { 19 | print("${da.substring(0, _maxLen)}"); 20 | da = da.substring(_maxLen, da.length); 21 | } else { 22 | print("$da"); 23 | da = ""; 24 | } 25 | } 26 | print( 27 | '$tag::$stag ============================= log end ============================='); 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /lib/video/base_video_ijk_page.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/cupertino.dart'; 2 | import 'package:flutter/material.dart'; 3 | import 'package:flutter_ijkplayer/flutter_ijkplayer.dart'; 4 | 5 | class BaseIJKVideoPage extends StatefulWidget { 6 | @override 7 | State createState() { 8 | return _HomePageState(); 9 | } 10 | 11 | static String get routeName => '/BaseIJKVideoPage'; 12 | } 13 | 14 | class _HomePageState extends State { 15 | IjkMediaController controller = IjkMediaController(); 16 | 17 | @override 18 | void initState() { 19 | controller = IjkMediaController(); 20 | index = 0; 21 | controller.ijkStatusStream.asBroadcastStream(onListen: (ijk) { 22 | print('ijkStatusStream: ${ijk.toString()}'); 23 | }); 24 | controller.textureIdStream.asBroadcastStream(onListen: (index) { 25 | print('textureIdStream: $index'); 26 | }); 27 | super.initState(); 28 | } 29 | 30 | @override 31 | void dispose() { 32 | controller.dispose(); 33 | super.dispose(); 34 | } 35 | 36 | @override 37 | Widget build(BuildContext context) { 38 | return Scaffold( 39 | appBar: AppBar( 40 | title: const Text('IJK video'), 41 | actions: [ 42 | IconButton( 43 | icon: Icon(Icons.store), 44 | onPressed: () {}, 45 | ), 46 | ], 47 | ), 48 | body: buildIjkPlayer(), 49 | floatingActionButton: FloatingActionButton( 50 | child: Icon(Icons.next_plan_outlined), 51 | onPressed: () async { 52 | await controller.setNetworkDataSource(url, autoPlay: true); 53 | print("set data source success"); 54 | // controller.playOrPause(); 55 | }, 56 | ), 57 | ); 58 | } 59 | 60 | int index = 0; 61 | String get url { 62 | index += 1; 63 | 64 | /// https://blog.csdn.net/suwu150/article/details/90345041 m3u8资源列表 65 | var list = [ 66 | 'https://vd3.bdstatic.com/mda-mc2t866ix18tmrbw/sc/cae_h264_clips/1614770378/mda-mc2t866ix18tmrbw.mp4', 67 | // 'https://vd2.bdstatic.com/mda-mdpdktv9j7dc629c/1080p/cae_h264/1619258626/mda-mdpdktv9j7dc629c.mp4', 68 | 'http://ivi.bupt.edu.cn/hls/cctv1hd.m3u8', 69 | 'http://ivi.bupt.edu.cn/hls/cctv2.m3u8', 70 | 'http://ivi.bupt.edu.cn/hls/cctv3hd.m3u8', 71 | 'http://ivi.bupt.edu.cn/hls/cctv4.m3u8', 72 | 'http://ivi.bupt.edu.cn/hls/cctv5phd.m3u8', 73 | ]; 74 | return list[index % (list.length)]; 75 | } 76 | 77 | Widget buildIjkPlayer() { 78 | return Center( 79 | child: Container( 80 | height: 400, // 这里随意 81 | child: IjkPlayer( 82 | mediaController: controller, 83 | ), 84 | ), 85 | ); 86 | } 87 | } 88 | -------------------------------------------------------------------------------- /test/widget_test.dart: -------------------------------------------------------------------------------- 1 | // This is a basic Flutter widget test. 2 | // 3 | // To perform an interaction with a widget in your test, use the WidgetTester 4 | // utility that Flutter provides. For example, you can send tap and scroll 5 | // gestures. You can also use WidgetTester to find child widgets in the widget 6 | // tree, read text, and verify that the values of widget properties are correct. 7 | 8 | import 'package:flutter/material.dart'; 9 | import 'package:flutter_test/flutter_test.dart'; 10 | 11 | import 'package:fluttertest01/main.dart'; 12 | 13 | void main() { 14 | testWidgets('Counter increments smoke test', (WidgetTester tester) async { 15 | // Build our app and trigger a frame. 16 | await tester.pumpWidget(MyApp()); 17 | 18 | // Verify that our counter starts at 0. 19 | expect(find.text('0'), findsOneWidget); 20 | expect(find.text('1'), findsNothing); 21 | 22 | // Tap the '+' icon and trigger a frame. 23 | await tester.tap(find.byIcon(Icons.add)); 24 | await tester.pump(); 25 | 26 | // Verify that our counter has incremented. 27 | expect(find.text('0'), findsNothing); 28 | expect(find.text('1'), findsOneWidget); 29 | }); 30 | } 31 | --------------------------------------------------------------------------------