├── .gitignore ├── .gradle ├── 6.1.1 │ ├── executionHistory │ │ ├── executionHistory.bin │ │ └── executionHistory.lock │ ├── fileChanges │ │ └── last-build.bin │ ├── fileHashes │ │ ├── fileHashes.bin │ │ └── fileHashes.lock │ └── gc.properties ├── buildOutputCleanup │ ├── buildOutputCleanup.lock │ ├── cache.properties │ └── outputFiles.bin ├── checksums │ ├── checksums.lock │ ├── md5-checksums.bin │ └── sha1-checksums.bin └── vcs-1 │ └── gc.properties ├── .metadata ├── README.en.md ├── README.md ├── analysis_options.yaml ├── android ├── .gitignore ├── app │ ├── build.gradle │ └── src │ │ ├── debug │ │ └── AndroidManifest.xml │ │ ├── main │ │ ├── AndroidManifest.xml │ │ ├── kotlin │ │ │ └── com │ │ │ │ └── flutter │ │ │ │ ├── demo │ │ │ │ └── MainActivity.kt │ │ │ │ └── flutter_demo │ │ │ │ └── MainActivity.kt │ │ └── res │ │ │ ├── drawable-v21 │ │ │ └── launch_background.xml │ │ │ ├── drawable │ │ │ └── launch_background.xml │ │ │ ├── mipmap-hdpi │ │ │ └── ic_launcher.png │ │ │ ├── mipmap-mdpi │ │ │ └── ic_launcher.png │ │ │ ├── mipmap-xhdpi │ │ │ └── ic_launcher.png │ │ │ ├── mipmap-xxhdpi │ │ │ └── ic_launcher.png │ │ │ ├── mipmap-xxxhdpi │ │ │ └── ic_launcher.png │ │ │ ├── values-night │ │ │ └── styles.xml │ │ │ └── values │ │ │ └── styles.xml │ │ └── profile │ │ └── AndroidManifest.xml ├── build.gradle ├── gradle.properties ├── gradle │ └── wrapper │ │ └── gradle-wrapper.properties └── settings.gradle ├── build.gradle ├── gradle └── wrapper │ ├── gradle-wrapper.jar │ └── gradle-wrapper.properties ├── gradlew ├── gradlew.bat ├── images ├── demo_image.png ├── duanwu.webp ├── error.png ├── flutter_logo.png ├── ht.png ├── icon_vip_fk.png ├── img.png ├── img_1.png ├── img_2.png ├── lbxx.png ├── logo_normal.png ├── zan.png └── zongzi.jpeg ├── ios ├── .gitignore ├── Flutter │ ├── 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 │ ├── AppIcon.appiconset │ │ ├── Contents.json │ │ ├── Icon-App-1024x1024@1x.png │ │ ├── Icon-App-20x20@1x.png │ │ ├── Icon-App-20x20@2x.png │ │ ├── Icon-App-20x20@3x.png │ │ ├── Icon-App-29x29@1x.png │ │ ├── Icon-App-29x29@2x.png │ │ ├── Icon-App-29x29@3x.png │ │ ├── Icon-App-40x40@1x.png │ │ ├── Icon-App-40x40@2x.png │ │ ├── Icon-App-40x40@3x.png │ │ ├── Icon-App-60x60@2x.png │ │ ├── Icon-App-60x60@3x.png │ │ ├── Icon-App-76x76@1x.png │ │ ├── Icon-App-76x76@2x.png │ │ └── Icon-App-83.5x83.5@2x.png │ └── LaunchImage.imageset │ │ ├── Contents.json │ │ ├── LaunchImage.png │ │ ├── LaunchImage@2x.png │ │ ├── LaunchImage@3x.png │ │ └── README.md │ ├── Base.lproj │ ├── LaunchScreen.storyboard │ └── Main.storyboard │ ├── Info.plist │ └── Runner-Bridging-Header.h ├── jsons └── user.json ├── lib ├── app.dart ├── common │ ├── global.dart │ ├── my_colors.dart │ ├── syntax_highlighter.dart │ ├── theme_common.dart │ └── widget.dart ├── dart │ └── dart_demo.dart ├── generated │ └── assets.dart ├── main.dart ├── models │ ├── app_theme.dart │ ├── car_item.dart │ ├── car_model.dart │ ├── home_bean.dart │ ├── name_bean.dart │ ├── news_list_bean.dart │ ├── qz_bean.dart │ ├── xf_res.dart │ └── xf_text_req.dart ├── pages │ ├── example_widget.dart │ ├── fucation_widget.dart │ ├── function │ │ ├── event │ │ │ ├── event_bus.dart │ │ │ ├── event_demo.dart │ │ │ ├── page_one.dart │ │ │ ├── page_three.dart │ │ │ └── page_two.dart │ │ ├── inherited_demo.dart │ │ ├── notification_demo.dart │ │ └── test_data.dart │ ├── home.dart │ ├── main_page.dart │ └── util_widget.dart ├── states │ ├── bloc │ │ ├── bloc_demo │ │ │ ├── bloc.dart │ │ │ ├── event.dart │ │ │ ├── state.dart │ │ │ └── view.dart │ │ └── cubit_demo │ │ │ └── cubit │ │ │ ├── cubit_cubit.dart │ │ │ ├── cubit_state.dart │ │ │ └── cubit_view.dart │ ├── bloc_demo.dart │ ├── change_notifier.dart │ ├── firm │ │ ├── provider.dart │ │ └── view.dart │ ├── getx │ │ ├── jump_page │ │ │ ├── jump_one │ │ │ │ ├── logic.dart │ │ │ │ └── view.dart │ │ │ └── jump_two │ │ │ │ ├── logic.dart │ │ │ │ └── view.dart │ │ ├── num │ │ │ ├── logic.dart │ │ │ ├── state.dart │ │ │ └── view.dart │ │ └── test │ │ │ ├── logic.dart │ │ │ ├── state.dart │ │ │ └── view.dart │ ├── provider │ │ └── p_num │ │ │ ├── provider.dart │ │ │ ├── state.dart │ │ │ └── view.dart │ ├── qqq_bloc.dart │ ├── qqq_event.dart │ └── qqq_state.dart ├── utils │ ├── bugly.dart │ ├── call_back.dart │ ├── sliver_to_widget.dart │ ├── socket_util.dart │ ├── sp_util.dart │ ├── status.dart │ ├── toast_util.dart │ ├── view │ │ ├── my_tab.dart │ │ ├── my_tab_bar.dart │ │ └── my_tab_indicator.dart │ ├── xf_manage.dart │ └── xf_utils.dart └── widgets │ ├── align.dart │ ├── animated.dart │ ├── animated2.dart │ ├── app_bar_search.dart │ ├── autocomplete_demo.dart │ ├── baseful_widget.dart │ ├── baseless_widget.dart │ ├── big_image.dart │ ├── button.dart │ ├── calendar.dart │ ├── canvas │ ├── bw.dart │ ├── curbox.dart │ ├── dolphin.dart │ ├── fan_book.dart │ ├── gestures_unlock.dart │ ├── joystick.dart │ ├── jue_jin_logo.dart │ ├── loading.dart │ ├── oval_loading.dart │ ├── shou_you.dart │ ├── toly_wave_loading.dart │ ├── touch_controller.dart │ ├── unlock_controller.dart │ ├── wq_qp2.dart │ └── xin_sui.dart │ ├── canvas_demo.dart │ ├── check.dart │ ├── clip_widget.dart │ ├── code_page.dart │ ├── container.dart │ ├── coordinate.dart │ ├── curve_box.dart │ ├── data │ ├── change_provider.dart │ ├── share_data.dart │ └── share_provider.dart │ ├── decorated_box.dart │ ├── dialog.dart │ ├── flex_demo.dart │ ├── form_edit.dart │ ├── gallery_example_item.dart │ ├── gesture_detector.dart │ ├── hero_demo.dart │ ├── icon.dart │ ├── list.dart │ ├── listener.dart │ ├── logo.dart │ ├── move_damo.dart │ ├── my_easy_refresh.dart │ ├── padding.dart │ ├── paint2_demo.dart │ ├── paint_demo.dart │ ├── polygonal.dart │ ├── polygonal_demo.dart │ ├── progress.dart │ ├── qi_pao.dart │ ├── qp_widget.dart │ ├── rain.dart │ ├── scroll_navigation.dart │ ├── size_box.dart │ ├── stack.dart │ ├── store.dart │ ├── stream_build.dart │ ├── stream_build_util.dart │ ├── summer.dart │ ├── tab_bar.dart │ ├── tab_bar_demo.dart │ ├── table_demo.dart │ ├── test.dart │ ├── text.dart │ ├── text_field.dart │ ├── theme.dart │ ├── transform.dart │ ├── util_page │ ├── my_toast.dart │ ├── num_demo.dart │ └── open_image.dart │ ├── world.dart │ ├── wq_qp.dart │ ├── wrap.dart │ ├── xlf_bg_button.dart │ ├── yy_text_demo.dart │ ├── zan.dart │ └── zong_zI_ke_pu.dart ├── linux ├── .gitignore ├── CMakeLists.txt ├── flutter │ ├── CMakeLists.txt │ ├── generated_plugin_registrant.cc │ ├── generated_plugin_registrant.h │ └── generated_plugins.cmake ├── main.cc ├── my_application.cc └── my_application.h ├── local.properties ├── macos ├── .gitignore ├── Flutter │ ├── Flutter-Debug.xcconfig │ ├── Flutter-Release.xcconfig │ └── GeneratedPluginRegistrant.swift ├── Podfile ├── Podfile.lock ├── Runner.xcodeproj │ ├── project.pbxproj │ ├── project.xcworkspace │ │ └── xcshareddata │ │ │ └── IDEWorkspaceChecks.plist │ └── xcshareddata │ │ └── xcschemes │ │ └── Runner.xcscheme ├── Runner.xcworkspace │ ├── contents.xcworkspacedata │ └── xcshareddata │ │ └── IDEWorkspaceChecks.plist └── Runner │ ├── AppDelegate.swift │ ├── Assets.xcassets │ └── AppIcon.appiconset │ │ ├── Contents.json │ │ ├── app_icon_1024.png │ │ ├── app_icon_128.png │ │ ├── app_icon_16.png │ │ ├── app_icon_256.png │ │ ├── app_icon_32.png │ │ ├── app_icon_512.png │ │ └── app_icon_64.png │ ├── Base.lproj │ └── MainMenu.xib │ ├── Configs │ ├── AppInfo.xcconfig │ ├── Debug.xcconfig │ ├── Release.xcconfig │ └── Warnings.xcconfig │ ├── DebugProfile.entitlements │ ├── Info.plist │ ├── MainFlutterWindow.swift │ └── Release.entitlements ├── pubspec.lock ├── pubspec.yaml ├── test └── widget_test.dart ├── web ├── favicon.png ├── icons │ ├── Icon-192.png │ ├── Icon-512.png │ ├── Icon-maskable-192.png │ └── Icon-maskable-512.png ├── index.html └── manifest.json └── windows ├── .gitignore ├── CMakeLists.txt ├── flutter ├── CMakeLists.txt ├── generated_plugin_registrant.cc ├── generated_plugin_registrant.h └── generated_plugins.cmake └── runner ├── CMakeLists.txt ├── Runner.rc ├── flutter_window.cpp ├── flutter_window.h ├── main.cpp ├── resource.h ├── resources └── app_icon.ico ├── runner.exe.manifest ├── utils.cpp ├── utils.h ├── win32_window.cpp └── win32_window.h /.gitignore: -------------------------------------------------------------------------------- 1 | <<<<<<< HEAD 2 | # Build and Release Folders 3 | bin-debug/ 4 | bin-release/ 5 | [Oo]bj/ 6 | [Bb]in/ 7 | 8 | # Other files and folders 9 | .settings/ 10 | 11 | # Executables 12 | *.swf 13 | *.air 14 | *.ipa 15 | *.apk 16 | 17 | # Project files, i.e. `.project`, `.actionScriptProperties` and `.flexProperties` 18 | # should NOT be excluded as they contain compiler settings and other important 19 | # information for Eclipse / Flash Builder. 20 | ======= 21 | # Miscellaneous 22 | *.class 23 | *.log 24 | *.pyc 25 | *.swp 26 | .DS_Store 27 | .atom/ 28 | .buildlog/ 29 | .history 30 | .svn/ 31 | 32 | # IntelliJ related 33 | *.iml 34 | *.ipr 35 | *.iws 36 | .idea/ 37 | 38 | # The .vscode folder contains launch configuration and tasks you configure in 39 | # VS Code which you may wish to be included in version control, so this line 40 | # is commented out by default. 41 | #.vscode/ 42 | 43 | # Flutter/Dart/Pub related 44 | **/doc/api/ 45 | **/ios/Flutter/.last_build_id 46 | .dart_tool/ 47 | .gradle/ 48 | .flutter-plugins 49 | .flutter-plugins-dependencies 50 | .packages 51 | .pub-cache/ 52 | .pub/ 53 | /build/ 54 | 55 | # Web related 56 | lib/generated_plugin_registrant.dart 57 | 58 | # Symbolication related 59 | app.*.symbols 60 | 61 | # Obfuscation related 62 | app.*.map.json 63 | 64 | # Android Studio will place build artifacts here 65 | /android/app/debug 66 | /android/app/profile 67 | /android/app/release 68 | >>>>>>> init 69 | -------------------------------------------------------------------------------- /.gradle/6.1.1/executionHistory/executionHistory.bin: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lixp185/flutter_demo/46f92f2895b84df59943ace1bf0b9c43aac6f2f5/.gradle/6.1.1/executionHistory/executionHistory.bin -------------------------------------------------------------------------------- /.gradle/6.1.1/executionHistory/executionHistory.lock: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lixp185/flutter_demo/46f92f2895b84df59943ace1bf0b9c43aac6f2f5/.gradle/6.1.1/executionHistory/executionHistory.lock -------------------------------------------------------------------------------- /.gradle/6.1.1/fileChanges/last-build.bin: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /.gradle/6.1.1/fileHashes/fileHashes.bin: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lixp185/flutter_demo/46f92f2895b84df59943ace1bf0b9c43aac6f2f5/.gradle/6.1.1/fileHashes/fileHashes.bin -------------------------------------------------------------------------------- /.gradle/6.1.1/fileHashes/fileHashes.lock: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lixp185/flutter_demo/46f92f2895b84df59943ace1bf0b9c43aac6f2f5/.gradle/6.1.1/fileHashes/fileHashes.lock -------------------------------------------------------------------------------- /.gradle/6.1.1/gc.properties: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lixp185/flutter_demo/46f92f2895b84df59943ace1bf0b9c43aac6f2f5/.gradle/6.1.1/gc.properties -------------------------------------------------------------------------------- /.gradle/buildOutputCleanup/buildOutputCleanup.lock: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lixp185/flutter_demo/46f92f2895b84df59943ace1bf0b9c43aac6f2f5/.gradle/buildOutputCleanup/buildOutputCleanup.lock -------------------------------------------------------------------------------- /.gradle/buildOutputCleanup/cache.properties: -------------------------------------------------------------------------------- 1 | #Fri Mar 19 14:44:33 CST 2021 2 | gradle.version=6.1.1 3 | -------------------------------------------------------------------------------- /.gradle/buildOutputCleanup/outputFiles.bin: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lixp185/flutter_demo/46f92f2895b84df59943ace1bf0b9c43aac6f2f5/.gradle/buildOutputCleanup/outputFiles.bin -------------------------------------------------------------------------------- /.gradle/checksums/checksums.lock: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lixp185/flutter_demo/46f92f2895b84df59943ace1bf0b9c43aac6f2f5/.gradle/checksums/checksums.lock -------------------------------------------------------------------------------- /.gradle/checksums/md5-checksums.bin: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lixp185/flutter_demo/46f92f2895b84df59943ace1bf0b9c43aac6f2f5/.gradle/checksums/md5-checksums.bin -------------------------------------------------------------------------------- /.gradle/checksums/sha1-checksums.bin: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lixp185/flutter_demo/46f92f2895b84df59943ace1bf0b9c43aac6f2f5/.gradle/checksums/sha1-checksums.bin -------------------------------------------------------------------------------- /.gradle/vcs-1/gc.properties: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lixp185/flutter_demo/46f92f2895b84df59943ace1bf0b9c43aac6f2f5/.gradle/vcs-1/gc.properties -------------------------------------------------------------------------------- /.metadata: -------------------------------------------------------------------------------- 1 | # This file tracks properties of this Flutter project. 2 | # Used by Flutter tool to assess capabilities and perform upgrades etc. 3 | # 4 | # This file should be version controlled. 5 | 6 | version: 7 | revision: 135454af32477f815a7525073027a3ff9eff1bfd 8 | channel: stable 9 | 10 | project_type: app 11 | 12 | # Tracks metadata for the flutter migrate command 13 | migration: 14 | platforms: 15 | - platform: root 16 | create_revision: 135454af32477f815a7525073027a3ff9eff1bfd 17 | base_revision: 135454af32477f815a7525073027a3ff9eff1bfd 18 | - platform: android 19 | create_revision: 135454af32477f815a7525073027a3ff9eff1bfd 20 | base_revision: 135454af32477f815a7525073027a3ff9eff1bfd 21 | - platform: ios 22 | create_revision: 135454af32477f815a7525073027a3ff9eff1bfd 23 | base_revision: 135454af32477f815a7525073027a3ff9eff1bfd 24 | - platform: linux 25 | create_revision: 135454af32477f815a7525073027a3ff9eff1bfd 26 | base_revision: 135454af32477f815a7525073027a3ff9eff1bfd 27 | - platform: macos 28 | create_revision: 135454af32477f815a7525073027a3ff9eff1bfd 29 | base_revision: 135454af32477f815a7525073027a3ff9eff1bfd 30 | - platform: web 31 | create_revision: 135454af32477f815a7525073027a3ff9eff1bfd 32 | base_revision: 135454af32477f815a7525073027a3ff9eff1bfd 33 | - platform: windows 34 | create_revision: 135454af32477f815a7525073027a3ff9eff1bfd 35 | base_revision: 135454af32477f815a7525073027a3ff9eff1bfd 36 | 37 | # User provided section 38 | 39 | # List of Local paths (relative to this file) that should be 40 | # ignored by the migrate tool. 41 | # 42 | # Files that are not part of the templates will be ignored by default. 43 | unmanaged_files: 44 | - 'lib/main.dart' 45 | - 'ios/Runner.xcodeproj/project.pbxproj' 46 | -------------------------------------------------------------------------------- /README.en.md: -------------------------------------------------------------------------------- 1 | # Flutter_Demo Record of personal Flutter introductory learning 2 | 3 | > This project can quickly let students who want to learn Flutter get started quickly, and there are also some example applications written by me for reference. 4 | 5 | ## Flutter_Demo Introduction 6 | 7 | ### Four major aspects 8 | Introduced from the following four aspects: 9 | 1. Common basic components 10 | 2. Commonly used functional components include mainstream state management frameworks 11 | 3. Some example demos written 12 | 4. Tool-type function arrangement 13 | 14 | - This project is relatively casual and only suitable for entry-level reference, and it will be maintained slowly when there is time in the future. 15 | 16 | Most of the examples in the project are detailed on my nuggets: 17 | [My Nuggets Homepage](https://juejin.cn/user/2620848963859582) -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | 2 | # Flutter_Demo 个人Flutter 入门学习的记录 3 | 4 | > 该项目可以快速让想学习Flutter的同学快速了解入手,同时里面还有我自己写的一些例子应用也可参考。 5 | 6 | ## Flutter_Demo 介绍 7 | 8 | ### 四大方面 9 | 从以下这四个方面介绍: 10 | 1、常用基础组件 11 | 2、常用功能性组件 包含主流状态管理框架 12 | 3、写的一些例子demo 13 | 4、工具型功能整理 14 | 15 | - 该项目比较随意,只适合入门参考,后续有时间也会慢慢维护。 16 | 17 | 项目中的示例大部分都在我的掘金上有详细的介绍: 18 | [我的掘金主页](https://juejin.cn/user/2620848963859582) 19 | 20 | -------------------------------------------------------------------------------- /analysis_options.yaml: -------------------------------------------------------------------------------- 1 | # This file configures the analyzer, which statically analyzes Dart code to 2 | # check for errors, warnings, and lints. 3 | # 4 | # The issues identified by the analyzer are surfaced in the UI of Dart-enabled 5 | # IDEs (https://dart.dev/tools#ides-and-editors). The analyzer can also be 6 | # invoked from the command line by running `flutter analyze`. 7 | 8 | # The following line activates a set of recommended lints for Flutter apps, 9 | # packages, and plugins designed to encourage good coding practices. 10 | include: package:flutter_lints/flutter.yaml 11 | 12 | linter: 13 | # The lint rules applied to this project can be customized in the 14 | # section below to disable rules from the `package:flutter_lints/flutter.yaml` 15 | # included above or to enable additional rules. A list of all available lints 16 | # and their documentation is published at 17 | # https://dart-lang.github.io/linter/lints/index.html. 18 | # 19 | # Instead of disabling a lint rule for the entire project in the 20 | # section below, it can also be suppressed for a single line of code 21 | # or a specific dart file by using the `// ignore: name_of_lint` and 22 | # `// ignore_for_file: name_of_lint` syntax on the line or in the file 23 | # producing the lint. 24 | rules: 25 | # avoid_print: false # Uncomment to disable the `avoid_print` rule 26 | # prefer_single_quotes: true # Uncomment to enable the `prefer_single_quotes` rule 27 | 28 | # Additional information about this file can be found at 29 | # https://dart.dev/guides/language/analysis-options 30 | -------------------------------------------------------------------------------- /android/.gitignore: -------------------------------------------------------------------------------- 1 | gradle-wrapper.jar 2 | /.gradle 3 | /captures/ 4 | /gradlew 5 | /gradlew.bat 6 | /local.properties 7 | GeneratedPluginRegistrant.java 8 | 9 | # Remember to never publicly share your keystore. 10 | # See https://flutter.dev/docs/deployment/android#reference-the-keystore-from-the-app 11 | key.properties 12 | -------------------------------------------------------------------------------- /android/app/build.gradle: -------------------------------------------------------------------------------- 1 | def localProperties = new Properties() 2 | def localPropertiesFile = rootProject.file('local.properties') 3 | if (localPropertiesFile.exists()) { 4 | localPropertiesFile.withReader('UTF-8') { reader -> 5 | localProperties.load(reader) 6 | } 7 | } 8 | 9 | def flutterRoot = localProperties.getProperty('flutter.sdk') 10 | if (flutterRoot == null) { 11 | throw new GradleException("Flutter SDK not found. Define location with flutter.sdk in the local.properties file.") 12 | } 13 | 14 | def flutterVersionCode = localProperties.getProperty('flutter.versionCode') 15 | if (flutterVersionCode == null) { 16 | flutterVersionCode = '1' 17 | } 18 | 19 | def flutterVersionName = localProperties.getProperty('flutter.versionName') 20 | if (flutterVersionName == null) { 21 | flutterVersionName = '1.0' 22 | } 23 | 24 | apply plugin: 'com.android.application' 25 | apply plugin: 'kotlin-android' 26 | apply from: "$flutterRoot/packages/flutter_tools/gradle/flutter.gradle" 27 | 28 | android { 29 | compileSdkVersion 33 30 | 31 | sourceSets { 32 | main.java.srcDirs += 'src/main/kotlin' 33 | } 34 | 35 | defaultConfig { 36 | // TODO: Specify your own unique Application ID (https://developer.android.com/studio/build/application-id.html). 37 | applicationId "com.flutter.demo" 38 | minSdkVersion 21 39 | targetSdkVersion 33 40 | versionCode flutterVersionCode.toInteger() 41 | versionName flutterVersionName 42 | // ndk{ 43 | // abiFilters 'armeabi-v7a' 44 | // } 45 | manifestPlaceholders = [ 46 | JPUSH_PKGNAME : applicationId, 47 | JPUSH_APPKEY : "cbdee844d6ebcaaed24b0cfa", // NOTE: JPush 上注册的包名对应的 Appkey. 48 | JPUSH_CHANNEL : "developer-default", //暂时填写默认值即可. 49 | ] 50 | } 51 | 52 | buildTypes { 53 | release { 54 | // TODO: Add your own signing config for the release build. 55 | // Signing with the debug keys for now, so `flutter run --release` works. 56 | signingConfig signingConfigs.debug 57 | } 58 | } 59 | } 60 | 61 | flutter { 62 | source '../..' 63 | } 64 | 65 | dependencies { 66 | implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version" 67 | } 68 | -------------------------------------------------------------------------------- /android/app/src/debug/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 3 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /android/app/src/main/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 12 | 20 | 24 | 28 | 33 | 37 | 38 | 39 | 40 | 41 | 42 | 44 | 47 | 48 | 49 | -------------------------------------------------------------------------------- /android/app/src/main/kotlin/com/flutter/demo/MainActivity.kt: -------------------------------------------------------------------------------- 1 | package com.flutter.demo 2 | 3 | import io.flutter.embedding.android.FlutterActivity 4 | 5 | class MainActivity: FlutterActivity() { 6 | } 7 | -------------------------------------------------------------------------------- /android/app/src/main/kotlin/com/flutter/flutter_demo/MainActivity.kt: -------------------------------------------------------------------------------- 1 | package com.flutter.flutter_demo 2 | 3 | import io.flutter.embedding.android.FlutterActivity 4 | 5 | class MainActivity: FlutterActivity() { 6 | } 7 | -------------------------------------------------------------------------------- /android/app/src/main/res/drawable-v21/launch_background.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 12 | 13 | -------------------------------------------------------------------------------- /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/lixp185/flutter_demo/46f92f2895b84df59943ace1bf0b9c43aac6f2f5/android/app/src/main/res/mipmap-hdpi/ic_launcher.png -------------------------------------------------------------------------------- /android/app/src/main/res/mipmap-mdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lixp185/flutter_demo/46f92f2895b84df59943ace1bf0b9c43aac6f2f5/android/app/src/main/res/mipmap-mdpi/ic_launcher.png -------------------------------------------------------------------------------- /android/app/src/main/res/mipmap-xhdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lixp185/flutter_demo/46f92f2895b84df59943ace1bf0b9c43aac6f2f5/android/app/src/main/res/mipmap-xhdpi/ic_launcher.png -------------------------------------------------------------------------------- /android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lixp185/flutter_demo/46f92f2895b84df59943ace1bf0b9c43aac6f2f5/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png -------------------------------------------------------------------------------- /android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lixp185/flutter_demo/46f92f2895b84df59943ace1bf0b9c43aac6f2f5/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png -------------------------------------------------------------------------------- /android/app/src/main/res/values-night/styles.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 9 | 15 | 18 | 19 | -------------------------------------------------------------------------------- /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 | ext.kotlin_version = '1.7.20' 3 | repositories { 4 | google() 5 | mavenCentral() 6 | } 7 | 8 | dependencies { 9 | classpath 'com.android.tools.build:gradle:7.2.2' 10 | classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version" 11 | } 12 | } 13 | 14 | allprojects { 15 | repositories { 16 | google() 17 | mavenCentral() 18 | } 19 | } 20 | 21 | rootProject.buildDir = '../build' 22 | subprojects { 23 | project.buildDir = "${rootProject.buildDir}/${project.name}" 24 | } 25 | subprojects { 26 | project.evaluationDependsOn(':app') 27 | } 28 | 29 | task clean(type: Delete) { 30 | delete rootProject.buildDir 31 | } 32 | -------------------------------------------------------------------------------- /android/gradle.properties: -------------------------------------------------------------------------------- 1 | org.gradle.jvmargs=-Xmx1536M 2 | android.useAndroidX=true 3 | android.enableJetifier=true 4 | -------------------------------------------------------------------------------- /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-7.4.2-all.zip 7 | -------------------------------------------------------------------------------- /android/settings.gradle: -------------------------------------------------------------------------------- 1 | include ':app' 2 | 3 | def localPropertiesFile = new File(rootProject.projectDir, "local.properties") 4 | def properties = new Properties() 5 | 6 | assert localPropertiesFile.exists() 7 | localPropertiesFile.withReader("UTF-8") { reader -> properties.load(reader) } 8 | 9 | def flutterSdkPath = properties.getProperty("flutter.sdk") 10 | assert flutterSdkPath != null, "flutter.sdk not set in local.properties" 11 | apply from: "$flutterSdkPath/packages/flutter_tools/gradle/app_plugin_loader.gradle" 12 | -------------------------------------------------------------------------------- /build.gradle: -------------------------------------------------------------------------------- 1 | buildscript { 2 | ext.kotlin_version = '1.3.50' 3 | repositories { 4 | google() 5 | mavenCentral() 6 | } 7 | 8 | dependencies { 9 | classpath 'com.android.tools.build:gradle:4.1.0' 10 | classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version" 11 | } 12 | } 13 | 14 | allprojects { 15 | repositories { 16 | google() 17 | mavenCentral() 18 | } 19 | } 20 | 21 | rootProject.buildDir = '../build' 22 | subprojects { 23 | project.buildDir = "${rootProject.buildDir}/${project.name}" 24 | } 25 | subprojects { 26 | project.evaluationDependsOn(':app') 27 | } 28 | 29 | task clean(type: Delete) { 30 | delete rootProject.buildDir 31 | } 32 | -------------------------------------------------------------------------------- /gradle/wrapper/gradle-wrapper.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lixp185/flutter_demo/46f92f2895b84df59943ace1bf0b9c43aac6f2f5/gradle/wrapper/gradle-wrapper.jar -------------------------------------------------------------------------------- /gradle/wrapper/gradle-wrapper.properties: -------------------------------------------------------------------------------- 1 | distributionBase=GRADLE_USER_HOME 2 | distributionPath=wrapper/dists 3 | distributionUrl=https\://services.gradle.org/distributions/gradle-6.1.1-bin.zip 4 | zipStoreBase=GRADLE_USER_HOME 5 | zipStorePath=wrapper/dists 6 | -------------------------------------------------------------------------------- /images/demo_image.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lixp185/flutter_demo/46f92f2895b84df59943ace1bf0b9c43aac6f2f5/images/demo_image.png -------------------------------------------------------------------------------- /images/duanwu.webp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lixp185/flutter_demo/46f92f2895b84df59943ace1bf0b9c43aac6f2f5/images/duanwu.webp -------------------------------------------------------------------------------- /images/error.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lixp185/flutter_demo/46f92f2895b84df59943ace1bf0b9c43aac6f2f5/images/error.png -------------------------------------------------------------------------------- /images/flutter_logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lixp185/flutter_demo/46f92f2895b84df59943ace1bf0b9c43aac6f2f5/images/flutter_logo.png -------------------------------------------------------------------------------- /images/ht.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lixp185/flutter_demo/46f92f2895b84df59943ace1bf0b9c43aac6f2f5/images/ht.png -------------------------------------------------------------------------------- /images/icon_vip_fk.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lixp185/flutter_demo/46f92f2895b84df59943ace1bf0b9c43aac6f2f5/images/icon_vip_fk.png -------------------------------------------------------------------------------- /images/img.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lixp185/flutter_demo/46f92f2895b84df59943ace1bf0b9c43aac6f2f5/images/img.png -------------------------------------------------------------------------------- /images/img_1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lixp185/flutter_demo/46f92f2895b84df59943ace1bf0b9c43aac6f2f5/images/img_1.png -------------------------------------------------------------------------------- /images/img_2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lixp185/flutter_demo/46f92f2895b84df59943ace1bf0b9c43aac6f2f5/images/img_2.png -------------------------------------------------------------------------------- /images/lbxx.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lixp185/flutter_demo/46f92f2895b84df59943ace1bf0b9c43aac6f2f5/images/lbxx.png -------------------------------------------------------------------------------- /images/logo_normal.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lixp185/flutter_demo/46f92f2895b84df59943ace1bf0b9c43aac6f2f5/images/logo_normal.png -------------------------------------------------------------------------------- /images/zan.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lixp185/flutter_demo/46f92f2895b84df59943ace1bf0b9c43aac6f2f5/images/zan.png -------------------------------------------------------------------------------- /images/zongzi.jpeg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lixp185/flutter_demo/46f92f2895b84df59943ace1bf0b9c43aac6f2f5/images/zongzi.jpeg -------------------------------------------------------------------------------- /ios/.gitignore: -------------------------------------------------------------------------------- 1 | **/dgph 2 | *.mode1v3 3 | *.mode2v3 4 | *.moved-aside 5 | *.pbxuser 6 | *.perspectivev3 7 | **/*sync/ 8 | .sconsign.dblite 9 | .tags* 10 | **/.vagrant/ 11 | **/DerivedData/ 12 | Icon? 13 | **/Pods/ 14 | **/.symlinks/ 15 | profile 16 | xcuserdata 17 | **/.generated/ 18 | Flutter/App.framework 19 | Flutter/Flutter.framework 20 | Flutter/Flutter.podspec 21 | Flutter/Generated.xcconfig 22 | Flutter/ephemeral/ 23 | Flutter/app.flx 24 | Flutter/app.zip 25 | Flutter/flutter_assets/ 26 | Flutter/flutter_export_environment.sh 27 | ServiceDefinitions.json 28 | Runner/GeneratedPluginRegistrant.* 29 | 30 | # Exceptions to above rules. 31 | !default.mode1v3 32 | !default.mode2v3 33 | !default.pbxuser 34 | !default.perspectivev3 35 | -------------------------------------------------------------------------------- /ios/Flutter/AppFrameworkInfo.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | en 7 | CFBundleExecutable 8 | App 9 | CFBundleIdentifier 10 | io.flutter.flutter.app 11 | CFBundleInfoDictionaryVersion 12 | 6.0 13 | CFBundleName 14 | App 15 | CFBundlePackageType 16 | FMWK 17 | CFBundleShortVersionString 18 | 1.0 19 | CFBundleSignature 20 | ???? 21 | CFBundleVersion 22 | 1.0 23 | MinimumOSVersion 24 | 11.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, '11.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/Podfile.lock: -------------------------------------------------------------------------------- 1 | PODS: 2 | - audioplayers_darwin (0.0.1): 3 | - Flutter 4 | - Flutter (1.0.0) 5 | - fluttertoast (0.0.2): 6 | - Flutter 7 | - Toast 8 | - image_picker_ios (0.0.1): 9 | - Flutter 10 | - path_provider_ios (0.0.1): 11 | - Flutter 12 | - permission_handler_apple (9.0.4): 13 | - Flutter 14 | - shared_preferences_ios (0.0.1): 15 | - Flutter 16 | - Toast (4.0.0) 17 | - url_launcher_ios (0.0.1): 18 | - Flutter 19 | - video_player_avfoundation (0.0.1): 20 | - Flutter 21 | 22 | DEPENDENCIES: 23 | - audioplayers_darwin (from `.symlinks/plugins/audioplayers_darwin/ios`) 24 | - Flutter (from `Flutter`) 25 | - fluttertoast (from `.symlinks/plugins/fluttertoast/ios`) 26 | - image_picker_ios (from `.symlinks/plugins/image_picker_ios/ios`) 27 | - path_provider_ios (from `.symlinks/plugins/path_provider_ios/ios`) 28 | - permission_handler_apple (from `.symlinks/plugins/permission_handler_apple/ios`) 29 | - shared_preferences_ios (from `.symlinks/plugins/shared_preferences_ios/ios`) 30 | - url_launcher_ios (from `.symlinks/plugins/url_launcher_ios/ios`) 31 | - video_player_avfoundation (from `.symlinks/plugins/video_player_avfoundation/ios`) 32 | 33 | SPEC REPOS: 34 | trunk: 35 | - Toast 36 | 37 | EXTERNAL SOURCES: 38 | audioplayers_darwin: 39 | :path: ".symlinks/plugins/audioplayers_darwin/ios" 40 | Flutter: 41 | :path: Flutter 42 | fluttertoast: 43 | :path: ".symlinks/plugins/fluttertoast/ios" 44 | image_picker_ios: 45 | :path: ".symlinks/plugins/image_picker_ios/ios" 46 | path_provider_ios: 47 | :path: ".symlinks/plugins/path_provider_ios/ios" 48 | permission_handler_apple: 49 | :path: ".symlinks/plugins/permission_handler_apple/ios" 50 | shared_preferences_ios: 51 | :path: ".symlinks/plugins/shared_preferences_ios/ios" 52 | url_launcher_ios: 53 | :path: ".symlinks/plugins/url_launcher_ios/ios" 54 | video_player_avfoundation: 55 | :path: ".symlinks/plugins/video_player_avfoundation/ios" 56 | 57 | SPEC CHECKSUMS: 58 | audioplayers_darwin: 877d9a4d06331c5c374595e46e16453ac7eafa40 59 | Flutter: f04841e97a9d0b0a8025694d0796dd46242b2854 60 | fluttertoast: eb263d302cc92e04176c053d2385237e9f43fad0 61 | image_picker_ios: b786a5dcf033a8336a657191401bfdf12017dabb 62 | path_provider_ios: 14f3d2fd28c4fdb42f44e0f751d12861c43cee02 63 | permission_handler_apple: 44366e37eaf29454a1e7b1b7d736c2cceaeb17ce 64 | shared_preferences_ios: 548a61f8053b9b8a49ac19c1ffbc8b92c50d68ad 65 | Toast: 91b396c56ee72a5790816f40d3a94dd357abc196 66 | url_launcher_ios: 839c58cdb4279282219f5e248c3321761ff3c4de 67 | video_player_avfoundation: e489aac24ef5cf7af82702979ed16f2a5ef84cff 68 | 69 | PODFILE CHECKSUM: ef19549a9bc3046e7bb7d2fab4d021637c0c58a3 70 | 71 | COCOAPODS: 1.11.3 72 | -------------------------------------------------------------------------------- /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.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 | return super.application(application, didFinishLaunchingWithOptions: launchOptions) 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-1024x1024@1x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lixp185/flutter_demo/46f92f2895b84df59943ace1bf0b9c43aac6f2f5/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/lixp185/flutter_demo/46f92f2895b84df59943ace1bf0b9c43aac6f2f5/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/lixp185/flutter_demo/46f92f2895b84df59943ace1bf0b9c43aac6f2f5/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/lixp185/flutter_demo/46f92f2895b84df59943ace1bf0b9c43aac6f2f5/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/lixp185/flutter_demo/46f92f2895b84df59943ace1bf0b9c43aac6f2f5/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/lixp185/flutter_demo/46f92f2895b84df59943ace1bf0b9c43aac6f2f5/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/lixp185/flutter_demo/46f92f2895b84df59943ace1bf0b9c43aac6f2f5/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/lixp185/flutter_demo/46f92f2895b84df59943ace1bf0b9c43aac6f2f5/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/lixp185/flutter_demo/46f92f2895b84df59943ace1bf0b9c43aac6f2f5/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/lixp185/flutter_demo/46f92f2895b84df59943ace1bf0b9c43aac6f2f5/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/lixp185/flutter_demo/46f92f2895b84df59943ace1bf0b9c43aac6f2f5/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/lixp185/flutter_demo/46f92f2895b84df59943ace1bf0b9c43aac6f2f5/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/lixp185/flutter_demo/46f92f2895b84df59943ace1bf0b9c43aac6f2f5/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/lixp185/flutter_demo/46f92f2895b84df59943ace1bf0b9c43aac6f2f5/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/lixp185/flutter_demo/46f92f2895b84df59943ace1bf0b9c43aac6f2f5/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-83.5x83.5@2x.png -------------------------------------------------------------------------------- /ios/Runner/Assets.xcassets/LaunchImage.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "filename" : "LaunchImage.png", 6 | "scale" : "1x" 7 | }, 8 | { 9 | "idiom" : "universal", 10 | "filename" : "LaunchImage@2x.png", 11 | "scale" : "2x" 12 | }, 13 | { 14 | "idiom" : "universal", 15 | "filename" : "LaunchImage@3x.png", 16 | "scale" : "3x" 17 | } 18 | ], 19 | "info" : { 20 | "version" : 1, 21 | "author" : "xcode" 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lixp185/flutter_demo/46f92f2895b84df59943ace1bf0b9c43aac6f2f5/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage.png -------------------------------------------------------------------------------- /ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lixp185/flutter_demo/46f92f2895b84df59943ace1bf0b9c43aac6f2f5/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@2x.png -------------------------------------------------------------------------------- /ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lixp185/flutter_demo/46f92f2895b84df59943ace1bf0b9c43aac6f2f5/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@3x.png -------------------------------------------------------------------------------- /ios/Runner/Assets.xcassets/LaunchImage.imageset/README.md: -------------------------------------------------------------------------------- 1 | # Launch Screen Assets 2 | 3 | You can customize the launch screen with your own desired assets by replacing the image files in this directory. 4 | 5 | You can also do it by opening your Flutter project's Xcode project with `open ios/Runner.xcworkspace`, selecting `Runner/Assets.xcassets` in the Project Navigator and dropping in the desired images. -------------------------------------------------------------------------------- /ios/Runner/Base.lproj/LaunchScreen.storyboard: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | -------------------------------------------------------------------------------- /ios/Runner/Base.lproj/Main.storyboard: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | -------------------------------------------------------------------------------- /ios/Runner/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | $(DEVELOPMENT_LANGUAGE) 7 | CFBundleDisplayName 8 | Flutter Demo 9 | CFBundleExecutable 10 | $(EXECUTABLE_NAME) 11 | CFBundleIdentifier 12 | $(PRODUCT_BUNDLE_IDENTIFIER) 13 | CFBundleInfoDictionaryVersion 14 | 6.0 15 | CFBundleName 16 | flutter_demo 17 | CFBundlePackageType 18 | APPL 19 | CFBundleShortVersionString 20 | $(FLUTTER_BUILD_NAME) 21 | CFBundleSignature 22 | ???? 23 | CFBundleVersion 24 | $(FLUTTER_BUILD_NUMBER) 25 | LSRequiresIPhoneOS 26 | 27 | UILaunchStoryboardName 28 | LaunchScreen 29 | UIMainStoryboardFile 30 | Main 31 | UISupportedInterfaceOrientations 32 | 33 | UIInterfaceOrientationPortrait 34 | UIInterfaceOrientationLandscapeLeft 35 | UIInterfaceOrientationLandscapeRight 36 | 37 | UISupportedInterfaceOrientations~ipad 38 | 39 | UIInterfaceOrientationPortrait 40 | UIInterfaceOrientationPortraitUpsideDown 41 | UIInterfaceOrientationLandscapeLeft 42 | UIInterfaceOrientationLandscapeRight 43 | 44 | UIViewControllerBasedStatusBarAppearance 45 | 46 | CADisableMinimumFrameDurationOnPhone 47 | 48 | UIApplicationSupportsIndirectInputEvents 49 | 50 | 51 | 52 | -------------------------------------------------------------------------------- /ios/Runner/Runner-Bridging-Header.h: -------------------------------------------------------------------------------- 1 | #import "GeneratedPluginRegistrant.h" 2 | -------------------------------------------------------------------------------- /jsons/user.json: -------------------------------------------------------------------------------- 1 | {} -------------------------------------------------------------------------------- /lib/common/global.dart: -------------------------------------------------------------------------------- 1 | import 'dart:io'; 2 | 3 | import 'package:flutter/material.dart'; 4 | import 'package:flutter/services.dart'; 5 | 6 | //全局变量 7 | class Global { 8 | Global._internal(); 9 | 10 | static Global instance = Global._internal(); 11 | 12 | // 是否release版 13 | static bool get isRelease => bool.fromEnvironment("dart.vm.product"); 14 | 15 | // 打开程序初始化一些准备工作 16 | Future init() async { 17 | // if (Platform.isAndroid) { 18 | // // 沉浸式 19 | // SystemUiOverlayStyle systemUiOverlayStyle = SystemUiOverlayStyle( 20 | // statusBarColor: Colors.transparent, 21 | // ); 22 | // SystemChrome.setSystemUIOverlayStyle(systemUiOverlayStyle); 23 | // } 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /lib/common/my_colors.dart: -------------------------------------------------------------------------------- 1 | import 'dart:ui'; 2 | 3 | class MyColors { 4 | //自定义色值 5 | static const Color white = Color(0xFFFFFFFF); 6 | static const Color color_333333 = Color(0xFF333333); 7 | static const Color color_666666 = Color(0xFF666666); 8 | static const Color color_f1f2f3 = Color(0xFFF1F2F3); 9 | static const Color color_999999 = Color(0xFF999999); 10 | static const Color color_d7d7d7 = Color(0xFFD7D7D7); 11 | static const Color color_f7605c = Color(0xFFF7605C); 12 | static const Color color_ff6332 = Color(0xFFFF6332); 13 | 14 | } 15 | -------------------------------------------------------------------------------- /lib/dart/dart_demo.dart: -------------------------------------------------------------------------------- 1 | void main() { 2 | // String a = '"Dart基础知识"'; 3 | // String b = "'Dart基础知识'"; 4 | // String c = '''Dart 5 | // 基础知识'''; 6 | // String d = String.fromCharCodes(Runes("\u2665")); 7 | // 8 | // num a = 1; 9 | // int b = 1; 10 | // double c = 0.5; 11 | // // print(a); 12 | // // a = b+c; 13 | // print(a); 14 | // 15 | // /// 编译期报错 16 | // // b= b+a; 17 | // print(b); 18 | // print(c); 19 | // print(d); 20 | // 21 | // String x = a == 0 ? "x" : "b"; 22 | // String y = a == 0 23 | // ? "x" 24 | // : b == 0 25 | // ? "y" 26 | // : "z"; 27 | // print(x); 28 | // print(y); 29 | // 30 | // Set s = {1, 2, 3}; 31 | // print(s); 32 | // 33 | // Map map = {"a": "0", "b": 1}; 34 | // 35 | // print(map); 36 | 37 | dynamic z; 38 | z = "dart"; 39 | print(z); 40 | z = 123; 41 | print(z); 42 | z = true; 43 | print(z); 44 | 45 | // int a =0; 46 | late int a; 47 | 48 | // Object? x; 49 | // z.abc(); 50 | // print(x?.toString()); 51 | } 52 | 53 | abstract class A { 54 | m(); 55 | } 56 | 57 | class B { 58 | 59 | 60 | Function()? back; 61 | Future Function(int page, Function()? back)? loadData; 62 | 63 | Future test() async { 64 | return await loadData?.call(1, () {}); 65 | } 66 | // 67 | 68 | } 69 | 70 | /// 生命 71 | mixin Life { 72 | eat() { 73 | /// 吃 74 | } 75 | 76 | /// 性别男特点 77 | man() {} 78 | 79 | /// 性别女特点 80 | woman() {} 81 | } 82 | 83 | /// 动物 84 | mixin Zoo { 85 | /// 速度快特点 86 | quickly() {} 87 | 88 | ///... 89 | } 90 | 91 | class Man with Life { 92 | @override 93 | man() { 94 | return super.man(); 95 | } 96 | } 97 | 98 | class Cat with Life, Zoo { 99 | @override 100 | eat() { 101 | return super.eat(); 102 | } 103 | 104 | @override 105 | quickly() { 106 | return super.quickly(); 107 | } 108 | 109 | } 110 | 111 | // class DartDemo extends A implements B { 112 | // num a = 1; 113 | // 114 | // double b = 0; 115 | // 116 | // static const int x = 0; 117 | // 118 | // test() { 119 | // if (a == b) {} 120 | // } 121 | // 122 | // @override 123 | // m() {} 124 | // 125 | // @override 126 | // n() { 127 | // throw UnimplementedError(); 128 | // } 129 | // } 130 | -------------------------------------------------------------------------------- /lib/models/car_item.dart: -------------------------------------------------------------------------------- 1 | 2 | class Item { 3 | Item({required this.price, required this.count}); 4 | 5 | double price; 6 | int count; 7 | } 8 | 9 | -------------------------------------------------------------------------------- /lib/models/car_model.dart: -------------------------------------------------------------------------------- 1 | import 'dart:collection'; 2 | 3 | import 'package:flutter/material.dart'; 4 | import 'package:flutter_demo/common/theme_common.dart'; 5 | 6 | import 'car_item.dart'; 7 | 8 | class CarModel extends ChangeNotifier { 9 | //购物车商品 10 | final List _items = []; 11 | 12 | ThemeData themeData = ThemeCommon.lightTheme; 13 | 14 | // 禁止改变购物车里的商品信息 15 | UnmodifiableListView get items => UnmodifiableListView(_items); 16 | 17 | double get totaPrice { 18 | return _items.fold( 19 | 0, (value, item) => value + item.count * item.price); 20 | } 21 | 22 | ThemeData get getTheme => themeData; 23 | 24 | 25 | void setTheme(ThemeData themeData) { 26 | this.themeData = themeData; 27 | notifyListeners(); 28 | } 29 | 30 | void add(Item item) { 31 | _items.add(item); 32 | // 通知监听器(订阅者),重新构建ShareProvider, 更新状态。 33 | notifyListeners(); 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /lib/models/home_bean.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/material.dart'; 2 | 3 | class HomeBean { 4 | final String title; 5 | final String? path; 6 | final Widget? page; 7 | 8 | final int? type; 9 | 10 | HomeBean(this.title, this.path, this.page,{this.type}); 11 | } 12 | -------------------------------------------------------------------------------- /lib/models/name_bean.dart: -------------------------------------------------------------------------------- 1 | /// initial : "A" 2 | /// nameList : [{"name":"老李"}] 3 | 4 | class NameBean { 5 | String? initial; 6 | List? nameList; 7 | 8 | NameBean({ 9 | this.initial, 10 | this.nameList, 11 | }); 12 | } 13 | 14 | /// name : "老李" 15 | 16 | class Name { 17 | String? name; 18 | 19 | Name({ 20 | this.name, 21 | }); 22 | } 23 | -------------------------------------------------------------------------------- /lib/models/news_list_bean.dart: -------------------------------------------------------------------------------- 1 | class NewsListBean { 2 | //资讯类型 0:资讯无图 1:资讯有图 2:3d广告 3 | final int type; 4 | final bool isFirst; 5 | final String title; 6 | final String image; 7 | 8 | NewsListBean(this.type, this.title, this.image, {this.isFirst = false}); 9 | } 10 | -------------------------------------------------------------------------------- /lib/models/qz_bean.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/cupertino.dart'; 2 | 3 | class QzBean { 4 | 5 | // 整块棋子 6 | List? offset; 7 | 8 | // 9 | } 10 | -------------------------------------------------------------------------------- /lib/models/xf_res.dart: -------------------------------------------------------------------------------- 1 | /// code : 0 2 | /// message : "success" 3 | /// sid : "tts000eb834@dx18113f02d1d6f2c902" 4 | /// data : {"audio":""} 5 | 6 | class XfRes { 7 | XfRes({ 8 | int? code, 9 | String? message, 10 | String? sid, 11 | Data? data,}){ 12 | _code = code; 13 | _message = message; 14 | _sid = sid; 15 | _data = data; 16 | } 17 | 18 | XfRes.fromJson(dynamic json) { 19 | _code = json['code']; 20 | _message = json['message']; 21 | _sid = json['sid']; 22 | _data = json['data'] != null ? Data.fromJson(json['data']) : null; 23 | } 24 | int? _code; 25 | String? _message; 26 | String? _sid; 27 | Data? _data; 28 | 29 | int? get code => _code; 30 | String? get message => _message; 31 | String? get sid => _sid; 32 | Data? get data => _data; 33 | 34 | Map toJson() { 35 | final map = {}; 36 | map['code'] = _code; 37 | map['message'] = _message; 38 | map['sid'] = _sid; 39 | if (_data != null) { 40 | map['data'] = _data?.toJson(); 41 | } 42 | return map; 43 | } 44 | 45 | } 46 | 47 | /// audio : "" 48 | 49 | class Data { 50 | Data({ 51 | String? audio,}){ 52 | _audio = audio; 53 | } 54 | 55 | Data.fromJson(dynamic json) { 56 | _audio = json['audio']; 57 | } 58 | String? _audio; 59 | 60 | String? get audio => _audio; 61 | 62 | Map toJson() { 63 | final map = {}; 64 | map['audio'] = _audio; 65 | return map; 66 | } 67 | 68 | } -------------------------------------------------------------------------------- /lib/pages/function/event/event_bus.dart: -------------------------------------------------------------------------------- 1 | import 'dart:async'; 2 | 3 | /// 基于Stream订阅分发跨组件的通信方式 4 | class EventBus { 5 | StreamController _streamController; 6 | 7 | /// 事件总线 8 | StreamController get streamController => _streamController; 9 | 10 | /// Creates an [EventBus]. 11 | /// 12 | /// If [sync] is true, events are passed directly to the stream's listeners 13 | /// during a [fire] call. If false (the default), the event will be passed 14 | /// to the listeners at a later time, after the code creating the event has completed. 15 | /// sync true add时直接发送 不保证一定收到数据 16 | /// sync false 不保证何时收到数据 在add完成之后通知监听器 17 | EventBus({bool sync = false}) 18 | : _streamController = StreamController.broadcast(sync: sync); 19 | 20 | /// 自定义控制器 单线通知 StreamController() 21 | EventBus.customController(StreamController controller) 22 | : _streamController = controller; 23 | 24 | /// 监听接收数据 支持多个监听者 25 | Stream on() { 26 | if (T == dynamic) { 27 | return streamController.stream as Stream; 28 | } else { 29 | return streamController.stream.where((event) => event is T).cast(); 30 | } 31 | } 32 | 33 | /// 发送数据 34 | void fire(event) { 35 | streamController.add(event); 36 | } 37 | 38 | /// 关闭总事件 一般情况下全局EventBus不需要调用这个方法 39 | /// 非全局EventBus在退出时调用 40 | void destroy() { 41 | _streamController.close(); 42 | } 43 | } 44 | -------------------------------------------------------------------------------- /lib/pages/function/event/event_demo.dart: -------------------------------------------------------------------------------- 1 | import 'dart:async'; 2 | 3 | import 'package:flutter_demo/pages/function/event/event_bus.dart'; 4 | 5 | 6 | 7 | class Event { 8 | static final EventBus eventBus = EventBus(sync: false); 9 | // static final EventBus eventBus2 = 10 | // EventBus.customController(StreamController()); 11 | } 12 | 13 | class CountEvent { 14 | int data = 0; 15 | 16 | CountEvent(this.data); 17 | } 18 | -------------------------------------------------------------------------------- /lib/pages/function/event/page_one.dart: -------------------------------------------------------------------------------- 1 | import 'dart:async'; 2 | 3 | import 'package:flutter/material.dart'; 4 | import 'package:flutter_demo/pages/function/event/event_demo.dart'; 5 | import 'package:flutter_demo/pages/function/event/page_two.dart'; 6 | 7 | class PageOne extends StatefulWidget { 8 | const PageOne({Key? key}) : super(key: key); 9 | 10 | @override 11 | State createState() => _PageOneState(); 12 | } 13 | 14 | class _PageOneState extends State { 15 | int num = 0; 16 | 17 | StreamSubscription? listen; 18 | 19 | @override 20 | void dispose() { 21 | listen?.cancel(); 22 | super.dispose(); 23 | } 24 | 25 | @override 26 | void initState() { 27 | super.initState(); 28 | // 如果 第一个页面和第三个页面共享数据 将这个数据全局处理 29 | listen = Event.eventBus.on().listen((event) { 30 | print("1111111"); 31 | setState(() { 32 | num = event.data; 33 | }); 34 | }); 35 | } 36 | 37 | @override 38 | Widget build(BuildContext context) { 39 | return Stack( 40 | children: [ 41 | Center( 42 | child: Text("two页面传递数据:--$num"), 43 | ), 44 | Positioned( 45 | child: ElevatedButton( 46 | onPressed: () { 47 | Navigator.push( 48 | context, 49 | MaterialPageRoute( 50 | fullscreenDialog: true, 51 | builder: (BuildContext c) { 52 | return PageTwo(); 53 | })); 54 | }, 55 | child: Text("跳转Two")), 56 | bottom: 20, 57 | right: 20, 58 | ) 59 | ], 60 | ); 61 | } 62 | } 63 | -------------------------------------------------------------------------------- /lib/pages/function/event/page_three.dart: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lixp185/flutter_demo/46f92f2895b84df59943ace1bf0b9c43aac6f2f5/lib/pages/function/event/page_three.dart -------------------------------------------------------------------------------- /lib/pages/function/event/page_two.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/material.dart'; 2 | import 'package:flutter_demo/pages/function/event/event_demo.dart'; 3 | 4 | class PageTwo extends StatefulWidget { 5 | const PageTwo({Key? key}) : super(key: key); 6 | 7 | @override 8 | State createState() => _PageTwoState(); 9 | } 10 | 11 | class _PageTwoState extends State { 12 | 13 | 14 | int num = 0; 15 | 16 | @override 17 | void initState() { 18 | super.initState(); 19 | } 20 | 21 | @override 22 | Widget build(BuildContext context) { 23 | return Scaffold( 24 | appBar: AppBar(title: Text("Page2"),), 25 | body: Center( 26 | child: Text("$num"), 27 | ), 28 | floatingActionButton: FloatingActionButton( 29 | onPressed: () { 30 | setState(() { 31 | num++; 32 | }); 33 | Event.eventBus.fire(CountEvent(num)); 34 | }, child: Icon(Icons.add),), 35 | ); 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /lib/pages/function/notification_demo.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/material.dart'; 2 | 3 | /// 作者: lixp 4 | /// 创建时间: 2022/9/27 16:25 5 | /// 类介绍: 通知 6 | class NotificationDemo extends StatefulWidget { 7 | const NotificationDemo({Key? key}) : super(key: key); 8 | 9 | @override 10 | State createState() => _NotificationDemoState(); 11 | } 12 | 13 | class _NotificationDemoState extends State { 14 | int num = 0; 15 | 16 | @override 17 | Widget build(BuildContext context) { 18 | return Container( 19 | child: NotificationListener( 20 | onNotification: (res) { 21 | print("res:$res"); 22 | setState(() { 23 | num = res.data; 24 | }); 25 | return true; 26 | }, 27 | child: Stack( 28 | children: [ 29 | Center( 30 | child: Text("接受到数据$num"), 31 | ), 32 | Positioned( 33 | child: BtWidget(), 34 | bottom: 20, 35 | right: 20, 36 | ) 37 | ], 38 | )), 39 | ); 40 | } 41 | } 42 | 43 | class MyNotificationData extends Notification { 44 | int data = 0; 45 | 46 | MyNotificationData(this.data); 47 | } 48 | 49 | class BtWidget extends StatefulWidget { 50 | const BtWidget({Key? key}) : super(key: key); 51 | 52 | @override 53 | State createState() => _BtWidgetState(); 54 | } 55 | 56 | class _BtWidgetState extends State { 57 | int num = 0; 58 | 59 | @override 60 | Widget build(BuildContext context) { 61 | return ElevatedButton( 62 | onPressed: () { 63 | MyNotificationData(num++).dispatch(context); 64 | }, 65 | child: Text("发送通知")); 66 | } 67 | } 68 | -------------------------------------------------------------------------------- /lib/pages/function/test_data.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/material.dart'; 2 | 3 | /// 数据共享 4 | class CountData extends InheritedWidget { 5 | 6 | final Widget child; 7 | 8 | final int data; // 共享数据 9 | 10 | const CountData({ 11 | Key? key, 12 | required this.child, 13 | required this.data, 14 | }) : super(key: key, child: child); 15 | 16 | /// 定义一个静态方法 获取数据 17 | static CountData? of(BuildContext context) { 18 | return context.dependOnInheritedWidgetOfExactType(); 19 | // return context.getElementForInheritedWidgetOfExactType()!.widget 20 | // as CountData; 21 | } 22 | 23 | // 该回调决定当data发生变化时,是否通知子树中依赖data的Widget重新build 24 | @override 25 | bool updateShouldNotify(covariant CountData oldWidget) { 26 | return data != oldWidget.data; 27 | // return false; 28 | } 29 | } 30 | 31 | 32 | -------------------------------------------------------------------------------- /lib/states/bloc/bloc_demo/bloc.dart: -------------------------------------------------------------------------------- 1 | import 'package:bloc/bloc.dart'; 2 | 3 | import 'event.dart'; 4 | import 'state.dart'; 5 | 6 | /// 逻辑处理层 7 | class DemoBloc extends Bloc { 8 | ///构造方法 9 | DemoBloc() : super(DemoState().init()) { 10 | /// on 注册所有事件 11 | on(_init); 12 | on(_add); 13 | } 14 | 15 | /// 私有化逻辑方法 暴露Event事件 16 | void _init(InitEvent event, Emitter emit) { 17 | emit(state.clone()); 18 | } 19 | 20 | _add(IncrementEvent event, Emitter emit) { 21 | state.num++; 22 | emit(state.clone()); 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /lib/states/bloc/bloc_demo/event.dart: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | /// 页面中所有的交互事件 5 | abstract class DemoEvent {} 6 | 7 | /// 初始化事件 8 | class InitEvent extends DemoEvent { 9 | 10 | } 11 | 12 | /// 自增事件 13 | class IncrementEvent extends DemoEvent {} 14 | -------------------------------------------------------------------------------- /lib/states/bloc/bloc_demo/state.dart: -------------------------------------------------------------------------------- 1 | 2 | /// 数据层 3 | class DemoState { 4 | late int num; 5 | 6 | DemoState init() { 7 | return DemoState()..num = 0; 8 | } 9 | 10 | DemoState clone() { 11 | return DemoState()..num = num; 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /lib/states/bloc/bloc_demo/view.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/material.dart'; 2 | import 'package:flutter_bloc/flutter_bloc.dart'; 3 | 4 | import 'bloc.dart'; 5 | import 'event.dart'; 6 | import 'state.dart'; 7 | 8 | /// 视图页面 9 | class BlocNumPage extends StatelessWidget { 10 | 11 | 12 | @override 13 | Widget build(BuildContext context) { 14 | return BlocProvider( 15 | create: (BuildContext context) => DemoBloc()..add(InitEvent()), 16 | child: Builder(builder: (context) => _buildPage(context)), 17 | ); 18 | } 19 | 20 | Widget _buildPage(BuildContext context) { 21 | final bloc = BlocProvider.of(context); 22 | return Stack( 23 | children: [ 24 | Center( 25 | child: BlocBuilder( 26 | builder: (context, state) { 27 | return Text("点击了${bloc.state.num}次"); 28 | }, 29 | ), 30 | ), 31 | Positioned( 32 | bottom: 20, 33 | right: 20, 34 | child: FloatingActionButton( 35 | onPressed: () { 36 | bloc.add(IncrementEvent()); 37 | }, 38 | child: Icon(Icons.add), 39 | ), 40 | ) 41 | ], 42 | ); 43 | } 44 | } 45 | -------------------------------------------------------------------------------- /lib/states/bloc/cubit_demo/cubit/cubit_cubit.dart: -------------------------------------------------------------------------------- 1 | import 'package:bloc/bloc.dart'; 2 | 3 | import 'cubit_state.dart'; 4 | 5 | /// 写逻辑 6 | class CubitCubit extends Cubit { 7 | CubitCubit() : super(CubitState().init()); 8 | 9 | ///自增 10 | void increment() => emit(state.clone()..num = state.num + 1); 11 | } 12 | -------------------------------------------------------------------------------- /lib/states/bloc/cubit_demo/cubit/cubit_state.dart: -------------------------------------------------------------------------------- 1 | 2 | 3 | /// 写数据 4 | class CubitState { 5 | late int num; 6 | 7 | 8 | CubitState init() { 9 | return CubitState()..num = 0; 10 | } 11 | 12 | CubitState clone() { 13 | return CubitState()..num = num; 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /lib/states/bloc/cubit_demo/cubit/cubit_view.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/material.dart'; 2 | import 'package:flutter_bloc/flutter_bloc.dart'; 3 | 4 | import 'cubit_cubit.dart'; 5 | import 'cubit_state.dart'; 6 | 7 | /// 写页面 8 | class CubitPage extends StatelessWidget { 9 | @override 10 | Widget build(BuildContext context) { 11 | return BlocProvider( 12 | create: (BuildContext context) => CubitCubit(), 13 | child: Builder(builder: (context) => _buildPage(context)), 14 | ); 15 | } 16 | 17 | Widget _buildPage(BuildContext context) { 18 | final cubit = BlocProvider.of(context); 19 | return Stack( 20 | children: [ 21 | BlocBuilder( 22 | builder: (context, state) { 23 | return Center( 24 | child: Text("点击了${state.num}次"), 25 | ); 26 | }, 27 | ), 28 | Positioned( 29 | child: FloatingActionButton( 30 | onPressed: () { 31 | cubit.increment(); 32 | }, 33 | child: Icon(Icons.add), 34 | ), 35 | bottom: 20, 36 | right: 20, 37 | ), 38 | ], 39 | ); 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /lib/states/bloc_demo.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter_bloc/flutter_bloc.dart'; 2 | 3 | class ConCubit extends Cubit { 4 | ConCubit(initialState) : super(initialState); 5 | 6 | @override 7 | void onChange(Change change) { 8 | super.onChange(change); 9 | } 10 | 11 | @override 12 | void onError(Object error, StackTrace stackTrace) { 13 | super.onError(error, stackTrace); 14 | } 15 | } 16 | 17 | class MyBlocObserver extends BlocObserver { 18 | @override 19 | void onCreate(BlocBase bloc) { 20 | super.onCreate(bloc); 21 | } 22 | 23 | @override 24 | void onChange(BlocBase bloc, Change change) { 25 | super.onChange(bloc, change); 26 | } 27 | 28 | @override 29 | void onClose(BlocBase bloc) { 30 | super.onClose(bloc); 31 | } 32 | 33 | @override 34 | void onError(BlocBase bloc, Object error, StackTrace stackTrace) { 35 | super.onError(bloc, error, stackTrace); 36 | } 37 | 38 | @override 39 | void onEvent(Bloc bloc, Object? event) { 40 | super.onEvent(bloc, event); 41 | } 42 | 43 | @override 44 | void onTransition(Bloc bloc, Transition transition) { 45 | super.onTransition(bloc, transition); 46 | } 47 | } 48 | -------------------------------------------------------------------------------- /lib/states/change_notifier.dart: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lixp185/flutter_demo/46f92f2895b84df59943ace1bf0b9c43aac6f2f5/lib/states/change_notifier.dart -------------------------------------------------------------------------------- /lib/states/firm/provider.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/material.dart'; 2 | 3 | class FirmProvider extends ChangeNotifier { 4 | 5 | } 6 | -------------------------------------------------------------------------------- /lib/states/firm/view.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/material.dart'; 2 | import 'package:provider/provider.dart'; 3 | 4 | import 'provider.dart'; 5 | 6 | class FirmPage extends StatelessWidget { 7 | @override 8 | Widget build(BuildContext context) { 9 | return ChangeNotifierProvider( 10 | create: (BuildContext context) => FirmProvider(), 11 | builder: (context, child) => _buildPage(context), 12 | ); 13 | } 14 | 15 | Widget _buildPage(BuildContext context) { 16 | final provider = context.read(); 17 | 18 | return Container(); 19 | } 20 | } 21 | 22 | -------------------------------------------------------------------------------- /lib/states/getx/jump_page/jump_one/logic.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter_demo/states/getx/jump_page/jump_two/view.dart'; 2 | import 'package:get/get.dart'; 3 | 4 | class GetJumpOneLogic extends GetxController { 5 | var count = 0; 6 | 7 | ///跳转到跨页面 8 | void toJumpTwo() { 9 | Get.to(GetJumpTwoPage(), arguments: {'msg': 'one页面传递数据'}); 10 | } 11 | 12 | ///跳转到跨页面 13 | void increase() { 14 | count++; 15 | update(); 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /lib/states/getx/jump_page/jump_one/view.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/material.dart'; 2 | import 'package:get/get.dart'; 3 | 4 | import 'logic.dart'; 5 | 6 | class GetJumpOnePage extends StatelessWidget { 7 | @override 8 | Widget build(BuildContext context) { 9 | /// 使用Get.put()实例化你的类,使其对当下的所有子路由可用。 10 | final logic = Get.put(GetJumpOneLogic()); 11 | return Stack( 12 | children: [ 13 | Center( 14 | child: GetBuilder( 15 | builder: (logic) { 16 | return Text('跨页面-Two点击了 ${logic.count} 次'); 17 | }, 18 | ), 19 | ), 20 | Positioned( 21 | child: ElevatedButton( 22 | onPressed: () => logic.toJumpTwo(), child: Text("跳转Two")), 23 | bottom: 20, 24 | right: 20, 25 | ) 26 | ], 27 | ); 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /lib/states/getx/jump_page/jump_two/logic.dart: -------------------------------------------------------------------------------- 1 | import 'package:get/get.dart'; 2 | 3 | class GetJumpTwoLogic extends GetxController { 4 | 5 | var count = 0; 6 | 7 | var msg = ''; 8 | 9 | 10 | /// 接受参数回调 Get.argument 11 | @override 12 | void onReady() { 13 | var map = Get.arguments; 14 | msg = map['msg']; 15 | // 16 | update(); 17 | 18 | super.onReady(); 19 | } 20 | 21 | ///跳转到跨页面 22 | void increase() { 23 | count++; 24 | update(); 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /lib/states/getx/jump_page/jump_two/view.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/material.dart'; 2 | import 'package:flutter_demo/states/getx/jump_page/jump_one/logic.dart'; 3 | import 'package:get/get.dart'; 4 | 5 | import 'logic.dart'; 6 | 7 | class GetJumpTwoPage extends StatelessWidget { 8 | final oneLogic = Get.find(); 9 | final twoLogic = Get.put(GetJumpTwoLogic()); 10 | 11 | @override 12 | Widget build(BuildContext context) { 13 | return Scaffold( 14 | backgroundColor: Colors.white, 15 | appBar: AppBar(title: Text('跨页面-Two')), 16 | floatingActionButton: FloatingActionButton( 17 | onPressed: () { 18 | // 调用上一页面自增方法 19 | oneLogic.increase(); 20 | twoLogic.increase(); 21 | }, 22 | child: const Icon(Icons.add), 23 | ), 24 | body: Center( 25 | child: Column(mainAxisSize: MainAxisSize.min, children: [ 26 | //计数显示 27 | GetBuilder( 28 | builder: (logic) { 29 | return Text( 30 | '跨页面-Two点击了 ${twoLogic.count} 次', 31 | ); 32 | }, 33 | ), 34 | 35 | //传递数据 36 | GetBuilder( 37 | builder: (logic) { 38 | return Text('传递的数据:${twoLogic.msg}',); 39 | }, 40 | ), 41 | ]), 42 | ), 43 | ); 44 | } 45 | } 46 | -------------------------------------------------------------------------------- /lib/states/getx/num/logic.dart: -------------------------------------------------------------------------------- 1 | import 'package:get/get.dart'; 2 | 3 | 4 | 5 | /// 逻辑层 6 | class NumLogic extends GetxController { 7 | RxInt data = 0.obs; 8 | add() { 9 | data++; 10 | // update(); 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /lib/states/getx/num/state.dart: -------------------------------------------------------------------------------- 1 | /// 数据层 2 | class NumState { 3 | late int num; 4 | 5 | NumState() { 6 | num = 0; 7 | } 8 | } 9 | -------------------------------------------------------------------------------- /lib/states/getx/num/view.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/material.dart'; 2 | import 'package:get/get.dart'; 3 | 4 | import 'logic.dart'; 5 | 6 | /// UI层 7 | class GetNumPage extends StatelessWidget { 8 | @override 9 | Widget build(BuildContext context) { 10 | final logic = Get.put(NumLogic()); 11 | 12 | return Stack( 13 | children: [ 14 | Obx(() { 15 | return Center( 16 | child: Text("点击了${logic.data.value}次"), 17 | ); 18 | }), 19 | Positioned( 20 | child: FloatingActionButton( 21 | onPressed: () { 22 | logic.add(); 23 | }, 24 | child: Icon(Icons.add), 25 | ), 26 | bottom: 20, 27 | right: 20, 28 | ) 29 | ], 30 | ); 31 | } 32 | } 33 | 34 | 35 | -------------------------------------------------------------------------------- /lib/states/getx/test/logic.dart: -------------------------------------------------------------------------------- 1 | import 'package:get/get.dart'; 2 | 3 | import 'state.dart'; 4 | 5 | class TestLogic extends GetxController { 6 | final TestState state = TestState(); 7 | } 8 | -------------------------------------------------------------------------------- /lib/states/getx/test/state.dart: -------------------------------------------------------------------------------- 1 | class TestState { 2 | TestState() { 3 | ///Initialize variables 4 | } 5 | } 6 | -------------------------------------------------------------------------------- /lib/states/getx/test/view.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/material.dart'; 2 | import 'package:get/get.dart'; 3 | 4 | import 'logic.dart'; 5 | 6 | class TestPage extends StatelessWidget { 7 | final logic = Get.put(TestLogic()); 8 | final state = Get.find().state; 9 | 10 | @override 11 | Widget build(BuildContext context) { 12 | return Container(); 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /lib/states/provider/p_num/provider.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/material.dart'; 2 | 3 | import 'state.dart'; 4 | 5 | /// 业务逻辑层 6 | class PNumProvider extends ChangeNotifier { 7 | /// 初始化数据对象 8 | final state = PNumState(num: 0); 9 | 10 | /// 自增计数方法 11 | add() { 12 | state.num++; 13 | notifyListeners(); 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /lib/states/provider/p_num/state.dart: -------------------------------------------------------------------------------- 1 | /// 数据层 2 | class PNumState { 3 | int num; 4 | 5 | // 初始化 6 | PNumState({this.num = 0}); 7 | 8 | PNumState clone() { 9 | // 获取最新对象 10 | return PNumState()..num = num; 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /lib/states/provider/p_num/view.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/material.dart'; 2 | import 'package:provider/provider.dart'; 3 | 4 | import 'provider.dart'; 5 | 6 | /// UI层 7 | class PNumPage extends StatelessWidget { 8 | const PNumPage({super.key}); 9 | 10 | @override 11 | Widget build(BuildContext context) { 12 | return ChangeNotifierProvider( 13 | create: (BuildContext context) => PNumProvider(), 14 | builder: (context, child) => _buildPage(context), 15 | ); 16 | } 17 | 18 | Widget _buildPage(BuildContext context) { 19 | final provider = context.read(); 20 | // final state = providerer.state; 21 | return Stack( 22 | children: [ 23 | Consumer( 24 | builder: (context, provider, child) { 25 | return Center(child: Text("点击了${provider.state.num}次")); 26 | }, 27 | ), 28 | Positioned( 29 | child: FloatingActionButton( 30 | onPressed: () { 31 | provider.add(); 32 | }, 33 | child: Icon(Icons.add), 34 | ), 35 | bottom: 20, 36 | right: 20, 37 | ) 38 | ], 39 | ); 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /lib/states/qqq_bloc.dart: -------------------------------------------------------------------------------- 1 | import 'dart:async'; 2 | 3 | import 'package:bloc/bloc.dart'; 4 | import 'package:meta/meta.dart'; 5 | 6 | part 'qqq_event.dart'; 7 | part 'qqq_state.dart'; 8 | 9 | class QqqBloc extends Bloc { 10 | QqqBloc() : super(QqqInitial()) { 11 | on((event, emit) { 12 | // TODO: implement event handler 13 | }); 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /lib/states/qqq_event.dart: -------------------------------------------------------------------------------- 1 | part of 'qqq_bloc.dart'; 2 | 3 | @immutable 4 | abstract class QqqEvent {} 5 | -------------------------------------------------------------------------------- /lib/states/qqq_state.dart: -------------------------------------------------------------------------------- 1 | part of 'qqq_bloc.dart'; 2 | 3 | @immutable 4 | abstract class QqqState {} 5 | 6 | class QqqInitial extends QqqState {} 7 | -------------------------------------------------------------------------------- /lib/utils/bugly.dart: -------------------------------------------------------------------------------- 1 | // import 'package:flutter_bugly/flutter_bugly.dart'; 2 | 3 | class Bugly { 4 | static const String BUGLY_APP_ID_ANDROID = "68c358fc79"; 5 | static const String BUGLY_APP_ID_IOS = ""; // iOS暂未申请id 6 | 7 | Bugly._internal(); //单例 8 | 9 | ///初始化BugLy 10 | static void init() { 11 | // FlutterBugly.init( 12 | // androidAppId: BUGLY_APP_ID_ANDROID, iOSAppId: BUGLY_APP_ID_IOS) 13 | // .then((_result) { 14 | // print("Bugly初始化结果: ${_result.isSuccess}"); 15 | // }); 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /lib/utils/call_back.dart: -------------------------------------------------------------------------------- 1 | // 定义一个OnName函数 相当于原生接口中的函数 2 | typedef OnName = void Function(String, String); 3 | 4 | ///定义一个回调类 5 | class CallBack { 6 | OnName? name; 7 | 8 | CallBack({this.name}); 9 | } 10 | 11 | // 再定义一个类 12 | 13 | class Name { 14 | 15 | loadName(OnName? onName) { 16 | 17 | 18 | onName?.call("老李", "李云龙"); 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /lib/utils/sliver_to_widget.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/material.dart'; 2 | 3 | class SliverToWidget extends StatelessWidget { 4 | final Key? key; 5 | final Widget widget; 6 | 7 | const SliverToWidget(this.widget, {this.key}) : super(key: key); 8 | 9 | @override 10 | Widget build(BuildContext context) { 11 | return SliverToBoxAdapter( 12 | key: key, 13 | child: widget, 14 | ); 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /lib/utils/socket_util.dart: -------------------------------------------------------------------------------- 1 | import 'dart:async'; 2 | import 'dart:convert' as convert; 3 | import 'package:web_socket_channel/io.dart'; 4 | 5 | const appId = "83836aa0"; 6 | const apiSecret = "Y2M5OTI1MmZjY2NkNWYzZWY5OGJkMDRk"; 7 | const apiKey = "445f5702911ec04cfc9155e1350b2a53"; 8 | const String hostUrl = "wss://tts-api.xfyun.cn/v2/tts"; 9 | 10 | class SocketUtils { 11 | SocketUtils._(); 12 | 13 | static SocketUtils instance = SocketUtils._(); 14 | IOWebSocketChannel? _channel; 15 | Timer? _timer; 16 | 17 | void initSocket() { 18 | getAuthUrl(hostUrl, apiKey, apiSecret); 19 | 20 | _channel = IOWebSocketChannel.connect(Uri.parse("url")); 21 | Map params = Map(); 22 | // params["userId"] = SpUtils().getUserInfo().appUserDetailsVO.drvId; 23 | // params["userName"] = SpUtils().getUserInfo().appUserDetailsVO.drvName; 24 | // params["token"] = SpUtils().getUserInfo().token; 25 | 26 | // 发送信息 27 | _channel?.sink.add(convert.jsonEncode(params)); 28 | 29 | // 接收信息 30 | _channel?.stream.listen(this.onData, onError: onError, onDone: onDone); 31 | startCountdownTimer(); 32 | } 33 | 34 | ///开启心跳 35 | void startCountdownTimer() { 36 | const oneSec = const Duration(seconds: 10); 37 | var callback = (timer) { 38 | if (_channel == null) { 39 | initSocket(); 40 | } else {} 41 | }; 42 | _timer = Timer.periodic(oneSec, callback); 43 | } 44 | 45 | onDone() { 46 | print("消息关闭"); 47 | _channel?.sink.close(); 48 | _channel = null; 49 | } 50 | 51 | onError(err) { 52 | print("消息错误$err"); 53 | if (_channel != null) { 54 | _channel?.sink.close(); 55 | _channel = null; 56 | } 57 | } 58 | 59 | onData(event) { 60 | print("result == $event"); 61 | } 62 | 63 | void dispose() { 64 | if (_channel != null) { 65 | _channel?.sink.close(); 66 | print("socket通道关闭"); 67 | _channel = null; 68 | } 69 | _timer?.cancel(); 70 | _timer = null; 71 | } 72 | 73 | /// 鉴权 74 | void getAuthUrl(String url1, String apiKey, String apiSecret) { 75 | 76 | 77 | 78 | 79 | 80 | } 81 | } 82 | -------------------------------------------------------------------------------- /lib/utils/status.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/material.dart'; 2 | import 'package:provider/provider.dart'; 3 | import 'package:flutter_demo/models/app_theme.dart'; 4 | 5 | //全部状态管理 6 | class Status { 7 | // 单例 8 | Status._internal(); 9 | 10 | // 全局初始化 11 | static Widget init(Widget child) { 12 | //多个Provider 状态 13 | return MultiProvider( 14 | providers: [ 15 | ChangeNotifierProvider( 16 | create: (_) => AppTheme(AppTheme.getDefaultTheme())), 17 | ], 18 | child: child, 19 | ); 20 | } 21 | 22 | //获取值 of(context) 这个会引起页面的整体刷新,如果全局是页面级别的 23 | static T value(BuildContext context, {bool listen = false}) { 24 | return Provider.of(context, listen: listen); 25 | } 26 | 27 | //获取值 of(context) 这个会引起页面的整体刷新,如果全局是页面级别的 28 | static T of(BuildContext context, {bool listen = true}) { 29 | return Provider.of(context, listen: listen); 30 | } 31 | 32 | // 不会引起页面的刷新,只刷新了 Consumer 的部分,极大地缩小你的控件刷新范围 33 | static Consumer connect({builder, child}) { 34 | return Consumer(builder: builder, child: child); 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /lib/utils/xf_utils.dart: -------------------------------------------------------------------------------- 1 | import 'dart:convert'; 2 | 3 | import 'package:crypto/crypto.dart'; 4 | import 'package:intl/intl.dart'; 5 | 6 | /// 讯飞鉴权 7 | 8 | ///如果项目中使用了国际化,请约束DateFormat使用英文样式 9 | ///获取鉴权地址 10 | String getAuthUrl(String host, String apiKey, String apiSecret) { 11 | final DateFormat df = DateFormat("EEE, dd MMM yyyy HH:mm:ss 'GMT'"); 12 | String date = df.format(DateTime.now()); 13 | final String signatureOrigin = 'host: $host\ndate: $date\nGET /v2/tts HTTP/1.1'; 14 | final String signature = _hmacSha256Base64(signatureOrigin, apiSecret); 15 | final String authorizationOrigin = 16 | 'api_key="$apiKey", algorithm="hmac-sha256", headers="host date request-line", signature="$signature"'; 17 | final String authorization = base64.encode(authorizationOrigin.codeUnits); 18 | //对日期进行uri编码 19 | date = Uri.encodeComponent(date); 20 | final String url = 21 | 'wss://$host/v2/tts?authorization=$authorization&date=$date&host=$host'; 22 | print("鉴权 = $url"); 23 | return url; 24 | } 25 | 26 | ///hmacSha256加密后再进行base64编码 27 | String _hmacSha256Base64(String message, String secret) { 28 | List messageBytes = utf8.encode(message); 29 | List secretBytes = utf8.encode(secret); 30 | Hmac hmac = Hmac(sha256, secretBytes); 31 | Digest digest = hmac.convert(messageBytes); 32 | return base64.encode(digest.bytes); 33 | } 34 | 35 | 36 | ///wss://tts-api.xfyun.cn/v2/tts? 37 | ///authorization=YXBpX2tleT0iNDQ1ZjU3MDI5MTFlYzA0Y2ZjOTE1NWUxMzUwYjJhNTMiLCBhbGdvcml0aG09ImhtYWMtc2hhMjU2IiwgaGVhZGVycz0iaG9zdCBkYXRlIHJlcXVlc3QtbGluZSIsIHNpZ25hdHVyZT0id0dZYnYzRHBaaitvNHZSNzdnMDhQcU5NNTVuSkVBQ0hiaUdKVDMvVTFBQT0i&date=Mon%2C%2030%20May%202022%2014%3A50%3A53%20GMT&host=tts-api.xfyun.cn 38 | -------------------------------------------------------------------------------- /lib/widgets/align.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/material.dart'; 2 | 3 | class AlignDemo extends StatelessWidget { 4 | @override 5 | Widget build(BuildContext context) { 6 | return Container( 7 | width: 120, 8 | height: 120, 9 | color: Colors.blue[200], 10 | child: Align( 11 | alignment: FractionalOffset(1.2, 0.5), 12 | child:Column( 13 | mainAxisSize: MainAxisSize.min, 14 | children: [ 15 | Icon(Icons.router,size: 40,), 16 | Icon(Icons.router,size: 40,) 17 | ], 18 | ) 19 | ), 20 | ); 21 | } 22 | } 23 | /// 位置的设定 0-1 为父控件比例 24 | /// 25 | /// -------------------------------------------------------------------------------- /lib/widgets/baseful_widget.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/material.dart'; 2 | 3 | import 'code_page.dart'; 4 | 5 | class BaseStatefulWidget extends StatefulWidget { 6 | final Widget widget; 7 | final String title; 8 | final String codePath; 9 | final VoidCallback? onClick; 10 | 11 | BaseStatefulWidget(this.widget, this.title, this.codePath, {this.onClick}); 12 | 13 | @override 14 | State createState() { 15 | return BaseWidgetState(); 16 | } 17 | } 18 | 19 | class BaseWidgetState extends State { 20 | @override 21 | void initState() { 22 | super.initState(); 23 | } 24 | 25 | @override 26 | Widget build(BuildContext context) { 27 | return _buildWidgetDefault(); 28 | } 29 | 30 | Widget _buildWidgetDefault() { 31 | ///使用appbar,也可直接只有 body 在 body 里自定义状态栏、标题栏 32 | // return _buildBody(); 33 | return WillPopScope( 34 | child: Scaffold( 35 | // primary: false, 36 | appBar: widget.title.isEmpty ? null : _buildAppBar(), 37 | body: Container( 38 | // padding: EdgeInsetsDirectional.only(top: 20), 39 | child: _buildBody(), 40 | ), 41 | ), 42 | onWillPop: _requestPop); 43 | } 44 | 45 | Future _requestPop() { 46 | bool b = true; 47 | 48 | return Future.value(b); 49 | } 50 | 51 | AppBar? _buildAppBar() { 52 | return AppBar( 53 | title: Text(widget.title), 54 | centerTitle: true, 55 | actions: [ 56 | IconButton( 57 | icon: const Icon(Icons.code), 58 | onPressed: () { 59 | 60 | if (widget.onClick == null) { 61 | Navigator.push(context, MaterialPageRoute(builder: (context) { 62 | return CodePage(widget.codePath); 63 | })); 64 | } else { 65 | widget.onClick?.call(); 66 | } 67 | }), 68 | ], 69 | ); 70 | } 71 | 72 | Widget _buildBody() { 73 | return widget.widget; 74 | } 75 | } 76 | -------------------------------------------------------------------------------- /lib/widgets/baseless_widget.dart: -------------------------------------------------------------------------------- 1 | 2 | import 'package:flutter/material.dart'; 3 | 4 | // 静态页面基类 5 | abstract class BaseStatelessWidget extends StatelessWidget{ 6 | 7 | //构造 8 | const BaseStatelessWidget({Key? key}) :super(key: key); 9 | 10 | @override 11 | Widget build(BuildContext context) { 12 | return initDefaultBuild(context); 13 | } 14 | 15 | //构建界面 init 16 | Widget initDefaultBuild(BuildContext context); 17 | 18 | } -------------------------------------------------------------------------------- /lib/widgets/calendar.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/material.dart'; 2 | 3 | /// 自定义日历组件 4 | class CalendarDemo extends StatefulWidget { 5 | @override 6 | _CalendarState createState() => _CalendarState(); 7 | } 8 | 9 | class _CalendarState extends State { 10 | @override 11 | Widget build(BuildContext context) { 12 | return Container( 13 | child: CalendarDatePicker( 14 | initialDate: DateTime.now(), 15 | //初始化选中日期 16 | firstDate: DateTime(2000), 17 | lastDate: DateTime(2024), 18 | initialCalendarMode: DatePickerMode.day, 19 | onDateChanged: (dateTime) { 20 | print("onChange $dateTime"); 21 | }, 22 | selectableDayPredicate: (date) { 23 | if (date == DateTime(2023, 1, 15) || 24 | date == DateTime(2023, 1, 16) || 25 | date == DateTime(2023, 1, 17)) { 26 | return false; 27 | } 28 | return true; 29 | }, 30 | ), 31 | ); 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /lib/widgets/canvas/curbox.dart: -------------------------------------------------------------------------------- 1 | import 'dart:math'; 2 | 3 | import 'package:flutter/material.dart'; 4 | 5 | class CurveBoxPainter extends CustomPainter { 6 | final Animation repaint; 7 | Animation angleAnimation; 8 | final Listenable listenable; 9 | Paint _paint = Paint(); 10 | 11 | CurveBoxPainter(this.repaint, this.angleAnimation, this.listenable) 12 | : super(repaint: listenable); 13 | 14 | @override 15 | void paint(Canvas canvas, Size size) { 16 | canvas.clipRect(Offset.zero & size); 17 | canvas.translate(size.width / 2, size.height / 2); 18 | _drawRing(canvas, size); 19 | _drawRedCircle(canvas, size); 20 | _drawGreenCircle(canvas, size); 21 | } 22 | 23 | //绘制环 24 | void _drawRing(Canvas canvas, Size size) { 25 | final double strokeWidth = 5; 26 | _paint 27 | ..color = Colors.blue 28 | ..style = PaintingStyle.stroke 29 | ..strokeWidth = strokeWidth; 30 | canvas.drawCircle(Offset.zero, size.width / 2 - strokeWidth, _paint); 31 | } 32 | 33 | // 绘制红球 34 | void _drawRedCircle(Canvas canvas, Size size) { 35 | canvas.save(); 36 | canvas.rotate(angleAnimation.value * 2 * pi); 37 | _paint 38 | ..color = Colors.red 39 | ..style = PaintingStyle.fill; 40 | canvas.drawCircle( 41 | Offset.zero.translate(0, -(size.width / 2 - 5)), 5, _paint); 42 | canvas.restore(); 43 | } 44 | 45 | // 绘制绿球 46 | void _drawGreenCircle(Canvas canvas, Size size) { 47 | canvas.save(); 48 | canvas.translate(0, repaint.value * (size.height - 10)); 49 | _paint 50 | ..color = Colors.green 51 | ..style = PaintingStyle.fill; 52 | canvas.drawCircle( 53 | Offset.zero.translate(0, -(size.width / 2 - 5)), 5, _paint); 54 | canvas.restore(); 55 | } 56 | 57 | @override 58 | bool shouldRepaint(CurveBoxPainter oldDelegate) { 59 | return oldDelegate.repaint != repaint; 60 | } 61 | } 62 | -------------------------------------------------------------------------------- /lib/widgets/canvas/loading.dart: -------------------------------------------------------------------------------- 1 | 2 | import 'package:flutter/material.dart'; 3 | 4 | import '../coordinate.dart'; 5 | 6 | 7 | class LoadingDemo extends StatefulWidget { 8 | const LoadingDemo({Key? key}) : super(key: key); 9 | 10 | @override 11 | _LoadingDemoState createState() => _LoadingDemoState(); 12 | } 13 | 14 | class ColorRectTween extends Tween { 15 | ColorRectTween({super.begin, super.end}); 16 | 17 | @override 18 | ColorRect lerp(double t) { 19 | return ColorRect(Color.lerp(begin?.color, end?.color, t) ?? Colors.white, 20 | Rect.lerp(begin?.rect, end?.rect, t) ?? Rect.zero); 21 | } 22 | } 23 | 24 | class StringTween extends Tween { 25 | StringTween({super.begin, super.end}); 26 | 27 | @override 28 | String lerp(double t) { 29 | if ((t * 100).round() % 10 < 5) { 30 | return "$begin${end?.substring(0, ((end!.length * t).round()))} |"; 31 | } else { 32 | return "$begin${end?.substring(0, ((end!.length * t).round()))} "; 33 | } 34 | } 35 | } 36 | 37 | class ColorRect { 38 | Color color; 39 | Rect rect; 40 | 41 | ColorRect(this.color, this.rect); 42 | } 43 | 44 | class _LoadingDemoState extends State 45 | with SingleTickerProviderStateMixin { 46 | 47 | 48 | 49 | 50 | 51 | 52 | @override 53 | void initState() { 54 | super.initState(); 55 | } 56 | 57 | @override 58 | void dispose() { 59 | super.dispose(); 60 | } 61 | 62 | @override 63 | Widget build(BuildContext context) { 64 | return Container( 65 | color: Colors.white, 66 | child: CustomPaint( 67 | size: const Size(double.infinity, double.infinity), 68 | painter: _LoadingPaint(), 69 | ), 70 | ); 71 | } 72 | } 73 | 74 | class _LoadingPaint extends CustomPainter { 75 | 76 | 77 | 78 | Coordinate coordinate = Coordinate(setP: 20); 79 | 80 | @override 81 | void paint(Canvas canvas, Size size) { 82 | canvas.translate(size.width / 2, size.height / 2); 83 | coordinate.paintT(canvas, size); 84 | 85 | 86 | Paint paint = Paint() 87 | ..color = Colors.black87 88 | ..style = PaintingStyle.stroke 89 | ..strokeWidth = 2; 90 | 91 | 92 | canvas.drawCircle(Offset(0, 0), 10, paint); 93 | 94 | 95 | 96 | 97 | 98 | } 99 | 100 | @override 101 | bool shouldRepaint(covariant _LoadingPaint oldDelegate) { 102 | return false; 103 | } 104 | 105 | 106 | } 107 | -------------------------------------------------------------------------------- /lib/widgets/canvas/shou_you.dart: -------------------------------------------------------------------------------- 1 | import 'dart:math'; 2 | 3 | import 'package:flutter/material.dart'; 4 | 5 | class ShowYou extends StatefulWidget { 6 | final double size; 7 | final double handleRadius; 8 | 9 | const ShowYou({Key? key, this.size = 60, this.handleRadius = 30}) 10 | : super(key: key); 11 | 12 | @override 13 | _ShowYouState createState() => _ShowYouState(); 14 | } 15 | 16 | class _ShowYouState extends State { 17 | ValueNotifier _offset = ValueNotifier(Offset.zero); 18 | 19 | @override 20 | void initState() { 21 | super.initState(); 22 | 23 | 24 | } 25 | 26 | @override 27 | Widget build(BuildContext context) { 28 | return GestureDetector( 29 | onPanEnd: reset, 30 | onPanUpdate: parser, 31 | child: CustomPaint( 32 | size: Size(widget.size, widget.size), 33 | painter: _HandlePainter( 34 | color: Colors.green, 35 | handleR: widget.handleRadius, 36 | offset: _offset))); 37 | } 38 | 39 | reset(DragEndDetails details) { 40 | _offset.value = Offset.zero; 41 | } 42 | 43 | parser(DragUpdateDetails details) { 44 | final offset = details.localPosition; 45 | double dx = 0.0; 46 | double dy = 0.0; 47 | dx = offset.dx - widget.size / 2; 48 | dy = offset.dy - widget.size / 2; 49 | var rad = atan2(dx, dy); 50 | if (dx < 0) { 51 | rad += 2 * pi; 52 | } 53 | var bgR = widget.size / 2 - widget.handleRadius; 54 | var thta = rad - pi / 2; //旋转坐标系90度 55 | var d = sqrt(dx * dx + dy * dy);// 开平方根 56 | if (d > bgR) {// 如果边长大于 57 | dx = bgR * cos(thta);// 知道斜边、角度求边长 58 | dy = -bgR * sin(thta); 59 | } 60 | _offset.value = Offset(dx, dy); 61 | } 62 | } 63 | 64 | class _HandlePainter extends CustomPainter { 65 | var _paint = Paint(); 66 | final ValueNotifier offset; 67 | final Color color; 68 | var handleR; 69 | 70 | _HandlePainter({this.handleR, required this.offset, this.color = Colors.blue}) 71 | : super(repaint: offset) { 72 | _paint 73 | ..color = Colors.blue 74 | ..style = PaintingStyle.fill 75 | ..isAntiAlias = true; 76 | } 77 | 78 | @override 79 | void paint(Canvas canvas, Size size) {} 80 | 81 | @override 82 | bool shouldRepaint(covariant _HandlePainter oldDelegate) { 83 | return oldDelegate.handleR != handleR; 84 | } 85 | } 86 | -------------------------------------------------------------------------------- /lib/widgets/canvas/touch_controller.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/material.dart'; 2 | 3 | class TouchController extends ChangeNotifier { 4 | List _points = []; //点集合 5 | int _selectIndex = -1; 6 | 7 | int get selectIndex => _selectIndex; 8 | 9 | List get points => _points; 10 | 11 | // 选择点 12 | set selectIndex(int value) { 13 | if (_selectIndex == value) return; 14 | _selectIndex = value; 15 | notifyListeners(); 16 | } 17 | 18 | // 添加点 19 | void addPoint(Offset point) { 20 | points.add(point); 21 | notifyListeners(); 22 | } 23 | 24 | void updatePoint(int index, Offset point) { 25 | points[index] = point; 26 | notifyListeners(); 27 | } 28 | 29 | void removeLast() { 30 | points.removeLast(); 31 | notifyListeners(); 32 | } 33 | 34 | Offset? get selectPoint => _selectIndex == -1 ? null : _points[_selectIndex]; 35 | } 36 | -------------------------------------------------------------------------------- /lib/widgets/canvas/unlock_controller.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/material.dart'; 2 | 3 | class UnlockController extends ChangeNotifier { 4 | // 存储按压的点集合 5 | List _points = []; 6 | 7 | List get points => _points; 8 | 9 | // 当前手指的位置 10 | Offset? _currentOffset; 11 | 12 | Offset? get currentOffset => _currentOffset; 13 | 14 | set currentOffset(Offset? value) { 15 | _currentOffset = value; 16 | notifyListeners(); 17 | } 18 | 19 | // 颜色控制 20 | Color _color = Colors.blue; 21 | 22 | Color get color => _color; 23 | 24 | set color(Color value) { 25 | _color = value; 26 | notifyListeners(); 27 | } 28 | 29 | resetColor() { 30 | _color = Colors.blue; 31 | notifyListeners(); 32 | } 33 | 34 | addPoint(PassWord offset) { 35 | _points.add(offset); 36 | notifyListeners(); 37 | } 38 | 39 | // 清除所有点 40 | clearAllPoint() { 41 | _points.clear(); 42 | notifyListeners(); 43 | } 44 | } 45 | 46 | class PassWord { 47 | int num; // 密码数字 48 | Offset offset; // 密码数字对应的点 49 | PassWord(this.num, this.offset); 50 | } 51 | -------------------------------------------------------------------------------- /lib/widgets/canvas/xin_sui.dart: -------------------------------------------------------------------------------- 1 | import 'dart:math'; 2 | 3 | import 'package:flutter/material.dart'; 4 | 5 | /// 心碎的感觉 6 | class XinSui extends StatefulWidget { 7 | const XinSui({Key? key}) : super(key: key); 8 | 9 | @override 10 | _XinSuiState createState() => _XinSuiState(); 11 | } 12 | 13 | class _XinSuiState extends State with SingleTickerProviderStateMixin { 14 | late AnimationController _controller = 15 | AnimationController(vsync: this, duration: Duration(milliseconds: 4000)) 16 | ..repeat(); 17 | late CurvedAnimation cure = 18 | CurvedAnimation(parent: _controller, curve: Curves.bounceInOut); 19 | 20 | late Animation animation = 21 | Tween(begin: 0.0, end: 1.0).animate(cure); 22 | 23 | @override 24 | Widget build(BuildContext context) { 25 | return Container( 26 | child: CustomPaint( 27 | size: Size(double.infinity, double.infinity), 28 | painter: _XinSuiPainter(animation), 29 | ), 30 | ); 31 | } 32 | 33 | @override 34 | void dispose() { 35 | _controller.dispose(); 36 | super.dispose(); 37 | } 38 | } 39 | 40 | class _XinSuiPainter extends CustomPainter { 41 | Animation animation; 42 | 43 | _XinSuiPainter(this.animation) : super(repaint: animation); 44 | 45 | @override 46 | void paint(Canvas canvas, Size size) { 47 | canvas.translate(size.width / 2, size.height / 2); 48 | Paint paint = Paint(); 49 | paint 50 | ..style = PaintingStyle.stroke 51 | ..strokeWidth = 2 52 | ..color = Colors.black87; 53 | Path path = Path(); 54 | path.moveTo(0, 0); 55 | path.cubicTo(-200, -80, -60, -240, 0, -140); 56 | path.relativeLineTo(-10, 30); 57 | path.relativeLineTo(20, 5); 58 | path.relativeLineTo(-20, 30); 59 | path.relativeLineTo(20, 20); 60 | path.relativeLineTo(-10, 20); 61 | path.relativeLineTo(10, 10); 62 | path.close(); 63 | Path path2 = Path(); 64 | canvas.save(); 65 | canvas.rotate(-pi / 4 * animation.value); 66 | canvas.drawPath( 67 | path, 68 | paint 69 | ..color = Colors.red 70 | ..color = Color.fromRGBO( 71 | 255 - (86 * animation.value).toInt(), 72 | (animation.value * 169).toInt(), 73 | (animation.value * 169).toInt(), 74 | 1) 75 | ..style = PaintingStyle.fill); 76 | canvas.restore(); 77 | path2.cubicTo(200, -80, 60, -240, 0, -140); 78 | path2.relativeLineTo(-10, 30); 79 | path2.relativeLineTo(20, 5); 80 | path2.relativeLineTo(-20, 30); 81 | path2.relativeLineTo(20, 20); 82 | path2.relativeLineTo(-10, 20); 83 | path2.relativeLineTo(10, 10); 84 | path2.close(); 85 | canvas.rotate(pi / 4 * animation.value); 86 | canvas.drawPath(path2, paint); 87 | } 88 | 89 | @override 90 | bool shouldRepaint(covariant _XinSuiPainter oldDelegate) { 91 | return oldDelegate.animation != animation; 92 | } 93 | } 94 | -------------------------------------------------------------------------------- /lib/widgets/canvas_demo.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/material.dart'; 2 | import 'package:flutter_demo/widgets/canvas/wq_qp2.dart'; 3 | 4 | /// 绘制组件 5 | class CanvasDemo extends StatefulWidget { 6 | @override 7 | _CanvasState createState() => _CanvasState(); 8 | } 9 | 10 | class _CanvasState extends State { 11 | int qpSize = 19; 12 | bool isTry = false; 13 | bool showNum = true; 14 | bool isClean = false; 15 | 16 | @override 17 | Widget build(BuildContext context) { 18 | return Container( 19 | color: Colors.white70, 20 | // padding: EdgeInsets.only(top: 40, left: 100), 21 | alignment: Alignment.topLeft, 22 | child: Column( 23 | children: [ 24 | Container( 25 | margin: EdgeInsetsDirectional.only(top: 20, bottom: 20), 26 | child: Row( 27 | mainAxisAlignment: MainAxisAlignment.spaceAround, 28 | children: [ 29 | ElevatedButton( 30 | onPressed: () { 31 | setState(() { 32 | isClean = true; 33 | qpSize = 9; 34 | }); 35 | }, 36 | child: Text("9路")), 37 | ElevatedButton( 38 | onPressed: () { 39 | setState(() { 40 | isClean = true; 41 | qpSize = 13; 42 | }); 43 | }, 44 | child: Text("13路")), 45 | ElevatedButton( 46 | onPressed: () { 47 | setState(() { 48 | isClean = true; 49 | qpSize = 19; 50 | }); 51 | }, 52 | child: Text("19路")), 53 | ElevatedButton( 54 | onPressed: () { 55 | setState(() { 56 | isClean = false; 57 | isTry = !isTry; 58 | }); 59 | }, 60 | child: Text(isTry ? "关闭试下" : "开启试下")), 61 | ElevatedButton( 62 | onPressed: () { 63 | setState(() { 64 | isClean = false; 65 | showNum = !showNum; 66 | }); 67 | }, 68 | child: Text(showNum ? "关闭手数" : "显示手数")), 69 | ], 70 | ), 71 | ), 72 | WqQp( 73 | size: MediaQuery.of(context).size.width, 74 | qpSize: qpSize, 75 | isOpenTry: isTry, 76 | isShowNum: showNum, 77 | isCleanQP: isClean, 78 | ) 79 | ], 80 | )); 81 | } 82 | } 83 | 84 | // QpWidget( 85 | // width: MediaQuery.of(context).size.width / 1.2, 86 | // height: MediaQuery.of(context).size.width / 1.2, 87 | // qpSize: qpSize, 88 | // ), 89 | -------------------------------------------------------------------------------- /lib/widgets/clip_widget.dart: -------------------------------------------------------------------------------- 1 | 2 | 3 | import 'package:flutter/material.dart'; 4 | 5 | /// 作者: lixp 6 | /// 创建时间: 2022/7/25 10:19 7 | /// 类介绍:裁剪demo 8 | class ClipWidget extends StatefulWidget { 9 | const ClipWidget({Key? key}) : super(key: key); 10 | 11 | @override 12 | _ClipWidgetState createState() => _ClipWidgetState(); 13 | } 14 | 15 | class _ClipWidgetState extends State { 16 | @override 17 | Widget build(BuildContext context) { 18 | return Container( 19 | child: Stack( 20 | children: [ 21 | ClipPath( 22 | clipper: MyClipPath(), 23 | child: Container( 24 | color: Colors.red, 25 | width: MediaQuery.of(context).size.width, 26 | height: MediaQuery.of(context).size.height, 27 | 28 | child: Text("aaaaaaaa"), 29 | ), 30 | ), 31 | ClipPath( 32 | clipper: MyClipPath2(), 33 | child: Container( 34 | color: Colors.green, 35 | width: 300, 36 | height: 400, 37 | 38 | child: Text("bbbbbbb"), 39 | ), 40 | ), 41 | ], 42 | ) 43 | ); 44 | } 45 | } 46 | 47 | 48 | class MyClipPath extends CustomClipper{ 49 | @override 50 | Path getClip(Size size) { 51 | Path path = Path(); 52 | 53 | path.quadraticBezierTo(100, 100,100,10); 54 | path.lineTo(100,10); 55 | path.close(); 56 | return path; 57 | } 58 | 59 | @override 60 | bool shouldReclip(covariant CustomClipper oldClipper) { 61 | 62 | return false; 63 | } 64 | } 65 | class MyClipPath2 extends CustomClipper{ 66 | @override 67 | Path getClip(Size size) { 68 | Path path = Path(); 69 | 70 | path.quadraticBezierTo(100, 50,100,10); 71 | path.lineTo(100,10); 72 | path.close(); 73 | return path; 74 | } 75 | 76 | @override 77 | bool shouldReclip(covariant CustomClipper oldClipper) { 78 | 79 | return false; 80 | } 81 | } 82 | -------------------------------------------------------------------------------- /lib/widgets/code_page.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/material.dart'; 2 | import 'package:flutter/services.dart'; 3 | import 'package:flutter_demo/common/syntax_highlighter.dart'; 4 | 5 | class CodePage extends StatefulWidget { 6 | final String demoFilePath; 7 | 8 | const CodePage(this.demoFilePath, {super.key}); 9 | 10 | @override 11 | _CodePageState createState() => _CodePageState(); 12 | } 13 | 14 | class _CodePageState extends State { 15 | String? _markdownCodeString; 16 | var style = SyntaxHighlighterStyle.darkThemeStyle(); 17 | 18 | @override 19 | void initState() { 20 | super.initState(); 21 | } 22 | @override 23 | void didChangeDependencies() { 24 | getExampleCode( 25 | context, widget.demoFilePath, DefaultAssetBundle.of(context)) 26 | .then((String? code) { 27 | if (mounted) { 28 | setState(() { 29 | _markdownCodeString = code ?? 'Example code not found'; 30 | }); 31 | } 32 | }); 33 | super.didChangeDependencies(); 34 | } 35 | 36 | @override 37 | Widget build(BuildContext context) { 38 | Widget mdCode; 39 | try { 40 | DartSyntaxHighlighter(style).format(_markdownCodeString ?? ""); 41 | mdCode = Padding( 42 | padding: const EdgeInsets.all(8.0), 43 | child: RichText( 44 | text: TextSpan( 45 | style: const TextStyle(fontSize: 12.0), 46 | children: [ 47 | DartSyntaxHighlighter(style).format(_markdownCodeString ?? ""), 48 | ], 49 | ), 50 | ), 51 | ); 52 | } catch (err) { 53 | mdCode = Text(_markdownCodeString ??= ''); 54 | } 55 | return Scaffold( 56 | backgroundColor: style.codeBackground, 57 | appBar: AppBar( 58 | title: Text('Demo code'), 59 | actions: [ 60 | IconButton( 61 | icon: Icon(Icons.wb_sunny), 62 | onPressed: () { 63 | setState(() { 64 | style = SyntaxHighlighterStyle.lightThemeStyle(); 65 | }); 66 | }), 67 | ], 68 | ), 69 | body: _markdownCodeString == null 70 | ? Center( 71 | child: Text('Not found'), 72 | ) 73 | : SingleChildScrollView( 74 | child: mdCode, 75 | ), 76 | ); 77 | } 78 | } 79 | 80 | Map? _exampleCode; 81 | String? _code; 82 | 83 | Future getExampleCode( 84 | context, String filePath, AssetBundle bundle) async { 85 | if (_exampleCode == null) await _parseExampleCode(context, filePath, bundle); 86 | return _code ?? ""; 87 | } 88 | 89 | Future _parseExampleCode( 90 | context, String filePath, AssetBundle bundle) async { 91 | String? code; 92 | try { 93 | code = await bundle.loadString(filePath); 94 | } catch (err) { 95 | Navigator.of(context).pop(); 96 | print("xxxerr$err"); 97 | } 98 | _code = code; 99 | // print("xxx$_code"); 100 | } 101 | -------------------------------------------------------------------------------- /lib/widgets/container.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/material.dart'; 2 | 3 | class ContainerDemo extends StatefulWidget { 4 | @override 5 | _ContainerDemoState createState() => _ContainerDemoState(); 6 | } 7 | 8 | class _ContainerDemoState extends State { 9 | @override 10 | Widget build(BuildContext context) { 11 | return Container( 12 | padding: EdgeInsets.all(20), 13 | color: Colors.blue, 14 | child: Text("最常用的组件 包裹布局"), 15 | ); 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /lib/widgets/curve_box.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/material.dart'; 2 | 3 | import 'canvas/curbox.dart'; 4 | 5 | class CurveBox extends StatefulWidget { 6 | final Color color; 7 | final Curve curve1; 8 | final Curve curve2; 9 | 10 | CurveBox( 11 | {Key? key, 12 | this.color = Colors.lightBlue, 13 | this.curve1 = Curves.linear, 14 | this.curve2 = Curves.bounceIn}) 15 | : super(key: key); 16 | 17 | @override 18 | _CurveBoxState createState() => _CurveBoxState(); 19 | } 20 | 21 | class _CurveBoxState extends State 22 | with SingleTickerProviderStateMixin { 23 | late AnimationController _controller = 24 | AnimationController(duration: Duration(seconds: 3), vsync: this); 25 | late Animation _angleAnimation = CurveTween(curve: widget.curve1) 26 | .animate(_controller) 27 | ..addStatusListener((status) {}); 28 | late Animation repaint = CurveTween(curve: widget.curve2) 29 | .animate(_controller) 30 | ..addStatusListener((status) {}); 31 | 32 | @override 33 | void initState() { 34 | super.initState(); 35 | _controller.repeat(); 36 | } 37 | 38 | @override 39 | void dispose() { 40 | _controller.dispose(); 41 | super.dispose(); 42 | } 43 | 44 | @override 45 | Widget build(BuildContext context) { 46 | return CustomPaint( 47 | size: Size(100, 100), 48 | painter: CurveBoxPainter(_angleAnimation, repaint, 49 | Listenable.merge([_angleAnimation, repaint])), 50 | ); 51 | } 52 | } 53 | -------------------------------------------------------------------------------- /lib/widgets/data/change_provider.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/material.dart'; 2 | import 'package:flutter_demo/widgets/data/share_provider.dart'; 3 | 4 | class ChangeNotifierProvider extends StatefulWidget { 5 | final T? data; 6 | final Widget child; 7 | 8 | const ChangeNotifierProvider({Key? key, this.data, required this.child}) 9 | : super(key: key); 10 | 11 | static T? of(BuildContext context) { 12 | final provider = 13 | context.dependOnInheritedWidgetOfExactType>(); 14 | return provider?.data; 15 | } 16 | 17 | @override 18 | State createState() { 19 | return _ChangeNotifierProviderState(); 20 | } 21 | } 22 | 23 | class _ChangeNotifierProviderState 24 | extends State> { 25 | 26 | void update() { 27 | setState(() {}); 28 | } 29 | 30 | @override 31 | void didUpdateWidget( 32 | covariant ChangeNotifierProvider oldWidget) { 33 | if (oldWidget.data != widget.data) { 34 | oldWidget.data?.removeListener(update); 35 | widget.data?.addListener(update); 36 | } 37 | super.didUpdateWidget(oldWidget); 38 | } 39 | 40 | @override 41 | void initState() { 42 | widget.data?.addListener(update); 43 | super.initState(); 44 | } 45 | 46 | @override 47 | void dispose() { 48 | widget.data?.removeListener(update); 49 | super.dispose(); 50 | } 51 | 52 | @override 53 | Widget build(BuildContext context) { 54 | return ShareProvider(widget.data, widget.child); 55 | } 56 | } 57 | -------------------------------------------------------------------------------- /lib/widgets/data/share_data.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/material.dart'; 2 | 3 | class ShareDataWidget extends InheritedWidget { 4 | final int data; 5 | 6 | ShareDataWidget({required this.data, required Widget child}) : super(child: child); 7 | 8 | // 依赖数据调用didChangeDependencies()方法 9 | static ShareDataWidget? of(BuildContext? context) { 10 | return context?.dependOnInheritedWidgetOfExactType(); 11 | } 12 | 13 | // 依赖数据不调用didChangeDependencies()方法 14 | static InheritedWidget? of2(BuildContext? context) { 15 | return context?.getElementForInheritedWidgetOfExactType()?.widget as InheritedWidget; 16 | } 17 | 18 | @override 19 | bool updateShouldNotify(covariant ShareDataWidget oldWidget) { 20 | return oldWidget.data != data; 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /lib/widgets/data/share_provider.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/material.dart'; 2 | 3 | class ShareProvider extends InheritedWidget { 4 | final T? data; 5 | 6 | ShareProvider(this.data, Widget child) : super(child: child) ; 7 | 8 | @override 9 | bool updateShouldNotify(covariant ShareProvider oldWidget) { 10 | return true; 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /lib/widgets/decorated_box.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/material.dart'; 2 | 3 | class DecoratedBoxDemo extends StatefulWidget { 4 | @override 5 | _DecoratedBoxState createState() => _DecoratedBoxState(); 6 | } 7 | 8 | class _DecoratedBoxState extends State { 9 | @override 10 | Widget build(BuildContext context) { 11 | return Container( 12 | child: Column( 13 | children: [ 14 | Container( 15 | margin: EdgeInsets.all(20), 16 | child: DecoratedBox( 17 | child: Padding( 18 | padding: EdgeInsets.symmetric(vertical: 10, horizontal: 60), 19 | child: Text( 20 | "but", 21 | style: TextStyle(color: Colors.white), 22 | ), 23 | ), 24 | decoration: BoxDecoration( 25 | gradient: LinearGradient( 26 | begin: Alignment.topCenter, 27 | end: Alignment.bottomCenter, 28 | colors: [Colors.blue, Colors.blue[200]!]), 29 | borderRadius: BorderRadius.circular(4.0), 30 | boxShadow: [ 31 | BoxShadow( 32 | color: Colors.black54, 33 | offset: Offset(1.0, 2.0), 34 | blurRadius: 4) 35 | ])), 36 | ) 37 | ], 38 | ), 39 | ); 40 | } 41 | } 42 | // BoxDecoration({ 43 | // Color color, //颜色 44 | // DecorationImage image,//图片 45 | // BoxBorder border, //边框 46 | // BorderRadiusGeometry borderRadius, //圆角 47 | // List boxShadow, //阴影,可以指定多个 48 | // Gradient gradient, //渐变 49 | // BlendMode backgroundBlendMode, //背景混合模式 50 | // BoxShape shape = BoxShape.rectangle, //形状 51 | // }) 52 | -------------------------------------------------------------------------------- /lib/widgets/flex_demo.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/material.dart'; 2 | 3 | 4 | class FlexDemo extends StatefulWidget { 5 | const FlexDemo({Key? key}) : super(key: key); 6 | 7 | @override 8 | _FlexDemoState createState() => _FlexDemoState(); 9 | } 10 | 11 | class _FlexDemoState extends State { 12 | @override 13 | Widget build(BuildContext context) { 14 | return Container( 15 | // color: Colors.blue, 16 | child: Column( 17 | children: [ 18 | Row( 19 | // verticalDirection: VerticalDirection.up, 20 | crossAxisAlignment: CrossAxisAlignment.baseline, 21 | textBaseline: TextBaseline.ideographic, 22 | // crossAxisAlignment: CrossAxisAlignment.stretch, // 交叉轴紧约束 23 | mainAxisAlignment: MainAxisAlignment.spaceAround, 24 | children: const [ 25 | SizedBox( 26 | width: 50, 27 | height: 50, 28 | child: ColoredBox( 29 | color: Colors.red, 30 | child: Text("1"), 31 | ), 32 | ), 33 | SizedBox( 34 | width: 50, 35 | height: 50, 36 | child: ColoredBox( 37 | color: Colors.lightBlue, 38 | ), 39 | ), 40 | SizedBox( 41 | width: 50, 42 | height: 80, 43 | child: ColoredBox( 44 | color: Colors.blue, 45 | ), 46 | ), 47 | SizedBox( 48 | width: 50, 49 | height: 50, 50 | child: ColoredBox( 51 | color: Colors.green, 52 | ), 53 | ) 54 | ], 55 | ), 56 | 57 | 58 | 59 | 60 | 61 | 62 | ], 63 | ) 64 | ); 65 | } 66 | } 67 | -------------------------------------------------------------------------------- /lib/widgets/gallery_example_item.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/widgets.dart'; 2 | 3 | class GalleryExampleItem { 4 | GalleryExampleItem({ 5 | required this.id, 6 | required this.resource, 7 | this.isSvg = false, 8 | }); 9 | 10 | final String id; 11 | final String resource; 12 | final bool isSvg; 13 | } 14 | 15 | class GalleryExampleItemThumbnail extends StatelessWidget { 16 | const GalleryExampleItemThumbnail({ 17 | Key? key, 18 | required this.galleryExampleItem, 19 | required this.onTap, 20 | }) : super(key: key); 21 | 22 | final GalleryExampleItem galleryExampleItem; 23 | 24 | final GestureTapCallback onTap; 25 | 26 | @override 27 | Widget build(BuildContext context) { 28 | return Container( 29 | padding: const EdgeInsets.symmetric(horizontal: 5.0), 30 | child: GestureDetector( 31 | onTap: onTap, 32 | child: Hero( 33 | tag: galleryExampleItem.id, 34 | child: Image.asset(galleryExampleItem.resource, height: 80.0), 35 | ), 36 | ), 37 | ); 38 | } 39 | } 40 | 41 | List galleryItems = [ 42 | GalleryExampleItem( 43 | id: "tag1", 44 | resource: 45 | "https://images.unsplash.com/photo-1477346611705-65d1883cee1e?ixlib=rb-1.2.1&ixid=eyJhcHBfaWQiOjEyMDd9&auto=format&fit=crop&w=500&q=60", 46 | ), 47 | // GalleryExampleItem( 48 | // id: "tag3", 49 | // resource: 50 | // "https://images.unsplash.com/photo-1498550744921-75f79806b8a7?ixlib=rb-1.2.1&ixid=eyJhcHBfaWQiOjEyMDd9&auto=format&fit=crop&w=1050&q=80", 51 | // ), 52 | // GalleryExampleItem( 53 | // id: "tag4", 54 | // resource: 55 | // "https://images.unsplash.com/photo-1451187580459-43490279c0fa?ixlib=rb-1.2.1&ixid=eyJhcHBfaWQiOjEyMDd9&auto=format&fit=crop&w=500&q=60", 56 | // ), 57 | ]; 58 | -------------------------------------------------------------------------------- /lib/widgets/gesture_detector.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/material.dart'; 2 | 3 | class GestureDetectorDemo extends StatefulWidget { 4 | @override 5 | _GestureDetectorDemoState createState() => _GestureDetectorDemoState(); 6 | } 7 | 8 | class _GestureDetectorDemoState extends State { 9 | double _top = 20.0; //距顶部的偏移 10 | double _left = 20.0; //距左边的偏移 11 | 12 | double _top2 = 100.0; //距顶部的偏移 13 | double _left2 = 100.0; //距左边的偏移 14 | @override 15 | Widget build(BuildContext context) { 16 | return Stack( 17 | children: [ 18 | Positioned( 19 | top: _top, 20 | left: _left, 21 | child: GestureDetector( 22 | child: CircleAvatar(backgroundColor: Colors.red,child: Text("A")), 23 | //手指按下时会触发此回调 24 | onPanDown: (DragDownDetails e) { 25 | //打印手指按下的位置(相对于屏幕) 26 | print("用户手指按下:${e.globalPosition}"); 27 | }, 28 | //手指滑动时会触发此回调 29 | onPanUpdate: (DragUpdateDetails e) { 30 | //用户手指滑动时,更新偏移,重新构建 31 | setState(() { 32 | _left += e.delta.dx; 33 | _top += e.delta.dy; 34 | }); 35 | }, 36 | onPanEnd: (DragEndDetails e) { 37 | //打印滑动结束时在x、y轴上的速度 38 | print(e.velocity); 39 | }, 40 | ), 41 | ), 42 | Positioned( 43 | top: _top2, 44 | left: _left2, 45 | child: GestureDetector( 46 | child: CircleAvatar(backgroundColor: Colors.blue,child: Text("B")), 47 | //手指按下时会触发此回调 48 | onPanDown: (DragDownDetails e) { 49 | //打印手指按下的位置(相对于屏幕) 50 | print("用户手指按下:${e.globalPosition}"); 51 | }, 52 | //手指滑动时会触发此回调 53 | onPanUpdate: (DragUpdateDetails e) { 54 | //用户手指滑动时,更新偏移,重新构建 55 | setState(() { 56 | _left2 += e.delta.dx; 57 | _top2 += e.delta.dy; 58 | }); 59 | }, 60 | onPanEnd: (DragEndDetails e) { 61 | //打印滑动结束时在x、y轴上的速度 62 | print(e.velocity); 63 | }, 64 | ), 65 | ) 66 | ], 67 | ); 68 | } 69 | } 70 | -------------------------------------------------------------------------------- /lib/widgets/hero_demo.dart: -------------------------------------------------------------------------------- 1 | 2 | 3 | import 'package:flutter/material.dart'; 4 | import 'package:photo_view/photo_view.dart'; 5 | 6 | 7 | /// Hero 动画 demo 8 | class HeroDemo extends StatefulWidget { 9 | const HeroDemo({Key? key}) : super(key: key); 10 | 11 | @override 12 | _HeroDemoState createState() => _HeroDemoState(); 13 | } 14 | 15 | class _HeroDemoState extends State { 16 | @override 17 | Widget build(BuildContext context) { 18 | return Container( 19 | child: Hero(tag: "k", child: PhotoView( 20 | imageProvider: AssetImage("images/lbxx.png"), 21 | // imageProvider: NetworkImage("imageUrl"), 22 | )) 23 | ); 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /lib/widgets/listener.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/material.dart'; 2 | import 'package:fluttertoast/fluttertoast.dart'; 3 | 4 | class ListenerWidgetDemo extends StatefulWidget { 5 | @override 6 | _ListenerWidgetDemoState createState() => _ListenerWidgetDemoState(); 7 | } 8 | 9 | class _ListenerWidgetDemoState extends State { 10 | //定义一个状态,保存当前指针位置 11 | PointerEvent? _event; 12 | 13 | @override 14 | Widget build(BuildContext context) { 15 | return Listener( 16 | child: Container( 17 | alignment: Alignment.center, 18 | color: Colors.blue, 19 | width: double.infinity, 20 | height: double.infinity, 21 | child: Text(_event.toString(), 22 | style: TextStyle(color: Colors.white)), 23 | ), 24 | onPointerDown: (event) { 25 | setState(() { 26 | Fluttertoast.showToast(msg: "点击"); 27 | _event = event; 28 | }); 29 | }, 30 | onPointerMove: (event) { 31 | setState(() { 32 | _event = event; 33 | }); 34 | }, 35 | onPointerUp: (event) { 36 | setState(() { 37 | Fluttertoast.showToast(msg: "抬起"); 38 | _event = event; 39 | }); 40 | }, 41 | onPointerCancel: (event) { 42 | setState(() { 43 | _event = event; 44 | }); 45 | }, 46 | ); 47 | } 48 | } 49 | -------------------------------------------------------------------------------- /lib/widgets/logo.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/material.dart'; 2 | import 'package:flutter_demo/widgets/canvas/jue_jin_logo.dart'; 3 | 4 | class LogoDemo extends StatefulWidget { 5 | const LogoDemo({Key? key}) : super(key: key); 6 | 7 | @override 8 | State createState() => _LogoDemoState(); 9 | } 10 | 11 | class _LogoDemoState extends State { 12 | @override 13 | Widget build(BuildContext context) { 14 | return Container( 15 | margin: const EdgeInsetsDirectional.only(top: 20, start: 20), 16 | padding: const EdgeInsetsDirectional.all(30), 17 | color: Colors.yellow, 18 | child: const JueJinLogo( 19 | height: 60, 20 | ), 21 | ); 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /lib/widgets/move_damo.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/material.dart'; 2 | import 'package:flutter_demo/widgets/canvas/joystick.dart'; 3 | 4 | /// 作者: lixp 5 | /// 创建时间: 2022/7/7 15:41 6 | /// 类介绍:操作移动demo 7 | class MoveDemo extends StatefulWidget { 8 | const MoveDemo({Key? key}) : super(key: key); 9 | 10 | @override 11 | _MoveDemoState createState() => _MoveDemoState(); 12 | } 13 | 14 | class _MoveDemoState extends State { 15 | @override 16 | Widget build(BuildContext context) { 17 | return Container( 18 | color: Colors.black, 19 | child: JoyStick(), 20 | ); 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /lib/widgets/my_easy_refresh.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/material.dart'; 2 | import 'package:flutter_easyrefresh/easy_refresh.dart'; 3 | 4 | 5 | /// 再次对刷新控件进行封装 6 | class MyEasyRefresh extends StatefulWidget { 7 | final Widget? child; 8 | 9 | /// 控制器 10 | static final EasyRefreshController controller = EasyRefreshController(); 11 | 12 | /// 刷新回调(null为不开启刷新) 13 | final OnRefreshCallback? onRefresh; 14 | 15 | /// 加载回调(null为不开启加载) 16 | final OnLoadCallback? onLoad; 17 | 18 | MyEasyRefresh({Key? key, required this.child, this.onRefresh, this.onLoad}) 19 | : super(key: key); 20 | 21 | @override 22 | _MyEasyRefreshState createState() => _MyEasyRefreshState(); 23 | } 24 | 25 | class _MyEasyRefreshState extends State { 26 | @override 27 | Widget build(BuildContext context) { 28 | return EasyRefresh( 29 | // 自己控制是否刷新或者加载完成 30 | enableControlFinishLoad: true, 31 | enableControlFinishRefresh: true, 32 | child: widget.child, 33 | controller: MyEasyRefresh.controller, 34 | onLoad: widget.onLoad, 35 | onRefresh: widget.onRefresh, 36 | header: ClassicalHeader( 37 | infoText: "下拉刷新", 38 | refreshedText: "刷新完成", 39 | refreshText: "下拉刷新", 40 | refreshingText: "刷新中...", 41 | refreshReadyText: "松手刷新"), 42 | footer: ClassicalFooter( 43 | infoText: "", 44 | loadingText: "加载中...", 45 | textColor: Colors.black54, 46 | noMoreText: "没有更多数据了~"), 47 | ); 48 | } 49 | } 50 | -------------------------------------------------------------------------------- /lib/widgets/padding.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/material.dart'; 2 | 3 | class PaddingDemo extends StatefulWidget { 4 | @override 5 | _PaddingDemoState createState() => _PaddingDemoState(); 6 | } 7 | 8 | class _PaddingDemoState extends State { 9 | @override 10 | Widget build(BuildContext context) { 11 | return Container( 12 | child: Padding( 13 | padding: EdgeInsets.all(20), 14 | child: Column( 15 | crossAxisAlignment: CrossAxisAlignment.start, 16 | children: [ 17 | Container( 18 | color: Colors.blue, 19 | child: Padding( 20 | padding: EdgeInsets.symmetric(vertical: 10), 21 | child: Text("上下内边距"), 22 | ), 23 | ), 24 | Container( 25 | margin: EdgeInsets.all(10), 26 | color: Colors.blue, 27 | child: Padding( 28 | padding: EdgeInsets.symmetric(horizontal: 10), 29 | child: Text("左右内边距"), 30 | ), 31 | ), 32 | Container( 33 | margin: EdgeInsets.all(10), 34 | color: Colors.blue, 35 | child: Padding( 36 | padding: EdgeInsets.only(bottom: 10), 37 | child: Text("下内边距"), 38 | )) 39 | ], 40 | ), 41 | ), 42 | ); 43 | } 44 | } 45 | 46 | /// 内边距 47 | -------------------------------------------------------------------------------- /lib/widgets/paint2_demo.dart: -------------------------------------------------------------------------------- 1 | import 'dart:math'; 2 | import 'package:flutter/material.dart'; 3 | 4 | /// 动画绘制结合 5 | class Pain2Painter extends CustomPainter { 6 | final ValueNotifier color; // 吃豆人的颜色 7 | final ValueNotifier color2; // 豆子的的颜色 8 | final Animation angle; // 吃豆人 9 | final Animation angle2; // 豆 10 | final Listenable listenable; 11 | final double ddSize; // 豆豆大小 12 | 13 | 14 | Pain2Painter( 15 | this.color, this.color2, this.angle, this.angle2, this.listenable, 16 | {this.ddSize = 6}) 17 | : super(repaint: listenable); 18 | Paint _paint = Paint(); 19 | 20 | @override 21 | void paint(Canvas canvas, Size size) { 22 | canvas.clipRect(Offset.zero & size); 23 | canvas.translate(size.width / 2, size.height / 2); 24 | // 画豆豆 25 | canvas.drawOval( 26 | Rect.fromCenter( 27 | center: Offset( 28 | size.width / 2 + 29 | ddSize - 30 | angle2.value * (size.width / 2 + ddSize), 31 | 0), 32 | width: ddSize, 33 | height: ddSize), 34 | _paint..color = color2.value); 35 | //画头 36 | _paint 37 | ..color = color.value 38 | ..style = PaintingStyle.fill; 39 | 40 | var rect = Rect.fromCenter( 41 | center: Offset(0, 0), width: size.width, height: size.height); 42 | 43 | /// 起始角度 44 | /// angle.value 动画控制器的值 0.2~1 0是完全闭合就是 起始0~360° 1是完全张开 起始 40°~ 280° 顺时针 45 | var a = angle.value * 40 / 180 * pi; 46 | // 绘制圆弧 47 | canvas.drawArc(rect, a, 2 * pi - a * 2, true, _paint); 48 | //画眼睛 49 | canvas.drawOval( 50 | Rect.fromCenter( 51 | center: Offset(0, -size.height / 3), width: 8, height: 8), 52 | _paint..color = Colors.black87); 53 | canvas.drawOval( 54 | Rect.fromCenter( 55 | center: Offset(-1.5, -size.height / 3 - 1.5), width: 3, height: 3), 56 | _paint..color = Colors.white); 57 | } 58 | 59 | @override 60 | bool shouldRepaint(covariant Pain2Painter oldDelegate) { 61 | return oldDelegate.listenable != listenable; 62 | } 63 | } 64 | -------------------------------------------------------------------------------- /lib/widgets/polygonal.dart: -------------------------------------------------------------------------------- 1 | import 'dart:math'; 2 | import 'package:flutter/material.dart'; 3 | enum Type { 4 | angle, // 角 5 | side, // 边 6 | all, // 都有 7 | } 8 | 9 | /// 角 边 型 10 | class Polygonal extends StatelessWidget { 11 | final double size; // 组件大小 12 | final double? bigR; // 大圆半径 13 | final double? smallR; // 小圆半径 14 | final int count; // 几边形 15 | final Type type; // 五角星or五边形 16 | final bool isFill; // 是否填充 17 | final Color color; // 颜色 18 | 19 | const Polygonal( 20 | {Key? key, 21 | this.size = 80, 22 | this.bigR, 23 | this.smallR, 24 | this.count = 3, 25 | this.type = Type.angle, 26 | this.isFill = false, 27 | this.color = Colors.black87}) 28 | : super(key: key); 29 | 30 | @override 31 | Widget build(BuildContext context) { 32 | return CustomPaint( 33 | size: Size(size, size), 34 | painter: _PolygonalPainter(bigR, smallR, 35 | color: color, count: count, type: type, isFill: isFill), 36 | ); 37 | } 38 | } 39 | 40 | class _PolygonalPainter extends CustomPainter { 41 | final double? bigR; 42 | final double? smallR; 43 | final int count; // 几边形 44 | final Type type; // 五角星or五边形 45 | final bool isFill; // 是否填充 46 | final Color color; // 颜色 47 | _PolygonalPainter(this.bigR, this.smallR, 48 | {required this.count, 49 | required this.type, 50 | required this.isFill, 51 | required this.color}); 52 | 53 | @override 54 | void paint(Canvas canvas, Size size) { 55 | canvas.clipRect(Offset.zero & size); 56 | canvas.translate(size.width / 2, size.height / 2); 57 | Paint paint2 = Paint() 58 | ..color = color 59 | ..strokeJoin = StrokeJoin.round 60 | ..style = isFill ? PaintingStyle.fill : PaintingStyle.stroke 61 | ..strokeWidth = 2; 62 | double r = bigR ?? size.width / 2 / 2; 63 | double r2 = smallR ?? size.width / 2 / 2 - 12; 64 | // 将圆等分 65 | Path path = Path(); 66 | canvas.rotate(pi / count + pi / 2 * 3); 67 | path.moveTo(r * cos(pi / count), r * sin(pi / count)); 68 | 69 | /// 绘制角 70 | if (type == Type.angle || type == Type.all) { 71 | for (int i = 2; i <= count * 2; i++) { 72 | if (i.isEven) { 73 | path.lineTo(r2 * cos(pi / count * i), r2 * sin(pi / count * i)); 74 | } else { 75 | path.lineTo(r * cos(pi / count * i), r * sin(pi / count * i)); 76 | } 77 | } 78 | path.close(); 79 | canvas.drawPath(path, paint2); 80 | } 81 | 82 | /// 绘制边 83 | if (type == Type.side || type == Type.all) { 84 | path.reset(); 85 | path.moveTo(r * cos(pi / count), r * sin(pi / count)); 86 | for (int i = 2; i <= count * 2; i++) { 87 | if (i.isOdd) { 88 | path.lineTo(r * cos(pi / count * i), r * sin(pi / count * i)); 89 | } 90 | } 91 | path.close(); 92 | canvas.drawPath(path, paint2); 93 | } 94 | 95 | } 96 | 97 | @override 98 | bool shouldRepaint(covariant CustomPainter oldDelegate) { 99 | return false; 100 | } 101 | } 102 | -------------------------------------------------------------------------------- /lib/widgets/progress.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/material.dart'; 2 | 3 | class ProgressWidgetDemo extends StatefulWidget { 4 | const ProgressWidgetDemo({super.key}); 5 | 6 | @override 7 | State createState() { 8 | return ProgressState(); 9 | } 10 | } 11 | 12 | class ProgressState extends State { 13 | @override 14 | Widget build(BuildContext context) { 15 | return Container( 16 | margin: EdgeInsets.all(10), 17 | child: Column( 18 | children: [ 19 | Container( 20 | margin: EdgeInsets.all(20), 21 | child: Text("LinearProgressIndicator"), 22 | ), 23 | Container( 24 | margin: EdgeInsets.all(20), 25 | child: LinearProgressIndicator( 26 | valueColor: AlwaysStoppedAnimation(Colors.blue), 27 | backgroundColor: Colors.blue[200], 28 | ), 29 | ), 30 | Container( 31 | height: 2, 32 | margin: EdgeInsets.all(20), 33 | child: LinearProgressIndicator( 34 | valueColor: AlwaysStoppedAnimation(Colors.blue), 35 | backgroundColor: Colors.blue[200], 36 | value: 0.4, 37 | ), 38 | ), 39 | Text("CircularProgressIndicator"), 40 | Row( 41 | children: [ 42 | Container( 43 | margin: EdgeInsets.all(20), 44 | child: CircularProgressIndicator( 45 | valueColor: AlwaysStoppedAnimation(Colors.blue), 46 | backgroundColor: Colors.blue[200], 47 | ), 48 | ), 49 | Container( 50 | width: 20, 51 | height: 20, 52 | margin: EdgeInsets.all(20), 53 | child: CircularProgressIndicator( 54 | valueColor: AlwaysStoppedAnimation(Colors.blue), 55 | backgroundColor: Colors.red[200], 56 | value: 0.4, 57 | ), 58 | ), 59 | ], 60 | ) 61 | ], 62 | ), 63 | ); 64 | } 65 | } 66 | 67 | ///LinearProgressIndicator 属性 68 | /// value 当前进度,0 ~ 1 69 | /// backgroundColor 进度条背景色 70 | /// valueColor Animation 进度条当前进度颜色, 71 | /// 使用不变的颜色可以使用 AlwaysStoppedAnimation(Colors.red) 72 | /// minHeight 最小宽度,默认为 4.0 73 | /// semanticsLabel 语义标签 74 | /// semanticsValue 语义Value 75 | 76 | /// CircularProgressIndicator 属性 77 | /// value 当前进度,0 ~ 1 78 | /// backgroundColor 进度条背景色 79 | /// valueColor Animation 进度条当前进度颜色, 80 | /// 使用不变的颜色可以使用 AlwaysStoppedAnimation(Colors.red) 81 | /// strokeWidth 最小宽度,默认为 4.0 82 | /// semanticsLabel 语义标签 83 | /// semanticsValue 语义Value 84 | -------------------------------------------------------------------------------- /lib/widgets/qi_pao.dart: -------------------------------------------------------------------------------- 1 | import 'dart:math'; 2 | 3 | import 'package:flutter/material.dart'; 4 | 5 | class QiPao extends StatelessWidget { 6 | final String text; 7 | 8 | const QiPao({Key? key, this.text = ""}) : super(key: key); 9 | 10 | @override 11 | Widget build(BuildContext context) { 12 | return Container( 13 | child: CustomPaint( 14 | size: Size(60, 60), 15 | painter: QiPaoPainter(text), 16 | ), 17 | ); 18 | } 19 | } 20 | 21 | class QiPaoPainter extends CustomPainter { 22 | final String text; 23 | 24 | QiPaoPainter(this.text); 25 | 26 | @override 27 | void paint(Canvas canvas, Size size) { 28 | // 原点移到左下角 29 | canvas.translate(size.width / 2, size.height / 2); 30 | Paint paint = Paint() 31 | ..color = Colors.redAccent 32 | ..strokeWidth = 2 33 | ..style = PaintingStyle.fill; 34 | 35 | Path path = Path(); 36 | // 绘制文字 37 | 38 | path.lineTo(0, -size.width / 2); 39 | // path.conicTo(33, -28, 20, 0, 1); 40 | 41 | path.arcToPoint(Offset(size.width / 2, 0), 42 | radius: Radius.circular(size.width / 2), 43 | largeArc: true, 44 | clockwise: true); 45 | path.close(); 46 | var bounds = path.getBounds(); 47 | canvas.save(); 48 | canvas.translate(-bounds.width / 2, bounds.height / 2); 49 | canvas.rotate(pi * 1.2); 50 | canvas.drawPath(path, paint); 51 | canvas.restore(); 52 | // 绘制文字 53 | var textPainter = TextPainter( 54 | text: TextSpan( 55 | text: text, 56 | style: TextStyle( 57 | fontSize: 24, 58 | foreground: Paint() 59 | ..style = PaintingStyle.fill 60 | ..color = Colors.white, 61 | )), 62 | textAlign: TextAlign.center, 63 | textDirection: TextDirection.ltr); 64 | textPainter.layout(); 65 | canvas.translate(-size.width, -size.height / 2); 66 | textPainter.paint(canvas, Offset(-size.width / 2.4, size.height / 1.2)); 67 | } 68 | 69 | @override 70 | bool shouldRepaint(covariant CustomPainter oldDelegate) { 71 | return false; 72 | } 73 | } 74 | -------------------------------------------------------------------------------- /lib/widgets/rain.dart: -------------------------------------------------------------------------------- 1 | 2 | 3 | class Rain{ 4 | 5 | } -------------------------------------------------------------------------------- /lib/widgets/size_box.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/material.dart'; 2 | 3 | class SizeBoxDemo extends StatefulWidget { 4 | @override 5 | _SizeBoxDemoState createState() => _SizeBoxDemoState(); 6 | } 7 | 8 | class _SizeBoxDemoState extends State { 9 | @override 10 | Widget build(BuildContext context) { 11 | return Container( 12 | margin: EdgeInsets.all(20), 13 | child: Column( 14 | mainAxisSize: MainAxisSize.max, 15 | children: [ 16 | ConstrainedBox( 17 | constraints: 18 | BoxConstraints(minWidth: double.infinity, minHeight: 50), 19 | child: Container( 20 | height: 1, 21 | child: DecoratedBox( 22 | child: Align( 23 | alignment: Alignment.center, 24 | child: Text("ConstrainedBox 限制最小高度"), 25 | ), 26 | decoration: BoxDecoration(color: Colors.blue), 27 | ), 28 | ), 29 | ), 30 | SizedBox( 31 | width: 100, 32 | height: 50, 33 | child: Container( 34 | color: Colors.red, 35 | child: Align( 36 | alignment: Alignment.center, 37 | child: Text("SizedBox 限制固定宽高"), 38 | ), 39 | ), 40 | ), 41 | ConstrainedBox( 42 | constraints: BoxConstraints(maxWidth: 100, maxHeight: 50), 43 | child: ConstrainedBox( 44 | constraints: BoxConstraints(maxWidth: 70, maxHeight: 100), 45 | child: Container( 46 | color: Colors.blue, 47 | child: Center( 48 | child: Text("限制最大宽高"), 49 | ), 50 | ), 51 | ), 52 | ) 53 | ], 54 | )); 55 | } 56 | } 57 | -------------------------------------------------------------------------------- /lib/widgets/stack.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/material.dart'; 2 | 3 | class StackWidgetDemo extends StatefulWidget { 4 | const StackWidgetDemo({super.key}); 5 | 6 | @override 7 | State createState() { 8 | return StackState(); 9 | } 10 | } 11 | 12 | class StackState extends State { 13 | @override 14 | Widget build(BuildContext context) { 15 | return ConstrainedBox( 16 | constraints: const BoxConstraints.expand(), 17 | child: Stack( 18 | alignment: Alignment.center, 19 | fit: StackFit.loose, 20 | children: _widgets(), 21 | )); 22 | } 23 | 24 | List _widgets() { 25 | List list = []; 26 | 27 | list.add(Container( 28 | color: Colors.black26, 29 | )); 30 | 31 | for (int i = 1; i < 100; i++) { 32 | list.add(Container( 33 | margin: EdgeInsets.all(10.0 * i), 34 | color: Colors.black.withOpacity(i / 100), 35 | )); 36 | } 37 | 38 | list.add(const Text("default")); 39 | list.add(const Positioned( 40 | left: 10, 41 | child: Text("left"), 42 | )); 43 | list.add(const Positioned( 44 | top: 10, 45 | child: Text("top"), 46 | )); 47 | list.add(const Positioned( 48 | right: 10, 49 | child: Text("right"), 50 | )); 51 | list.add( 52 | const Positioned( 53 | bottom: 10, 54 | child: Text("bottom"), 55 | ), 56 | ); 57 | 58 | return list; 59 | } 60 | } 61 | -------------------------------------------------------------------------------- /lib/widgets/store.dart: -------------------------------------------------------------------------------- 1 | 2 | import 'package:flutter/material.dart'; 3 | import 'package:provider/provider.dart'; 4 | import 'package:flutter_demo/common/theme_common.dart'; 5 | 6 | class Store{ 7 | /// 单例 8 | Store._internal(); 9 | 10 | /// 全局初始化 11 | static init(Widget child) { 12 | //多个Provider 13 | return MultiProvider( 14 | providers: [ 15 | // ChangeNotifierProvider(create: (_) => AppTheme(ThemeCommon.lightTheme)), 16 | ], 17 | child: child, 18 | ); 19 | } 20 | 21 | //获取值 of(context) 这个会引起页面的整体刷新,如果全局是页面级别的 22 | static T value(BuildContext context, {bool listen = false}) { 23 | return Provider.of(context, listen: listen); 24 | } 25 | 26 | //获取值 of(context) 这个会引起页面的整体刷新,如果全局是页面级别的 27 | static T of(BuildContext context, {bool listen = true}) { 28 | return Provider.of(context, listen: listen); 29 | } 30 | 31 | // 不会引起页面的刷新,只刷新了 Consumer 的部分,极大地缩小你的控件刷新范围 32 | static Consumer connect({builder, child}) { 33 | return Consumer(builder: builder, child: child); 34 | } 35 | } -------------------------------------------------------------------------------- /lib/widgets/stream_build.dart: -------------------------------------------------------------------------------- 1 | import 'dart:async'; 2 | 3 | import 'package:flutter/material.dart'; 4 | 5 | import 'stream_build_util.dart'; 6 | 7 | /// 局部刷新状态 8 | class StreamBuild { 9 | late StreamController _controller; 10 | 11 | T? t; 12 | 13 | final String key; 14 | 15 | StreamBuild(this.key) { 16 | _controller = StreamController.broadcast(); 17 | } 18 | 19 | factory StreamBuild.instance(String key) { 20 | return StreamBuild(key); 21 | } 22 | 23 | get outer => _controller.stream; 24 | 25 | get data => t; 26 | 27 | // 改变数据发送 28 | changeData(T t) { 29 | this.t = t; 30 | _controller.sink.add(t); 31 | } 32 | 33 | dis() { 34 | _controller.close(); 35 | } 36 | 37 | // 监听者 38 | Widget addObserver(Widget Function(T t) ob, {required T initialData}) { 39 | this.t = data ?? initialData; 40 | // var streamBuild = this as StreamBuild; 41 | return StreamBuilderWidget( 42 | streamBuild: this, 43 | builder: ob, 44 | initialData: initialData, 45 | ); 46 | } 47 | } 48 | 49 | class StreamBuilderWidget extends StatefulWidget { 50 | final StreamBuild streamBuild; 51 | final Widget Function(T t) builder; 52 | final T? initialData; 53 | 54 | const StreamBuilderWidget( 55 | {Key? key, 56 | required this.streamBuild, 57 | required this.builder, 58 | required this.initialData}) 59 | : super(key: key); 60 | 61 | @override 62 | _StreamBuilderWidgetState createState() => _StreamBuilderWidgetState(); 63 | } 64 | 65 | class _StreamBuilderWidgetState extends State { 66 | @override 67 | Widget build(BuildContext context) { 68 | return StreamBuilder( 69 | initialData: widget.initialData, 70 | stream: widget.streamBuild.outer, 71 | builder: (context, n) { 72 | return widget.builder(n.data as T); 73 | }); 74 | } 75 | 76 | @override 77 | void dispose() { 78 | super.dispose(); 79 | widget.streamBuild.dis(); 80 | 81 | StreamBuildUtil.instance.onDisposeKey(widget.streamBuild.key); // 清除map数据 82 | } 83 | } 84 | -------------------------------------------------------------------------------- /lib/widgets/stream_build_util.dart: -------------------------------------------------------------------------------- 1 | import 'stream_build.dart'; 2 | 3 | /// 局部刷新工具类 4 | class StreamBuildUtil { 5 | static StreamBuildUtil? _instance; 6 | 7 | StreamBuildUtil._(); 8 | 9 | factory StreamBuildUtil() { 10 | return instance; 11 | } 12 | 13 | static StreamBuildUtil get instance => _getInstance(); 14 | 15 | static StreamBuildUtil _getInstance() { 16 | if (_instance == null) { 17 | _instance = StreamBuildUtil._(); 18 | } 19 | return _instance ?? StreamBuildUtil._(); 20 | } 21 | 22 | final Map dataBus = {}; 23 | 24 | /// key = 刷新局部标记 25 | StreamBuild getStream(String key) { 26 | if (!dataBus.containsKey(key)) { 27 | StreamBuild streamBuild = StreamBuild.instance(key); 28 | dataBus[key] = streamBuild; 29 | } 30 | if (dataBus[key] == null) { 31 | return StreamBuild.instance(key); 32 | } else { 33 | return dataBus[key]!; 34 | } 35 | } 36 | 37 | void onDisposeAll() { 38 | if (dataBus.length > 0) { 39 | dataBus.values.forEach((f) => f.dis()); 40 | dataBus.clear(); 41 | } 42 | } 43 | 44 | void onDisposeKey(String? key) { 45 | if (dataBus.length > 0) { 46 | dataBus.remove(key); 47 | } 48 | } 49 | } 50 | -------------------------------------------------------------------------------- /lib/widgets/tab_bar.dart: -------------------------------------------------------------------------------- 1 | 2 | 3 | import 'package:flutter/material.dart'; 4 | 5 | class TabBarWidgetDemo extends StatefulWidget{ 6 | @override 7 | State createState() { 8 | return TabBarState(); 9 | } 10 | } 11 | 12 | class TabBarState extends State { 13 | @override 14 | Widget build(BuildContext context) { 15 | 16 | return Container( 17 | 18 | ); 19 | } 20 | } -------------------------------------------------------------------------------- /lib/widgets/tab_bar_demo.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/material.dart'; 2 | import 'package:flutter_demo/utils/view/my_tab_indicator.dart'; 3 | 4 | /// TabBarDemo 5 | class TabBarDemo extends StatefulWidget { 6 | const TabBarDemo({Key? key}) : super(key: key); 7 | 8 | @override 9 | _TabBarDemoState createState() => _TabBarDemoState(); 10 | } 11 | 12 | class _TabBarDemoState extends State 13 | with SingleTickerProviderStateMixin { 14 | List tabs = ["TAB1", "TAB2", "TAB3", "TAB4", "TAB5", "TAB6"]; 15 | late TabController _tabController = 16 | TabController(length: tabs.length, vsync: this); //tab 控制器 17 | 18 | @override 19 | void initState() { 20 | super.initState(); 21 | } 22 | 23 | @override 24 | Widget build(BuildContext context) { 25 | return Column( 26 | children: [ 27 | TabBar( 28 | isScrollable: true, 29 | indicator: MyTabIndicator( 30 | borderSide: BorderSide( 31 | width: 4, 32 | color: Colors.redAccent, 33 | ), 34 | // indicatorWidth: 4, 35 | indicatorBottom: 20, 36 | indicatorWidth: 30 37 | // tabController: _tabController 38 | ), 39 | controller: _tabController, 40 | tabs: tabs 41 | .map((value) => Tab( 42 | height: 44, 43 | text: value, 44 | )) 45 | .toList(), 46 | labelColor: Colors.black87, 47 | unselectedLabelColor: Colors.black87, 48 | ), 49 | Expanded( 50 | child: TabBarView( 51 | controller: _tabController, 52 | children: tabs.map((value) => Test()).toList(), 53 | ),) 54 | ], 55 | ); 56 | } 57 | } 58 | 59 | class Test extends StatefulWidget { 60 | const Test({Key? key}) : super(key: key); 61 | 62 | @override 63 | _TestState createState() => _TestState(); 64 | } 65 | 66 | class _TestState extends State { 67 | @override 68 | void initState() { 69 | super.initState(); 70 | 71 | } 72 | 73 | @override 74 | Widget build(BuildContext context) { 75 | return Container( 76 | child: Text("xxx"), 77 | ); 78 | } 79 | } 80 | -------------------------------------------------------------------------------- /lib/widgets/table_demo.dart: -------------------------------------------------------------------------------- 1 | import 'dart:math'; 2 | 3 | import 'package:flutter/material.dart'; 4 | 5 | class TableDemo extends StatefulWidget { 6 | const TableDemo({Key? key}) : super(key: key); 7 | 8 | @override 9 | _TableDemoState createState() => _TableDemoState(); 10 | } 11 | 12 | class _TableDemoState extends State { 13 | @override 14 | Widget build(BuildContext context) { 15 | return Container( 16 | height: 400, 17 | margin: EdgeInsetsDirectional.all(20), 18 | child: SingleChildScrollView( 19 | scrollDirection: Axis.vertical, 20 | child: SingleChildScrollView( 21 | scrollDirection: Axis.horizontal, 22 | child: Table( 23 | textBaseline: TextBaseline.alphabetic, 24 | defaultVerticalAlignment: TableCellVerticalAlignment.middle, 25 | defaultColumnWidth: IntrinsicColumnWidth(), 26 | children: _getTabRows(), 27 | border: TableBorder.all(color: Colors.red, width: 1), 28 | ),)), 29 | ); 30 | } 31 | List _getTabRows() { 32 | 33 | Wrap(); 34 | List tabs = []; 35 | 36 | // 设置学科 37 | tabs.add(TableRow( 38 | decoration: BoxDecoration(color: Colors.grey), 39 | children: titles(), 40 | )); 41 | // 成绩 60人 42 | for (int i = 0; i < 3; i++) { 43 | tabs.add(TableRow( 44 | decoration: BoxDecoration(color: Colors.white), 45 | children: contents(i==0?"法外狂徒张三$i":'张三$i'), 46 | )); 47 | } 48 | return tabs; 49 | } 50 | 51 | List titles() { 52 | List titles = []; 53 | titles.add(xkTitle("姓名")); 54 | // 学科 55 | titles.add(xkTitle("语文")); 56 | titles.add(xkTitle("数学")); 57 | titles.add(xkTitle("英语")); 58 | // titles.add(xkTitle("物理")); 59 | // titles.add(xkTitle("化学")); 60 | // titles.add(xkTitle("生物")); 61 | // titles.add(xkTitle("地理")); 62 | // titles.add(xkTitle("历史")); 63 | // titles.add(xkTitle("政治")); 64 | return titles; 65 | } 66 | 67 | Widget xkTitle(String text) { 68 | return TableCell( 69 | child: Container( 70 | alignment: Alignment.center, 71 | padding: EdgeInsetsDirectional.all(10), 72 | child: Text(text), 73 | ), 74 | verticalAlignment: TableCellVerticalAlignment.middle, 75 | ); 76 | } 77 | 78 | List contents(String name) { 79 | List titles = []; 80 | Random random = Random.secure(); 81 | for (int i = 0; i < 4; i++) { 82 | titles.add(TableCell( 83 | child: Container( 84 | // height: 200, 85 | alignment: Alignment.center, 86 | padding: EdgeInsetsDirectional.all(10), 87 | child: Text(i == 0 ? name : random.nextInt(100).toString()), 88 | ), 89 | verticalAlignment: TableCellVerticalAlignment.middle, 90 | )); 91 | } 92 | return titles; 93 | } 94 | } 95 | -------------------------------------------------------------------------------- /lib/widgets/test.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/material.dart'; 2 | 3 | // 定义一个Hello函数 相当于原生接口中的函数 4 | typedef Hello = void Function(String, String); 5 | 6 | class Test extends StatefulWidget { 7 | final Hello? hello; 8 | 9 | const Test({Key? key, this.hello}) : super(key: key); 10 | 11 | @override 12 | _TestState createState() => _TestState(); 13 | } 14 | 15 | class _TestState extends State { 16 | @override 17 | void initState() { 18 | super.initState(); 19 | //调用 20 | getName(); 21 | } 22 | 23 | dynamic getName() { 24 | // 具体实现函数的地方 25 | widget.hello?.call("老李", "李云龙"); 26 | } 27 | 28 | @override 29 | Widget build(BuildContext context) { 30 | return Container(); 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /lib/widgets/theme.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/material.dart'; 2 | import 'package:flutter_demo/models/app_theme.dart'; 3 | import 'package:flutter_demo/utils/status.dart'; 4 | 5 | class ThemeWidgetDemo extends StatefulWidget { 6 | const ThemeWidgetDemo({super.key}); 7 | 8 | @override 9 | State createState() { 10 | return _ThemeWidgetState(); 11 | } 12 | } 13 | 14 | class _ThemeWidgetState extends State { 15 | @override 16 | Widget build(BuildContext context) { 17 | return Container( 18 | child: Column( 19 | children: _themeList, 20 | ), 21 | ); 22 | } 23 | 24 | get _themeList => getColorList(); 25 | 26 | List getColorList() { 27 | List list = []; 28 | for (var i in AppTheme.materialColors) { 29 | list.add(InkWell( 30 | child: Container( 31 | margin: EdgeInsets.all(10), 32 | width: double.infinity, 33 | height: 30, 34 | color: i, 35 | ), 36 | onTap: () { 37 | Status.value(context) 38 | .changeThemeColor(AppTheme.materialColors.indexOf(i)); 39 | }, 40 | )); 41 | } 42 | return list; 43 | } 44 | } 45 | -------------------------------------------------------------------------------- /lib/widgets/transform.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/material.dart'; 2 | import 'dart:math' as math; 3 | 4 | class TransformDemo extends StatefulWidget { 5 | @override 6 | _TransformDemoState createState() => _TransformDemoState(); 7 | } 8 | 9 | class _TransformDemoState extends State { 10 | @override 11 | Widget build(BuildContext context) { 12 | return Container( 13 | margin: EdgeInsets.all(50), 14 | child: Column( 15 | children: [ 16 | Container( 17 | color: Colors.blue, 18 | child: Transform( 19 | alignment: Alignment.topLeft, //相对于坐标系原点的对齐方式 20 | transform: Matrix4.skewY(-0.2), //沿Y轴倾斜0.2弧度 21 | child: Container( 22 | color: Colors.red, 23 | padding: EdgeInsets.all(10), 24 | child: Text("Apartment for rent!"), 25 | ), 26 | ), 27 | ), 28 | 29 | 30 | 31 | Container( 32 | margin: EdgeInsets.all(50), 33 | color: Colors.blue, 34 | child: Transform( 35 | alignment: Alignment.topRight, //相对于坐标系原点的对齐方式 36 | transform: Matrix4.skewY(0.2), //沿Y轴倾斜0.2弧度 37 | child: Container( 38 | color: Colors.red, 39 | padding: EdgeInsets.all(10), 40 | child: Text("Apartment for rent!"), 41 | ), 42 | ), 43 | ), 44 | Container( 45 | color: Colors.blue, 46 | child: Transform.translate( 47 | offset: Offset(-10, -10), // x,y轴 左上角0,0 跟屏幕坐标轴一样 48 | child: Text("平移"), 49 | )), 50 | Container( 51 | margin: EdgeInsets.all(20), 52 | color: Colors.blue, 53 | child: Transform.rotate( 54 | angle: math.pi * 1.5, // 旋转270 55 | child: Text("旋转"), 56 | )), 57 | Container( 58 | margin: EdgeInsets.all(20), 59 | color: Colors.blue, 60 | child: Transform.scale( 61 | scale: 1.2, 62 | child: Text("缩放 放大1.2倍"), 63 | )), 64 | 65 | Row( 66 | children: [ 67 | 68 | ], 69 | ) 70 | ], 71 | ), 72 | ); 73 | } 74 | } 75 | -------------------------------------------------------------------------------- /lib/widgets/util_page/my_toast.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/material.dart'; 2 | import 'package:flutter_demo/utils/toast_util.dart'; 3 | 4 | /// toast 演示 5 | class MyToast extends StatelessWidget { 6 | @override 7 | Widget build(BuildContext context) { 8 | return Container( 9 | alignment: Alignment.center, 10 | child: Column( 11 | children: [ 12 | ElevatedButton( 13 | onPressed: () { 14 | ToastUtil.show("我是一个普通toast"); 15 | }, 16 | child: Text("普通吐司")), 17 | ElevatedButton( 18 | onPressed: () { 19 | ToastUtil.showError("我是一个错误toast"); 20 | }, 21 | child: Text("错误吐司")) 22 | ], 23 | ), 24 | ); 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /lib/widgets/util_page/num_demo.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/material.dart'; 2 | import 'dart:math'; 3 | 4 | class NumDemo extends StatefulWidget { 5 | const NumDemo({Key? key}) : super(key: key); 6 | 7 | @override 8 | _NumDemoState createState() => _NumDemoState(); 9 | } 10 | 11 | class _NumDemoState extends State { 12 | List result = []; 13 | 14 | @override 15 | void initState() { 16 | super.initState(); 17 | var a = -11; 18 | var b = 3; 19 | 20 | setState(() { 21 | result.add((a % b).toString()); 22 | result.add((a ~/ b).toString()); 23 | result.add(1.2.round().toString()); 24 | result.add("${(3 / 2).floor().toString()}"); 25 | result.add("${asin(1)}"); 26 | result.add("${num.tryParse("123www")}"); 27 | }); 28 | } 29 | 30 | @override 31 | Widget build(BuildContext context) { 32 | return Container( 33 | child: ListView.builder( 34 | itemBuilder: (context, index) { 35 | return Text(result[index]); 36 | }, 37 | itemCount: result.length, 38 | ), 39 | ); 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /lib/widgets/wrap.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/material.dart'; 2 | 3 | /// 自适应组件 4 | class WrapWidgetDemo extends StatefulWidget { 5 | @override 6 | State createState() { 7 | return WrapState(); 8 | } 9 | } 10 | 11 | class WrapState extends State { 12 | @override 13 | Widget build(BuildContext context) { 14 | return Container( 15 | margin: EdgeInsets.all(20), 16 | child: Wrap( 17 | children: [ 18 | Container( 19 | margin: EdgeInsets.all(10), 20 | child: Text("色谱", style: TextStyle(color: Colors.blue)), 21 | ), 22 | Container( 23 | margin: EdgeInsets.all(10), 24 | child: Text("气相色谱", style: TextStyle(color: Colors.blue)), 25 | ), 26 | Container( 27 | margin: EdgeInsets.all(10), 28 | child: Text("仪器信息网", style: TextStyle(color: Colors.blue)), 29 | ), 30 | Container( 31 | margin: EdgeInsets.all(10), 32 | child: Text("我要测", style: TextStyle(color: Colors.blue)), 33 | ), 34 | Container( 35 | margin: EdgeInsets.all(10), 36 | child: Text("更多标签xx", style: TextStyle(color: Colors.blue)), 37 | ) 38 | ], 39 | ), 40 | ); 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /lib/widgets/xlf_bg_button.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/material.dart'; 2 | 3 | ///TextButton 背景样式 4 | class XlfBgButton extends StatelessWidget { 5 | /// 按钮文本 6 | final String? text; 7 | 8 | /// 按钮点击事件 9 | final VoidCallback? onPressed; 10 | 11 | /// 长按事件 12 | final VoidCallback? onLongPress; 13 | 14 | /// 边距 15 | final EdgeInsetsGeometry? margin; 16 | 17 | /// 内边距 18 | final EdgeInsetsGeometry? padding; 19 | 20 | final AlignmentGeometry? alignment; 21 | 22 | /// 按钮宽 23 | final double? width; 24 | 25 | /// 按钮高 26 | final double? height; 27 | 28 | /// 字体 29 | final double? fontSize; 30 | 31 | /// 是否可点击 32 | final bool isClick; 33 | 34 | /// 自定义按钮 35 | final Widget? child; 36 | 37 | /// 圆角 38 | final double? radius; 39 | 40 | /// 背景颜色 41 | final Color backgroundColor; 42 | 43 | /// 圆形按钮 44 | 45 | 46 | 47 | XlfBgButton({ 48 | Key? key, 49 | required this.text, 50 | required this.onPressed, 51 | this.onLongPress, 52 | this.margin, 53 | this.width, 54 | this.height, 55 | this.fontSize, 56 | this.isClick = true, 57 | this.alignment, 58 | this.child, 59 | this.radius, 60 | this.padding, 61 | this.backgroundColor = const Color(0xffff6332), 62 | }) : super(key: key); 63 | 64 | @override 65 | Widget build(BuildContext context) { 66 | return Container( 67 | alignment: alignment, 68 | width: width ?? double.infinity, 69 | height: height, 70 | margin: margin ?? EdgeInsetsDirectional.only(start: 32, end: 32), 71 | child: ElevatedButton( 72 | style: ButtonStyle( 73 | elevation: MaterialStateProperty.all(0), 74 | minimumSize: MaterialStateProperty.all(const Size(0, 0)), 75 | padding: MaterialStateProperty.all(padding ?? 76 | EdgeInsetsDirectional.only(top: 10, bottom: 10)), 77 | shape: MaterialStateProperty.all(RoundedRectangleBorder( 78 | borderRadius: BorderRadius.circular(radius ?? 4))), 79 | 80 | // shape: MaterialStateProperty.all(const StadiumBorder()), 81 | overlayColor: MaterialStateProperty.all(Colors.transparent), 82 | backgroundColor: MaterialStateProperty.resolveWith((states) { 83 | //设置按下时的背景颜色 84 | if (states.contains(MaterialState.pressed)) { 85 | return backgroundColor.withOpacity(0.8); 86 | } else if (states.contains(MaterialState.disabled)) { 87 | return backgroundColor.withOpacity(0.32); 88 | } 89 | //默认不使用背景颜色 90 | return backgroundColor; 91 | })), 92 | onPressed: isClick ? onPressed : null, 93 | onLongPress: isClick ? onLongPress : null, 94 | child: child ?? 95 | Text( 96 | text!, 97 | style: TextStyle( 98 | color: Colors.white, 99 | fontSize: fontSize, 100 | ), 101 | ), 102 | )); 103 | } 104 | } 105 | -------------------------------------------------------------------------------- /lib/widgets/yy_text_demo.dart: -------------------------------------------------------------------------------- 1 | import 'dart:async'; 2 | import 'dart:io'; 3 | 4 | import 'package:flutter/material.dart'; 5 | // import 'package:flutter_sound/flutter_sound.dart'; 6 | import 'package:path_provider/path_provider.dart'; 7 | import 'package:permission_handler/permission_handler.dart'; 8 | import 'dart:ui' as ui; 9 | 10 | /// 作者: lixp 11 | /// 创建时间: 2022/6/13 13:47 12 | /// 类介绍:语音识别 (1分钟即时转换) 13 | class YYTextDemo extends StatefulWidget { 14 | const YYTextDemo({Key? key}) : super(key: key); 15 | 16 | @override 17 | _YYTextDemoState createState() => _YYTextDemoState(); 18 | } 19 | 20 | class _YYTextDemoState extends State { 21 | // final FlutterSoundRecorder _mRecorder = FlutterSoundRecorder(); 22 | // 23 | // late final StreamController recordingDataController = 24 | // StreamController(); 25 | 26 | @override 27 | void initState() { 28 | super.initState(); 29 | // init(); 30 | } 31 | 32 | Future openTheRecorder() async { 33 | var status = await Permission.microphone.request(); 34 | if (status != PermissionStatus.granted) { 35 | // throw RecordingPermissionException('Microphone permission not granted'); 36 | } 37 | // await _mRecorder.openRecorder(); 38 | 39 | // recordingDataController.stream.listen((buffer) { 40 | // if (buffer is FoodData) { 41 | // print("data ${buffer.data}"); 42 | // } 43 | // }); 44 | //用户允许使用麦克风之后开始录音 45 | Directory tempDir = await getTemporaryDirectory(); 46 | // var time = DateTime.now().millisecondsSinceEpoch; 47 | // String path = '${tempDir.path}/$time${ext[Codec.aacADTS.index]}'; 48 | // await _mRecorder.startRecorder( 49 | // toFile: path, 50 | // codec: Codec.aacADTS, 51 | // bitRate: 8000, 52 | // numChannels: 1, 53 | // sampleRate: 8000, 54 | // // toStream: recordingDataController.sink, 55 | // ); 56 | } 57 | 58 | @override 59 | void dispose() { 60 | super.dispose(); 61 | // recordingDataController.close(); 62 | } 63 | 64 | @override 65 | Widget build(BuildContext context) { 66 | return Center( 67 | child: GestureDetector( 68 | onLongPressStart: (d) { 69 | print("长按开始"); 70 | openTheRecorder(); 71 | }, 72 | onLongPressEnd: (d) { 73 | print("长安结束"); 74 | // _mRecorder.closeRecorder(); 75 | }, 76 | child: Container( 77 | color: Colors.blue, 78 | padding: EdgeInsetsDirectional.all(20), 79 | child: Text("按住讲话"), 80 | ), 81 | )); 82 | } 83 | 84 | Future init() async { 85 | await openTheRecorder(); 86 | } 87 | } 88 | -------------------------------------------------------------------------------- /linux/.gitignore: -------------------------------------------------------------------------------- 1 | flutter/ephemeral 2 | -------------------------------------------------------------------------------- /linux/flutter/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | # This file controls Flutter-level build steps. It should not be edited. 2 | cmake_minimum_required(VERSION 3.10) 3 | 4 | set(EPHEMERAL_DIR "${CMAKE_CURRENT_SOURCE_DIR}/ephemeral") 5 | 6 | # Configuration provided via flutter tool. 7 | include(${EPHEMERAL_DIR}/generated_config.cmake) 8 | 9 | # TODO: Move the rest of this into files in ephemeral. See 10 | # https://github.com/flutter/flutter/issues/57146. 11 | 12 | # Serves the same purpose as list(TRANSFORM ... PREPEND ...), 13 | # which isn't available in 3.10. 14 | function(list_prepend LIST_NAME PREFIX) 15 | set(NEW_LIST "") 16 | foreach(element ${${LIST_NAME}}) 17 | list(APPEND NEW_LIST "${PREFIX}${element}") 18 | endforeach(element) 19 | set(${LIST_NAME} "${NEW_LIST}" PARENT_SCOPE) 20 | endfunction() 21 | 22 | # === Flutter Library === 23 | # System-level dependencies. 24 | find_package(PkgConfig REQUIRED) 25 | pkg_check_modules(GTK REQUIRED IMPORTED_TARGET gtk+-3.0) 26 | pkg_check_modules(GLIB REQUIRED IMPORTED_TARGET glib-2.0) 27 | pkg_check_modules(GIO REQUIRED IMPORTED_TARGET gio-2.0) 28 | 29 | set(FLUTTER_LIBRARY "${EPHEMERAL_DIR}/libflutter_linux_gtk.so") 30 | 31 | # Published to parent scope for install step. 32 | set(FLUTTER_LIBRARY ${FLUTTER_LIBRARY} PARENT_SCOPE) 33 | set(FLUTTER_ICU_DATA_FILE "${EPHEMERAL_DIR}/icudtl.dat" PARENT_SCOPE) 34 | set(PROJECT_BUILD_DIR "${PROJECT_DIR}/build/" PARENT_SCOPE) 35 | set(AOT_LIBRARY "${PROJECT_DIR}/build/lib/libapp.so" PARENT_SCOPE) 36 | 37 | list(APPEND FLUTTER_LIBRARY_HEADERS 38 | "fl_basic_message_channel.h" 39 | "fl_binary_codec.h" 40 | "fl_binary_messenger.h" 41 | "fl_dart_project.h" 42 | "fl_engine.h" 43 | "fl_json_message_codec.h" 44 | "fl_json_method_codec.h" 45 | "fl_message_codec.h" 46 | "fl_method_call.h" 47 | "fl_method_channel.h" 48 | "fl_method_codec.h" 49 | "fl_method_response.h" 50 | "fl_plugin_registrar.h" 51 | "fl_plugin_registry.h" 52 | "fl_standard_message_codec.h" 53 | "fl_standard_method_codec.h" 54 | "fl_string_codec.h" 55 | "fl_value.h" 56 | "fl_view.h" 57 | "flutter_linux.h" 58 | ) 59 | list_prepend(FLUTTER_LIBRARY_HEADERS "${EPHEMERAL_DIR}/flutter_linux/") 60 | add_library(flutter INTERFACE) 61 | target_include_directories(flutter INTERFACE 62 | "${EPHEMERAL_DIR}" 63 | ) 64 | target_link_libraries(flutter INTERFACE "${FLUTTER_LIBRARY}") 65 | target_link_libraries(flutter INTERFACE 66 | PkgConfig::GTK 67 | PkgConfig::GLIB 68 | PkgConfig::GIO 69 | ) 70 | add_dependencies(flutter flutter_assemble) 71 | 72 | # === Flutter tool backend === 73 | # _phony_ is a non-existent file to force this command to run every time, 74 | # since currently there's no way to get a full input/output list from the 75 | # flutter tool. 76 | add_custom_command( 77 | OUTPUT ${FLUTTER_LIBRARY} ${FLUTTER_LIBRARY_HEADERS} 78 | ${CMAKE_CURRENT_BINARY_DIR}/_phony_ 79 | COMMAND ${CMAKE_COMMAND} -E env 80 | ${FLUTTER_TOOL_ENVIRONMENT} 81 | "${FLUTTER_ROOT}/packages/flutter_tools/bin/tool_backend.sh" 82 | ${FLUTTER_TARGET_PLATFORM} ${CMAKE_BUILD_TYPE} 83 | VERBATIM 84 | ) 85 | add_custom_target(flutter_assemble DEPENDS 86 | "${FLUTTER_LIBRARY}" 87 | ${FLUTTER_LIBRARY_HEADERS} 88 | ) 89 | -------------------------------------------------------------------------------- /linux/flutter/generated_plugin_registrant.cc: -------------------------------------------------------------------------------- 1 | // 2 | // Generated file. Do not edit. 3 | // 4 | 5 | // clang-format off 6 | 7 | #include "generated_plugin_registrant.h" 8 | 9 | #include 10 | #include 11 | 12 | void fl_register_plugins(FlPluginRegistry* registry) { 13 | g_autoptr(FlPluginRegistrar) audioplayers_linux_registrar = 14 | fl_plugin_registry_get_registrar_for_plugin(registry, "AudioplayersLinuxPlugin"); 15 | audioplayers_linux_plugin_register_with_registrar(audioplayers_linux_registrar); 16 | g_autoptr(FlPluginRegistrar) url_launcher_linux_registrar = 17 | fl_plugin_registry_get_registrar_for_plugin(registry, "UrlLauncherPlugin"); 18 | url_launcher_plugin_register_with_registrar(url_launcher_linux_registrar); 19 | } 20 | -------------------------------------------------------------------------------- /linux/flutter/generated_plugin_registrant.h: -------------------------------------------------------------------------------- 1 | // 2 | // Generated file. Do not edit. 3 | // 4 | 5 | // clang-format off 6 | 7 | #ifndef GENERATED_PLUGIN_REGISTRANT_ 8 | #define GENERATED_PLUGIN_REGISTRANT_ 9 | 10 | #include 11 | 12 | // Registers Flutter plugins. 13 | void fl_register_plugins(FlPluginRegistry* registry); 14 | 15 | #endif // GENERATED_PLUGIN_REGISTRANT_ 16 | -------------------------------------------------------------------------------- /linux/flutter/generated_plugins.cmake: -------------------------------------------------------------------------------- 1 | # 2 | # Generated file, do not edit. 3 | # 4 | 5 | list(APPEND FLUTTER_PLUGIN_LIST 6 | audioplayers_linux 7 | url_launcher_linux 8 | ) 9 | 10 | list(APPEND FLUTTER_FFI_PLUGIN_LIST 11 | ) 12 | 13 | set(PLUGIN_BUNDLED_LIBRARIES) 14 | 15 | foreach(plugin ${FLUTTER_PLUGIN_LIST}) 16 | add_subdirectory(flutter/ephemeral/.plugin_symlinks/${plugin}/linux plugins/${plugin}) 17 | target_link_libraries(${BINARY_NAME} PRIVATE ${plugin}_plugin) 18 | list(APPEND PLUGIN_BUNDLED_LIBRARIES $) 19 | list(APPEND PLUGIN_BUNDLED_LIBRARIES ${${plugin}_bundled_libraries}) 20 | endforeach(plugin) 21 | 22 | foreach(ffi_plugin ${FLUTTER_FFI_PLUGIN_LIST}) 23 | add_subdirectory(flutter/ephemeral/.plugin_symlinks/${ffi_plugin}/linux plugins/${ffi_plugin}) 24 | list(APPEND PLUGIN_BUNDLED_LIBRARIES ${${ffi_plugin}_bundled_libraries}) 25 | endforeach(ffi_plugin) 26 | -------------------------------------------------------------------------------- /linux/main.cc: -------------------------------------------------------------------------------- 1 | #include "my_application.h" 2 | 3 | int main(int argc, char** argv) { 4 | g_autoptr(MyApplication) app = my_application_new(); 5 | return g_application_run(G_APPLICATION(app), argc, argv); 6 | } 7 | -------------------------------------------------------------------------------- /linux/my_application.h: -------------------------------------------------------------------------------- 1 | #ifndef FLUTTER_MY_APPLICATION_H_ 2 | #define FLUTTER_MY_APPLICATION_H_ 3 | 4 | #include 5 | 6 | G_DECLARE_FINAL_TYPE(MyApplication, my_application, MY, APPLICATION, 7 | GtkApplication) 8 | 9 | /** 10 | * my_application_new: 11 | * 12 | * Creates a new Flutter-based application. 13 | * 14 | * Returns: a new #MyApplication. 15 | */ 16 | MyApplication* my_application_new(); 17 | 18 | #endif // FLUTTER_MY_APPLICATION_H_ 19 | -------------------------------------------------------------------------------- /local.properties: -------------------------------------------------------------------------------- 1 | ## This file must *NOT* be checked into Version Control Systems, 2 | # as it contains information specific to your local configuration. 3 | # 4 | # Location of the SDK. This is only used by Gradle. 5 | # For customization when using a Version Control System, please read the 6 | # header note. 7 | #Fri Jan 06 10:59:13 CST 2023 8 | sdk.dir=/Users/lixp/Library/Android/sdk 9 | -------------------------------------------------------------------------------- /macos/.gitignore: -------------------------------------------------------------------------------- 1 | # Flutter-related 2 | **/Flutter/ephemeral/ 3 | **/Pods/ 4 | 5 | # Xcode-related 6 | **/dgph 7 | **/xcuserdata/ 8 | -------------------------------------------------------------------------------- /macos/Flutter/Flutter-Debug.xcconfig: -------------------------------------------------------------------------------- 1 | #include? "Pods/Target Support Files/Pods-Runner/Pods-Runner.debug.xcconfig" 2 | #include "ephemeral/Flutter-Generated.xcconfig" 3 | -------------------------------------------------------------------------------- /macos/Flutter/Flutter-Release.xcconfig: -------------------------------------------------------------------------------- 1 | #include? "Pods/Target Support Files/Pods-Runner/Pods-Runner.release.xcconfig" 2 | #include "ephemeral/Flutter-Generated.xcconfig" 3 | -------------------------------------------------------------------------------- /macos/Flutter/GeneratedPluginRegistrant.swift: -------------------------------------------------------------------------------- 1 | // 2 | // Generated file. Do not edit. 3 | // 4 | 5 | import FlutterMacOS 6 | import Foundation 7 | 8 | import audioplayers_darwin 9 | import path_provider_macos 10 | import shared_preferences_macos 11 | import url_launcher_macos 12 | 13 | func RegisterGeneratedPlugins(registry: FlutterPluginRegistry) { 14 | AudioplayersDarwinPlugin.register(with: registry.registrar(forPlugin: "AudioplayersDarwinPlugin")) 15 | PathProviderPlugin.register(with: registry.registrar(forPlugin: "PathProviderPlugin")) 16 | SharedPreferencesPlugin.register(with: registry.registrar(forPlugin: "SharedPreferencesPlugin")) 17 | UrlLauncherPlugin.register(with: registry.registrar(forPlugin: "UrlLauncherPlugin")) 18 | } 19 | -------------------------------------------------------------------------------- /macos/Podfile: -------------------------------------------------------------------------------- 1 | platform :osx, '10.11' 2 | 3 | # CocoaPods analytics sends network stats synchronously affecting flutter build latency. 4 | ENV['COCOAPODS_DISABLE_STATS'] = 'true' 5 | 6 | project 'Runner', { 7 | 'Debug' => :debug, 8 | 'Profile' => :release, 9 | 'Release' => :release, 10 | } 11 | 12 | def flutter_root 13 | generated_xcode_build_settings_path = File.expand_path(File.join('..', 'Flutter', 'ephemeral', 'Flutter-Generated.xcconfig'), __FILE__) 14 | unless File.exist?(generated_xcode_build_settings_path) 15 | raise "#{generated_xcode_build_settings_path} must exist. If you're running pod install manually, make sure \"flutter pub get\" is executed first" 16 | end 17 | 18 | File.foreach(generated_xcode_build_settings_path) do |line| 19 | matches = line.match(/FLUTTER_ROOT\=(.*)/) 20 | return matches[1].strip if matches 21 | end 22 | raise "FLUTTER_ROOT not found in #{generated_xcode_build_settings_path}. Try deleting Flutter-Generated.xcconfig, then run \"flutter pub get\"" 23 | end 24 | 25 | require File.expand_path(File.join('packages', 'flutter_tools', 'bin', 'podhelper'), flutter_root) 26 | 27 | flutter_macos_podfile_setup 28 | 29 | target 'Runner' do 30 | use_frameworks! 31 | use_modular_headers! 32 | 33 | flutter_install_all_macos_pods File.dirname(File.realpath(__FILE__)) 34 | end 35 | 36 | post_install do |installer| 37 | installer.pods_project.targets.each do |target| 38 | flutter_additional_macos_build_settings(target) 39 | end 40 | end 41 | -------------------------------------------------------------------------------- /macos/Podfile.lock: -------------------------------------------------------------------------------- 1 | PODS: 2 | - audioplayers_darwin (0.0.1): 3 | - FlutterMacOS 4 | - FlutterMacOS (1.0.0) 5 | - path_provider_macos (0.0.1): 6 | - FlutterMacOS 7 | - shared_preferences_macos (0.0.1): 8 | - FlutterMacOS 9 | - url_launcher_macos (0.0.1): 10 | - FlutterMacOS 11 | 12 | DEPENDENCIES: 13 | - audioplayers_darwin (from `Flutter/ephemeral/.symlinks/plugins/audioplayers_darwin/macos`) 14 | - FlutterMacOS (from `Flutter/ephemeral`) 15 | - path_provider_macos (from `Flutter/ephemeral/.symlinks/plugins/path_provider_macos/macos`) 16 | - shared_preferences_macos (from `Flutter/ephemeral/.symlinks/plugins/shared_preferences_macos/macos`) 17 | - url_launcher_macos (from `Flutter/ephemeral/.symlinks/plugins/url_launcher_macos/macos`) 18 | 19 | EXTERNAL SOURCES: 20 | audioplayers_darwin: 21 | :path: Flutter/ephemeral/.symlinks/plugins/audioplayers_darwin/macos 22 | FlutterMacOS: 23 | :path: Flutter/ephemeral 24 | path_provider_macos: 25 | :path: Flutter/ephemeral/.symlinks/plugins/path_provider_macos/macos 26 | shared_preferences_macos: 27 | :path: Flutter/ephemeral/.symlinks/plugins/shared_preferences_macos/macos 28 | url_launcher_macos: 29 | :path: Flutter/ephemeral/.symlinks/plugins/url_launcher_macos/macos 30 | 31 | SPEC CHECKSUMS: 32 | audioplayers_darwin: dcad41de4fbd0099cb3749f7ab3b0cb8f70b810c 33 | FlutterMacOS: ae6af50a8ea7d6103d888583d46bd8328a7e9811 34 | path_provider_macos: 3c0c3b4b0d4a76d2bf989a913c2de869c5641a19 35 | shared_preferences_macos: 8b221d457159a85f478c0b9d2f19aeae9feff475 36 | url_launcher_macos: 597e05b8e514239626bcf4a850fcf9ef5c856ec3 37 | 38 | PODFILE CHECKSUM: 6eac6b3292e5142cfc23bdeb71848a40ec51c14c 39 | 40 | COCOAPODS: 1.11.3 41 | -------------------------------------------------------------------------------- /macos/Runner.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | IDEDidComputeMac32BitWarning 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /macos/Runner.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 9 | 10 | 11 | -------------------------------------------------------------------------------- /macos/Runner.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | IDEDidComputeMac32BitWarning 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /macos/Runner/AppDelegate.swift: -------------------------------------------------------------------------------- 1 | import Cocoa 2 | import FlutterMacOS 3 | 4 | @NSApplicationMain 5 | class AppDelegate: FlutterAppDelegate { 6 | override func applicationShouldTerminateAfterLastWindowClosed(_ sender: NSApplication) -> Bool { 7 | return true 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /macos/Runner/Assets.xcassets/AppIcon.appiconset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "size" : "16x16", 5 | "idiom" : "mac", 6 | "filename" : "app_icon_16.png", 7 | "scale" : "1x" 8 | }, 9 | { 10 | "size" : "16x16", 11 | "idiom" : "mac", 12 | "filename" : "app_icon_32.png", 13 | "scale" : "2x" 14 | }, 15 | { 16 | "size" : "32x32", 17 | "idiom" : "mac", 18 | "filename" : "app_icon_32.png", 19 | "scale" : "1x" 20 | }, 21 | { 22 | "size" : "32x32", 23 | "idiom" : "mac", 24 | "filename" : "app_icon_64.png", 25 | "scale" : "2x" 26 | }, 27 | { 28 | "size" : "128x128", 29 | "idiom" : "mac", 30 | "filename" : "app_icon_128.png", 31 | "scale" : "1x" 32 | }, 33 | { 34 | "size" : "128x128", 35 | "idiom" : "mac", 36 | "filename" : "app_icon_256.png", 37 | "scale" : "2x" 38 | }, 39 | { 40 | "size" : "256x256", 41 | "idiom" : "mac", 42 | "filename" : "app_icon_256.png", 43 | "scale" : "1x" 44 | }, 45 | { 46 | "size" : "256x256", 47 | "idiom" : "mac", 48 | "filename" : "app_icon_512.png", 49 | "scale" : "2x" 50 | }, 51 | { 52 | "size" : "512x512", 53 | "idiom" : "mac", 54 | "filename" : "app_icon_512.png", 55 | "scale" : "1x" 56 | }, 57 | { 58 | "size" : "512x512", 59 | "idiom" : "mac", 60 | "filename" : "app_icon_1024.png", 61 | "scale" : "2x" 62 | } 63 | ], 64 | "info" : { 65 | "version" : 1, 66 | "author" : "xcode" 67 | } 68 | } 69 | -------------------------------------------------------------------------------- /macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_1024.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lixp185/flutter_demo/46f92f2895b84df59943ace1bf0b9c43aac6f2f5/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_1024.png -------------------------------------------------------------------------------- /macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_128.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lixp185/flutter_demo/46f92f2895b84df59943ace1bf0b9c43aac6f2f5/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_128.png -------------------------------------------------------------------------------- /macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_16.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lixp185/flutter_demo/46f92f2895b84df59943ace1bf0b9c43aac6f2f5/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_16.png -------------------------------------------------------------------------------- /macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_256.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lixp185/flutter_demo/46f92f2895b84df59943ace1bf0b9c43aac6f2f5/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_256.png -------------------------------------------------------------------------------- /macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_32.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lixp185/flutter_demo/46f92f2895b84df59943ace1bf0b9c43aac6f2f5/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_32.png -------------------------------------------------------------------------------- /macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_512.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lixp185/flutter_demo/46f92f2895b84df59943ace1bf0b9c43aac6f2f5/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_512.png -------------------------------------------------------------------------------- /macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_64.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lixp185/flutter_demo/46f92f2895b84df59943ace1bf0b9c43aac6f2f5/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_64.png -------------------------------------------------------------------------------- /macos/Runner/Configs/AppInfo.xcconfig: -------------------------------------------------------------------------------- 1 | // Application-level settings for the Runner target. 2 | // 3 | // This may be replaced with something auto-generated from metadata (e.g., pubspec.yaml) in the 4 | // future. If not, the values below would default to using the project name when this becomes a 5 | // 'flutter create' template. 6 | 7 | // The application's name. By default this is also the title of the Flutter window. 8 | PRODUCT_NAME = flutter_demo 9 | 10 | // The application's bundle identifier 11 | PRODUCT_BUNDLE_IDENTIFIER = com.flutter.flutterDemo 12 | 13 | // The copyright displayed in application information 14 | PRODUCT_COPYRIGHT = Copyright © 2023 com.flutter. All rights reserved. 15 | -------------------------------------------------------------------------------- /macos/Runner/Configs/Debug.xcconfig: -------------------------------------------------------------------------------- 1 | #include "../../Flutter/Flutter-Debug.xcconfig" 2 | #include "Warnings.xcconfig" 3 | -------------------------------------------------------------------------------- /macos/Runner/Configs/Release.xcconfig: -------------------------------------------------------------------------------- 1 | #include "../../Flutter/Flutter-Release.xcconfig" 2 | #include "Warnings.xcconfig" 3 | -------------------------------------------------------------------------------- /macos/Runner/Configs/Warnings.xcconfig: -------------------------------------------------------------------------------- 1 | WARNING_CFLAGS = -Wall -Wconditional-uninitialized -Wnullable-to-nonnull-conversion -Wmissing-method-return-type -Woverlength-strings 2 | GCC_WARN_UNDECLARED_SELECTOR = YES 3 | CLANG_UNDEFINED_BEHAVIOR_SANITIZER_NULLABILITY = YES 4 | CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE 5 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES 6 | CLANG_WARN_PRAGMA_PACK = YES 7 | CLANG_WARN_STRICT_PROTOTYPES = YES 8 | CLANG_WARN_COMMA = YES 9 | GCC_WARN_STRICT_SELECTOR_MATCH = YES 10 | CLANG_WARN_OBJC_REPEATED_USE_OF_WEAK = YES 11 | CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES 12 | GCC_WARN_SHADOW = YES 13 | CLANG_WARN_UNREACHABLE_CODE = YES 14 | -------------------------------------------------------------------------------- /macos/Runner/DebugProfile.entitlements: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | com.apple.security.app-sandbox 6 | 7 | com.apple.security.cs.allow-jit 8 | 9 | com.apple.security.network.server 10 | 11 | 12 | 13 | -------------------------------------------------------------------------------- /macos/Runner/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | $(DEVELOPMENT_LANGUAGE) 7 | CFBundleExecutable 8 | $(EXECUTABLE_NAME) 9 | CFBundleIconFile 10 | 11 | CFBundleIdentifier 12 | $(PRODUCT_BUNDLE_IDENTIFIER) 13 | CFBundleInfoDictionaryVersion 14 | 6.0 15 | CFBundleName 16 | $(PRODUCT_NAME) 17 | CFBundlePackageType 18 | APPL 19 | CFBundleShortVersionString 20 | $(FLUTTER_BUILD_NAME) 21 | CFBundleVersion 22 | $(FLUTTER_BUILD_NUMBER) 23 | LSMinimumSystemVersion 24 | $(MACOSX_DEPLOYMENT_TARGET) 25 | NSHumanReadableCopyright 26 | $(PRODUCT_COPYRIGHT) 27 | NSMainNibFile 28 | MainMenu 29 | NSPrincipalClass 30 | NSApplication 31 | 32 | 33 | -------------------------------------------------------------------------------- /macos/Runner/MainFlutterWindow.swift: -------------------------------------------------------------------------------- 1 | import Cocoa 2 | import FlutterMacOS 3 | 4 | class MainFlutterWindow: NSWindow { 5 | override func awakeFromNib() { 6 | let flutterViewController = FlutterViewController.init() 7 | let windowFrame = self.frame 8 | self.contentViewController = flutterViewController 9 | self.setFrame(windowFrame, display: true) 10 | 11 | RegisterGeneratedPlugins(registry: flutterViewController) 12 | 13 | super.awakeFromNib() 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /macos/Runner/Release.entitlements: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | com.apple.security.app-sandbox 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /pubspec.yaml: -------------------------------------------------------------------------------- 1 | name: flutter_demo 2 | description: flutter_demo 3 | 4 | publish_to: 'none' # Remove this line if you wish to publish to pub.dev 5 | 6 | version: 1.0.0+1 7 | 8 | environment: 9 | sdk: ">=2.17.1 <3.0.0" 10 | 11 | dependencies: 12 | flutter: 13 | sdk: flutter 14 | 15 | 16 | # The following adds the Cupertino Icons font to your application. 17 | # Use with the CupertinoIcons class for iOS style icons. 18 | cupertino_icons: ^1.0.2 19 | # qrscan: ^0.2.22 20 | dio: ^4.0.0 21 | keyboard_actions: ^3.4.0 22 | keyboard_avoider: ^0.1.2 23 | path_provider: ^2.0.1 24 | fluttertoast: ^8.0.3 25 | 26 | shared_preferences: ^2.0.5 27 | # flutter_bugly: ^0.3.1 28 | # jpush_flutter: ^2.0.1 29 | flutter_easyrefresh: ^2.2.1 30 | # 启动URL 拨打电话等 https://pub.dev/packages/url_launcher 31 | url_launcher: ^6.0.8 32 | image_picker: ^0.8.2 33 | video_player: ^2.1.10 34 | photo_view: ^0.13.0 35 | image: ^3.1.3 36 | # listView 滚动指定item 37 | scrollable_positioned_list: ^0.2.3 38 | lpinyin: ^2.0.3 39 | flutter_lints: ^1.0.4 40 | # flutter_vibrate: ^1.3.0 41 | web_socket_channel: ^2.2.0 42 | # 格式化 43 | intl: ^0.17.0 44 | # 加密 45 | crypto: ^3.0.2 46 | 47 | # sound_stream: ^0.3.0 48 | # 音频播放器 49 | audioplayers: ^2.0.0 50 | # 录制音频 51 | # flutter_sound: ^9.2.13 52 | permission_handler: ^10.2.0 53 | 54 | # 状态管理 55 | provider: ^6.0.3 56 | flutter_bloc: ^8.1.1 57 | get: ^4.6.5 58 | 59 | dev_dependencies: 60 | flutter_test: 61 | sdk: flutter 62 | 63 | # For information on the generic Dart part of this file, see the 64 | # following page: https://dart.dev/tools/pub/pubspec 65 | 66 | # The following section is specific to Flutter. 67 | flutter: 68 | 69 | # The following line ensures that the Material Icons font is 70 | # included with your application, so that you can use the icons in 71 | # the material Icons class. 72 | uses-material-design: true 73 | assets: 74 | - lib/widgets/ 75 | - images/ 76 | -------------------------------------------------------------------------------- /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 | import 'package:flutter_demo/app.dart'; 11 | 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 | -------------------------------------------------------------------------------- /web/favicon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lixp185/flutter_demo/46f92f2895b84df59943ace1bf0b9c43aac6f2f5/web/favicon.png -------------------------------------------------------------------------------- /web/icons/Icon-192.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lixp185/flutter_demo/46f92f2895b84df59943ace1bf0b9c43aac6f2f5/web/icons/Icon-192.png -------------------------------------------------------------------------------- /web/icons/Icon-512.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lixp185/flutter_demo/46f92f2895b84df59943ace1bf0b9c43aac6f2f5/web/icons/Icon-512.png -------------------------------------------------------------------------------- /web/icons/Icon-maskable-192.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lixp185/flutter_demo/46f92f2895b84df59943ace1bf0b9c43aac6f2f5/web/icons/Icon-maskable-192.png -------------------------------------------------------------------------------- /web/icons/Icon-maskable-512.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lixp185/flutter_demo/46f92f2895b84df59943ace1bf0b9c43aac6f2f5/web/icons/Icon-maskable-512.png -------------------------------------------------------------------------------- /web/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | flutter_demo 33 | 34 | 35 | 39 | 40 | 41 | 42 | 43 | 57 | 58 | 59 | -------------------------------------------------------------------------------- /web/manifest.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "flutter_demo", 3 | "short_name": "flutter_demo", 4 | "start_url": ".", 5 | "display": "standalone", 6 | "background_color": "#0175C2", 7 | "theme_color": "#0175C2", 8 | "description": "A new Flutter project.", 9 | "orientation": "portrait-primary", 10 | "prefer_related_applications": false, 11 | "icons": [ 12 | { 13 | "src": "icons/Icon-192.png", 14 | "sizes": "192x192", 15 | "type": "image/png" 16 | }, 17 | { 18 | "src": "icons/Icon-512.png", 19 | "sizes": "512x512", 20 | "type": "image/png" 21 | }, 22 | { 23 | "src": "icons/Icon-maskable-192.png", 24 | "sizes": "192x192", 25 | "type": "image/png", 26 | "purpose": "maskable" 27 | }, 28 | { 29 | "src": "icons/Icon-maskable-512.png", 30 | "sizes": "512x512", 31 | "type": "image/png", 32 | "purpose": "maskable" 33 | } 34 | ] 35 | } 36 | -------------------------------------------------------------------------------- /windows/.gitignore: -------------------------------------------------------------------------------- 1 | flutter/ephemeral/ 2 | 3 | # Visual Studio user-specific files. 4 | *.suo 5 | *.user 6 | *.userosscache 7 | *.sln.docstates 8 | 9 | # Visual Studio build-related files. 10 | x64/ 11 | x86/ 12 | 13 | # Visual Studio cache files 14 | # files ending in .cache can be ignored 15 | *.[Cc]ache 16 | # but keep track of directories ending in .cache 17 | !*.[Cc]ache/ 18 | -------------------------------------------------------------------------------- /windows/flutter/generated_plugin_registrant.cc: -------------------------------------------------------------------------------- 1 | // 2 | // Generated file. Do not edit. 3 | // 4 | 5 | // clang-format off 6 | 7 | #include "generated_plugin_registrant.h" 8 | 9 | #include 10 | #include 11 | #include 12 | 13 | void RegisterPlugins(flutter::PluginRegistry* registry) { 14 | AudioplayersWindowsPluginRegisterWithRegistrar( 15 | registry->GetRegistrarForPlugin("AudioplayersWindowsPlugin")); 16 | PermissionHandlerWindowsPluginRegisterWithRegistrar( 17 | registry->GetRegistrarForPlugin("PermissionHandlerWindowsPlugin")); 18 | UrlLauncherWindowsRegisterWithRegistrar( 19 | registry->GetRegistrarForPlugin("UrlLauncherWindows")); 20 | } 21 | -------------------------------------------------------------------------------- /windows/flutter/generated_plugin_registrant.h: -------------------------------------------------------------------------------- 1 | // 2 | // Generated file. Do not edit. 3 | // 4 | 5 | // clang-format off 6 | 7 | #ifndef GENERATED_PLUGIN_REGISTRANT_ 8 | #define GENERATED_PLUGIN_REGISTRANT_ 9 | 10 | #include 11 | 12 | // Registers Flutter plugins. 13 | void RegisterPlugins(flutter::PluginRegistry* registry); 14 | 15 | #endif // GENERATED_PLUGIN_REGISTRANT_ 16 | -------------------------------------------------------------------------------- /windows/flutter/generated_plugins.cmake: -------------------------------------------------------------------------------- 1 | # 2 | # Generated file, do not edit. 3 | # 4 | 5 | list(APPEND FLUTTER_PLUGIN_LIST 6 | audioplayers_windows 7 | permission_handler_windows 8 | url_launcher_windows 9 | ) 10 | 11 | list(APPEND FLUTTER_FFI_PLUGIN_LIST 12 | ) 13 | 14 | set(PLUGIN_BUNDLED_LIBRARIES) 15 | 16 | foreach(plugin ${FLUTTER_PLUGIN_LIST}) 17 | add_subdirectory(flutter/ephemeral/.plugin_symlinks/${plugin}/windows plugins/${plugin}) 18 | target_link_libraries(${BINARY_NAME} PRIVATE ${plugin}_plugin) 19 | list(APPEND PLUGIN_BUNDLED_LIBRARIES $) 20 | list(APPEND PLUGIN_BUNDLED_LIBRARIES ${${plugin}_bundled_libraries}) 21 | endforeach(plugin) 22 | 23 | foreach(ffi_plugin ${FLUTTER_FFI_PLUGIN_LIST}) 24 | add_subdirectory(flutter/ephemeral/.plugin_symlinks/${ffi_plugin}/windows plugins/${ffi_plugin}) 25 | list(APPEND PLUGIN_BUNDLED_LIBRARIES ${${ffi_plugin}_bundled_libraries}) 26 | endforeach(ffi_plugin) 27 | -------------------------------------------------------------------------------- /windows/runner/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | cmake_minimum_required(VERSION 3.14) 2 | project(runner LANGUAGES CXX) 3 | 4 | # Define the application target. To change its name, change BINARY_NAME in the 5 | # top-level CMakeLists.txt, not the value here, or `flutter run` will no longer 6 | # work. 7 | # 8 | # Any new source files that you add to the application should be added here. 9 | add_executable(${BINARY_NAME} WIN32 10 | "flutter_window.cpp" 11 | "main.cpp" 12 | "utils.cpp" 13 | "win32_window.cpp" 14 | "${FLUTTER_MANAGED_DIR}/generated_plugin_registrant.cc" 15 | "Runner.rc" 16 | "runner.exe.manifest" 17 | ) 18 | 19 | # Apply the standard set of build settings. This can be removed for applications 20 | # that need different build settings. 21 | apply_standard_settings(${BINARY_NAME}) 22 | 23 | # Add preprocessor definitions for the build version. 24 | target_compile_definitions(${BINARY_NAME} PRIVATE "FLUTTER_VERSION=\"${FLUTTER_VERSION}\"") 25 | target_compile_definitions(${BINARY_NAME} PRIVATE "FLUTTER_VERSION_MAJOR=${FLUTTER_VERSION_MAJOR}") 26 | target_compile_definitions(${BINARY_NAME} PRIVATE "FLUTTER_VERSION_MINOR=${FLUTTER_VERSION_MINOR}") 27 | target_compile_definitions(${BINARY_NAME} PRIVATE "FLUTTER_VERSION_PATCH=${FLUTTER_VERSION_PATCH}") 28 | target_compile_definitions(${BINARY_NAME} PRIVATE "FLUTTER_VERSION_BUILD=${FLUTTER_VERSION_BUILD}") 29 | 30 | # Disable Windows macros that collide with C++ standard library functions. 31 | target_compile_definitions(${BINARY_NAME} PRIVATE "NOMINMAX") 32 | 33 | # Add dependency libraries and include directories. Add any application-specific 34 | # dependencies here. 35 | target_link_libraries(${BINARY_NAME} PRIVATE flutter flutter_wrapper_app) 36 | target_include_directories(${BINARY_NAME} PRIVATE "${CMAKE_SOURCE_DIR}") 37 | 38 | # Run the Flutter tool portions of the build. This must not be removed. 39 | add_dependencies(${BINARY_NAME} flutter_assemble) 40 | -------------------------------------------------------------------------------- /windows/runner/flutter_window.cpp: -------------------------------------------------------------------------------- 1 | #include "flutter_window.h" 2 | 3 | #include 4 | 5 | #include "flutter/generated_plugin_registrant.h" 6 | 7 | FlutterWindow::FlutterWindow(const flutter::DartProject& project) 8 | : project_(project) {} 9 | 10 | FlutterWindow::~FlutterWindow() {} 11 | 12 | bool FlutterWindow::OnCreate() { 13 | if (!Win32Window::OnCreate()) { 14 | return false; 15 | } 16 | 17 | RECT frame = GetClientArea(); 18 | 19 | // The size here must match the window dimensions to avoid unnecessary surface 20 | // creation / destruction in the startup path. 21 | flutter_controller_ = std::make_unique( 22 | frame.right - frame.left, frame.bottom - frame.top, project_); 23 | // Ensure that basic setup of the controller was successful. 24 | if (!flutter_controller_->engine() || !flutter_controller_->view()) { 25 | return false; 26 | } 27 | RegisterPlugins(flutter_controller_->engine()); 28 | SetChildContent(flutter_controller_->view()->GetNativeWindow()); 29 | return true; 30 | } 31 | 32 | void FlutterWindow::OnDestroy() { 33 | if (flutter_controller_) { 34 | flutter_controller_ = nullptr; 35 | } 36 | 37 | Win32Window::OnDestroy(); 38 | } 39 | 40 | LRESULT 41 | FlutterWindow::MessageHandler(HWND hwnd, UINT const message, 42 | WPARAM const wparam, 43 | LPARAM const lparam) noexcept { 44 | // Give Flutter, including plugins, an opportunity to handle window messages. 45 | if (flutter_controller_) { 46 | std::optional result = 47 | flutter_controller_->HandleTopLevelWindowProc(hwnd, message, wparam, 48 | lparam); 49 | if (result) { 50 | return *result; 51 | } 52 | } 53 | 54 | switch (message) { 55 | case WM_FONTCHANGE: 56 | flutter_controller_->engine()->ReloadSystemFonts(); 57 | break; 58 | } 59 | 60 | return Win32Window::MessageHandler(hwnd, message, wparam, lparam); 61 | } 62 | -------------------------------------------------------------------------------- /windows/runner/flutter_window.h: -------------------------------------------------------------------------------- 1 | #ifndef RUNNER_FLUTTER_WINDOW_H_ 2 | #define RUNNER_FLUTTER_WINDOW_H_ 3 | 4 | #include 5 | #include 6 | 7 | #include 8 | 9 | #include "win32_window.h" 10 | 11 | // A window that does nothing but host a Flutter view. 12 | class FlutterWindow : public Win32Window { 13 | public: 14 | // Creates a new FlutterWindow hosting a Flutter view running |project|. 15 | explicit FlutterWindow(const flutter::DartProject& project); 16 | virtual ~FlutterWindow(); 17 | 18 | protected: 19 | // Win32Window: 20 | bool OnCreate() override; 21 | void OnDestroy() override; 22 | LRESULT MessageHandler(HWND window, UINT const message, WPARAM const wparam, 23 | LPARAM const lparam) noexcept override; 24 | 25 | private: 26 | // The project to run. 27 | flutter::DartProject project_; 28 | 29 | // The Flutter instance hosted by this window. 30 | std::unique_ptr flutter_controller_; 31 | }; 32 | 33 | #endif // RUNNER_FLUTTER_WINDOW_H_ 34 | -------------------------------------------------------------------------------- /windows/runner/main.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | #include "flutter_window.h" 6 | #include "utils.h" 7 | 8 | int APIENTRY wWinMain(_In_ HINSTANCE instance, _In_opt_ HINSTANCE prev, 9 | _In_ wchar_t *command_line, _In_ int show_command) { 10 | // Attach to console when present (e.g., 'flutter run') or create a 11 | // new console when running with a debugger. 12 | if (!::AttachConsole(ATTACH_PARENT_PROCESS) && ::IsDebuggerPresent()) { 13 | CreateAndAttachConsole(); 14 | } 15 | 16 | // Initialize COM, so that it is available for use in the library and/or 17 | // plugins. 18 | ::CoInitializeEx(nullptr, COINIT_APARTMENTTHREADED); 19 | 20 | flutter::DartProject project(L"data"); 21 | 22 | std::vector command_line_arguments = 23 | GetCommandLineArguments(); 24 | 25 | project.set_dart_entrypoint_arguments(std::move(command_line_arguments)); 26 | 27 | FlutterWindow window(project); 28 | Win32Window::Point origin(10, 10); 29 | Win32Window::Size size(1280, 720); 30 | if (!window.CreateAndShow(L"flutter_demo", origin, size)) { 31 | return EXIT_FAILURE; 32 | } 33 | window.SetQuitOnClose(true); 34 | 35 | ::MSG msg; 36 | while (::GetMessage(&msg, nullptr, 0, 0)) { 37 | ::TranslateMessage(&msg); 38 | ::DispatchMessage(&msg); 39 | } 40 | 41 | ::CoUninitialize(); 42 | return EXIT_SUCCESS; 43 | } 44 | -------------------------------------------------------------------------------- /windows/runner/resource.h: -------------------------------------------------------------------------------- 1 | //{{NO_DEPENDENCIES}} 2 | // Microsoft Visual C++ generated include file. 3 | // Used by Runner.rc 4 | // 5 | #define IDI_APP_ICON 101 6 | 7 | // Next default values for new objects 8 | // 9 | #ifdef APSTUDIO_INVOKED 10 | #ifndef APSTUDIO_READONLY_SYMBOLS 11 | #define _APS_NEXT_RESOURCE_VALUE 102 12 | #define _APS_NEXT_COMMAND_VALUE 40001 13 | #define _APS_NEXT_CONTROL_VALUE 1001 14 | #define _APS_NEXT_SYMED_VALUE 101 15 | #endif 16 | #endif 17 | -------------------------------------------------------------------------------- /windows/runner/resources/app_icon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lixp185/flutter_demo/46f92f2895b84df59943ace1bf0b9c43aac6f2f5/windows/runner/resources/app_icon.ico -------------------------------------------------------------------------------- /windows/runner/runner.exe.manifest: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | PerMonitorV2 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | -------------------------------------------------------------------------------- /windows/runner/utils.cpp: -------------------------------------------------------------------------------- 1 | #include "utils.h" 2 | 3 | #include 4 | #include 5 | #include 6 | #include 7 | 8 | #include 9 | 10 | void CreateAndAttachConsole() { 11 | if (::AllocConsole()) { 12 | FILE *unused; 13 | if (freopen_s(&unused, "CONOUT$", "w", stdout)) { 14 | _dup2(_fileno(stdout), 1); 15 | } 16 | if (freopen_s(&unused, "CONOUT$", "w", stderr)) { 17 | _dup2(_fileno(stdout), 2); 18 | } 19 | std::ios::sync_with_stdio(); 20 | FlutterDesktopResyncOutputStreams(); 21 | } 22 | } 23 | 24 | std::vector GetCommandLineArguments() { 25 | // Convert the UTF-16 command line arguments to UTF-8 for the Engine to use. 26 | int argc; 27 | wchar_t** argv = ::CommandLineToArgvW(::GetCommandLineW(), &argc); 28 | if (argv == nullptr) { 29 | return std::vector(); 30 | } 31 | 32 | std::vector command_line_arguments; 33 | 34 | // Skip the first argument as it's the binary name. 35 | for (int i = 1; i < argc; i++) { 36 | command_line_arguments.push_back(Utf8FromUtf16(argv[i])); 37 | } 38 | 39 | ::LocalFree(argv); 40 | 41 | return command_line_arguments; 42 | } 43 | 44 | std::string Utf8FromUtf16(const wchar_t* utf16_string) { 45 | if (utf16_string == nullptr) { 46 | return std::string(); 47 | } 48 | int target_length = ::WideCharToMultiByte( 49 | CP_UTF8, WC_ERR_INVALID_CHARS, utf16_string, 50 | -1, nullptr, 0, nullptr, nullptr); 51 | std::string utf8_string; 52 | if (target_length == 0 || target_length > utf8_string.max_size()) { 53 | return utf8_string; 54 | } 55 | utf8_string.resize(target_length); 56 | int converted_length = ::WideCharToMultiByte( 57 | CP_UTF8, WC_ERR_INVALID_CHARS, utf16_string, 58 | -1, utf8_string.data(), 59 | target_length, nullptr, nullptr); 60 | if (converted_length == 0) { 61 | return std::string(); 62 | } 63 | return utf8_string; 64 | } 65 | -------------------------------------------------------------------------------- /windows/runner/utils.h: -------------------------------------------------------------------------------- 1 | #ifndef RUNNER_UTILS_H_ 2 | #define RUNNER_UTILS_H_ 3 | 4 | #include 5 | #include 6 | 7 | // Creates a console for the process, and redirects stdout and stderr to 8 | // it for both the runner and the Flutter library. 9 | void CreateAndAttachConsole(); 10 | 11 | // Takes a null-terminated wchar_t* encoded in UTF-16 and returns a std::string 12 | // encoded in UTF-8. Returns an empty std::string on failure. 13 | std::string Utf8FromUtf16(const wchar_t* utf16_string); 14 | 15 | // Gets the command line arguments passed in as a std::vector, 16 | // encoded in UTF-8. Returns an empty std::vector on failure. 17 | std::vector GetCommandLineArguments(); 18 | 19 | #endif // RUNNER_UTILS_H_ 20 | --------------------------------------------------------------------------------