├── .gitignore ├── .gradle ├── 5.2.1 │ ├── fileChanges │ │ └── last-build.bin │ ├── fileHashes │ │ └── fileHashes.lock │ └── gc.properties ├── buildOutputCleanup │ ├── buildOutputCleanup.lock │ └── cache.properties └── vcs-1 │ └── gc.properties ├── .metadata ├── README.md ├── README_images ├── gridview_demo.gif ├── voice_play.gif └── voice_send.gif ├── android ├── app │ ├── build.gradle │ └── src │ │ ├── debug │ │ └── AndroidManifest.xml │ │ ├── main │ │ ├── AndroidManifest.xml │ │ ├── java │ │ │ └── flutter │ │ │ │ └── accs │ │ │ │ └── com │ │ │ │ └── flutter_app_demo │ │ │ │ └── MainActivity.java │ │ └── res │ │ │ ├── drawable │ │ │ └── launch_background.xml │ │ │ ├── mipmap-hdpi │ │ │ └── ic_launcher.png │ │ │ ├── mipmap-mdpi │ │ │ └── ic_launcher.png │ │ │ ├── mipmap-xhdpi │ │ │ └── ic_launcher.png │ │ │ ├── mipmap-xxhdpi │ │ │ └── ic_launcher.png │ │ │ ├── mipmap-xxxhdpi │ │ │ └── ic_launcher.png │ │ │ └── values │ │ │ └── styles.xml │ │ └── profile │ │ └── AndroidManifest.xml ├── build.gradle ├── gradle.properties ├── gradle │ └── wrapper │ │ └── gradle-wrapper.properties └── settings.gradle ├── data └── EntryData.json ├── images ├── WechatIMG1.jpeg ├── camera_ico.png ├── cancel_voice.png ├── chat_room_left_voice.png ├── delete.png ├── emoji │ ├── collection.png │ ├── defaultEmoji.png │ ├── fuck01.png │ ├── fuck02.png │ ├── fuck03.png │ ├── fuck04.png │ ├── fuck05.png │ ├── fuck06.png │ ├── fuck07.png │ ├── fuck08.png │ ├── fuck09.png │ ├── fuck10.png │ ├── fuck100.png │ ├── fuck11.png │ ├── fuck12.png │ ├── fuck13.png │ ├── fuck14.png │ ├── fuck15.png │ ├── fuck16.png │ ├── fuck18.png │ ├── fuck19.png │ ├── fuck20.png │ ├── fuck21.png │ ├── fuck22.png │ ├── fuck23.png │ ├── fuck24.png │ ├── fuck26.png │ ├── fuck27.png │ ├── fuck28.png │ ├── fuck29.png │ ├── fuck30.png │ ├── fuck31.png │ ├── fuck32.png │ ├── fuck33.png │ ├── fuck34.png │ ├── fuck35.png │ ├── fuck37.png │ ├── fuck38.png │ ├── fuck39.png │ ├── fuck40.png │ ├── fuck41.png │ ├── fuck42.png │ ├── fuck43.png │ ├── fuck45.png │ ├── fuck46.png │ ├── fuck47.png │ ├── fuck48.png │ ├── fuck49.png │ ├── fuck50.png │ ├── fuck51.png │ ├── fuck52.png │ ├── fuck53.png │ ├── fuck55.png │ ├── fuck56.png │ ├── fuck57.png │ ├── fuck58.png │ ├── fuck61.png │ ├── fuck63.png │ ├── fuck64.png │ ├── fuck65.png │ ├── fuck66.png │ ├── fuck67.png │ ├── fuck68.png │ ├── fuck69.png │ ├── fuck71.png │ ├── fuck75.png │ ├── fuck76.png │ ├── fuck77.png │ ├── fuck79.png │ ├── fuck80.png │ ├── fuck81.png │ ├── fuck82.png │ ├── fuck83.png │ ├── fuck84.png │ ├── fuck85.png │ ├── fuck86.png │ ├── fuck90.png │ ├── fuck93.png │ ├── fuck94.png │ ├── fuck95.png │ ├── fuck96.png │ ├── fuck97.png │ ├── fuck98.png │ └── fuck99.png ├── file_ico.png ├── group_add_ico.png ├── group_delete_ico.png ├── img.jpg ├── left_voice_1.png ├── left_voice_2.png ├── left_voice_3.png ├── material_ico.png ├── photo_ico.png ├── pwd.png ├── search.png ├── transfer_ico.png ├── voice_left.png ├── voice_too_short_ico.png ├── voice_volume_1.png ├── voice_volume_2.png ├── voice_volume_3.png ├── voice_volume_4.png ├── voice_volume_5.png ├── voice_volume_6.png └── voice_volume_7.png ├── ios ├── Flutter │ ├── AppFrameworkInfo.plist │ ├── Debug.xcconfig │ └── Release.xcconfig ├── Podfile ├── Runner.xcodeproj │ ├── project.pbxproj │ ├── project.xcworkspace │ │ └── contents.xcworkspacedata │ └── xcshareddata │ │ └── xcschemes │ │ └── Runner.xcscheme ├── Runner.xcworkspace │ ├── contents.xcworkspacedata │ └── xcshareddata │ │ └── IDEWorkspaceChecks.plist └── 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 ├── lib ├── NavigatorUtils.dart ├── animation │ ├── mainAnimation.dart │ ├── voice_animation_image.dart │ ├── voice_view_screen.dart │ └── wechat_voice_screen.dart ├── bloc │ ├── BlocBase.dart │ ├── blocdemo │ │ ├── bloc │ │ │ └── LoginBloc.dart │ │ ├── model │ │ │ └── UserInfo.dart │ │ ├── presenter │ │ │ └── LoginPresenter.dart │ │ ├── provider │ │ │ └── LoginApiProvider.dart │ │ └── ui │ │ │ └── LoginScreen.dart │ ├── mainBloc.dart │ └── mainStream.dart ├── business_ui │ ├── async_screen.dart │ └── value_notifier_screen.dart ├── chat │ └── mainSysytem.dart ├── color.dart ├── customWidget │ ├── CoustomHomePage.dart │ ├── CustomCombinedWidget.dart │ ├── CustomPainterPageState.dart │ └── my_custom_painter.dart ├── demo │ ├── BasicAppBarSample.dart │ ├── MyIcons.dart │ ├── SlideWidget.dart │ ├── TimerDemo.dart │ ├── chat_item_view.dart │ ├── mainAudio.dart │ ├── mainDatabse.dart │ ├── mainDuration.dart │ ├── mainLoginUi.dart │ ├── mainMyIons.dart │ ├── mainSPutil.dart │ ├── mainSendMessageToChild.dart │ ├── mainWarp.dart │ ├── main_audioplayers.dart │ └── mainvoice.dart ├── eventbus │ ├── animation_event.dart │ └── native_event.dart ├── generated │ └── i18n.dart ├── image │ ├── dragscale_screen.dart │ └── image_pick_demo_screen.dart ├── main.dart ├── model │ ├── chat_room_member.dart │ ├── reply_model.dart │ ├── screen_model.dart │ └── user_info.dart ├── performance.analysis │ ├── PerformanceAnalysis1Screen.dart │ └── PerformanceAnalysis2Screen.dart ├── r.dart ├── stream │ ├── stream_demo_screen.dart │ └── stream_singleton.dart ├── template.dart ├── utils │ ├── emoji_util.dart │ ├── emoticon_widget.dart │ ├── more_chat_widget.dart │ ├── route_helper.dart │ ├── toast.dart │ └── utils.dart ├── widget │ ├── custom_popup_window.dart │ ├── loading │ │ └── progress_dialog.dart │ ├── net_loading_dalog.dart │ ├── popup_window.dart │ ├── progress_dialog.dart │ └── search_widget.dart └── widget_demo │ ├── my_expansion_panel_list.dart │ ├── ui │ ├── FilePickerScreen.dart │ ├── SplashPage.dart │ ├── StickNestedScrollViewScreen.dart │ ├── StickyDemo_screen.dart │ ├── clip_board_screen.dart │ ├── container_demo_screen.dart │ ├── custom_slider_screen.dart │ ├── custom_slider_screen2.dart │ ├── dialog_demo_screen.dart │ ├── emoji_screen.dart │ ├── expandableListView_screen.dart │ ├── expansion_panel_list_screen.dart │ ├── expansion_title_demo_screen.dart │ ├── grid_view_demo_screen.dart │ ├── image_demo_screen.dart │ ├── inheritedwidget_screen.dart │ ├── listview_demo_screen.dart │ ├── mergeable_material_item_screen.dart │ ├── multl_list_widget │ │ ├── EntryNew.dart │ │ └── multi_list_widget.dart │ ├── notification_screen.dart │ ├── popup_page_screen.dart │ ├── progress_dialog_demo_screen.dart │ ├── radio_screen.dart │ ├── refreshIndicator_demo_screen.dart │ ├── slider_screen.dart │ ├── stack_demo_screen.dart │ ├── tab_bar_view_demo_screen.dart │ ├── text_edit_demo_screen.dart │ ├── view_pager_indicator_demo.dart │ └── webview_demo_screen.dart │ └── widget_demo_screen.dart ├── pubspec.lock ├── pubspec.yaml ├── res └── values │ └── strings_en.arb └── test └── widget_test.dart /.gitignore: -------------------------------------------------------------------------------- 1 | # Miscellaneous 2 | *.class 3 | *.log 4 | *.pyc 5 | *.swp 6 | .DS_Store 7 | .atom/ 8 | .buildlog/ 9 | .history 10 | .svn/ 11 | 12 | # IntelliJ related 13 | *.iml 14 | *.ipr 15 | *.iws 16 | .idea/ 17 | 18 | # Visual Studio Code related 19 | .vscode/ 20 | 21 | # Flutter/Dart/Pub related 22 | **/doc/api/ 23 | .dart_tool/ 24 | .flutter-plugins 25 | .packages 26 | .pub-cache/ 27 | .pub/ 28 | /build/ 29 | 30 | # Android related 31 | **/android/**/gradle-wrapper.jar 32 | **/android/.gradle 33 | **/android/captures/ 34 | **/android/gradlew 35 | **/android/gradlew.bat 36 | **/android/local.properties 37 | **/android/**/GeneratedPluginRegistrant.java 38 | 39 | # iOS/XCode related 40 | **/ios/**/*.mode1v3 41 | **/ios/**/*.mode2v3 42 | **/ios/**/*.moved-aside 43 | **/ios/**/*.pbxuser 44 | **/ios/**/*.perspectivev3 45 | **/ios/**/*sync/ 46 | **/ios/**/.sconsign.dblite 47 | **/ios/**/.tags* 48 | **/ios/**/.vagrant/ 49 | **/ios/**/DerivedData/ 50 | **/ios/**/Icon? 51 | **/ios/**/Pods/ 52 | **/ios/**/.symlinks/ 53 | **/ios/**/profile 54 | **/ios/**/xcuserdata 55 | **/ios/.generated/ 56 | **/ios/Flutter/App.framework 57 | **/ios/Flutter/Flutter.framework 58 | **/ios/Flutter/Generated.xcconfig 59 | **/ios/Flutter/app.flx 60 | **/ios/Flutter/app.zip 61 | **/ios/Flutter/flutter_assets/ 62 | **/ios/ServiceDefinitions.json 63 | **/ios/Runner/GeneratedPluginRegistrant.* 64 | 65 | # Exceptions to above rules. 66 | !**/ios/**/default.mode1v3 67 | !**/ios/**/default.mode2v3 68 | !**/ios/**/default.pbxuser 69 | !**/ios/**/default.perspectivev3 70 | !/packages/flutter_tools/test/data/dart_dependencies_test/**/.packages 71 | -------------------------------------------------------------------------------- /.gradle/5.2.1/fileChanges/last-build.bin: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /.gradle/5.2.1/fileHashes/fileHashes.lock: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yxwandroid/Flutter-Study-Demo/1051f3ae861fdcc861d8185463d36a00fc3effc7/.gradle/5.2.1/fileHashes/fileHashes.lock -------------------------------------------------------------------------------- /.gradle/5.2.1/gc.properties: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yxwandroid/Flutter-Study-Demo/1051f3ae861fdcc861d8185463d36a00fc3effc7/.gradle/5.2.1/gc.properties -------------------------------------------------------------------------------- /.gradle/buildOutputCleanup/buildOutputCleanup.lock: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yxwandroid/Flutter-Study-Demo/1051f3ae861fdcc861d8185463d36a00fc3effc7/.gradle/buildOutputCleanup/buildOutputCleanup.lock -------------------------------------------------------------------------------- /.gradle/buildOutputCleanup/cache.properties: -------------------------------------------------------------------------------- 1 | #Thu Apr 02 14:10:43 CST 2020 2 | gradle.version=5.2.1 3 | -------------------------------------------------------------------------------- /.gradle/vcs-1/gc.properties: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yxwandroid/Flutter-Study-Demo/1051f3ae861fdcc861d8185463d36a00fc3effc7/.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 and should not be manually edited. 5 | 6 | version: 7 | revision: 8661d8aecd626f7f57ccbcb735553edc05a2e713 8 | channel: stable 9 | 10 | project_type: app 11 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | [TOC] 2 | ## 学习Flutter 相关的总结 3 | 4 | 5 | ## 已经实现的功能 6 | 7 | 8 | 1. 仿微信语音发送动画 9 | 2. GridView仿微信群详情界面 10 | 3. 仿微信语音播放动画 11 | 12 |   13 | 14 | 15 | 16 | ## 实现的Flutter插件 17 | 18 | 1. [Flutter录音插件](https://github.com/yxwandroid/flutter_plugin_record) 19 | 2. [Flutter友盟统计插件](https://github.com/yxwandroid/flutter_plugin_umpush) 20 | 3. [Flutter二维码扫描插件](https://github.com/yxwandroid/flutter_plugin_qrcode) 21 | 4. [Flutter视频播放插件(支持直播 各种格式视频播放)](https://github.com/yxwandroid/flutter_tencentplayer) 22 | 23 | 24 | 25 | 26 | 27 | ###### 关注公众号获取更多内容 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | -------------------------------------------------------------------------------- /README_images/gridview_demo.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yxwandroid/Flutter-Study-Demo/1051f3ae861fdcc861d8185463d36a00fc3effc7/README_images/gridview_demo.gif -------------------------------------------------------------------------------- /README_images/voice_play.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yxwandroid/Flutter-Study-Demo/1051f3ae861fdcc861d8185463d36a00fc3effc7/README_images/voice_play.gif -------------------------------------------------------------------------------- /README_images/voice_send.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yxwandroid/Flutter-Study-Demo/1051f3ae861fdcc861d8185463d36a00fc3effc7/README_images/voice_send.gif -------------------------------------------------------------------------------- /android/app/build.gradle: -------------------------------------------------------------------------------- 1 | def localProperties = new Properties() 2 | def localPropertiesFile = rootProject.file('local.properties') 3 | if (localPropertiesFile.exists()) { 4 | localPropertiesFile.withReader('UTF-8') { reader -> 5 | localProperties.load(reader) 6 | } 7 | } 8 | 9 | def flutterRoot = localProperties.getProperty('flutter.sdk') 10 | if (flutterRoot == null) { 11 | throw new GradleException("Flutter SDK not found. Define location with flutter.sdk in the local.properties file.") 12 | } 13 | 14 | def flutterVersionCode = localProperties.getProperty('flutter.versionCode') 15 | if (flutterVersionCode == null) { 16 | flutterVersionCode = '1' 17 | } 18 | 19 | def flutterVersionName = localProperties.getProperty('flutter.versionName') 20 | if (flutterVersionName == null) { 21 | flutterVersionName = '1.0' 22 | } 23 | 24 | apply plugin: 'com.android.application' 25 | apply from: "$flutterRoot/packages/flutter_tools/gradle/flutter.gradle" 26 | 27 | android { 28 | compileSdkVersion 29 29 | 30 | lintOptions { 31 | disable 'InvalidPackage' 32 | } 33 | 34 | defaultConfig { 35 | // TODO: Specify your own unique Application ID (https://developer.android.com/studio/build/application-id.html). 36 | applicationId "flutter.accs.com.flutter_app_demo" 37 | minSdkVersion 16 38 | targetSdkVersion 29 39 | versionCode flutterVersionCode.toInteger() 40 | versionName flutterVersionName 41 | testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner" 42 | } 43 | 44 | buildTypes { 45 | release { 46 | // TODO: Add your own signing config for the release build. 47 | // Signing with the debug keys for now, so `flutter run --release` works. 48 | signingConfig signingConfigs.debug 49 | } 50 | } 51 | } 52 | 53 | flutter { 54 | source '../..' 55 | } 56 | 57 | dependencies { 58 | testImplementation 'junit:junit:4.12' 59 | androidTestImplementation 'androidx.test.ext:junit:1.1.1' 60 | androidTestImplementation 'androidx.test.espresso:espresso-core:3.1.0' 61 | } 62 | 63 | 64 | subprojects { 65 | project.configurations.all { 66 | resolutionStrategy.eachDependency { details -> 67 | if (details.requested.group == 'com.android.support' 68 | && !details.requested.name.contains('multidex') ) { 69 | details.useVersion "27.1.1" 70 | } 71 | } 72 | } 73 | } -------------------------------------------------------------------------------- /android/app/src/debug/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 3 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /android/app/src/main/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 3 | 4 | 9 | 13 | 20 | 24 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | -------------------------------------------------------------------------------- /android/app/src/main/java/flutter/accs/com/flutter_app_demo/MainActivity.java: -------------------------------------------------------------------------------- 1 | package flutter.accs.com.flutter_app_demo; 2 | 3 | import android.os.Bundle; 4 | import io.flutter.app.FlutterActivity; 5 | import io.flutter.plugin.common.EventChannel; 6 | import io.flutter.plugins.GeneratedPluginRegistrant; 7 | 8 | public class MainActivity extends FlutterActivity { 9 | @Override 10 | protected void onCreate(Bundle savedInstanceState) { 11 | super.onCreate(savedInstanceState); 12 | GeneratedPluginRegistrant.registerWith(this); 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /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/yxwandroid/Flutter-Study-Demo/1051f3ae861fdcc861d8185463d36a00fc3effc7/android/app/src/main/res/mipmap-hdpi/ic_launcher.png -------------------------------------------------------------------------------- /android/app/src/main/res/mipmap-mdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yxwandroid/Flutter-Study-Demo/1051f3ae861fdcc861d8185463d36a00fc3effc7/android/app/src/main/res/mipmap-mdpi/ic_launcher.png -------------------------------------------------------------------------------- /android/app/src/main/res/mipmap-xhdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yxwandroid/Flutter-Study-Demo/1051f3ae861fdcc861d8185463d36a00fc3effc7/android/app/src/main/res/mipmap-xhdpi/ic_launcher.png -------------------------------------------------------------------------------- /android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yxwandroid/Flutter-Study-Demo/1051f3ae861fdcc861d8185463d36a00fc3effc7/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png -------------------------------------------------------------------------------- /android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yxwandroid/Flutter-Study-Demo/1051f3ae861fdcc861d8185463d36a00fc3effc7/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png -------------------------------------------------------------------------------- /android/app/src/main/res/values/styles.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 8 | 9 | -------------------------------------------------------------------------------- /android/app/src/profile/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 3 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /android/build.gradle: -------------------------------------------------------------------------------- 1 | buildscript { 2 | repositories { 3 | google() 4 | jcenter() 5 | } 6 | 7 | dependencies { 8 | classpath 'com.android.tools.build:gradle:3.5.3' 9 | } 10 | } 11 | 12 | allprojects { 13 | repositories { 14 | google() 15 | jcenter() 16 | } 17 | } 18 | 19 | rootProject.buildDir = '../build' 20 | subprojects { 21 | project.buildDir = "${rootProject.buildDir}/${project.name}" 22 | } 23 | subprojects { 24 | project.evaluationDependsOn(':app') 25 | } 26 | 27 | task clean(type: Delete) { 28 | delete rootProject.buildDir 29 | } 30 | -------------------------------------------------------------------------------- /android/gradle.properties: -------------------------------------------------------------------------------- 1 | org.gradle.jvmargs=-Xmx1536M 2 | android.enableR8=true 3 | android.useAndroidX=true 4 | android.enableJetifier=true 5 | -------------------------------------------------------------------------------- /android/gradle/wrapper/gradle-wrapper.properties: -------------------------------------------------------------------------------- 1 | #Thu Dec 12 17:36:27 CST 2019 2 | distributionBase=GRADLE_USER_HOME 3 | distributionPath=wrapper/dists 4 | zipStoreBase=GRADLE_USER_HOME 5 | zipStorePath=wrapper/dists 6 | distributionUrl=https\://services.gradle.org/distributions/gradle-5.4.1-all.zip 7 | -------------------------------------------------------------------------------- /android/settings.gradle: -------------------------------------------------------------------------------- 1 | include ':app' 2 | 3 | def flutterProjectRoot = rootProject.projectDir.parentFile.toPath() 4 | 5 | def plugins = new Properties() 6 | def pluginsFile = new File(flutterProjectRoot.toFile(), '.flutter-plugins') 7 | if (pluginsFile.exists()) { 8 | pluginsFile.withReader('UTF-8') { reader -> plugins.load(reader) } 9 | } 10 | 11 | plugins.each { name, path -> 12 | def pluginDirectory = flutterProjectRoot.resolve(path).resolve('android').toFile() 13 | include ":$name" 14 | project(":$name").projectDir = pluginDirectory 15 | } 16 | -------------------------------------------------------------------------------- /images/WechatIMG1.jpeg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yxwandroid/Flutter-Study-Demo/1051f3ae861fdcc861d8185463d36a00fc3effc7/images/WechatIMG1.jpeg -------------------------------------------------------------------------------- /images/camera_ico.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yxwandroid/Flutter-Study-Demo/1051f3ae861fdcc861d8185463d36a00fc3effc7/images/camera_ico.png -------------------------------------------------------------------------------- /images/cancel_voice.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yxwandroid/Flutter-Study-Demo/1051f3ae861fdcc861d8185463d36a00fc3effc7/images/cancel_voice.png -------------------------------------------------------------------------------- /images/chat_room_left_voice.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yxwandroid/Flutter-Study-Demo/1051f3ae861fdcc861d8185463d36a00fc3effc7/images/chat_room_left_voice.png -------------------------------------------------------------------------------- /images/delete.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yxwandroid/Flutter-Study-Demo/1051f3ae861fdcc861d8185463d36a00fc3effc7/images/delete.png -------------------------------------------------------------------------------- /images/emoji/collection.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yxwandroid/Flutter-Study-Demo/1051f3ae861fdcc861d8185463d36a00fc3effc7/images/emoji/collection.png -------------------------------------------------------------------------------- /images/emoji/defaultEmoji.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yxwandroid/Flutter-Study-Demo/1051f3ae861fdcc861d8185463d36a00fc3effc7/images/emoji/defaultEmoji.png -------------------------------------------------------------------------------- /images/emoji/fuck01.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yxwandroid/Flutter-Study-Demo/1051f3ae861fdcc861d8185463d36a00fc3effc7/images/emoji/fuck01.png -------------------------------------------------------------------------------- /images/emoji/fuck02.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yxwandroid/Flutter-Study-Demo/1051f3ae861fdcc861d8185463d36a00fc3effc7/images/emoji/fuck02.png -------------------------------------------------------------------------------- /images/emoji/fuck03.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yxwandroid/Flutter-Study-Demo/1051f3ae861fdcc861d8185463d36a00fc3effc7/images/emoji/fuck03.png -------------------------------------------------------------------------------- /images/emoji/fuck04.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yxwandroid/Flutter-Study-Demo/1051f3ae861fdcc861d8185463d36a00fc3effc7/images/emoji/fuck04.png -------------------------------------------------------------------------------- /images/emoji/fuck05.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yxwandroid/Flutter-Study-Demo/1051f3ae861fdcc861d8185463d36a00fc3effc7/images/emoji/fuck05.png -------------------------------------------------------------------------------- /images/emoji/fuck06.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yxwandroid/Flutter-Study-Demo/1051f3ae861fdcc861d8185463d36a00fc3effc7/images/emoji/fuck06.png -------------------------------------------------------------------------------- /images/emoji/fuck07.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yxwandroid/Flutter-Study-Demo/1051f3ae861fdcc861d8185463d36a00fc3effc7/images/emoji/fuck07.png -------------------------------------------------------------------------------- /images/emoji/fuck08.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yxwandroid/Flutter-Study-Demo/1051f3ae861fdcc861d8185463d36a00fc3effc7/images/emoji/fuck08.png -------------------------------------------------------------------------------- /images/emoji/fuck09.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yxwandroid/Flutter-Study-Demo/1051f3ae861fdcc861d8185463d36a00fc3effc7/images/emoji/fuck09.png -------------------------------------------------------------------------------- /images/emoji/fuck10.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yxwandroid/Flutter-Study-Demo/1051f3ae861fdcc861d8185463d36a00fc3effc7/images/emoji/fuck10.png -------------------------------------------------------------------------------- /images/emoji/fuck100.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yxwandroid/Flutter-Study-Demo/1051f3ae861fdcc861d8185463d36a00fc3effc7/images/emoji/fuck100.png -------------------------------------------------------------------------------- /images/emoji/fuck11.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yxwandroid/Flutter-Study-Demo/1051f3ae861fdcc861d8185463d36a00fc3effc7/images/emoji/fuck11.png -------------------------------------------------------------------------------- /images/emoji/fuck12.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yxwandroid/Flutter-Study-Demo/1051f3ae861fdcc861d8185463d36a00fc3effc7/images/emoji/fuck12.png -------------------------------------------------------------------------------- /images/emoji/fuck13.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yxwandroid/Flutter-Study-Demo/1051f3ae861fdcc861d8185463d36a00fc3effc7/images/emoji/fuck13.png -------------------------------------------------------------------------------- /images/emoji/fuck14.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yxwandroid/Flutter-Study-Demo/1051f3ae861fdcc861d8185463d36a00fc3effc7/images/emoji/fuck14.png -------------------------------------------------------------------------------- /images/emoji/fuck15.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yxwandroid/Flutter-Study-Demo/1051f3ae861fdcc861d8185463d36a00fc3effc7/images/emoji/fuck15.png -------------------------------------------------------------------------------- /images/emoji/fuck16.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yxwandroid/Flutter-Study-Demo/1051f3ae861fdcc861d8185463d36a00fc3effc7/images/emoji/fuck16.png -------------------------------------------------------------------------------- /images/emoji/fuck18.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yxwandroid/Flutter-Study-Demo/1051f3ae861fdcc861d8185463d36a00fc3effc7/images/emoji/fuck18.png -------------------------------------------------------------------------------- /images/emoji/fuck19.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yxwandroid/Flutter-Study-Demo/1051f3ae861fdcc861d8185463d36a00fc3effc7/images/emoji/fuck19.png -------------------------------------------------------------------------------- /images/emoji/fuck20.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yxwandroid/Flutter-Study-Demo/1051f3ae861fdcc861d8185463d36a00fc3effc7/images/emoji/fuck20.png -------------------------------------------------------------------------------- /images/emoji/fuck21.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yxwandroid/Flutter-Study-Demo/1051f3ae861fdcc861d8185463d36a00fc3effc7/images/emoji/fuck21.png -------------------------------------------------------------------------------- /images/emoji/fuck22.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yxwandroid/Flutter-Study-Demo/1051f3ae861fdcc861d8185463d36a00fc3effc7/images/emoji/fuck22.png -------------------------------------------------------------------------------- /images/emoji/fuck23.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yxwandroid/Flutter-Study-Demo/1051f3ae861fdcc861d8185463d36a00fc3effc7/images/emoji/fuck23.png -------------------------------------------------------------------------------- /images/emoji/fuck24.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yxwandroid/Flutter-Study-Demo/1051f3ae861fdcc861d8185463d36a00fc3effc7/images/emoji/fuck24.png -------------------------------------------------------------------------------- /images/emoji/fuck26.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yxwandroid/Flutter-Study-Demo/1051f3ae861fdcc861d8185463d36a00fc3effc7/images/emoji/fuck26.png -------------------------------------------------------------------------------- /images/emoji/fuck27.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yxwandroid/Flutter-Study-Demo/1051f3ae861fdcc861d8185463d36a00fc3effc7/images/emoji/fuck27.png -------------------------------------------------------------------------------- /images/emoji/fuck28.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yxwandroid/Flutter-Study-Demo/1051f3ae861fdcc861d8185463d36a00fc3effc7/images/emoji/fuck28.png -------------------------------------------------------------------------------- /images/emoji/fuck29.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yxwandroid/Flutter-Study-Demo/1051f3ae861fdcc861d8185463d36a00fc3effc7/images/emoji/fuck29.png -------------------------------------------------------------------------------- /images/emoji/fuck30.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yxwandroid/Flutter-Study-Demo/1051f3ae861fdcc861d8185463d36a00fc3effc7/images/emoji/fuck30.png -------------------------------------------------------------------------------- /images/emoji/fuck31.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yxwandroid/Flutter-Study-Demo/1051f3ae861fdcc861d8185463d36a00fc3effc7/images/emoji/fuck31.png -------------------------------------------------------------------------------- /images/emoji/fuck32.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yxwandroid/Flutter-Study-Demo/1051f3ae861fdcc861d8185463d36a00fc3effc7/images/emoji/fuck32.png -------------------------------------------------------------------------------- /images/emoji/fuck33.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yxwandroid/Flutter-Study-Demo/1051f3ae861fdcc861d8185463d36a00fc3effc7/images/emoji/fuck33.png -------------------------------------------------------------------------------- /images/emoji/fuck34.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yxwandroid/Flutter-Study-Demo/1051f3ae861fdcc861d8185463d36a00fc3effc7/images/emoji/fuck34.png -------------------------------------------------------------------------------- /images/emoji/fuck35.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yxwandroid/Flutter-Study-Demo/1051f3ae861fdcc861d8185463d36a00fc3effc7/images/emoji/fuck35.png -------------------------------------------------------------------------------- /images/emoji/fuck37.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yxwandroid/Flutter-Study-Demo/1051f3ae861fdcc861d8185463d36a00fc3effc7/images/emoji/fuck37.png -------------------------------------------------------------------------------- /images/emoji/fuck38.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yxwandroid/Flutter-Study-Demo/1051f3ae861fdcc861d8185463d36a00fc3effc7/images/emoji/fuck38.png -------------------------------------------------------------------------------- /images/emoji/fuck39.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yxwandroid/Flutter-Study-Demo/1051f3ae861fdcc861d8185463d36a00fc3effc7/images/emoji/fuck39.png -------------------------------------------------------------------------------- /images/emoji/fuck40.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yxwandroid/Flutter-Study-Demo/1051f3ae861fdcc861d8185463d36a00fc3effc7/images/emoji/fuck40.png -------------------------------------------------------------------------------- /images/emoji/fuck41.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yxwandroid/Flutter-Study-Demo/1051f3ae861fdcc861d8185463d36a00fc3effc7/images/emoji/fuck41.png -------------------------------------------------------------------------------- /images/emoji/fuck42.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yxwandroid/Flutter-Study-Demo/1051f3ae861fdcc861d8185463d36a00fc3effc7/images/emoji/fuck42.png -------------------------------------------------------------------------------- /images/emoji/fuck43.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yxwandroid/Flutter-Study-Demo/1051f3ae861fdcc861d8185463d36a00fc3effc7/images/emoji/fuck43.png -------------------------------------------------------------------------------- /images/emoji/fuck45.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yxwandroid/Flutter-Study-Demo/1051f3ae861fdcc861d8185463d36a00fc3effc7/images/emoji/fuck45.png -------------------------------------------------------------------------------- /images/emoji/fuck46.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yxwandroid/Flutter-Study-Demo/1051f3ae861fdcc861d8185463d36a00fc3effc7/images/emoji/fuck46.png -------------------------------------------------------------------------------- /images/emoji/fuck47.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yxwandroid/Flutter-Study-Demo/1051f3ae861fdcc861d8185463d36a00fc3effc7/images/emoji/fuck47.png -------------------------------------------------------------------------------- /images/emoji/fuck48.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yxwandroid/Flutter-Study-Demo/1051f3ae861fdcc861d8185463d36a00fc3effc7/images/emoji/fuck48.png -------------------------------------------------------------------------------- /images/emoji/fuck49.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yxwandroid/Flutter-Study-Demo/1051f3ae861fdcc861d8185463d36a00fc3effc7/images/emoji/fuck49.png -------------------------------------------------------------------------------- /images/emoji/fuck50.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yxwandroid/Flutter-Study-Demo/1051f3ae861fdcc861d8185463d36a00fc3effc7/images/emoji/fuck50.png -------------------------------------------------------------------------------- /images/emoji/fuck51.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yxwandroid/Flutter-Study-Demo/1051f3ae861fdcc861d8185463d36a00fc3effc7/images/emoji/fuck51.png -------------------------------------------------------------------------------- /images/emoji/fuck52.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yxwandroid/Flutter-Study-Demo/1051f3ae861fdcc861d8185463d36a00fc3effc7/images/emoji/fuck52.png -------------------------------------------------------------------------------- /images/emoji/fuck53.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yxwandroid/Flutter-Study-Demo/1051f3ae861fdcc861d8185463d36a00fc3effc7/images/emoji/fuck53.png -------------------------------------------------------------------------------- /images/emoji/fuck55.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yxwandroid/Flutter-Study-Demo/1051f3ae861fdcc861d8185463d36a00fc3effc7/images/emoji/fuck55.png -------------------------------------------------------------------------------- /images/emoji/fuck56.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yxwandroid/Flutter-Study-Demo/1051f3ae861fdcc861d8185463d36a00fc3effc7/images/emoji/fuck56.png -------------------------------------------------------------------------------- /images/emoji/fuck57.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yxwandroid/Flutter-Study-Demo/1051f3ae861fdcc861d8185463d36a00fc3effc7/images/emoji/fuck57.png -------------------------------------------------------------------------------- /images/emoji/fuck58.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yxwandroid/Flutter-Study-Demo/1051f3ae861fdcc861d8185463d36a00fc3effc7/images/emoji/fuck58.png -------------------------------------------------------------------------------- /images/emoji/fuck61.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yxwandroid/Flutter-Study-Demo/1051f3ae861fdcc861d8185463d36a00fc3effc7/images/emoji/fuck61.png -------------------------------------------------------------------------------- /images/emoji/fuck63.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yxwandroid/Flutter-Study-Demo/1051f3ae861fdcc861d8185463d36a00fc3effc7/images/emoji/fuck63.png -------------------------------------------------------------------------------- /images/emoji/fuck64.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yxwandroid/Flutter-Study-Demo/1051f3ae861fdcc861d8185463d36a00fc3effc7/images/emoji/fuck64.png -------------------------------------------------------------------------------- /images/emoji/fuck65.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yxwandroid/Flutter-Study-Demo/1051f3ae861fdcc861d8185463d36a00fc3effc7/images/emoji/fuck65.png -------------------------------------------------------------------------------- /images/emoji/fuck66.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yxwandroid/Flutter-Study-Demo/1051f3ae861fdcc861d8185463d36a00fc3effc7/images/emoji/fuck66.png -------------------------------------------------------------------------------- /images/emoji/fuck67.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yxwandroid/Flutter-Study-Demo/1051f3ae861fdcc861d8185463d36a00fc3effc7/images/emoji/fuck67.png -------------------------------------------------------------------------------- /images/emoji/fuck68.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yxwandroid/Flutter-Study-Demo/1051f3ae861fdcc861d8185463d36a00fc3effc7/images/emoji/fuck68.png -------------------------------------------------------------------------------- /images/emoji/fuck69.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yxwandroid/Flutter-Study-Demo/1051f3ae861fdcc861d8185463d36a00fc3effc7/images/emoji/fuck69.png -------------------------------------------------------------------------------- /images/emoji/fuck71.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yxwandroid/Flutter-Study-Demo/1051f3ae861fdcc861d8185463d36a00fc3effc7/images/emoji/fuck71.png -------------------------------------------------------------------------------- /images/emoji/fuck75.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yxwandroid/Flutter-Study-Demo/1051f3ae861fdcc861d8185463d36a00fc3effc7/images/emoji/fuck75.png -------------------------------------------------------------------------------- /images/emoji/fuck76.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yxwandroid/Flutter-Study-Demo/1051f3ae861fdcc861d8185463d36a00fc3effc7/images/emoji/fuck76.png -------------------------------------------------------------------------------- /images/emoji/fuck77.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yxwandroid/Flutter-Study-Demo/1051f3ae861fdcc861d8185463d36a00fc3effc7/images/emoji/fuck77.png -------------------------------------------------------------------------------- /images/emoji/fuck79.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yxwandroid/Flutter-Study-Demo/1051f3ae861fdcc861d8185463d36a00fc3effc7/images/emoji/fuck79.png -------------------------------------------------------------------------------- /images/emoji/fuck80.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yxwandroid/Flutter-Study-Demo/1051f3ae861fdcc861d8185463d36a00fc3effc7/images/emoji/fuck80.png -------------------------------------------------------------------------------- /images/emoji/fuck81.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yxwandroid/Flutter-Study-Demo/1051f3ae861fdcc861d8185463d36a00fc3effc7/images/emoji/fuck81.png -------------------------------------------------------------------------------- /images/emoji/fuck82.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yxwandroid/Flutter-Study-Demo/1051f3ae861fdcc861d8185463d36a00fc3effc7/images/emoji/fuck82.png -------------------------------------------------------------------------------- /images/emoji/fuck83.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yxwandroid/Flutter-Study-Demo/1051f3ae861fdcc861d8185463d36a00fc3effc7/images/emoji/fuck83.png -------------------------------------------------------------------------------- /images/emoji/fuck84.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yxwandroid/Flutter-Study-Demo/1051f3ae861fdcc861d8185463d36a00fc3effc7/images/emoji/fuck84.png -------------------------------------------------------------------------------- /images/emoji/fuck85.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yxwandroid/Flutter-Study-Demo/1051f3ae861fdcc861d8185463d36a00fc3effc7/images/emoji/fuck85.png -------------------------------------------------------------------------------- /images/emoji/fuck86.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yxwandroid/Flutter-Study-Demo/1051f3ae861fdcc861d8185463d36a00fc3effc7/images/emoji/fuck86.png -------------------------------------------------------------------------------- /images/emoji/fuck90.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yxwandroid/Flutter-Study-Demo/1051f3ae861fdcc861d8185463d36a00fc3effc7/images/emoji/fuck90.png -------------------------------------------------------------------------------- /images/emoji/fuck93.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yxwandroid/Flutter-Study-Demo/1051f3ae861fdcc861d8185463d36a00fc3effc7/images/emoji/fuck93.png -------------------------------------------------------------------------------- /images/emoji/fuck94.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yxwandroid/Flutter-Study-Demo/1051f3ae861fdcc861d8185463d36a00fc3effc7/images/emoji/fuck94.png -------------------------------------------------------------------------------- /images/emoji/fuck95.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yxwandroid/Flutter-Study-Demo/1051f3ae861fdcc861d8185463d36a00fc3effc7/images/emoji/fuck95.png -------------------------------------------------------------------------------- /images/emoji/fuck96.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yxwandroid/Flutter-Study-Demo/1051f3ae861fdcc861d8185463d36a00fc3effc7/images/emoji/fuck96.png -------------------------------------------------------------------------------- /images/emoji/fuck97.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yxwandroid/Flutter-Study-Demo/1051f3ae861fdcc861d8185463d36a00fc3effc7/images/emoji/fuck97.png -------------------------------------------------------------------------------- /images/emoji/fuck98.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yxwandroid/Flutter-Study-Demo/1051f3ae861fdcc861d8185463d36a00fc3effc7/images/emoji/fuck98.png -------------------------------------------------------------------------------- /images/emoji/fuck99.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yxwandroid/Flutter-Study-Demo/1051f3ae861fdcc861d8185463d36a00fc3effc7/images/emoji/fuck99.png -------------------------------------------------------------------------------- /images/file_ico.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yxwandroid/Flutter-Study-Demo/1051f3ae861fdcc861d8185463d36a00fc3effc7/images/file_ico.png -------------------------------------------------------------------------------- /images/group_add_ico.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yxwandroid/Flutter-Study-Demo/1051f3ae861fdcc861d8185463d36a00fc3effc7/images/group_add_ico.png -------------------------------------------------------------------------------- /images/group_delete_ico.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yxwandroid/Flutter-Study-Demo/1051f3ae861fdcc861d8185463d36a00fc3effc7/images/group_delete_ico.png -------------------------------------------------------------------------------- /images/img.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yxwandroid/Flutter-Study-Demo/1051f3ae861fdcc861d8185463d36a00fc3effc7/images/img.jpg -------------------------------------------------------------------------------- /images/left_voice_1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yxwandroid/Flutter-Study-Demo/1051f3ae861fdcc861d8185463d36a00fc3effc7/images/left_voice_1.png -------------------------------------------------------------------------------- /images/left_voice_2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yxwandroid/Flutter-Study-Demo/1051f3ae861fdcc861d8185463d36a00fc3effc7/images/left_voice_2.png -------------------------------------------------------------------------------- /images/left_voice_3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yxwandroid/Flutter-Study-Demo/1051f3ae861fdcc861d8185463d36a00fc3effc7/images/left_voice_3.png -------------------------------------------------------------------------------- /images/material_ico.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yxwandroid/Flutter-Study-Demo/1051f3ae861fdcc861d8185463d36a00fc3effc7/images/material_ico.png -------------------------------------------------------------------------------- /images/photo_ico.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yxwandroid/Flutter-Study-Demo/1051f3ae861fdcc861d8185463d36a00fc3effc7/images/photo_ico.png -------------------------------------------------------------------------------- /images/pwd.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yxwandroid/Flutter-Study-Demo/1051f3ae861fdcc861d8185463d36a00fc3effc7/images/pwd.png -------------------------------------------------------------------------------- /images/search.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yxwandroid/Flutter-Study-Demo/1051f3ae861fdcc861d8185463d36a00fc3effc7/images/search.png -------------------------------------------------------------------------------- /images/transfer_ico.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yxwandroid/Flutter-Study-Demo/1051f3ae861fdcc861d8185463d36a00fc3effc7/images/transfer_ico.png -------------------------------------------------------------------------------- /images/voice_left.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yxwandroid/Flutter-Study-Demo/1051f3ae861fdcc861d8185463d36a00fc3effc7/images/voice_left.png -------------------------------------------------------------------------------- /images/voice_too_short_ico.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yxwandroid/Flutter-Study-Demo/1051f3ae861fdcc861d8185463d36a00fc3effc7/images/voice_too_short_ico.png -------------------------------------------------------------------------------- /images/voice_volume_1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yxwandroid/Flutter-Study-Demo/1051f3ae861fdcc861d8185463d36a00fc3effc7/images/voice_volume_1.png -------------------------------------------------------------------------------- /images/voice_volume_2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yxwandroid/Flutter-Study-Demo/1051f3ae861fdcc861d8185463d36a00fc3effc7/images/voice_volume_2.png -------------------------------------------------------------------------------- /images/voice_volume_3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yxwandroid/Flutter-Study-Demo/1051f3ae861fdcc861d8185463d36a00fc3effc7/images/voice_volume_3.png -------------------------------------------------------------------------------- /images/voice_volume_4.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yxwandroid/Flutter-Study-Demo/1051f3ae861fdcc861d8185463d36a00fc3effc7/images/voice_volume_4.png -------------------------------------------------------------------------------- /images/voice_volume_5.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yxwandroid/Flutter-Study-Demo/1051f3ae861fdcc861d8185463d36a00fc3effc7/images/voice_volume_5.png -------------------------------------------------------------------------------- /images/voice_volume_6.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yxwandroid/Flutter-Study-Demo/1051f3ae861fdcc861d8185463d36a00fc3effc7/images/voice_volume_6.png -------------------------------------------------------------------------------- /images/voice_volume_7.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yxwandroid/Flutter-Study-Demo/1051f3ae861fdcc861d8185463d36a00fc3effc7/images/voice_volume_7.png -------------------------------------------------------------------------------- /ios/Flutter/AppFrameworkInfo.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | en 7 | CFBundleExecutable 8 | App 9 | CFBundleIdentifier 10 | io.flutter.flutter.app 11 | CFBundleInfoDictionaryVersion 12 | 6.0 13 | CFBundleName 14 | App 15 | CFBundlePackageType 16 | FMWK 17 | CFBundleShortVersionString 18 | 1.0 19 | CFBundleSignature 20 | ???? 21 | CFBundleVersion 22 | 1.0 23 | MinimumOSVersion 24 | 8.0 25 | 26 | 27 | -------------------------------------------------------------------------------- /ios/Flutter/Debug.xcconfig: -------------------------------------------------------------------------------- 1 | #include "Pods/Target Support Files/Pods-Runner/Pods-Runner.debug.xcconfig" 2 | #include "Generated.xcconfig" 3 | -------------------------------------------------------------------------------- /ios/Flutter/Release.xcconfig: -------------------------------------------------------------------------------- 1 | #include "Pods/Target Support Files/Pods-Runner/Pods-Runner.release.xcconfig" 2 | #include "Generated.xcconfig" 3 | -------------------------------------------------------------------------------- /ios/Podfile: -------------------------------------------------------------------------------- 1 | # Uncomment this line to define a global platform for your project 2 | # platform :ios, '9.0' 3 | source 'https://github.com/CocoaPods/Specs.git' 4 | # CocoaPods analytics sends network stats synchronously affecting flutter build latency. 5 | ENV['COCOAPODS_DISABLE_STATS'] = 'true' 6 | 7 | project 'Runner', { 8 | 'Debug' => :debug, 9 | 'Profile' => :release, 10 | 'Release' => :release, 11 | } 12 | 13 | def parse_KV_file(file, separator='=') 14 | file_abs_path = File.expand_path(file) 15 | if !File.exists? file_abs_path 16 | return []; 17 | end 18 | generated_key_values = {} 19 | skip_line_start_symbols = ["#", "/"] 20 | File.foreach(file_abs_path) do |line| 21 | next if skip_line_start_symbols.any? { |symbol| line =~ /^\s*#{symbol}/ } 22 | plugin = line.split(pattern=separator) 23 | if plugin.length == 2 24 | podname = plugin[0].strip() 25 | path = plugin[1].strip() 26 | podpath = File.expand_path("#{path}", file_abs_path) 27 | generated_key_values[podname] = podpath 28 | else 29 | puts "Invalid plugin specification: #{line}" 30 | end 31 | end 32 | generated_key_values 33 | end 34 | 35 | target 'Runner' do 36 | use_frameworks! 37 | use_modular_headers! 38 | 39 | # Flutter Pod 40 | 41 | copied_flutter_dir = File.join(__dir__, 'Flutter') 42 | copied_framework_path = File.join(copied_flutter_dir, 'Flutter.framework') 43 | copied_podspec_path = File.join(copied_flutter_dir, 'Flutter.podspec') 44 | unless File.exist?(copied_framework_path) && File.exist?(copied_podspec_path) 45 | # Copy Flutter.framework and Flutter.podspec to Flutter/ to have something to link against if the xcode backend script has not run yet. 46 | # That script will copy the correct debug/profile/release version of the framework based on the currently selected Xcode configuration. 47 | # CocoaPods will not embed the framework on pod install (before any build phases can generate) if the dylib does not exist. 48 | 49 | generated_xcode_build_settings_path = File.join(copied_flutter_dir, 'Generated.xcconfig') 50 | unless File.exist?(generated_xcode_build_settings_path) 51 | raise "Generated.xcconfig must exist. If you're running pod install manually, make sure flutter pub get is executed first" 52 | end 53 | generated_xcode_build_settings = parse_KV_file(generated_xcode_build_settings_path) 54 | cached_framework_dir = generated_xcode_build_settings['FLUTTER_FRAMEWORK_DIR']; 55 | 56 | unless File.exist?(copied_framework_path) 57 | FileUtils.cp_r(File.join(cached_framework_dir, 'Flutter.framework'), copied_flutter_dir) 58 | end 59 | unless File.exist?(copied_podspec_path) 60 | FileUtils.cp(File.join(cached_framework_dir, 'Flutter.podspec'), copied_flutter_dir) 61 | end 62 | end 63 | 64 | # Keep pod path relative so it can be checked into Podfile.lock. 65 | pod 'Flutter', :path => 'Flutter' 66 | 67 | # Plugin Pods 68 | 69 | # Prepare symlinks folder. We use symlinks to avoid having Podfile.lock 70 | # referring to absolute paths on developers' machines. 71 | system('rm -rf .symlinks') 72 | system('mkdir -p .symlinks/plugins') 73 | plugin_pods = parse_KV_file('../.flutter-plugins') 74 | plugin_pods.each do |name, path| 75 | symlink = File.join('.symlinks', 'plugins', name) 76 | File.symlink(path, symlink) 77 | pod name, :path => File.join(symlink, 'ios') 78 | end 79 | end 80 | 81 | # Prevent Cocoapods from embedding a second Flutter framework and causing an error with the new Xcode build system. 82 | install! 'cocoapods', :disable_input_output_paths => true 83 | 84 | post_install do |installer| 85 | installer.pods_project.targets.each do |target| 86 | target.build_configurations.each do |config| 87 | config.build_settings['ENABLE_BITCODE'] = 'NO' 88 | end 89 | end 90 | end 91 | -------------------------------------------------------------------------------- /ios/Runner.xcodeproj/project.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /ios/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme: -------------------------------------------------------------------------------- 1 | 2 | 5 | 8 | 9 | 15 | 21 | 22 | 23 | 24 | 25 | 31 | 32 | 33 | 34 | 40 | 41 | 42 | 43 | 44 | 45 | 56 | 58 | 64 | 65 | 66 | 67 | 68 | 69 | 75 | 77 | 83 | 84 | 85 | 86 | 88 | 89 | 92 | 93 | 94 | -------------------------------------------------------------------------------- /ios/Runner.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 9 | 10 | 11 | -------------------------------------------------------------------------------- /ios/Runner.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | IDEDidComputeMac32BitWarning 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: [UIApplicationLaunchOptionsKey: Any]? 9 | ) -> Bool { 10 | GeneratedPluginRegistrant.register(with: self) 11 | return super.application(application, didFinishLaunchingWithOptions: launchOptions) 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /ios/Runner/Assets.xcassets/AppIcon.appiconset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "size" : "20x20", 5 | "idiom" : "iphone", 6 | "filename" : "Icon-App-20x20@2x.png", 7 | "scale" : "2x" 8 | }, 9 | { 10 | "size" : "20x20", 11 | "idiom" : "iphone", 12 | "filename" : "Icon-App-20x20@3x.png", 13 | "scale" : "3x" 14 | }, 15 | { 16 | "size" : "29x29", 17 | "idiom" : "iphone", 18 | "filename" : "Icon-App-29x29@1x.png", 19 | "scale" : "1x" 20 | }, 21 | { 22 | "size" : "29x29", 23 | "idiom" : "iphone", 24 | "filename" : "Icon-App-29x29@2x.png", 25 | "scale" : "2x" 26 | }, 27 | { 28 | "size" : "29x29", 29 | "idiom" : "iphone", 30 | "filename" : "Icon-App-29x29@3x.png", 31 | "scale" : "3x" 32 | }, 33 | { 34 | "size" : "40x40", 35 | "idiom" : "iphone", 36 | "filename" : "Icon-App-40x40@2x.png", 37 | "scale" : "2x" 38 | }, 39 | { 40 | "size" : "40x40", 41 | "idiom" : "iphone", 42 | "filename" : "Icon-App-40x40@3x.png", 43 | "scale" : "3x" 44 | }, 45 | { 46 | "size" : "60x60", 47 | "idiom" : "iphone", 48 | "filename" : "Icon-App-60x60@2x.png", 49 | "scale" : "2x" 50 | }, 51 | { 52 | "size" : "60x60", 53 | "idiom" : "iphone", 54 | "filename" : "Icon-App-60x60@3x.png", 55 | "scale" : "3x" 56 | }, 57 | { 58 | "size" : "20x20", 59 | "idiom" : "ipad", 60 | "filename" : "Icon-App-20x20@1x.png", 61 | "scale" : "1x" 62 | }, 63 | { 64 | "size" : "20x20", 65 | "idiom" : "ipad", 66 | "filename" : "Icon-App-20x20@2x.png", 67 | "scale" : "2x" 68 | }, 69 | { 70 | "size" : "29x29", 71 | "idiom" : "ipad", 72 | "filename" : "Icon-App-29x29@1x.png", 73 | "scale" : "1x" 74 | }, 75 | { 76 | "size" : "29x29", 77 | "idiom" : "ipad", 78 | "filename" : "Icon-App-29x29@2x.png", 79 | "scale" : "2x" 80 | }, 81 | { 82 | "size" : "40x40", 83 | "idiom" : "ipad", 84 | "filename" : "Icon-App-40x40@1x.png", 85 | "scale" : "1x" 86 | }, 87 | { 88 | "size" : "40x40", 89 | "idiom" : "ipad", 90 | "filename" : "Icon-App-40x40@2x.png", 91 | "scale" : "2x" 92 | }, 93 | { 94 | "size" : "76x76", 95 | "idiom" : "ipad", 96 | "filename" : "Icon-App-76x76@1x.png", 97 | "scale" : "1x" 98 | }, 99 | { 100 | "size" : "76x76", 101 | "idiom" : "ipad", 102 | "filename" : "Icon-App-76x76@2x.png", 103 | "scale" : "2x" 104 | }, 105 | { 106 | "size" : "83.5x83.5", 107 | "idiom" : "ipad", 108 | "filename" : "Icon-App-83.5x83.5@2x.png", 109 | "scale" : "2x" 110 | }, 111 | { 112 | "size" : "1024x1024", 113 | "idiom" : "ios-marketing", 114 | "filename" : "Icon-App-1024x1024@1x.png", 115 | "scale" : "1x" 116 | } 117 | ], 118 | "info" : { 119 | "version" : 1, 120 | "author" : "xcode" 121 | } 122 | } 123 | -------------------------------------------------------------------------------- /ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-1024x1024@1x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yxwandroid/Flutter-Study-Demo/1051f3ae861fdcc861d8185463d36a00fc3effc7/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/yxwandroid/Flutter-Study-Demo/1051f3ae861fdcc861d8185463d36a00fc3effc7/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/yxwandroid/Flutter-Study-Demo/1051f3ae861fdcc861d8185463d36a00fc3effc7/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/yxwandroid/Flutter-Study-Demo/1051f3ae861fdcc861d8185463d36a00fc3effc7/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/yxwandroid/Flutter-Study-Demo/1051f3ae861fdcc861d8185463d36a00fc3effc7/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/yxwandroid/Flutter-Study-Demo/1051f3ae861fdcc861d8185463d36a00fc3effc7/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/yxwandroid/Flutter-Study-Demo/1051f3ae861fdcc861d8185463d36a00fc3effc7/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/yxwandroid/Flutter-Study-Demo/1051f3ae861fdcc861d8185463d36a00fc3effc7/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/yxwandroid/Flutter-Study-Demo/1051f3ae861fdcc861d8185463d36a00fc3effc7/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/yxwandroid/Flutter-Study-Demo/1051f3ae861fdcc861d8185463d36a00fc3effc7/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/yxwandroid/Flutter-Study-Demo/1051f3ae861fdcc861d8185463d36a00fc3effc7/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/yxwandroid/Flutter-Study-Demo/1051f3ae861fdcc861d8185463d36a00fc3effc7/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/yxwandroid/Flutter-Study-Demo/1051f3ae861fdcc861d8185463d36a00fc3effc7/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/yxwandroid/Flutter-Study-Demo/1051f3ae861fdcc861d8185463d36a00fc3effc7/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/yxwandroid/Flutter-Study-Demo/1051f3ae861fdcc861d8185463d36a00fc3effc7/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/yxwandroid/Flutter-Study-Demo/1051f3ae861fdcc861d8185463d36a00fc3effc7/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage.png -------------------------------------------------------------------------------- /ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yxwandroid/Flutter-Study-Demo/1051f3ae861fdcc861d8185463d36a00fc3effc7/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@2x.png -------------------------------------------------------------------------------- /ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yxwandroid/Flutter-Study-Demo/1051f3ae861fdcc861d8185463d36a00fc3effc7/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 | 6 | io.flutter.embedded_views_preview 7 | YES 8 | NSPhotoLibraryUsageDescription 9 | Example usage description 10 | NSCameraUsageDescription 11 | Example usage description 12 | NSCameraUsageDescription 13 | Camera permission is required for barcode scanning. 14 | 15 | NSAppTransportSecurity 16 | 17 | NSAllowsArbitraryLoads 18 | 19 | 20 | CFBundleDevelopmentRegion 21 | en 22 | CFBundleExecutable 23 | $(EXECUTABLE_NAME) 24 | CFBundleIdentifier 25 | $(PRODUCT_BUNDLE_IDENTIFIER) 26 | CFBundleInfoDictionaryVersion 27 | 6.0 28 | CFBundleName 29 | flutter_app_demo 30 | CFBundlePackageType 31 | APPL 32 | CFBundleShortVersionString 33 | $(FLUTTER_BUILD_NAME) 34 | CFBundleSignature 35 | ???? 36 | CFBundleVersion 37 | $(FLUTTER_BUILD_NUMBER) 38 | LSRequiresIPhoneOS 39 | 40 | UILaunchStoryboardName 41 | LaunchScreen 42 | UIMainStoryboardFile 43 | Main 44 | UISupportedInterfaceOrientations 45 | 46 | UIInterfaceOrientationPortrait 47 | UIInterfaceOrientationLandscapeLeft 48 | UIInterfaceOrientationLandscapeRight 49 | 50 | UISupportedInterfaceOrientations~ipad 51 | 52 | UIInterfaceOrientationPortrait 53 | UIInterfaceOrientationPortraitUpsideDown 54 | UIInterfaceOrientationLandscapeLeft 55 | UIInterfaceOrientationLandscapeRight 56 | 57 | UIViewControllerBasedStatusBarAppearance 58 | 59 | 60 | 61 | -------------------------------------------------------------------------------- /ios/Runner/Runner-Bridging-Header.h: -------------------------------------------------------------------------------- 1 | #import "GeneratedPluginRegistrant.h" -------------------------------------------------------------------------------- /lib/NavigatorUtils.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/cupertino.dart'; 2 | 3 | /// 路由的监听者 4 | class NavigatorUtils extends NavigatorObserver { 5 | static NavigatorUtils navigatorUtils; 6 | static NavigatorUtils getInstance() { 7 | if (navigatorUtils == null) { 8 | navigatorUtils = new NavigatorUtils(); 9 | } 10 | 11 | return navigatorUtils; 12 | } 13 | 14 | 15 | @override 16 | void didPush(Route route, Route previousRoute) { 17 | print("didPush----"+route.settings.name); 18 | super.didPush(route, previousRoute); 19 | } 20 | 21 | 22 | @override 23 | void didRemove(Route route, Route previousRoute) { 24 | print("didRemove----"+route.settings.name); 25 | super.didRemove(route, previousRoute); 26 | } 27 | @override 28 | void didReplace({Route newRoute, Route oldRoute}) { 29 | print("didReplace----"+newRoute.settings.name); 30 | // super.didReplace(newRoute, oldRoute); 31 | } 32 | } -------------------------------------------------------------------------------- /lib/animation/mainAnimation.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/material.dart'; 2 | 3 | 4 | 5 | class MyFadeTest extends StatefulWidget { 6 | MyFadeTest({Key key}) : super(key: key); 7 | 8 | @override 9 | State createState() => new _MyFadeTest(); 10 | } 11 | 12 | class _MyFadeTest extends State with TickerProviderStateMixin { 13 | AnimationController controller;//动画控制器 14 | CurvedAnimation curved;//曲线动画,动画插值, 15 | bool forward = true; 16 | 17 | @override 18 | void initState() {//初始化,当当前widget被插入到树中时调用 19 | super.initState(); 20 | controller = new AnimationController(value: 2, duration: const Duration(seconds: 3)); 21 | curved = new CurvedAnimation(parent: controller, curve: Curves.bounceOut);//模仿小球自由落体运动轨迹 22 | // controller.forward();//放在这里开启动画 ,打开页面就播放动画 23 | } 24 | 25 | @override 26 | Widget build(BuildContext context) { 27 | return new Scaffold( 28 | appBar: new AppBar( 29 | title: new Text('FadeTest'), 30 | ), 31 | body: new Center( 32 | child: new FadeTransition(//透明度动画 33 | opacity: curved,//将动画传入不同的动画widget 34 | child: new FlutterLogo(//创建一个小部件,用于绘制Flutter徽标 35 | size: 200.0, 36 | ), 37 | ), 38 | // child: new RotationTransition(//旋转动画 39 | // turns: curved, 40 | // child: new FlutterLogo( 41 | // size: 200.0, 42 | // ), 43 | // 44 | // ), 45 | 46 | ), 47 | floatingActionButton: new FloatingActionButton( 48 | onPressed: () { 49 | if (forward) 50 | controller.forward();//向前播放动画 51 | else 52 | controller.reverse();//向后播放动画 53 | forward = !forward; 54 | }, 55 | tooltip: 'fade', 56 | child: new Icon(Icons.track_changes), 57 | ), 58 | ); 59 | } 60 | } 61 | -------------------------------------------------------------------------------- /lib/animation/voice_animation_image.dart: -------------------------------------------------------------------------------- 1 | // 帧动画Image 2 | import 'package:flutter/material.dart'; 3 | 4 | class VoiceAnimationImage extends StatefulWidget { 5 | final List _assetList; 6 | final double width; 7 | final double height; 8 | int interval = 200; 9 | bool isStop= false; 10 | var callStart; 11 | VoiceAnimationImageState voiceAnimationImageState; 12 | 13 | 14 | VoiceAnimationImage(this._assetList, 15 | {this.width, this.height, this.isStop,this.interval}); 16 | 17 | @override 18 | State createState() { 19 | voiceAnimationImageState = VoiceAnimationImageState(); 20 | return voiceAnimationImageState; 21 | } 22 | 23 | 24 | start(){ 25 | voiceAnimationImageState.start(); 26 | } 27 | 28 | stop(){ 29 | voiceAnimationImageState.stop(); 30 | } 31 | 32 | 33 | } 34 | 35 | class VoiceAnimationImageState extends State 36 | with SingleTickerProviderStateMixin { 37 | // 动画控制 38 | Animation _animation; 39 | AnimationController _controller; 40 | int interval = 200; 41 | 42 | @override 43 | void initState() { 44 | super.initState(); 45 | 46 | if (widget.interval != null) { 47 | interval = widget.interval; 48 | } 49 | final int imageCount = widget._assetList.length; 50 | final int maxTime = interval * imageCount; 51 | 52 | 53 | // 启动动画controller 54 | _controller = new AnimationController(duration: Duration(milliseconds: maxTime)); 55 | _controller.addStatusListener((AnimationStatus status) { 56 | if (status == AnimationStatus.completed) { 57 | _controller.forward(from: 0.0); // 完成后重新开始 58 | } 59 | }); 60 | 61 | _animation = new Tween(begin: 0, end: imageCount.toDouble()) 62 | .animate(_controller) 63 | ..addListener(() { 64 | setState(() { 65 | }); 66 | }); 67 | } 68 | 69 | @override 70 | void dispose() { 71 | _controller.dispose(); 72 | super.dispose(); 73 | } 74 | 75 | stop() { 76 | _controller.stop(); 77 | } 78 | 79 | start() { 80 | _controller.forward(); 81 | } 82 | 83 | @override 84 | Widget build(BuildContext context) { 85 | 86 | if(widget.isStop){ 87 | start(); 88 | }else{ 89 | stop(); 90 | } 91 | int ix = _animation.value.floor() % widget._assetList.length; 92 | List images = []; 93 | // 把所有图片都加载进内容,否则每一帧加载时会卡顿 94 | for (int i = 0; i < widget._assetList.length; ++i) { 95 | if (i != ix) { 96 | images.add(Image.asset( 97 | widget._assetList[i], 98 | width: 0, 99 | height: 0, 100 | )); 101 | } 102 | } 103 | images.add(Image.asset( 104 | widget._assetList[ix], 105 | width: widget.width, 106 | height: widget.height, 107 | )); 108 | return Stack(alignment: AlignmentDirectional.center, children: images); 109 | } 110 | } 111 | -------------------------------------------------------------------------------- /lib/animation/voice_view_screen.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/material.dart'; 2 | 3 | 4 | /// 仿微信录制语音动画 5 | class VoiceViewScreen extends StatefulWidget { 6 | VoiceViewScreen({Key key}) : super(key: key); 7 | 8 | 9 | @override 10 | _VoiceViewScreenState createState() => _VoiceViewScreenState(); 11 | } 12 | 13 | class _VoiceViewScreenState extends State { 14 | double start = 0.0; 15 | double offset = 0.0; 16 | bool isUp = false; 17 | String textShow = "按住说话"; 18 | String toastShow = "手指上滑,取消发送"; 19 | ///默认隐藏状态 20 | bool isVoiceState = true; 21 | 22 | @override 23 | void initState() { 24 | super.initState(); 25 | } 26 | 27 | showVoiceView() { 28 | setState(() { 29 | textShow = "松开结束"; 30 | isVoiceState = false; 31 | }); 32 | } 33 | 34 | hideVoiceView() { 35 | setState(() { 36 | textShow = "按住说话"; 37 | isVoiceState = true; 38 | }); 39 | 40 | if(isUp){ 41 | print("取消发送"); 42 | }else{ 43 | print("进行发送"); 44 | } 45 | } 46 | 47 | moveVoiceView(){ 48 | // print(offset - start); 49 | setState(() { 50 | isUp = start - offset > 100 ? true : false; 51 | if (isUp) { 52 | textShow = "松开手指,取消发送"; 53 | toastShow = textShow; 54 | } else { 55 | textShow = "松开结束"; 56 | toastShow = "手指上滑,取消发送"; 57 | } 58 | }); 59 | } 60 | 61 | @override 62 | Widget build(BuildContext context) { 63 | return Scaffold( 64 | appBar: AppBar( 65 | title: Text("仿微信录制语音动画"), 66 | ), 67 | body: Container( 68 | width: double.infinity, 69 | height: double.infinity, 70 | color: Colors.white, 71 | child: Column( 72 | children: [ 73 | Expanded( 74 | child: Offstage( 75 | offstage: isVoiceState, 76 | child: Center( 77 | child: Opacity( 78 | opacity: 0.5, 79 | child: Container( 80 | width: 160, 81 | height: 160, 82 | decoration: BoxDecoration( 83 | color: Color(0xff77797A), 84 | borderRadius: BorderRadius.all(Radius.circular(20.0)), 85 | ), 86 | child: Column( 87 | children: [ 88 | Container( 89 | margin: EdgeInsets.only(top: 10), 90 | child: new Image.asset( 91 | "images/voice_volume_7.png", 92 | width: 100, 93 | height: 100, 94 | ), 95 | ), 96 | Container( 97 | padding: 98 | EdgeInsets.only(right: 20, left: 20, top: 0), 99 | child: Text( 100 | toastShow, 101 | style: TextStyle(color: Colors.white), 102 | ), 103 | ) 104 | ], 105 | ), 106 | ), 107 | ), 108 | ), 109 | ), 110 | ), 111 | GestureDetector( 112 | onVerticalDragStart: (details) { 113 | start = details.globalPosition.dy; 114 | showVoiceView(); 115 | }, 116 | onVerticalDragEnd: (details) { 117 | hideVoiceView(); 118 | }, 119 | onVerticalDragUpdate: (details) { 120 | offset = details.globalPosition.dy; 121 | moveVoiceView(); 122 | }, 123 | child: Container( 124 | height: 60, 125 | color: Colors.blue, 126 | margin: EdgeInsets.fromLTRB(50, 0, 50, 20), 127 | child: Center( 128 | child: Text( 129 | textShow, 130 | ), 131 | ), 132 | ), 133 | ), 134 | ], 135 | ), 136 | ), 137 | ); 138 | } 139 | } 140 | -------------------------------------------------------------------------------- /lib/animation/wechat_voice_screen.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/material.dart'; 2 | import 'package:flutter_app_demo/animation/voice_animation_image.dart'; 3 | 4 | ///类似微信语音播放动画 5 | class WeChatVoiceScreen extends StatefulWidget { 6 | WeChatVoiceScreen({Key key}) : super(key: key); 7 | 8 | @override 9 | _WeChatVoiceScreenState createState() => _WeChatVoiceScreenState(); 10 | } 11 | 12 | class _WeChatVoiceScreenState extends State { 13 | List _assetList = new List(); 14 | bool isStop = true; 15 | 16 | @override 17 | void initState() { 18 | super.initState(); 19 | 20 | _assetList.add("images/left_voice_1.png"); 21 | _assetList.add("images/left_voice_2.png"); 22 | _assetList.add("images/left_voice_3.png"); 23 | } 24 | 25 | @override 26 | Widget build(BuildContext context) { 27 | return Scaffold( 28 | appBar: AppBar( 29 | title: Text("微信语音播放动画"), 30 | ), 31 | body: Column( 32 | children: [ 33 | VoiceAnimationImage( 34 | _assetList, 35 | width: 100, 36 | height: 100, 37 | isStop: isStop, 38 | ), 39 | FlatButton( 40 | child: new Text("开始动画"), 41 | onPressed: () { 42 | setState(() { 43 | isStop = true; 44 | }); 45 | }, 46 | ), 47 | FlatButton( 48 | child: new Text("停止动画"), 49 | onPressed: () { 50 | setState(() { 51 | isStop = false; 52 | }); 53 | }, 54 | ), 55 | ], 56 | ), 57 | ); 58 | } 59 | 60 | callBackO(bool stop) { 61 | print(stop); 62 | } 63 | } 64 | -------------------------------------------------------------------------------- /lib/bloc/BlocBase.dart: -------------------------------------------------------------------------------- 1 | // Generic Interface for all BLoCs 2 | import 'package:flutter/cupertino.dart'; 3 | 4 | abstract class BlocBase { 5 | void dispose(); 6 | } 7 | 8 | // Generic BLoC provider 9 | class BlocProvider extends StatefulWidget { 10 | BlocProvider({ 11 | Key key, 12 | @required this.child, 13 | @required this.bloc, 14 | }): super(key: key); 15 | 16 | final T bloc; 17 | final Widget child; 18 | 19 | @override 20 | _BlocProviderState createState() => _BlocProviderState(); 21 | 22 | static T of(BuildContext context){ 23 | final type = _typeOf>(); 24 | BlocProvider provider = context.ancestorWidgetOfExactType(type); 25 | return provider.bloc; 26 | } 27 | 28 | static Type _typeOf() => T; 29 | } 30 | 31 | class _BlocProviderState extends State>{ 32 | @override 33 | void dispose(){ 34 | 35 | widget.bloc.dispose(); 36 | 37 | super.dispose(); 38 | } 39 | 40 | @override 41 | Widget build(BuildContext context){ 42 | return widget.child; 43 | } 44 | } -------------------------------------------------------------------------------- /lib/bloc/blocdemo/bloc/LoginBloc.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter_app_demo/bloc/blocdemo/model/UserInfo.dart'; 2 | import 'package:flutter_app_demo/bloc/blocdemo/presenter/LoginPresenter.dart'; 3 | import 'package:rxdart/rxdart.dart'; 4 | /// 5 | /// bloc控制模块 6 | /// 7 | class LoginBloc { 8 | 9 | 10 | final loginPresenter = LoginPresenter(); 11 | 12 | final _loginFetcher = PublishSubject(); 13 | 14 | Observable get getUserInfo=>_loginFetcher.stream; 15 | 16 | 17 | login() async{ 18 | UserInfo userInfo = await loginPresenter.login(); 19 | _loginFetcher.sink.add(userInfo); 20 | 21 | } 22 | 23 | 24 | 25 | dispose(){ 26 | _loginFetcher.close(); 27 | } 28 | 29 | } 30 | 31 | 32 | final loginBloc = LoginBloc(); 33 | -------------------------------------------------------------------------------- /lib/bloc/blocdemo/model/UserInfo.dart: -------------------------------------------------------------------------------- 1 | class UserInfo { 2 | String userName; 3 | String age; 4 | 5 | UserInfo(this.userName, this.age); 6 | } 7 | -------------------------------------------------------------------------------- /lib/bloc/blocdemo/presenter/LoginPresenter.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter_app_demo/bloc/blocdemo/model/UserInfo.dart'; 2 | import 'package:flutter_app_demo/bloc/blocdemo/provider/LoginApiProvider.dart'; 3 | 4 | /// 5 | ///登录模块的控制类 6 | /// 7 | class LoginPresenter { 8 | final loginApiProvider = new LoginApiProvider(); 9 | 10 | Future login() => loginApiProvider.login(); 11 | } 12 | -------------------------------------------------------------------------------- /lib/bloc/blocdemo/provider/LoginApiProvider.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter_app_demo/bloc/blocdemo/model/UserInfo.dart'; 2 | 3 | /// 4 | /// 访问APi的接口类 5 | /// 6 | class LoginApiProvider { 7 | 8 | 9 | 10 | ///访问登录接口 11 | Future login() async { 12 | return UserInfo("wilson", "20"); 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /lib/bloc/blocdemo/ui/LoginScreen.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/material.dart'; 2 | import 'package:flutter_app_demo/bloc/blocdemo/bloc/LoginBloc.dart'; 3 | import 'package:flutter_app_demo/bloc/blocdemo/model/UserInfo.dart'; 4 | 5 | class LoginScreen extends StatefulWidget { 6 | LoginScreen({Key key}) : super(key: key); 7 | 8 | @override 9 | _LoginScreenState createState() { 10 | return _LoginScreenState(); 11 | } 12 | } 13 | 14 | class _LoginScreenState extends State { 15 | @override 16 | void initState() { 17 | super.initState(); 18 | loginBloc.login(); 19 | } 20 | 21 | @override 22 | void dispose() { 23 | super.dispose(); 24 | loginBloc.dispose(); 25 | } 26 | 27 | @override 28 | Widget build(BuildContext context) { 29 | return Scaffold( 30 | appBar: AppBar( 31 | title: Text("login"), 32 | ), 33 | body: Container( 34 | child: FlatButton( 35 | onPressed: () {}, 36 | child: StreamBuilder( 37 | stream: loginBloc.getUserInfo, 38 | builder: (context, AsyncSnapshot snapshot) { 39 | if (snapshot.hasData) { 40 | return Text(snapshot.data.userName); 41 | } else { 42 | return Text("获取数据"); 43 | } 44 | }, 45 | ), 46 | ), 47 | ), 48 | ); 49 | } 50 | } 51 | -------------------------------------------------------------------------------- /lib/bloc/mainBloc.dart: -------------------------------------------------------------------------------- 1 | import 'dart:async'; 2 | 3 | import 'package:flutter/material.dart'; 4 | 5 | import 'BlocBase.dart'; 6 | 7 | 8 | void main() => runApp(new MyApp()); 9 | 10 | class MyApp extends StatelessWidget { 11 | @override 12 | Widget build(BuildContext context) { 13 | return new MaterialApp( 14 | title: 'Streams Demo', 15 | theme: new ThemeData( 16 | primarySwatch: Colors.blue, 17 | ), 18 | home: BlocProvider( 19 | bloc: IncrementBloc(), 20 | child: CounterPage(), 21 | ), 22 | ); 23 | } 24 | } 25 | 26 | class CounterPage extends StatelessWidget { 27 | @override 28 | Widget build(BuildContext context) { 29 | final IncrementBloc bloc = BlocProvider.of(context); 30 | 31 | return Scaffold( 32 | appBar: AppBar(title: Text('Stream version of the Counter App')), 33 | body: Center( 34 | child: StreamBuilder( 35 | stream: bloc.outCounter, 36 | initialData: 0, 37 | builder: (BuildContext context, AsyncSnapshot snapshot){ 38 | return Text('You hit me: ${snapshot.data} times'); 39 | } 40 | ), 41 | ), 42 | floatingActionButton: FloatingActionButton( 43 | child: const Icon(Icons.add), 44 | onPressed: (){ 45 | bloc.incrementCounter.add(null); 46 | }, 47 | ), 48 | ); 49 | } 50 | } 51 | 52 | class IncrementBloc implements BlocBase { 53 | int _counter; 54 | 55 | // 56 | // Stream to handle the counter 57 | // 58 | StreamController _counterController = StreamController(); 59 | StreamSink get _inAdd => _counterController.sink; 60 | Stream get outCounter => _counterController.stream; 61 | 62 | // 63 | // Stream to handle the action on the counter 64 | // 65 | StreamController _actionController = StreamController(); 66 | StreamSink get incrementCounter => _actionController.sink; 67 | 68 | // 69 | // Constructor 70 | // 71 | IncrementBloc(){ 72 | _counter = 0; 73 | _actionController.stream 74 | .listen(_handleLogic); 75 | } 76 | 77 | void dispose(){ 78 | _actionController.close(); 79 | _counterController.close(); 80 | } 81 | 82 | void _handleLogic(data){ 83 | _counter = _counter + 1; 84 | _inAdd.add(_counter); 85 | } 86 | } 87 | -------------------------------------------------------------------------------- /lib/bloc/mainStream.dart: -------------------------------------------------------------------------------- 1 | import 'dart:async'; 2 | 3 | import 'package:flutter/material.dart'; 4 | 5 | void main() => runApp(MyApp()); 6 | 7 | class MyApp extends StatelessWidget { 8 | 9 | @override 10 | Widget build(BuildContext context) { 11 | return MaterialApp( 12 | title: 'Flutter Demo', 13 | theme: ThemeData( 14 | primarySwatch: Colors.blue, 15 | ), 16 | home: CounterPage(), 17 | ); 18 | } 19 | 20 | } 21 | 22 | class CounterPage extends StatefulWidget { 23 | @override 24 | _CounterPageState createState() => _CounterPageState(); 25 | } 26 | 27 | class _CounterPageState extends State { 28 | int _counter = 0; 29 | final StreamController _streamController = StreamController(); 30 | 31 | @override 32 | void dispose(){ 33 | _streamController.close(); 34 | super.dispose(); 35 | } 36 | 37 | @override 38 | Widget build(BuildContext context) { 39 | return Scaffold( 40 | appBar: AppBar(title: Text('Stream version of the Counter App')), 41 | body: Center( 42 | child: StreamBuilder( 43 | stream: _streamController.stream, 44 | initialData: _counter, 45 | builder: (BuildContext context, AsyncSnapshot snapshot){ 46 | return Text('You hit me: ${snapshot.data} times'); 47 | } 48 | ), 49 | ), 50 | floatingActionButton: FloatingActionButton( 51 | child: const Icon(Icons.add), 52 | onPressed: (){ 53 | _streamController.sink.add(++_counter); 54 | }, 55 | ), 56 | ); 57 | } 58 | } -------------------------------------------------------------------------------- /lib/business_ui/async_screen.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/material.dart'; 2 | 3 | //http://flutter.link/2018/04/12/Dart%E4%B8%AD%E7%9A%84%E5%BC%82%E6%AD%A5%E6%93%8D%E4%BD%9C/ 4 | class AsyncScreen extends StatefulWidget { 5 | @override 6 | _AsyncScreenState createState() => _AsyncScreenState(); 7 | } 8 | 9 | class _AsyncScreenState extends State { 10 | @override 11 | void initState() { 12 | super.initState(); 13 | } 14 | 15 | String enterRestaurant() { 16 | return "和朋友进入了一家餐馆"; 17 | } 18 | 19 | String waitForDinner() { 20 | return "我们的菜来了,我要开始吃饭了"; 21 | } 22 | 23 | String startChat() { 24 | return "我们朋友聊起家常"; 25 | } 26 | 27 | String playPhone() { 28 | return "等了好好久了,我还是玩会手机吧"; 29 | } 30 | 31 | @override 32 | Widget build(BuildContext context) { 33 | // 34 | // print(enterRestaurant()); 35 | // print(waitForDinner()); 36 | // print(startChat()); 37 | // print(playPhone()); 38 | 39 | // print(enterRestaurant()); 40 | // Future waitDinnerFuture = new Future(waitForDinner); 41 | // waitDinnerFuture.then((str) { 42 | // print(str); 43 | // }); 44 | // print(startChat()); 45 | // print(playPhone()); 46 | 47 | return Scaffold( 48 | appBar: AppBar( 49 | title: Text("Flutter异步使用"), 50 | ), 51 | body: Container( 52 | child: Text("详细内容看代码"), 53 | ), 54 | floatingActionButton: FloatingActionButton( 55 | onPressed: () {}, 56 | tooltip: 'Increment', 57 | child: Icon(Icons.add), 58 | ), 59 | ); 60 | } 61 | } 62 | -------------------------------------------------------------------------------- /lib/business_ui/value_notifier_screen.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/material.dart'; 2 | class ComplicatedObject { 3 | int number; 4 | String title; 5 | 6 | ComplicatedObject({this.number, this.title}); 7 | } 8 | class ComplicatedObjectNotifier extends ValueNotifier { 9 | 10 | ComplicatedObjectNotifier(ComplicatedObject object): super(object); 11 | 12 | void setTitle(String newTitle) { 13 | value.title = newTitle; 14 | //这句是关键 一定要写。 15 | notifyListeners(); 16 | } 17 | 18 | } 19 | 20 | ///参考 21 | ///http://www.muliba.net/flutter/2019/06/14/flutter%E6%95%B0%E6%8D%AE%E7%9B%91%E5%90%AC%E5%99%A8.html 22 | class ValueNotifierScreen extends StatefulWidget { 23 | @override 24 | _ValueNotifierScreenState createState() => _ValueNotifierScreenState(); 25 | } 26 | 27 | 28 | class _ValueNotifierScreenState extends State { 29 | final ComplicatedObjectNotifier _notifier = ComplicatedObjectNotifier(ComplicatedObject(number: 0, title: '标题')); 30 | //中间不变的内容 31 | Widget _content; 32 | 33 | void _incrementCounter() { 34 | _notifier.setTitle('又是新标题'); 35 | } 36 | 37 | @override 38 | void initState() { 39 | _content = Center( 40 | child: Text( 41 | '这里是内容。。。。。。。。。。。。。', 42 | )); 43 | super.initState(); 44 | } 45 | 46 | @override 47 | Widget build(BuildContext context) { 48 | return Scaffold( 49 | appBar: AppBar( 50 | title: Text("value Notifier使用"), 51 | ), 52 | body: ValueListenableBuilder( 53 | valueListenable: _notifier, 54 | builder: (BuildContext context, ComplicatedObject value, Widget child) { 55 | return Column( 56 | children: [ 57 | Container( 58 | height: 48, 59 | child: Text('${value.title}', 60 | style: Theme.of(context).textTheme.display1), 61 | ), 62 | Expanded( 63 | child: child, 64 | flex: 1, 65 | ), 66 | Container( 67 | height: 48, 68 | child: Text('${value.number}', 69 | style: Theme.of(context).textTheme.caption), 70 | ), 71 | ], 72 | ); 73 | }, 74 | child: _content,//这里是传入上面生成好的不变的Widget 75 | ), 76 | 77 | floatingActionButton: FloatingActionButton( 78 | onPressed: _incrementCounter, 79 | tooltip: 'Increment', 80 | child: Icon(Icons.add), 81 | ), 82 | ); 83 | } 84 | } -------------------------------------------------------------------------------- /lib/chat/mainSysytem.dart: -------------------------------------------------------------------------------- 1 | import 'dart:convert'; 2 | 3 | import 'package:flutter/material.dart'; 4 | import 'package:flutter_app_demo/utils/utils.dart'; 5 | 6 | 7 | 8 | class MyChat extends StatefulWidget { 9 | MyChat({Key key, this.title}) : super(key: key); 10 | 11 | final String title; 12 | 13 | @override 14 | _MyChatState createState() => _MyChatState(); 15 | } 16 | 17 | class _MyChatState extends State { 18 | static String avatar; 19 | @override 20 | void initState() { 21 | super.initState(); 22 | avatar = 23 | "https://kefures.oss-cn-shenzhen.aliyuncs.com/avatar/8D2B68A578A8463381640F8E4CB62554/fb91beb7b653530bd00069aa4550af22.png"; 24 | // 25 | // String jsonStr = "{\"durationMs\":3084,\"url\":\"https://kefures.oss-cn-shenzhen.aliyuncs.com/weremote/chat-logs/8D2B68A578A8463381640F8E4CB62554/34/msg_22100206041956194873fe7100.mp3\"}"; 26 | // Map jsonObject = json.decode(jsonStr); 27 | // print(jsonObject["url"]); 28 | 29 | // 30 | // String content = "wxid_8mpz7k4zi1di12:\nhttps://kefures.oss-cn-shenzhen.aliyuncs.com/weremote/chat-logs/8D2B68A578A8463381640F8E4CB62554/34/msg_3915280604193004b7ef80b106.mp3"; 31 | // String temp = content.replaceAll("\n", ""); 32 | // List contents = temp.split(':'); 33 | // String wechatId = contents[0]; 34 | // String msg = contents[1]+":"+contents[2]; 35 | // print(msg); 36 | } 37 | 38 | @override 39 | Widget build(BuildContext context) { 40 | return Scaffold( 41 | appBar: AppBar( 42 | title: Text(widget.title), 43 | ), 44 | body: buildChatLeftVoice(), 45 | ); 46 | } 47 | 48 | static Widget buildMemberChange() { 49 | return Container( 50 | margin: const EdgeInsets.symmetric(horizontal: 8.0), 51 | child: Center( 52 | child: Container( 53 | width: 300, 54 | padding: EdgeInsets.fromLTRB(15, 5, 15, 5), 55 | decoration: BoxDecoration( 56 | color: Colors.yellow, 57 | borderRadius: BorderRadius.all( 58 | Radius.circular(5.0), 59 | ), 60 | ), 61 | child: new Text( 62 | "337373337373373733373733373733373337373337373373733373733373733373733373733373733373733373733373733373733373733373733337373337373337373337373733373733373733373733373733373733373733373733373733337373337373337373337373", 63 | textAlign: TextAlign.center, 64 | )), 65 | ), 66 | ); 67 | } 68 | 69 | ///聊天左侧语音界面 70 | static Widget buildChatLeftVoice() { 71 | return Container( 72 | color: Colors.black, 73 | margin: const EdgeInsets.only(left: 5.0, right: 10.0), 74 | padding: const EdgeInsets.symmetric(vertical: 10.0), 75 | child: Row( 76 | crossAxisAlignment: CrossAxisAlignment.start, //对齐方式,左上对齐 77 | children: [ 78 | CircleAvatar( 79 | backgroundImage: NetworkImage(avatar), 80 | radius: 20.0, 81 | ), 82 | Container( 83 | margin: const EdgeInsets.only(left: 5.0, right: 0, top: 0), 84 | child: Container( 85 | width: 80, 86 | height: 50, 87 | decoration: BoxDecoration( 88 | //设置背景 89 | color: Colors.yellow, 90 | borderRadius: BorderRadius.all( 91 | Radius.circular(5.0), 92 | ), 93 | ), 94 | child: Row( 95 | mainAxisAlignment: MainAxisAlignment.spaceBetween, 96 | crossAxisAlignment: CrossAxisAlignment.center, 97 | //对齐方式,左上对齐 98 | children: [ 99 | Container( 100 | color: Colors.black, 101 | margin: EdgeInsets.fromLTRB(5, 0, 0, 0), 102 | child: new Text("60\"")), 103 | Container( 104 | margin: EdgeInsets.fromLTRB(0, 0, 5, 0), 105 | child: new Image.asset( 106 | Utils.getImgPath("chat_room_left_voice"))), 107 | ], 108 | ), 109 | ), 110 | ) 111 | ], 112 | ), 113 | ); 114 | } 115 | } 116 | -------------------------------------------------------------------------------- /lib/color.dart: -------------------------------------------------------------------------------- 1 | class AppColor { 2 | 3 | static final int groupTextColor = 0xff7F8389; 4 | } -------------------------------------------------------------------------------- /lib/customWidget/CoustomHomePage.dart: -------------------------------------------------------------------------------- 1 | //首先导入自定义Widget所在文件 2 | import 'package:flutter/material.dart'; 3 | 4 | import 'CustomCombinedWidget.dart'; 5 | 6 | //在页面Widget中使用 7 | 8 | 9 | class CoustomHomePage extends StatefulWidget{ 10 | @override 11 | _HomePageState createState() => new _HomePageState(); 12 | 13 | } 14 | 15 | class _HomePageState extends State { 16 | String tips = '这里是提示'; 17 | 18 | @override 19 | Widget build(BuildContext context) { 20 | // TODO: implement build 21 | return Scaffold( 22 | appBar: AppBar( 23 | title: Text('自定义组合Widget'), 24 | ), 25 | body: Container( 26 | child: buildCombinedWidget(), 27 | ), 28 | ); 29 | } 30 | 31 | Widget buildCombinedWidget() { 32 | return Center( 33 | child: Column( 34 | children: [ 35 | Row( 36 | mainAxisAlignment: MainAxisAlignment.spaceAround, 37 | children: [ 38 | CustomCombinedWidget( //使用自定义Widget 39 | iconData: Icons.home, 40 | title: '首页', 41 | onTap: () { 42 | setState(() { 43 | this.tips = '点击了首页'; 44 | }); 45 | }, 46 | ), 47 | CustomCombinedWidget( 48 | iconData: Icons.list, 49 | title: '产品', 50 | onTap: () { 51 | setState(() { 52 | this.tips = '点击了产品'; 53 | }); 54 | }, 55 | ), 56 | CustomCombinedWidget( 57 | iconData: Icons.more_horiz, 58 | title: '更多', 59 | onTap: () { 60 | setState(() { 61 | this.tips = '点击了更多'; 62 | }); 63 | }, 64 | ), 65 | ], 66 | ), 67 | Padding( 68 | padding: EdgeInsets.only(top: 50), 69 | child: Text( 70 | this.tips, 71 | style: TextStyle(fontSize: 20, color: Colors.blue), 72 | ), 73 | ), 74 | ], 75 | ), 76 | ); 77 | } 78 | } 79 | -------------------------------------------------------------------------------- /lib/customWidget/CustomCombinedWidget.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/cupertino.dart'; 2 | import 'package:flutter/material.dart'; 3 | 4 | class CustomCombinedWidget extends StatefulWidget { 5 | 6 | final IconData iconData; 7 | final String title; 8 | final GestureTapCallback onTap; 9 | 10 | const CustomCombinedWidget({Key key, this.iconData, this.title, this.onTap}): super(key: key); 11 | 12 | @override 13 | State createState() { 14 | // TODO: implement createState 15 | return CustomCombinedWidgetState(); 16 | } 17 | 18 | } 19 | 20 | class CustomCombinedWidgetState extends State { 21 | 22 | @override 23 | Widget build(BuildContext context) { 24 | // TODO: implement build 25 | return GestureDetector( 26 | onTap: this.widget.onTap, 27 | child: Column( 28 | children: [ 29 | Icon(this.widget.iconData, size: 45.0,), 30 | Text(this.widget.title == null ? "" : this.widget.title, style: TextStyle(fontSize: 14.0, color: Colors.black),), 31 | ], 32 | ), 33 | ); 34 | } 35 | 36 | } 37 | 38 | -------------------------------------------------------------------------------- /lib/customWidget/CustomPainterPageState.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/material.dart'; 2 | 3 | import 'my_custom_painter.dart'; 4 | 5 | class CustomPainterPage extends StatefulWidget { 6 | @override 7 | CustomPainterPageState createState() => new CustomPainterPageState(); 8 | } 9 | 10 | class CustomPainterPageState extends State { 11 | List data = List(); 12 | 13 | @override 14 | Widget build(BuildContext context) { 15 | // TODO: implement build 16 | return Scaffold( 17 | appBar: AppBar( 18 | title: Text('自定义绘制Widget'), 19 | ), 20 | body: Container( 21 | child: buildDemoPaintWidget(), 22 | ), 23 | ); 24 | } 25 | 26 | Widget buildDemoPaintWidget() { 27 | return Column( 28 | crossAxisAlignment: CrossAxisAlignment.start, 29 | children: [ 30 | Container( 31 | height: 350, 32 | child: buildPaintWidget(), 33 | ), 34 | Container( 35 | child: Row( 36 | mainAxisAlignment: MainAxisAlignment.spaceAround, 37 | children: [ 38 | MaterialButton( 39 | onPressed: () { 40 | BaseData book1 = BaseData(name: '书籍A', num: 5000); 41 | BaseData book2 = BaseData(name: '书籍B', num: 2000); 42 | BaseData book3 = BaseData(name: '书籍C', num: 3000); 43 | List dataList = List(); 44 | dataList.add(book1); 45 | dataList.add(book2); 46 | dataList.add(book3); 47 | setState(() { 48 | this.data = dataList; 49 | }); 50 | }, 51 | child: Text('三本书'), 52 | ), 53 | MaterialButton( 54 | onPressed: () { 55 | BaseData book4 = BaseData(name: '书籍D', num: 4500); 56 | setState(() { 57 | this.data.add(book4); 58 | }); 59 | }, 60 | child: Text('四本书'), 61 | ), 62 | MaterialButton( 63 | onPressed: () { 64 | BaseData book5 = BaseData(name: '书籍E', num: 2500); 65 | setState(() { 66 | this.data.add(book5); 67 | }); 68 | }, 69 | child: Text('五本书'), 70 | ), 71 | ], 72 | ), 73 | ), 74 | ], 75 | ); 76 | } 77 | 78 | //构建自定义绘制的Widget 79 | Widget buildPaintWidget() { 80 | return CustomPaint( 81 | painter: MyCustomPainter(data), 82 | ); 83 | } 84 | } 85 | -------------------------------------------------------------------------------- /lib/customWidget/my_custom_painter.dart: -------------------------------------------------------------------------------- 1 | import 'dart:ui'; 2 | import 'dart:ui' as ui show TextStyle; 3 | 4 | import 'package:flutter/material.dart'; 5 | 6 | class BaseData { 7 | String name; 8 | int num; 9 | 10 | BaseData({this.name, this.num}); 11 | } 12 | 13 | class MyCustomPainter extends CustomPainter { 14 | //绘制区域宽度 15 | final int width = 300; 16 | 17 | //绘制区域高度 18 | final int height = 350; 19 | 20 | //坐标原点 21 | final Offset origin = const Offset(50.0, 280.0); 22 | 23 | //纵坐标顶点 24 | final Offset vertexVer = const Offset(50.0, 20.0); 25 | 26 | //横坐标顶点 27 | final Offset vertexHor = const Offset(300.0, 280.0); 28 | 29 | //纵坐标刻度间隔 30 | final int scaleInterval = 1000; 31 | 32 | const MyCustomPainter(this.data); 33 | 34 | final List data; 35 | 36 | //根据文本内容和字体大小等构建一段文本 37 | Paragraph buildParagraph(String text, double textSize, double constWidth) { 38 | ParagraphBuilder builder = ParagraphBuilder( 39 | ParagraphStyle( 40 | textAlign: TextAlign.right, 41 | fontSize: textSize, 42 | fontWeight: FontWeight.normal, 43 | ), 44 | ); 45 | builder.pushStyle(ui.TextStyle(color: Colors.black)); 46 | builder.addText(text); 47 | ParagraphConstraints constraints = ParagraphConstraints(width: constWidth); 48 | return builder.build()..layout(constraints); 49 | } 50 | 51 | @override 52 | void paint(Canvas canvas, Size size) { 53 | // TODO: implement paint 54 | var paint = Paint() 55 | ..color = Colors.black 56 | ..strokeWidth = 2.0 57 | ..strokeCap = StrokeCap.square; 58 | 59 | //绘制纵坐标轴线 60 | canvas.drawLine(origin, vertexVer, paint); 61 | canvas.drawLine( 62 | vertexVer, Offset(vertexVer.dx - 5, vertexVer.dy + 10), paint); 63 | canvas.drawLine( 64 | vertexVer, Offset(vertexVer.dx + 5, vertexVer.dy + 10), paint); 65 | canvas.drawParagraph( 66 | buildParagraph('印刷量', 14, origin.dx - 5), Offset(0, vertexVer.dy - 8)); 67 | 68 | //绘制横坐标轴线 69 | canvas.drawLine(origin, vertexHor, paint); 70 | canvas.drawLine( 71 | vertexHor, Offset(vertexHor.dx - 10, vertexHor.dy - 5), paint); 72 | canvas.drawLine( 73 | vertexHor, Offset(vertexHor.dx - 10, vertexHor.dy + 5), paint); 74 | canvas.drawParagraph(buildParagraph('书籍名', 14, origin.dx - 5), 75 | Offset(vertexHor.dx, origin.dy + 8)); 76 | 77 | //绘制纵坐标刻度 78 | //实际最大值 79 | double realMaxY = origin.dy - vertexVer.dy - 20; 80 | //刻度间隔实际值 81 | double scaleInte = realMaxY / 5; 82 | for (int i = 0; i < 5; i++) { 83 | canvas.drawLine(Offset(origin.dx, origin.dy - (i + 1) * scaleInte), 84 | Offset(origin.dx + 5, origin.dy - (i + 1) * scaleInte), paint); 85 | canvas.drawParagraph( 86 | buildParagraph( 87 | ((i + 1) * scaleInterval).toString(), 12, origin.dx - 5), 88 | Offset(0, origin.dy - (i + 1) * scaleInte - 8.0)); 89 | } 90 | 91 | if (data == null || data.length == 0) { 92 | return; 93 | } 94 | //计算纵坐标上的刻度 95 | int size = data.length; 96 | //柱状图间隔值 97 | double horiScalInte = (vertexHor.dx - origin.dx - 20) / size; 98 | //柱状图宽 99 | double chartWidth = 5; 100 | for (int i = 0; i < size; i++) { 101 | BaseData curData = data[i]; 102 | double valueY = curData.num * scaleInte / scaleInterval; 103 | canvas.drawRect( 104 | Rect.fromLTWH(origin.dx + (i + 1) * horiScalInte, origin.dy - valueY, 105 | chartWidth, valueY), 106 | paint); 107 | canvas.drawParagraph(buildParagraph(curData.name, 12, origin.dx - 5), 108 | Offset(origin.dx + (i + 1) * horiScalInte - 25, origin.dy + 8)); 109 | } 110 | } 111 | 112 | @override 113 | bool shouldRepaint(MyCustomPainter oldDelegate) { 114 | // TODO: implement shouldRepaint 115 | return oldDelegate.data != data; 116 | } 117 | } 118 | -------------------------------------------------------------------------------- /lib/demo/BasicAppBarSample.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/material.dart'; 2 | 3 | // This app is a stateful, it tracks the user's current choice. 4 | class BasicAppBarSample extends StatefulWidget { 5 | @override 6 | _BasicAppBarSampleState createState() => _BasicAppBarSampleState(); 7 | } 8 | 9 | class _BasicAppBarSampleState extends State { 10 | Choice _selectedChoice = choices[0]; // The app's "state". 11 | 12 | void _select(Choice choice) { 13 | setState(() { // Causes the app to rebuild with the new _selectedChoice. 14 | _selectedChoice = choice; 15 | }); 16 | } 17 | 18 | @override 19 | Widget build(BuildContext context) { 20 | return MaterialApp( 21 | home: Scaffold( 22 | appBar: AppBar( 23 | title: const Text('Basic AppBar'), 24 | actions: [ 25 | IconButton( // action button 26 | icon: Icon(choices[0].icon), 27 | onPressed: () { _select(choices[0]); }, 28 | ), 29 | IconButton( // action button 30 | icon: Icon(choices[1].icon), 31 | onPressed: () { _select(choices[1]); }, 32 | ), 33 | PopupMenuButton( // overflow menu 34 | onSelected: _select, 35 | itemBuilder: (BuildContext context) { 36 | return choices.skip(2).map>((Choice choice) { 37 | return PopupMenuItem( 38 | value: choice, 39 | child: Text(choice.title), 40 | ); 41 | }).toList(); 42 | }, 43 | ), 44 | ], 45 | ), 46 | body: Padding( 47 | padding: const EdgeInsets.all(16.0), 48 | child: ChoiceCard(choice: _selectedChoice), 49 | ), 50 | ), 51 | ); 52 | } 53 | } 54 | 55 | class Choice { 56 | const Choice({ this.title, this.icon }); 57 | final String title; 58 | final IconData icon; 59 | } 60 | 61 | const List choices = [ 62 | Choice(title: 'Car', icon: Icons.directions_car), 63 | Choice(title: 'Bicycle', icon: Icons.directions_bike), 64 | Choice(title: 'Boat', icon: Icons.directions_boat), 65 | Choice(title: 'Bus', icon: Icons.directions_bus), 66 | Choice(title: 'Train', icon: Icons.directions_railway), 67 | Choice(title: 'Walk', icon: Icons.directions_walk), 68 | ]; 69 | 70 | class ChoiceCard extends StatelessWidget { 71 | const ChoiceCard({ Key key, this.choice }) : super(key: key); 72 | 73 | final Choice choice; 74 | 75 | @override 76 | Widget build(BuildContext context) { 77 | final TextStyle textStyle = Theme.of(context).textTheme.display1; 78 | return Card( 79 | color: Colors.white, 80 | child: Center( 81 | child: Column( 82 | mainAxisSize: MainAxisSize.min, 83 | crossAxisAlignment: CrossAxisAlignment.center, 84 | children: [ 85 | Icon(choice.icon, size: 128.0, color: textStyle.color), 86 | Text(choice.title, style: textStyle), 87 | ], 88 | ), 89 | ), 90 | ); 91 | } 92 | } 93 | -------------------------------------------------------------------------------- /lib/demo/MyIcons.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/widgets.dart'; 2 | 3 | class MyIcons { 4 | //  5 | 6 | 7 | static const IconData addac = const IconData(0xe800, fontFamily:'myIcon', matchTextDirection: true); 8 | 9 | // book 图标 10 | static const IconData bowok = const IconData(0xe604, fontFamily: 'myIcon', matchTextDirection: true); 11 | 12 | // book 图标 13 | static const IconData book = 14 | const IconData(0xe614, fontFamily: 'myIcon', matchTextDirection: true); 15 | 16 | // 微信图标 17 | static const IconData wechat = 18 | const IconData(0xec7d, fontFamily: 'myIcon', matchTextDirection: true); 19 | } 20 | -------------------------------------------------------------------------------- /lib/demo/TimerDemo.dart: -------------------------------------------------------------------------------- 1 | import 'dart:async'; 2 | 3 | import 'package:flutter/material.dart'; 4 | 5 | void main() => runApp(MyApp()); 6 | 7 | class MyApp extends StatelessWidget { 8 | @override 9 | Widget build(BuildContext context) { 10 | return MaterialApp( 11 | title: 'Flutter Demo', 12 | theme: ThemeData( 13 | primarySwatch: Colors.blue, 14 | ), 15 | home: MyHomePage(title: 'Flutter Demo Home Page'), 16 | ); 17 | } 18 | } 19 | 20 | class MyHomePage extends StatefulWidget { 21 | MyHomePage({Key key, this.title}) : super(key: key); 22 | 23 | final String title; 24 | 25 | @override 26 | _MyHomePageState createState() => _MyHomePageState(); 27 | } 28 | 29 | class _MyHomePageState extends State { 30 | Timer mTimer ; 31 | @override 32 | void initState() { 33 | 34 | // 方法二 35 | Timer.periodic( Duration( milliseconds: 1000 ), ( timer ) { 36 | print('一秒钟后输出'); 37 | // 每隔 1 秒钟会调用一次,如果要结束调用 38 | // timer.cancel(); 39 | 40 | mTimer= timer; 41 | } ); 42 | super.initState(); 43 | } 44 | @override 45 | Widget build(BuildContext context) { 46 | return Scaffold( 47 | appBar: AppBar( 48 | title: Text(widget.title), 49 | ), 50 | body: Center( 51 | child: Column( 52 | mainAxisAlignment: MainAxisAlignment.center, 53 | children: [ 54 | FlatButton( 55 | onPressed: (){ 56 | mTimer.cancel(); 57 | }, 58 | child: Text("ee"), 59 | ), 60 | Text( 61 | 'You have pushed the button: en ', 62 | ), 63 | ], 64 | ), 65 | ), 66 | ); 67 | } 68 | 69 | 70 | @override 71 | void dispose() { 72 | if(mTimer!=null){ 73 | mTimer.cancel(); 74 | } 75 | super.dispose(); 76 | } 77 | } 78 | -------------------------------------------------------------------------------- /lib/demo/mainAudio.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/material.dart'; 2 | import 'package:audioplayer/audioplayer.dart'; 3 | void main() => runApp(MyApp()); 4 | 5 | class MyApp extends StatelessWidget { 6 | @override 7 | Widget build(BuildContext context) { 8 | return MaterialApp( 9 | title: 'Flutter Demo', 10 | theme: ThemeData( 11 | primarySwatch: Colors.blue, 12 | ), 13 | home: MyHomePage(title: 'Flutter Demo Home Page'), 14 | ); 15 | } 16 | } 17 | 18 | class MyHomePage extends StatefulWidget { 19 | MyHomePage({Key key, this.title}) : super(key: key); 20 | 21 | final String title; 22 | 23 | @override 24 | _MyHomePageState createState() => _MyHomePageState(); 25 | } 26 | 27 | //const kUrl = 'http://m10.music.126.net/20190606154312/8e4f4ae65f9a682002f482e5c5632a6c/ymusic/d60e/d53a/a031/1578f4093912b3c1f41a0bfd6c10115d.mp3'; 28 | const kUrl = 'http://kefures.oss-cn-shenzhen.aliyuncs.com/weremote/chat-logs/8D2B68A578A8463381640F8E4CB62554/93/1aa5d13c-db47-49c9-808a-fe6b63dd7448/wav-20190619045224.wav'; 29 | 30 | class _MyHomePageState extends State { 31 | 32 | 33 | bool isPlay = false; 34 | AudioPlayer audioPlayer; 35 | @override 36 | void initState() { 37 | // TODO: implement initState 38 | super.initState(); 39 | audioPlayer = new AudioPlayer(); 40 | } 41 | 42 | Future play() async { 43 | await audioPlayer.play(kUrl); 44 | isPlay = true; 45 | } 46 | 47 | Future stop() async { 48 | await audioPlayer.stop(); 49 | isPlay = false; 50 | 51 | } 52 | 53 | 54 | 55 | @override 56 | Widget build(BuildContext context) { 57 | return Scaffold( 58 | appBar: AppBar( 59 | title: Text(widget.title), 60 | ), 61 | body: Center( 62 | child: Column( 63 | mainAxisAlignment: MainAxisAlignment.center, 64 | children: [ 65 | RaisedButton( 66 | onPressed: (){ 67 | 68 | if(isPlay){ 69 | stop(); 70 | }else{ 71 | play(); 72 | } 73 | 74 | }, 75 | child: new Text("play"), 76 | ), 77 | ], 78 | ), 79 | ), 80 | ); 81 | } 82 | } 83 | -------------------------------------------------------------------------------- /lib/demo/mainDatabse.dart: -------------------------------------------------------------------------------- 1 | import 'package:collection/collection.dart'; 2 | import 'package:flutter/material.dart'; 3 | import 'package:path/path.dart'; 4 | import 'package:sqflite/sqflite.dart'; 5 | void main() => runApp(MyApp()); 6 | 7 | class MyApp extends StatelessWidget { 8 | @override 9 | Widget build(BuildContext context) { 10 | return MaterialApp( 11 | title: 'Flutter Demo', 12 | theme: ThemeData( 13 | primarySwatch: Colors.blue, 14 | ), 15 | home: MyHomePage(title: 'Flutter Demo Home Page'), 16 | ); 17 | } 18 | } 19 | 20 | class MyHomePage extends StatefulWidget { 21 | MyHomePage({Key key, this.title}) : super(key: key); 22 | 23 | final String title; 24 | 25 | @override 26 | _MyHomePageState createState() => _MyHomePageState(); 27 | } 28 | 29 | class _MyHomePageState extends State { 30 | 31 | 32 | 33 | 34 | 35 | @override 36 | void initState() { 37 | super.initState(); 38 | initDataBase(); 39 | 40 | 41 | } 42 | 43 | 44 | 45 | initDataBase() async { 46 | // Get a location using getDatabasesPath 47 | var databasesPath = await getDatabasesPath(); 48 | String path = join(databasesPath, 'demo.db'); 49 | 50 | 51 | print(path); 52 | // open the database 53 | Database database = await openDatabase(path, version: 1, 54 | onCreate: (Database db, int version) async { 55 | // When creating the db, create the table 56 | await db.execute( 57 | 'CREATE TABLE Test (id INTEGER PRIMARY KEY, name TEXT, value INTEGER, num REAL)'); 58 | }); 59 | 60 | 61 | // Insert some records in a transaction 62 | await database.transaction((txn) async { 63 | int id1 = await txn.rawInsert( 64 | 'INSERT INTO Test(name, value, num) VALUES("some name", 1234, 456.789)'); 65 | print('inserted1: $id1'); 66 | int id2 = await txn.rawInsert( 67 | 'INSERT INTO Test(name, value, num) VALUES(?, ?, ?)', 68 | ['another name', 12345678, 3.1416]); 69 | print('inserted2: $id2'); 70 | }); 71 | 72 | // Update some record 73 | int count = await database.rawUpdate( 74 | 'UPDATE Test SET name = ?, VALUE = ? WHERE name = ?', 75 | ['updated name', '9876', 'some name']); 76 | print('updated: $count'); 77 | 78 | // Get the records 79 | List list = await database.rawQuery('SELECT * FROM Test'); 80 | List expectedList = [ 81 | {'name': 'updated name', 'id': 1, 'value': 9876, 'num': 456.789}, 82 | {'name': 'another name', 'id': 2, 'value': 12345678, 'num': 3.1416} 83 | ]; 84 | print(list); 85 | print(expectedList); 86 | assert(const DeepCollectionEquality().equals(list, expectedList)); 87 | 88 | // Count the records 89 | count = Sqflite 90 | .firstIntValue(await database.rawQuery('SELECT COUNT(*) FROM Test')); 91 | assert(count == 2); 92 | 93 | // Delete a record 94 | count = await database 95 | .rawDelete('DELETE FROM Test WHERE name = ?', ['another name']); 96 | assert(count == 1); 97 | 98 | // Close the database 99 | await database.close(); 100 | 101 | } 102 | @override 103 | Widget build(BuildContext context) { 104 | return Scaffold( 105 | appBar: AppBar( 106 | title: Text(widget.title), 107 | ), 108 | body: Center( 109 | child: Column( 110 | mainAxisAlignment: MainAxisAlignment.center, 111 | children: [ 112 | Text( 113 | 'You have pushed the button: en ', 114 | ), 115 | ], 116 | ), 117 | ), 118 | ); 119 | } 120 | } 121 | -------------------------------------------------------------------------------- /lib/demo/mainDuration.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/material.dart'; 2 | import 'package:rxdart/rxdart.dart'; 3 | void main() => runApp(MyApp()); 4 | 5 | class MyApp extends StatelessWidget { 6 | @override 7 | Widget build(BuildContext context) { 8 | return MaterialApp( 9 | title: 'Flutter Demo', 10 | theme: ThemeData( 11 | primarySwatch: Colors.blue, 12 | ), 13 | home: MyHomePage(title: 'Flutter Demo Home Page'), 14 | ); 15 | } 16 | } 17 | 18 | class MyHomePage extends StatefulWidget { 19 | MyHomePage({Key key, this.title}) : super(key: key); 20 | 21 | final String title; 22 | 23 | @override 24 | _MyHomePageState createState() => _MyHomePageState(); 25 | } 26 | 27 | class _MyHomePageState extends State { 28 | 29 | 30 | @override 31 | void initState() { 32 | super.initState(); 33 | 34 | 35 | } 36 | 37 | 38 | 39 | start(){ 40 | Observable.just(1).delay(new Duration(milliseconds: 1000)).listen((_) { 41 | 42 | print("eee wilson"); 43 | 44 | 45 | }); 46 | 47 | } 48 | @override 49 | Widget build(BuildContext context) { 50 | return Scaffold( 51 | appBar: AppBar( 52 | title: Text(widget.title), 53 | ), 54 | body: Center( 55 | child: Column( 56 | mainAxisAlignment: MainAxisAlignment.center, 57 | children: [ 58 | new RaisedButton(onPressed: (){ 59 | start(); 60 | }), 61 | ], 62 | ), 63 | ), 64 | ); 65 | } 66 | } 67 | -------------------------------------------------------------------------------- /lib/demo/mainMyIons.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/material.dart'; 2 | 3 | import 'MyIcons.dart'; 4 | 5 | void main() => runApp(MyApp()); 6 | 7 | class MyApp extends StatelessWidget { 8 | // This widget is the root of your application. 9 | @override 10 | Widget build(BuildContext context) { 11 | return MaterialApp( 12 | 13 | title: 'Flutter Demo', 14 | theme: ThemeData( 15 | primarySwatch: Colors.blue, 16 | ), 17 | home: MyHomePage(title: 'Flutter Demo Home Page'), 18 | ); 19 | } 20 | } 21 | 22 | class MyHomePage extends StatefulWidget { 23 | MyHomePage({Key key, this.title}) : super(key: key); 24 | 25 | final String title; 26 | 27 | @override 28 | _MyHomePageState createState() => _MyHomePageState(); 29 | } 30 | 31 | class _MyHomePageState extends State { 32 | @override 33 | Widget build(BuildContext context) { 34 | return Scaffold( 35 | appBar: AppBar( 36 | leading: Icon(MyIcons.addac,size: 5,color: Colors.yellow,), 37 | title: Text(widget.title), 38 | ), 39 | body: Center( 40 | child: new Container( 41 | child: new Text("www"), 42 | ), 43 | ), 44 | ); 45 | } 46 | } 47 | -------------------------------------------------------------------------------- /lib/demo/mainSPutil.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/material.dart'; 2 | import 'package:flustars/flustars.dart'; 3 | void main() => runApp(MyApp()); 4 | 5 | class MyApp extends StatelessWidget { 6 | @override 7 | Widget build(BuildContext context) { 8 | return MaterialApp( 9 | title: 'Flutter Demo', 10 | theme: ThemeData( 11 | primarySwatch: Colors.blue, 12 | ), 13 | home: MyHomePage(title: 'Flutter Demo Home Page'), 14 | ); 15 | } 16 | } 17 | 18 | class MyHomePage extends StatefulWidget { 19 | MyHomePage({Key key, this.title}) : super(key: key); 20 | 21 | final String title; 22 | 23 | 24 | 25 | 26 | @override 27 | _MyHomePageState createState() => _MyHomePageState(); 28 | } 29 | 30 | class _MyHomePageState extends State { 31 | 32 | 33 | 34 | @override 35 | void initState() { 36 | super.initState(); 37 | _initAsync(); 38 | } 39 | 40 | _initAsync() async { 41 | /// App启动时读取Sp数据,需要异步等待Sp初始化完成。 42 | await SpUtil.getInstance(); 43 | 44 | /// 同步使用Sp。 45 | SpUtil.remove("username"); 46 | String defName = SpUtil.getString("username", defValue: "sky"); 47 | SpUtil.putString("username", "sky24"); 48 | String name = SpUtil.getString("username"); 49 | print("MyApp defName: $defName, name: $name"); 50 | } 51 | @override 52 | Widget build(BuildContext context) { 53 | return Scaffold( 54 | appBar: AppBar( 55 | title: Text(widget.title), 56 | ), 57 | body: Center( 58 | child: Column( 59 | mainAxisAlignment: MainAxisAlignment.center, 60 | children: [ 61 | Text( 62 | 'You have pushed the button: en ', 63 | ), 64 | ], 65 | ), 66 | ), 67 | ); 68 | } 69 | } 70 | -------------------------------------------------------------------------------- /lib/demo/mainSendMessageToChild.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/foundation.dart'; 2 | import 'package:flutter/material.dart'; 3 | ///页面传值 4 | class Todo { 5 | final String title; 6 | final String description; 7 | 8 | Todo(this.title, this.description); 9 | } 10 | 11 | void main() { 12 | runApp(new MaterialApp( 13 | title: 'Passing Data', 14 | home: new TodosScreen( 15 | todos: new List.generate( 16 | 20, 17 | (i) => new Todo( 18 | 'Todo $i', 19 | 'A description of what needs to be done for Todo $i', 20 | ), 21 | ), 22 | ), 23 | )); 24 | } 25 | 26 | class TodosScreen extends StatelessWidget { 27 | final List todos; 28 | 29 | TodosScreen({Key key, @required this.todos}) : super(key: key); 30 | 31 | @override 32 | Widget build(BuildContext context) { 33 | return new Scaffold( 34 | appBar: new AppBar( 35 | title: new Text('Todos'), 36 | ), 37 | body: new ListView.builder( 38 | itemCount: todos.length, 39 | itemBuilder: (context, index) { 40 | return new ListTile( 41 | title: new Text(todos[index].title), 42 | // When a user taps on the ListTile, navigate to the DetailScreen. 43 | // Notice that we're not only creating a new DetailScreen, we're 44 | // also passing the current todo through to it! 45 | onTap: () { 46 | Navigator.push( 47 | context, 48 | new MaterialPageRoute( 49 | builder: (context) => new DetailScreen(todo: todos[index]), 50 | ), 51 | ); 52 | }, 53 | ); 54 | }, 55 | ), 56 | ); 57 | } 58 | } 59 | 60 | class DetailScreen extends StatelessWidget { 61 | // Declare a field that holds the Todo 62 | final Todo todo; 63 | 64 | // In the constructor, require a Todo 65 | DetailScreen({Key key, @required this.todo}) : super(key: key); 66 | 67 | @override 68 | Widget build(BuildContext context) { 69 | // Use the Todo to create our UI 70 | return new Scaffold( 71 | appBar: new AppBar( 72 | title: new Text("${todo.title}"), 73 | ), 74 | body: new Padding( 75 | padding: new EdgeInsets.all(16.0), 76 | child: new Text('${todo.description}'), 77 | ), 78 | ); 79 | } 80 | } -------------------------------------------------------------------------------- /lib/demo/mainWarp.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/material.dart'; 2 | 3 | class MyHomePage extends StatefulWidget { 4 | MyHomePage({Key key, this.title}) : super(key: key); 5 | 6 | final String title; 7 | 8 | @override 9 | _MyHomePageState createState() => _MyHomePageState(); 10 | } 11 | 12 | class _MyHomePageState extends State { 13 | @override 14 | void initState() { 15 | super.initState(); 16 | 17 | String ss = "[微笑]"; 18 | String sss = "[坏笑][左哼哼]"; 19 | String ssss = "你好[坏笑][左哼哼][右哼哼]你好那你"; 20 | String str = "你好[坏笑][左哼哼]呃呃呃[右哼哼]试试的"; 21 | 22 | var emojiReg = new RegExp("(\\[.+?\\])"); 23 | var emojiMatches = emojiReg.allMatches(str); 24 | 25 | 26 | List emojis = new List(); 27 | for (Match m in emojiMatches) { 28 | String match = m.group(0); 29 | print(match); 30 | emojis.add(match); 31 | } 32 | 33 | 34 | 35 | List strs = new List(); 36 | String temp = str; 37 | int tempPosition = 0; 38 | 39 | 40 | 41 | 42 | 43 | } 44 | 45 | 46 | 47 | 48 | getEmojiImage(){ 49 | 50 | } 51 | 52 | @override 53 | Widget build(BuildContext context) { 54 | return Scaffold( 55 | appBar: AppBar( 56 | title: Text(widget.title), 57 | ), 58 | body: Center( 59 | child: Column( 60 | mainAxisAlignment: MainAxisAlignment.center, 61 | children: [ 62 | Wrap( 63 | children: [ 64 | Text( 65 | 'You have', 66 | ), 67 | Image.asset( 68 | "images/emoji/fuck27.png", 69 | width: 20, 70 | height: 20, 71 | ), 72 | Image.asset( 73 | "images/emoji/fuck27.png", 74 | width: 20, 75 | height: 20, 76 | ), 77 | Image.asset( 78 | "images/emoji/fuck27.png", 79 | width: 20, 80 | height: 20, 81 | ), 82 | Image.asset( 83 | "images/emoji/fuck27.png", 84 | width: 20, 85 | height: 20, 86 | ), 87 | Image.asset( 88 | "images/emoji/fuck27.png", 89 | width: 20, 90 | height: 20, 91 | ), 92 | Image.asset( 93 | "images/emoji/fuck27.png", 94 | width: 20, 95 | height: 20, 96 | ), 97 | Image.asset( 98 | "images/emoji/fuck27.png", 99 | width: 20, 100 | height: 20, 101 | ), 102 | Image.asset( 103 | "images/emoji/fuck27.png", 104 | width: 20, 105 | height: 20, 106 | ), 107 | Image.asset( 108 | "images/emoji/fuck27.png", 109 | width: 20, 110 | height: 20, 111 | ), 112 | Image.asset( 113 | "images/emoji/fuck27.png", 114 | width: 20, 115 | height: 20, 116 | ), 117 | Image.asset( 118 | "images/emoji/fuck27.png", 119 | width: 20, 120 | height: 20, 121 | ), 122 | Text( 123 | 'You have', 124 | ), 125 | Text( 126 | 'You have', 127 | ), 128 | Text( 129 | 'You have', 130 | ), 131 | Image.asset( 132 | "images/emoji/fuck27.png", 133 | width: 20, 134 | height: 20, 135 | ), 136 | Text( 137 | 'You have', 138 | ), 139 | Text( 140 | 'You have', 141 | ), 142 | Text( 143 | 'You have', 144 | ), 145 | Text( 146 | 'You have', 147 | ), 148 | ], 149 | ), 150 | ], 151 | ), 152 | ), 153 | ); 154 | } 155 | } 156 | -------------------------------------------------------------------------------- /lib/demo/main_audioplayers.dart: -------------------------------------------------------------------------------- 1 | //import 'package:flutter/material.dart'; 2 | //import 'package:audioplayers/audioplayers.dart'; 3 | //import 'package:flutter/foundation.dart'; 4 | //void main() => runApp(MyApp()); 5 | // 6 | //class MyApp extends StatelessWidget { 7 | // @override 8 | // Widget build(BuildContext context) { 9 | // return MaterialApp( 10 | // title: 'Flutter Demo', 11 | // theme: ThemeData( 12 | // primarySwatch: Colors.blue, 13 | // ), 14 | // home: MyHomePage(title: 'Flutter Demo Home Page'), 15 | // ); 16 | // } 17 | //} 18 | // 19 | //class MyHomePage extends StatefulWidget { 20 | // MyHomePage({Key key, this.title}) : super(key: key); 21 | // 22 | // final String title; 23 | // 24 | // @override 25 | // _MyHomePageState createState() => _MyHomePageState(); 26 | //} 27 | // 28 | //class _MyHomePageState extends State { 29 | // 30 | //// String url = 'https://kefures.oss-cn-shenzhen.aliyuncs.com/weremote/chat-logs/8D2B68A578A8463381640F8E4CB62554/34/msg_21135906041956194873707103.mp3'; 31 | // 32 | // String url ="https://luan.xyz/files/audio/nasa_on_a_mission.mp3"; 33 | // 34 | // bool isPlay = false; 35 | // AudioPlayer audioPlayer; 36 | // 37 | // 38 | // @override 39 | // void initState() { 40 | // super.initState(); 41 | // audioPlayer = AudioPlayer(); 42 | // } 43 | // @override 44 | // Widget build(BuildContext context) { 45 | // return Scaffold( 46 | // appBar: AppBar( 47 | // title: Text(widget.title), 48 | // ), 49 | // body: Center( 50 | // child: new RaisedButton( 51 | // child: new Text("播放"), 52 | // onPressed: (){ 53 | // if(!isPlay){ 54 | // play(); 55 | // }else{ 56 | // stop(); 57 | // } 58 | // 59 | // }), 60 | // ), 61 | // ); 62 | // } 63 | // 64 | // 65 | // 66 | // play() async { 67 | // int result = await audioPlayer.play(url); 68 | // if (result == 1) { 69 | // isPlay= true; 70 | // print("play success"); 71 | // } 72 | // } 73 | // 74 | // stop() async { 75 | // int result = await audioPlayer.stop(); 76 | // if (result == 1) { 77 | // isPlay= false; 78 | // print("stop success"); 79 | // } 80 | // } 81 | //} 82 | // 83 | // 84 | -------------------------------------------------------------------------------- /lib/demo/mainvoice.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/material.dart'; 2 | 3 | void main() => runApp(MyApp()); 4 | 5 | class MyApp extends StatelessWidget { 6 | @override 7 | Widget build(BuildContext context) { 8 | return MaterialApp( 9 | title: 'Flutter Demo', 10 | theme: ThemeData( 11 | primarySwatch: Colors.blue, 12 | ), 13 | home: MyHomePage(title: 'Flutter Demo Home Page'), 14 | ); 15 | } 16 | } 17 | 18 | class MyHomePage extends StatefulWidget { 19 | MyHomePage({Key key, this.title}) : super(key: key); 20 | 21 | final String title; 22 | 23 | @override 24 | _MyHomePageState createState() => _MyHomePageState(); 25 | } 26 | 27 | class _MyHomePageState extends State { 28 | @override 29 | Widget build(BuildContext context) { 30 | return Scaffold( 31 | appBar: AppBar( 32 | title: Text(widget.title), 33 | ), 34 | body: Center( 35 | child:_buildChatLeftVoice("https://pp.myapp.com/ma_icon/0/icon_42284557_1517984341/96"), 36 | ), 37 | ); 38 | } 39 | 40 | // http://wx.qlogo.cn/mmhead/ver_1/g2eNdU7Zfvria6O99VKnw8IItlNhurBYBvkJmSJZy0JIGUH3VvRGVSe2bK6Dcia5lforNXp02wL9d4Ffg9xsGOyLhvibfqClraqqw39TyF9Gto/0 41 | ///聊天左侧语音 42 | Widget _buildChatLeftVoice(message) { 43 | 44 | 45 | Widget voiceWidget = new Container( 46 | child:new Row(children: [ 47 | Image.asset("assets/images/voice_left.png") 48 | ],),); 49 | return Container( 50 | margin: const EdgeInsets.only(left: 5.0, right: 10.0), 51 | padding: const EdgeInsets.symmetric(vertical: 10.0), 52 | child: Row( 53 | crossAxisAlignment: CrossAxisAlignment.start, //对齐方式,左上对齐 54 | children: [ 55 | CircleAvatar( 56 | backgroundImage: NetworkImage( 57 | 'https://pp.myapp.com/ma_icon/0/icon_42284557_1517984341/96'), 58 | radius: 20.0, 59 | ), 60 | Container( 61 | margin: const EdgeInsets.only(left: 10.0, right: 10, top: 10), 62 | child:voiceWidget , 63 | ) 64 | ], 65 | ), 66 | ); 67 | } 68 | } 69 | -------------------------------------------------------------------------------- /lib/eventbus/animation_event.dart: -------------------------------------------------------------------------------- 1 | class AnimationEvent{ 2 | bool isStop ; 3 | AnimationEvent(this.isStop); 4 | } -------------------------------------------------------------------------------- /lib/eventbus/native_event.dart: -------------------------------------------------------------------------------- 1 | import 'package:event_bus/event_bus.dart'; 2 | class NativeEvent{ 3 | static EventBus eventBus=new EventBus(); 4 | } -------------------------------------------------------------------------------- /lib/generated/i18n.dart: -------------------------------------------------------------------------------- 1 | import 'dart:async'; 2 | 3 | import 'package:flutter/foundation.dart'; 4 | import 'package:flutter/material.dart'; 5 | 6 | // ignore_for_file: non_constant_identifier_names 7 | // ignore_for_file: camel_case_types 8 | // ignore_for_file: prefer_single_quotes 9 | 10 | // This file is automatically generated. DO NOT EDIT, all your changes would be lost. 11 | class S implements WidgetsLocalizations { 12 | const S(); 13 | 14 | static S current; 15 | 16 | static const GeneratedLocalizationsDelegate delegate = 17 | GeneratedLocalizationsDelegate(); 18 | 19 | static S of(BuildContext context) => Localizations.of(context, S); 20 | 21 | @override 22 | TextDirection get textDirection => TextDirection.ltr; 23 | 24 | } 25 | 26 | class $en extends S { 27 | const $en(); 28 | } 29 | 30 | class GeneratedLocalizationsDelegate extends LocalizationsDelegate { 31 | const GeneratedLocalizationsDelegate(); 32 | 33 | List get supportedLocales { 34 | return const [ 35 | Locale("en", ""), 36 | ]; 37 | } 38 | 39 | LocaleListResolutionCallback listResolution({Locale fallback, bool withCountry = true}) { 40 | return (List locales, Iterable supported) { 41 | if (locales == null || locales.isEmpty) { 42 | return fallback ?? supported.first; 43 | } else { 44 | return _resolve(locales.first, fallback, supported, withCountry); 45 | } 46 | }; 47 | } 48 | 49 | LocaleResolutionCallback resolution({Locale fallback, bool withCountry = true}) { 50 | return (Locale locale, Iterable supported) { 51 | return _resolve(locale, fallback, supported, withCountry); 52 | }; 53 | } 54 | 55 | @override 56 | Future load(Locale locale) { 57 | final String lang = getLang(locale); 58 | if (lang != null) { 59 | switch (lang) { 60 | case "en": 61 | S.current = const $en(); 62 | return SynchronousFuture(S.current); 63 | default: 64 | // NO-OP. 65 | } 66 | } 67 | S.current = const S(); 68 | return SynchronousFuture(S.current); 69 | } 70 | 71 | @override 72 | bool isSupported(Locale locale) => _isSupported(locale, true); 73 | 74 | @override 75 | bool shouldReload(GeneratedLocalizationsDelegate old) => false; 76 | 77 | /// 78 | /// Internal method to resolve a locale from a list of locales. 79 | /// 80 | Locale _resolve(Locale locale, Locale fallback, Iterable supported, bool withCountry) { 81 | if (locale == null || !_isSupported(locale, withCountry)) { 82 | return fallback ?? supported.first; 83 | } 84 | 85 | final Locale languageLocale = Locale(locale.languageCode, ""); 86 | if (supported.contains(locale)) { 87 | return locale; 88 | } else if (supported.contains(languageLocale)) { 89 | return languageLocale; 90 | } else { 91 | final Locale fallbackLocale = fallback ?? supported.first; 92 | return fallbackLocale; 93 | } 94 | } 95 | 96 | /// 97 | /// Returns true if the specified locale is supported, false otherwise. 98 | /// 99 | bool _isSupported(Locale locale, bool withCountry) { 100 | if (locale != null) { 101 | for (Locale supportedLocale in supportedLocales) { 102 | // Language must always match both locales. 103 | if (supportedLocale.languageCode != locale.languageCode) { 104 | continue; 105 | } 106 | 107 | // If country code matches, return this locale. 108 | if (supportedLocale.countryCode == locale.countryCode) { 109 | return true; 110 | } 111 | 112 | // If no country requirement is requested, check if this locale has no country. 113 | if (true != withCountry && (supportedLocale.countryCode == null || supportedLocale.countryCode.isEmpty)) { 114 | return true; 115 | } 116 | } 117 | } 118 | return false; 119 | } 120 | } 121 | 122 | String getLang(Locale l) => l == null 123 | ? null 124 | : l.countryCode != null && l.countryCode.isEmpty 125 | ? l.languageCode 126 | : l.toString(); 127 | -------------------------------------------------------------------------------- /lib/image/dragscale_screen.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/material.dart'; 2 | import 'package:flutter_drag_scale/core/drag_scale_widget.dart'; 3 | 4 | class DragScaleDemoScreen extends StatefulWidget { 5 | @override 6 | DragScaleDemoScreenState createState() { 7 | return DragScaleDemoScreenState(); 8 | } 9 | } 10 | 11 | class DragScaleDemoScreenState extends State { 12 | @override 13 | Widget build(BuildContext context) { 14 | return Container( 15 | height: 400.0, 16 | width: 400, 17 | child: Center( 18 | child: DragScaleContainer( 19 | doubleTapStillScale: true, 20 | child: new Image( 21 | image: new NetworkImage( 22 | 'http://h.hiphotos.baidu.com/zhidao/wh%3D450%2C600/sign=0d023672312ac65c67506e77cec29e27/9f2f070828381f30dea167bbad014c086e06f06c.jpg'), 23 | ), 24 | ), 25 | ), 26 | ); 27 | } 28 | } -------------------------------------------------------------------------------- /lib/image/image_pick_demo_screen.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/material.dart'; 2 | import 'package:image_picker/image_picker.dart'; 3 | import 'dart:io'; 4 | 5 | class ImagePickDemoScreen extends StatefulWidget { 6 | @override 7 | _ImagePickDemoScreenState createState() => _ImagePickDemoScreenState(); 8 | } 9 | 10 | class _ImagePickDemoScreenState extends State { 11 | Future _imageFile; 12 | 13 | void _selectedImage() { 14 | setState(() { 15 | _imageFile = ImagePicker.pickImage(source: ImageSource.gallery); 16 | print(_imageFile); 17 | }); 18 | } 19 | 20 | Widget _previewImage() { 21 | return FutureBuilder( 22 | future: _imageFile, 23 | builder: (BuildContext context, AsyncSnapshot snapshot) { 24 | if (snapshot.connectionState == ConnectionState.done && 25 | snapshot.data != null) { 26 | return new ClipOval( 27 | child: SizedBox( 28 | width: 70.0, 29 | height: 70.0, 30 | child: Image.file(snapshot.data, fit: BoxFit.cover)), 31 | ); 32 | } else { 33 | return new Image.asset("images/delete.png", 34 | height: 70.0, width: 70.0); 35 | } 36 | }); 37 | } 38 | 39 | @override 40 | Widget build(BuildContext context) { 41 | return Scaffold( 42 | appBar: AppBar( 43 | title: Text("相册选择"), 44 | ), 45 | body: Column( 46 | children: [ 47 | _previewImage(), 48 | FlatButton( 49 | onPressed: (){ 50 | _selectedImage(); 51 | }, 52 | child: Text("选择照片"), 53 | ) 54 | ], 55 | ), 56 | ); 57 | } 58 | } 59 | -------------------------------------------------------------------------------- /lib/model/chat_room_member.dart: -------------------------------------------------------------------------------- 1 | //群成员信息model 2 | class ChatRoomMember { 3 | String wechatId; 4 | String nickname; 5 | String avatar; 6 | 7 | ChatRoomMember({this.wechatId, this.nickname, this.avatar}); 8 | 9 | ChatRoomMember.fromJson(Map json) { 10 | this.wechatId = json['wechatId']; 11 | this.nickname = json['nickname']; 12 | this.avatar = json['avatar']; 13 | } 14 | 15 | Map toJson() { 16 | final Map data = new Map(); 17 | data['wechatId'] = this.wechatId; 18 | data['nickname'] = this.nickname; 19 | data['avatar'] = this.avatar; 20 | return data; 21 | } 22 | 23 | } 24 | -------------------------------------------------------------------------------- /lib/model/reply_model.dart: -------------------------------------------------------------------------------- 1 | class ReplyModel1 { 2 | String groupName; 3 | int id; 4 | int sortIndex; 5 | int parentId; 6 | int replyType; 7 | List replys; 8 | 9 | ReplyModel1( 10 | {this.groupName, 11 | this.id, 12 | this.sortIndex, 13 | this.parentId, 14 | this.replyType, 15 | this.replys}); 16 | 17 | ReplyModel1.fromJson(Map json) { 18 | this.groupName = json['groupName']; 19 | this.id = json['id']; 20 | this.sortIndex = json['sortIndex']; 21 | this.parentId = json['parentId']; 22 | this.replyType = json['replyType']; 23 | this.replys = (json['replys'] as List) != null 24 | ? (json['replys'] as List) 25 | .map((i) => ReplysListBean.fromJson(i)) 26 | .toList() 27 | : null; 28 | } 29 | 30 | Map toJson() { 31 | final Map data = new Map(); 32 | data['groupName'] = this.groupName; 33 | data['id'] = this.id; 34 | data['sortIndex'] = this.sortIndex; 35 | data['parentId'] = this.parentId; 36 | data['replyType'] = this.replyType; 37 | data['replys'] = this.replys != null 38 | ? this.replys.map((i) => i.toJson()).toList() 39 | : null; 40 | return data; 41 | } 42 | 43 | @override 44 | String toString() { 45 | return 'ReplyModel1{groupName: $groupName, id: $id, sortIndex: $sortIndex, parentId: $parentId, replyType: $replyType, replys: $replys}'; 46 | } 47 | } 48 | 49 | class ReplysListBean { 50 | String title; 51 | String content; 52 | String createTime; 53 | String lastUpdateTime; 54 | int id; 55 | int tenantId; 56 | int groupId; 57 | int accountId; 58 | int msgType; 59 | int sortIndex; 60 | 61 | ReplysListBean( 62 | {this.title, 63 | this.content, 64 | this.createTime, 65 | this.lastUpdateTime, 66 | this.id, 67 | this.tenantId, 68 | this.groupId, 69 | this.accountId, 70 | this.msgType, 71 | this.sortIndex}); 72 | 73 | ReplysListBean.fromJson(Map json) { 74 | this.title = json['title']; 75 | this.content = json['content']; 76 | this.createTime = json['createTime']; 77 | this.lastUpdateTime = json['lastUpdateTime']; 78 | this.id = json['id']; 79 | this.tenantId = json['tenantId']; 80 | this.groupId = json['groupId']; 81 | this.accountId = json['accountId']; 82 | this.msgType = json['msgType']; 83 | this.sortIndex = json['sortIndex']; 84 | } 85 | 86 | Map toJson() { 87 | final Map data = new Map(); 88 | data['title'] = this.title; 89 | data['content'] = this.content; 90 | data['createTime'] = this.createTime; 91 | data['lastUpdateTime'] = this.lastUpdateTime; 92 | data['id'] = this.id; 93 | data['tenantId'] = this.tenantId; 94 | data['groupId'] = this.groupId; 95 | data['accountId'] = this.accountId; 96 | data['msgType'] = this.msgType; 97 | data['sortIndex'] = this.sortIndex; 98 | return data; 99 | } 100 | 101 | @override 102 | String toString() { 103 | return 'ReplysListBean{title: $title, content: $content, createTime: $createTime, lastUpdateTime: $lastUpdateTime, id: $id, tenantId: $tenantId, groupId: $groupId, accountId: $accountId, msgType: $msgType, sortIndex: $sortIndex}'; 104 | } 105 | } 106 | -------------------------------------------------------------------------------- /lib/model/screen_model.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/material.dart'; 2 | 3 | class ScreenModel{ 4 | String name; 5 | String url; 6 | Widget widget; 7 | ScreenModel(this.name, this.widget,{this.url}); 8 | 9 | } -------------------------------------------------------------------------------- /lib/model/user_info.dart: -------------------------------------------------------------------------------- 1 | class UserInfo { 2 | String accessToken; 3 | String tokenType; 4 | String refreshToken; 5 | int expiresIn; 6 | 7 | UserInfo({this.accessToken, this.tokenType, this.refreshToken, this.expiresIn}); 8 | 9 | UserInfo.fromJson(Map json) { 10 | this.accessToken = json['access_token']; 11 | this.tokenType = json['token_type']; 12 | this.refreshToken = json['refresh_token']; 13 | this.expiresIn = json['expires_in']; 14 | } 15 | 16 | Map toJson() { 17 | final Map data = new Map(); 18 | data['access_token'] = this.accessToken; 19 | data['token_type'] = this.tokenType; 20 | data['refresh_token'] = this.refreshToken; 21 | data['expires_in'] = this.expiresIn; 22 | return data; 23 | } 24 | 25 | } 26 | -------------------------------------------------------------------------------- /lib/performance.analysis/PerformanceAnalysis1Screen.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/cupertino.dart'; 2 | 3 | /** 4 | * https://zhuanlan.zhihu.com/p/120734866 5 | * 性能检测 6 | */ 7 | class PerformanceAnalysis1Screen extends StatefulWidget { 8 | @override 9 | _PerformanceAnalysis1ScreenState createState() => 10 | _PerformanceAnalysis1ScreenState(); 11 | } 12 | 13 | class _PerformanceAnalysis1ScreenState 14 | extends State { 15 | @override 16 | Widget build(BuildContext context) { 17 | return CupertinoTabScaffold( 18 | tabBar: CupertinoTabBar(items: [ 19 | BottomNavigationBarItem( 20 | icon: Icon(CupertinoIcons.book_solid), title: Text('书籍')), 21 | BottomNavigationBarItem( 22 | icon: Icon(CupertinoIcons.eye_solid), title: Text('观看')) 23 | ]), 24 | tabBuilder: (context, position) { 25 | return CupertinoTabView( 26 | builder: (context) { 27 | return CupertinoPageScaffold( 28 | navigationBar: CupertinoNavigationBar( 29 | middle: (position == 0) ? Text("书籍") : Text("观看"), 30 | ), 31 | child: Center( 32 | child: CupertinoButton( 33 | child: Text( 34 | "this is tab :$position", 35 | ), 36 | onPressed: () { 37 | // Navigator.of(context) 38 | // .push(CupertinoPageRoute(builder: (context) { 39 | // return DetailScreen((position == 0) ? "书籍" : "观看"); 40 | // })); 41 | })), 42 | ); 43 | }, 44 | ); 45 | }); 46 | } 47 | } 48 | -------------------------------------------------------------------------------- /lib/performance.analysis/PerformanceAnalysis2Screen.dart: -------------------------------------------------------------------------------- 1 | import 'dart:convert'; 2 | 3 | import 'package:crypto/crypto.dart'; 4 | import 'package:flutter/cupertino.dart'; 5 | import 'package:convert/convert.dart'; 6 | import 'package:flutter/material.dart'; 7 | /** 8 | * https://zhuanlan.zhihu.com/p/120734866 9 | * 性能检测 10 | */ 11 | class PerformanceAnalysis2Screen extends StatefulWidget { 12 | @override 13 | _PerformanceAnalysis2ScreenState createState() => 14 | _PerformanceAnalysis2ScreenState(); 15 | } 16 | 17 | class _PerformanceAnalysis2ScreenState 18 | extends State { 19 | 20 | String generateMd5(String data) { 21 | //MD5固定算法 22 | var content = new Utf8Encoder().convert(data); 23 | var digest = md5.convert(content); 24 | return hex.encode(digest.bytes); 25 | } 26 | 27 | 28 | @override 29 | Widget build(BuildContext context) { 30 | return Scaffold( 31 | appBar: AppBar(title: Text('demo')), 32 | body: ListView.builder( 33 | itemCount: 30, // 列表元素个数 34 | itemBuilder: (context, index) { 35 | //反复迭代计算MD5 36 | String str = '1234567890abcdefghijklmnopqrstuvwxyz'; 37 | for (int i = 0; i < 10000; i++) { 38 | str = generateMd5(str); 39 | } 40 | return ListTile(title: Text("Index : $index"), subtitle: Text(str)); 41 | } // 列表项创建方法 42 | ), 43 | ); 44 | } 45 | } 46 | -------------------------------------------------------------------------------- /lib/stream/stream_demo_screen.dart: -------------------------------------------------------------------------------- 1 | 2 | import 'dart:async'; 3 | 4 | import 'package:flutter/material.dart'; 5 | import 'package:flutter_app_demo/stream/stream_singleton.dart'; 6 | import 'package:flutter_app_demo/utils/toast.dart'; 7 | 8 | class StreamDemoScreen extends StatefulWidget { 9 | @override 10 | StreamDemoScreenState createState() => new StreamDemoScreenState(); 11 | } 12 | 13 | ///参考https://juejin.im/post/5cc2acf86fb9a0321f042041 14 | class StreamDemoScreenState extends State { 15 | 16 | ///事件订阅对象 17 | StreamSubscription _dataSubscription; 18 | 19 | @override 20 | void initState() { 21 | super.initState(); 22 | _dataSubscription= StreamSingleton.getInstance.getStrem.listen((value){ 23 | print(value); 24 | ToastUtil.showToast(value); 25 | }); 26 | } 27 | 28 | 29 | @override 30 | Widget build(BuildContext context) { 31 | return new Scaffold( 32 | appBar: new AppBar( 33 | title: InkWell( 34 | onTap: (){ 35 | }, 36 | child: Text("回调的值显示"), 37 | ), 38 | ), 39 | body: FlatButton(onPressed: (){ 40 | StreamSingleton.getInstance.addInfo(); 41 | }, child: Text("stream ")), 42 | ); 43 | } 44 | 45 | // dispose 46 | @override 47 | void dispose() { 48 | _dataSubscription.cancel(); 49 | StreamSingleton.getInstance.close(); 50 | 51 | super.dispose(); 52 | } 53 | 54 | 55 | } 56 | -------------------------------------------------------------------------------- /lib/stream/stream_singleton.dart: -------------------------------------------------------------------------------- 1 | import 'dart:async'; 2 | 3 | class StreamSingleton { 4 | ///初始化init的回调 5 | // ignore: close_sinks 6 | StreamController _dataController = new StreamController.broadcast(); 7 | Stream get getStrem => _dataController.stream; 8 | StreamSink get _dataSink => _dataController.sink; 9 | addInfo(){ 10 | _dataSink.add("wilson"); 11 | } 12 | 13 | 14 | // 私有构造函数 15 | StreamSingleton._() { 16 | // 具体初始化代码 17 | } 18 | 19 | // 静态私有成员,没有初始化 20 | static StreamSingleton _instance; 21 | 22 | // 静态、同步、私有访问点 23 | static StreamSingleton _sharedInstance() { 24 | if (_instance == null) { 25 | _instance = StreamSingleton._(); 26 | } 27 | return _instance; 28 | } 29 | 30 | // 单例公开访问点 31 | static StreamSingleton get getInstance => _sharedInstance(); 32 | 33 | 34 | 35 | close(){ 36 | _dataController.close(); 37 | } 38 | 39 | 40 | } 41 | -------------------------------------------------------------------------------- /lib/template.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/material.dart'; 2 | 3 | void main() => runApp(MyApp()); 4 | 5 | class MyApp extends StatelessWidget { 6 | @override 7 | Widget build(BuildContext context) { 8 | return MaterialApp( 9 | title: 'Flutter Demo', 10 | theme: ThemeData( 11 | primarySwatch: Colors.blue, 12 | ), 13 | home: MyHomePage(title: 'Flutter Demo Home Page'), 14 | ); 15 | } 16 | } 17 | 18 | class MyHomePage extends StatefulWidget { 19 | MyHomePage({Key key, this.title}) : super(key: key); 20 | 21 | final String title; 22 | 23 | @override 24 | _MyHomePageState createState() => _MyHomePageState(); 25 | } 26 | 27 | class _MyHomePageState extends State { 28 | @override 29 | Widget build(BuildContext context) { 30 | return Scaffold( 31 | appBar: AppBar( 32 | title: Text(widget.title), 33 | ), 34 | body: Center( 35 | child: Column( 36 | mainAxisAlignment: MainAxisAlignment.center, 37 | children: [ 38 | Text( 39 | 'You have pushed the button: en ', 40 | ), 41 | ], 42 | ), 43 | ), 44 | ); 45 | } 46 | } 47 | -------------------------------------------------------------------------------- /lib/utils/emoticon_widget.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/material.dart'; 2 | import 'package:page_indicator/page_indicator.dart'; 3 | 4 | import 'emoji_util.dart'; 5 | // ignore: must_be_immutable 6 | class EmoticonWidget extends StatefulWidget { 7 | 8 | var func; 9 | EmoticonWidget(this.func); 10 | 11 | @override 12 | State createState() { 13 | return EmoticonWidgetState(); 14 | } 15 | } 16 | 17 | //onTap: widget.onTap, 18 | 19 | class EmoticonWidgetState extends State { 20 | List getAllPage() { 21 | List pages = new List(); 22 | EmojiUtil.pages.forEach((page) { 23 | pages.add(getWrapByPage(page)); 24 | }); 25 | 26 | return pages; 27 | } 28 | 29 | Widget getWrapByPage(Map emojiPage) { 30 | List emojis = new List(); 31 | emojiPage.forEach((key, value) { 32 | print('key: $key, value:$value'); 33 | Widget item = getItem(key, value); 34 | emojis.add(item); 35 | }); 36 | 37 | Widget page = Stack( 38 | children: [ 39 | Container( 40 | 41 | margin: EdgeInsets.all(20), // padding: EdgeInsets.all(10), 42 | child: Wrap( 43 | alignment: WrapAlignment.start, 44 | spacing: 30, 45 | crossAxisAlignment:WrapCrossAlignment.center, 46 | runSpacing: 30, 47 | children: emojis, 48 | ), 49 | ), 50 | Positioned( 51 | bottom: 58, 52 | right: 35.0, 53 | child: Image.asset( 54 | "images/delete.png", 55 | width: 20, 56 | height: 20, 57 | ), 58 | ) 59 | ], 60 | ); 61 | 62 | return page; 63 | } 64 | 65 | Widget getItem(String key, String emoji) { 66 | Widget item = GestureDetector( 67 | onTap: () { 68 | this.widget.func(key); 69 | }, 70 | child: Image.asset( 71 | emoji, 72 | width: 20, 73 | height: 20, 74 | ), 75 | ); 76 | return item; 77 | } 78 | 79 | 80 | 81 | @override 82 | Widget build(BuildContext context) { 83 | return new Container( 84 | color: Color(0xffF6F6F6), 85 | child: Container( 86 | height: 200.0, 87 | child: PageIndicatorContainer( 88 | indicatorColor: Color(0xffD8D8D8), 89 | pageView: PageView( 90 | children: getAllPage(), 91 | //controller: controller, 92 | ), 93 | align: IndicatorAlign.bottom, 94 | length: 4, 95 | indicatorSpace: 5.0, 96 | ), 97 | ), 98 | ); 99 | } 100 | } 101 | -------------------------------------------------------------------------------- /lib/utils/more_chat_widget.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/material.dart'; 2 | 3 | // ignore: must_be_immutable 4 | class MoreChatWidget extends StatefulWidget { 5 | var func; 6 | MoreChatWidget(this.func); 7 | 8 | @override 9 | State createState() { 10 | return MoreWidgetState(); 11 | } 12 | } 13 | 14 | //onTap: widget.onTap, 15 | 16 | class MoreWidgetState extends State { 17 | Map icoPath = new Map(); 18 | List icoWidget = new List(); 19 | @override 20 | void initState() { 21 | super.initState(); 22 | icoPath["照片"] = "images/photo_ico.png"; 23 | icoPath["相机"] = "images/camera_ico.png"; 24 | icoPath["素材"] = "images/material_ico.png"; 25 | icoPath["转接"] = "images/transfer_ico.png"; 26 | icoPath["文件"] = "images/file_ico.png"; 27 | 28 | getAllWidget(); 29 | } 30 | 31 | getAllWidget() { 32 | icoPath.forEach((key, value) { 33 | Widget item = getItem(key, value); 34 | icoWidget.add(item); 35 | }); 36 | } 37 | 38 | Widget getItem(String icoName ,String imagePath) { 39 | Widget item = GestureDetector( 40 | onTap: () { 41 | this.widget.func(icoName); 42 | }, 43 | child:Column(children: [ 44 | ClipOval( 45 | child: Container( 46 | height: 50, 47 | width: 50, 48 | padding: EdgeInsets.all(10), 49 | color:Color(0xff2DA8F7), 50 | child: Image.asset( 51 | imagePath, 52 | width: 20, 53 | height: 20, 54 | fit: BoxFit.contain, 55 | ), 56 | ), 57 | ), 58 | Text(icoName) 59 | 60 | 61 | ],), 62 | ); 63 | return item; 64 | } 65 | 66 | @override 67 | Widget build(BuildContext context) { 68 | return new Container( 69 | margin: EdgeInsets.all(20), 70 | height: 200, 71 | color: Color(0xffF8F8FA), 72 | child: Center( 73 | child: Wrap( 74 | alignment: WrapAlignment.start, 75 | spacing: 30, 76 | runSpacing: 30, 77 | children: icoWidget, 78 | ), 79 | ), 80 | ); 81 | } 82 | } 83 | -------------------------------------------------------------------------------- /lib/utils/route_helper.dart: -------------------------------------------------------------------------------- 1 | import 'dart:async'; 2 | 3 | import 'package:flutter/material.dart'; 4 | 5 | class RouteHelper { 6 | static pushWidget(BuildContext context, Widget widget) { 7 | Navigator.push(context, MaterialPageRoute(builder: (context) => widget)); 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /lib/utils/toast.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/material.dart'; 2 | import 'package:fluttertoast/fluttertoast.dart'; 3 | class ToastUtil{ 4 | 5 | 6 | 7 | /*显示Toast的方法*/ 8 | static showToast(String value){ 9 | Fluttertoast.showToast( 10 | msg: value, 11 | toastLength: Toast.LENGTH_SHORT, 12 | gravity: ToastGravity.CENTER, 13 | timeInSecForIos: 1, 14 | backgroundColor: Colors.black, 15 | textColor: Colors.white, 16 | fontSize: 16.0 17 | ); 18 | 19 | } 20 | 21 | 22 | 23 | } -------------------------------------------------------------------------------- /lib/utils/utils.dart: -------------------------------------------------------------------------------- 1 | import 'package:common_utils/common_utils.dart'; 2 | import 'package:flutter/material.dart'; 3 | 4 | class Utils { 5 | static String getImgPath(String name, {String format: 'png'}) { 6 | return 'images/$name.$format'; 7 | } 8 | 9 | 10 | 11 | 12 | // 'images/icon/circle_home.png', 13 | static String getIcoImgPath(String name, {String format: 'png'}) { 14 | return 'images/icon/$name.$format'; 15 | } 16 | // static String getPinyin(String str) { 17 | // return PinyinHelper.getShortPinyin(str).substring(0, 1).toUpperCase(); 18 | // } 19 | // 20 | // static Color getCircleBg(String str) { 21 | // String pinyin = getPinyin(str); 22 | // return getCircleAvatarBg(pinyin); 23 | // } 24 | // 25 | // static Color getCircleAvatarBg(String key) { 26 | // return circleAvatarMap[key]; 27 | // } 28 | // 29 | // static Color getChipBgColor(String name) { 30 | // String pinyin = PinyinHelper.getFirstWordPinyin(name); 31 | // pinyin = pinyin.substring(0, 1).toUpperCase(); 32 | // return nameToColor(pinyin); 33 | // } 34 | 35 | static Color nameToColor(String name) { 36 | // assert(name.length > 1); 37 | final int hash = name.hashCode & 0xffff; 38 | final double hue = (360.0 * hash / (1 << 15)) % 360.0; 39 | return HSVColor.fromAHSV(1.0, hue, 0.4, 0.90).toColor(); 40 | } 41 | 42 | static String getTimeLine(BuildContext context, int timeMillis) { 43 | // LogUtil.e("countryCode: " + 44 | // Localizations.localeOf(context).countryCode + 45 | // " languageCode: " + 46 | // Localizations.localeOf(context).languageCode); 47 | return TimelineUtil.format(timeMillis, 48 | locale: Localizations.localeOf(context).languageCode, 49 | dayFormat: DayFormat.Common); 50 | } 51 | 52 | static double getTitleFontSize(String title) { 53 | if (ObjectUtil.isEmpty(title) || title.length < 10) { 54 | return 18.0; 55 | } 56 | int count = 0; 57 | List list = title.split(""); 58 | for (int i = 0, length = list.length; i < length; i++) { 59 | String ss = list[i]; 60 | if (RegexUtil.isZh(ss)) { 61 | count++; 62 | } 63 | } 64 | 65 | return (count >= 10 || title.length > 16) ? 14.0 : 18.0; 66 | } 67 | 68 | /// 0 69 | /// -1 70 | /// 1 71 | // static int getUpdateStatus(String version) { 72 | // String locVersion = AppConfig.version; 73 | // int remote = int.tryParse(version.replaceAll('.', '')); 74 | // int loc = int.tryParse(locVersion.replaceAll('.', '')); 75 | // if (remote <= loc) { 76 | // return 0; 77 | // } else { 78 | // return (remote - loc >= 2) ? -1 : 1; 79 | // } 80 | // } 81 | } 82 | -------------------------------------------------------------------------------- /lib/widget/loading/progress_dialog.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/material.dart'; 2 | 3 | class ProgressDialog extends StatelessWidget { 4 | //子布局 5 | final Widget child; 6 | 7 | //加载中是否显示 8 | final bool loading; 9 | 10 | //进度提醒内容 11 | final String msg; 12 | 13 | //加载中动画 14 | final Widget progress; 15 | 16 | //背景透明度 17 | final double alpha; 18 | 19 | //字体颜色 20 | final Color textColor; 21 | 22 | ProgressDialog( 23 | {Key key, 24 | @required this.loading, 25 | this.msg, 26 | this.progress = const CircularProgressIndicator(), 27 | this.alpha = 0.6, 28 | this.textColor = Colors.white, 29 | @required this.child}) 30 | : assert(child != null), 31 | assert(loading != null), 32 | super(key: key); 33 | 34 | @override 35 | Widget build(BuildContext context) { 36 | List widgetList = []; 37 | widgetList.add(child); 38 | if (loading) { 39 | Widget layoutProgress; 40 | if (msg == null) { 41 | layoutProgress = Center( 42 | child: progress, 43 | ); 44 | } else { 45 | layoutProgress = Center( 46 | child: Container( 47 | padding: const EdgeInsets.all(20.0), 48 | decoration: BoxDecoration( 49 | color: Colors.black87, 50 | borderRadius: BorderRadius.circular(4.0)), 51 | child: Column( 52 | mainAxisAlignment: MainAxisAlignment.center, 53 | crossAxisAlignment: CrossAxisAlignment.center, 54 | mainAxisSize: MainAxisSize.min, 55 | children: [ 56 | progress, 57 | Container( 58 | padding: const EdgeInsets.fromLTRB(10.0, 10.0, 10.0, 0), 59 | child: Text( 60 | msg, 61 | style: TextStyle(color: textColor, fontSize: 16.0), 62 | ), 63 | ) 64 | ], 65 | ), 66 | ), 67 | ); 68 | } 69 | widgetList.add(Opacity( 70 | opacity: alpha, 71 | child: new ModalBarrier(color: Colors.black87), 72 | )); 73 | widgetList.add(layoutProgress); 74 | } 75 | return Stack( 76 | children: widgetList, 77 | ); 78 | } 79 | } 80 | -------------------------------------------------------------------------------- /lib/widget/net_loading_dalog.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/cupertino.dart'; 2 | import 'package:flutter/material.dart'; 3 | 4 | // ignore: must_be_immutable 5 | class NetLoadingDialog extends StatefulWidget { 6 | String loadingText; 7 | bool outsideDismiss; 8 | 9 | Function dismissDialog; 10 | 11 | NetLoadingDialog( 12 | {Key key, 13 | this.loadingText = "loading...", 14 | this.outsideDismiss = true, 15 | this.dismissDialog}) 16 | : super(key: key); 17 | 18 | @override 19 | State createState() => _LoadingDialog(); 20 | } 21 | 22 | class _LoadingDialog extends State { 23 | _dismissDialog() { 24 | Navigator.of(context).pop(); 25 | } 26 | 27 | @override 28 | void initState() { 29 | super.initState(); 30 | if (widget.dismissDialog != null) { 31 | widget.dismissDialog( 32 | 33 | //将关闭 dialog的方法传递到调用的页面. 34 | () { 35 | Navigator.of(context).pop(); 36 | }); 37 | } 38 | } 39 | 40 | @override 41 | Widget build(BuildContext context) { 42 | return new GestureDetector( 43 | onTap: widget.outsideDismiss ? _dismissDialog : null, 44 | child: Material( 45 | type: MaterialType.transparency, 46 | child: new Center( 47 | child: new SizedBox( 48 | width: 120.0, 49 | height: 120.0, 50 | child: new Container( 51 | decoration: ShapeDecoration( 52 | color: Colors.black, 53 | shape: RoundedRectangleBorder( 54 | borderRadius: BorderRadius.all( 55 | Radius.circular(8.0), 56 | ), 57 | ), 58 | ), 59 | child: new Column( 60 | mainAxisAlignment: MainAxisAlignment.center, 61 | crossAxisAlignment: CrossAxisAlignment.center, 62 | children: [ 63 | new CupertinoActivityIndicator( 64 | radius: 20, 65 | ), 66 | new Padding( 67 | padding: const EdgeInsets.only( 68 | top: 20.0, 69 | ), 70 | child: new Text( 71 | widget.loadingText, 72 | style: new TextStyle( 73 | fontSize: 12.0, 74 | color: Colors.white, 75 | ), 76 | ), 77 | ), 78 | ], 79 | ), 80 | ), 81 | ), 82 | ), 83 | ), 84 | ); 85 | } 86 | } 87 | -------------------------------------------------------------------------------- /lib/widget/progress_dialog.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/cupertino.dart'; 2 | import 'package:flutter/material.dart'; 3 | 4 | class ProgressDialog extends StatelessWidget { 5 | final bool loading; 6 | final Widget child; 7 | 8 | ProgressDialog({Key key, @required this.loading, @required this.child}) 9 | : assert(child != null), 10 | assert(loading != null), 11 | super(key: key); 12 | 13 | @override 14 | Widget build(BuildContext context) { 15 | List widgetList = []; 16 | widgetList.add(child); 17 | //如果正在加载,则显示加载添加加载中布局 18 | if (loading) { 19 | //环形进度条 20 | widgetList.add(Center( 21 | child: Container( 22 | width: 130, 23 | height: 130, 24 | // padding: const EdgeInsets.all(30.0), 25 | decoration: BoxDecoration( 26 | //黑色背景 27 | color: Colors.black87, 28 | //圆角边框 29 | borderRadius: BorderRadius.circular(10.0)), 30 | child: Column( 31 | //控件里面内容主轴负轴剧中显示 32 | mainAxisAlignment: MainAxisAlignment.center, 33 | crossAxisAlignment: CrossAxisAlignment.center, 34 | //主轴高度最小 35 | mainAxisSize: MainAxisSize.min, 36 | children: [ 37 | CupertinoActivityIndicator( 38 | radius: 20, 39 | ), 40 | Container( 41 | margin: EdgeInsets.only(top: 20), 42 | child: Text( 43 | '准备开始群聊...', 44 | style: TextStyle(color: Colors.white), 45 | ), 46 | ) 47 | ], 48 | ), 49 | ), 50 | )); 51 | } 52 | return Stack( 53 | children: widgetList, 54 | ); 55 | } 56 | } 57 | -------------------------------------------------------------------------------- /lib/widget/search_widget.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/cupertino.dart'; 2 | 3 | class SearchWidget { 4 | /// 添加头布局 5 | static Widget getHeaderView() { 6 | return new Container( 7 | height: 35, 8 | margin: const EdgeInsets.all(10.0), 9 | // padding: const EdgeInsets.all(10.0), 10 | decoration: new BoxDecoration( 11 | // border: new Border.all(width: 1.0,color: Colors.grey), 12 | color: Color(0xffffffff), //#ffffff 13 | borderRadius: new BorderRadius.all(new Radius.circular(10.0)), 14 | ), 15 | child: Row( 16 | mainAxisAlignment: MainAxisAlignment.center, 17 | children: [ 18 | new Container( 19 | width: 15, 20 | height: 15, 21 | child: Image.asset("images/search.png"), 22 | ), 23 | Text( 24 | '昵称/备注/标签', 25 | ), 26 | ], 27 | ), 28 | ); 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /lib/widget_demo/ui/SplashPage.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/cupertino.dart'; 2 | import 'package:flutter/material.dart'; 3 | 4 | class SplashPage extends StatefulWidget { 5 | static final String sName = "/"; 6 | 7 | @override 8 | _SplashPageState createState() => _SplashPageState(); 9 | } 10 | 11 | class _SplashPageState extends State { 12 | @override 13 | Widget build(BuildContext context) { 14 | return Scaffold( 15 | appBar: AppBar( 16 | title: Text("启动页"), 17 | ), 18 | body: Center( 19 | child: Container( 20 | child: Text("splash"), 21 | ), 22 | ), 23 | ); 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /lib/widget_demo/ui/StickNestedScrollViewScreen.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/material.dart'; 2 | 3 | class StickNestedScrollViewScreen extends StatefulWidget { 4 | @override 5 | _StickNestedPageState createState() => _StickNestedPageState(); 6 | } 7 | 8 | class _StickNestedPageState extends State 9 | with 10 | SingleTickerProviderStateMixin, 11 | AutomaticKeepAliveClientMixin { 12 | TabController _timeTabController; 13 | 14 | @override 15 | void initState() { 16 | super.initState(); 17 | this._timeTabController = TabController(length: 2, vsync: this); 18 | } 19 | 20 | @override 21 | void dispose() { 22 | _timeTabController.dispose(); 23 | super.dispose(); 24 | } 25 | 26 | @override 27 | Widget build(BuildContext context) { 28 | super.build(context); 29 | double _spikeHeight = 300; 30 | double _appBarHeight = _spikeHeight - kToolbarHeight; 31 | 32 | return Scaffold( 33 | appBar: AppBar( 34 | title: Text("标题"), 35 | ), 36 | body: NestedScrollView( 37 | headerSliverBuilder: (BuildContext context, bool innerBoxIsScrolled) { 38 | return [ 39 | SliverOverlapAbsorber( 40 | handle: NestedScrollView.sliverOverlapAbsorberHandleFor(context), 41 | sliver: SliverAppBar( 42 | backgroundColor: Color(0xfff1f1f1), 43 | forceElevated: innerBoxIsScrolled, 44 | bottom: PreferredSize( 45 | child: Container(), 46 | preferredSize: Size.fromHeight(_appBarHeight)), 47 | flexibleSpace: Column( 48 | children: [ 49 | Container( 50 | color: Colors.white, 51 | width: double.infinity, 52 | height: _spikeHeight, 53 | child: Text("32"), 54 | ) 55 | ], 56 | ), 57 | ), 58 | ), 59 | SliverPersistentHeader( 60 | delegate: StickyTabBarDelegate( 61 | child: TabBar( 62 | labelColor: Colors.black, 63 | controller: this._timeTabController, 64 | tabs: [ 65 | Tab(text: 'Home'), 66 | Tab(text: 'Profile'), 67 | ], 68 | ), 69 | ), 70 | pinned: true, 71 | ), 72 | ]; 73 | }, 74 | body: TabBarView(controller: _timeTabController, children: [ 75 | Container( 76 | height: 500, 77 | child: Center(child: Text("11")), 78 | ), 79 | Container( 80 | height: 500, 81 | child: Center(child: Text("22")), 82 | ) 83 | ]), 84 | ), 85 | ); 86 | } 87 | 88 | @override 89 | bool get wantKeepAlive => true; 90 | } 91 | 92 | class StickyTabBarDelegate extends SliverPersistentHeaderDelegate { 93 | final TabBar child; 94 | 95 | StickyTabBarDelegate({@required this.child}); 96 | 97 | @override 98 | Widget build( 99 | BuildContext context, double shrinkOffset, bool overlapsContent) { 100 | return this.child; 101 | } 102 | 103 | @override 104 | double get maxExtent => this.child.preferredSize.height; 105 | 106 | @override 107 | double get minExtent => this.child.preferredSize.height; 108 | 109 | @override 110 | bool shouldRebuild(SliverPersistentHeaderDelegate oldDelegate) { 111 | return true; 112 | } 113 | } 114 | -------------------------------------------------------------------------------- /lib/widget_demo/ui/StickyDemo_screen.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/material.dart'; 2 | 3 | class StickyDemoScreen extends StatefulWidget { 4 | 5 | @override 6 | _StickyDemoScreenState createState() => _StickyDemoScreenState(); 7 | } 8 | 9 | class _StickyDemoScreenState extends State 10 | with SingleTickerProviderStateMixin { 11 | TabController tabController; 12 | 13 | @override 14 | void initState() { 15 | super.initState(); 16 | this.tabController = TabController(length: 2, vsync: this); 17 | } 18 | 19 | @override 20 | Widget build(BuildContext context) { 21 | return Scaffold( 22 | body: CustomScrollView( 23 | slivers: [ 24 | 25 | SliverAppBar( 26 | pinned: true, 27 | elevation: 0, 28 | expandedHeight: 250, 29 | flexibleSpace: FlexibleSpaceBar( 30 | title: Text('Sliver-sticky效果'), 31 | background: Image.network( 32 | 'http://img1.mukewang.com/5c18cf540001ac8206000338.jpg', 33 | fit: BoxFit.cover, 34 | ), 35 | ), 36 | ), 37 | SliverPersistentHeader( 38 | pinned: true, 39 | delegate: StickyTabBarDelegate( 40 | child: TabBar( 41 | labelColor: Colors.black, 42 | controller: this.tabController, 43 | tabs: [ 44 | Tab(text: 'Home'), 45 | Tab(text: 'Profile'), 46 | ], 47 | ), 48 | ), 49 | ), 50 | SliverFillRemaining( 51 | child: TabBarView( 52 | controller: this.tabController, 53 | children: [ 54 | Center(child: Text('Content of Home')), 55 | Center(child: Text('Content of Profile')), 56 | ], 57 | ), 58 | ), 59 | ], 60 | ), 61 | ); 62 | } 63 | } 64 | 65 | class StickyTabBarDelegate extends SliverPersistentHeaderDelegate { 66 | final TabBar child; 67 | 68 | StickyTabBarDelegate({@required this.child}); 69 | 70 | @override 71 | Widget build(BuildContext context, double shrinkOffset, bool overlapsContent) { 72 | return this.child; 73 | } 74 | 75 | @override 76 | double get maxExtent => this.child.preferredSize.height; 77 | 78 | @override 79 | double get minExtent => this.child.preferredSize.height; 80 | 81 | @override 82 | bool shouldRebuild(SliverPersistentHeaderDelegate oldDelegate) { 83 | return true; 84 | } 85 | } -------------------------------------------------------------------------------- /lib/widget_demo/ui/clip_board_screen.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/material.dart'; 2 | import 'package:flutter/services.dart'; 3 | 4 | 5 | 6 | 7 | class ClipBoardScreen extends StatefulWidget { 8 | @override 9 | ClipBoardScreenState createState() => new ClipBoardScreenState(); 10 | } 11 | 12 | class ClipBoardScreenState extends State { 13 | 14 | String text ="复制内容 "; 15 | @override 16 | Widget build(BuildContext context) { 17 | return Scaffold( 18 | appBar: AppBar( 19 | title: Text("ClipBoard实现"), 20 | ), 21 | body: Container( 22 | child: Column( 23 | children: [ 24 | new GestureDetector( 25 | child: new Tooltip( 26 | preferBelow: false, message: "Copy", child: new Text(text)), 27 | onTap: () { 28 | Clipboard.setData(new ClipboardData(text: text)); 29 | }, 30 | ), 31 | ], 32 | ), 33 | ), 34 | ); 35 | } 36 | @override 37 | void initState() { 38 | super.initState(); 39 | } 40 | 41 | 42 | } -------------------------------------------------------------------------------- /lib/widget_demo/ui/container_demo_screen.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/material.dart'; 2 | 3 | class ContainerDemoScreen extends StatefulWidget { 4 | static enter(BuildContext context) { 5 | return Navigator.push( 6 | context, 7 | MaterialPageRoute( 8 | builder: (BuildContext content) => ContainerDemoScreen( 9 | ))); 10 | } 11 | 12 | ContainerDemoScreen({Key key,}) : super(key: key); 13 | 14 | 15 | @override 16 | ContainerDemoScreenState createState() => ContainerDemoScreenState(); 17 | } 18 | 19 | class ContainerDemoScreenState extends State { 20 | @override 21 | Widget build(BuildContext context) { 22 | return Scaffold( 23 | appBar: AppBar( 24 | title: Text("container "), 25 | ), 26 | body: Container( 27 | child: Center( 28 | child: Container( 29 | width: 200, 30 | height: 150, 31 | decoration: BoxDecoration( 32 | color: Colors.blue, //背景颜色 33 | border: Border.all( 34 | width: 1,//边框大小 35 | color: Colors.black //边框颜色 36 | ), 37 | borderRadius: BorderRadius.all(Radius.circular(20)) //圆角大小 38 | ), 39 | child: Center(child: Text("Container 内容")), 40 | ), 41 | ), 42 | ), 43 | ); 44 | } 45 | } 46 | -------------------------------------------------------------------------------- /lib/widget_demo/ui/emoji_screen.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/material.dart'; 2 | import 'package:flutter_app_demo/utils/emoji_util.dart'; 3 | import 'package:flutter_app_demo/utils/emoticon_widget.dart'; 4 | import 'package:page_indicator/page_indicator.dart'; 5 | 6 | class EmojiScreen extends StatefulWidget { 7 | 8 | static enter(BuildContext context) { 9 | return Navigator.push(context, 10 | MaterialPageRoute(builder: (BuildContext content) => EmojiScreen())); 11 | } 12 | 13 | EmojiScreen({Key key}) : super(key: key); 14 | 15 | @override 16 | _EmojiScreenState createState() => new _EmojiScreenState(); 17 | } 18 | 19 | class _EmojiScreenState extends State { 20 | 21 | @override 22 | void initState() { 23 | super.initState(); 24 | 25 | print(EmojiUtil.emojiMap.length.toString()); 26 | } 27 | 28 | @override 29 | void dispose() { 30 | super.dispose(); 31 | } 32 | 33 | 34 | @override 35 | Widget build(BuildContext context) { 36 | return new Scaffold( 37 | appBar: new AppBar( 38 | title: new Text("微信表情组件"), 39 | ), 40 | body: EmoticonWidget(emoticonClick), 41 | ); 42 | } 43 | 44 | emoticonClick(String name){ 45 | print(name); 46 | } 47 | 48 | } 49 | -------------------------------------------------------------------------------- /lib/widget_demo/ui/expansion_panel_list_screen.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/material.dart'; 2 | 3 | 4 | class ExpandStateBean { 5 | var isOpen; 6 | var index; 7 | 8 | ExpandStateBean(this.index, this.isOpen); 9 | } 10 | 11 | /// 包含自定义的ExpansionPanelistScreen的使用 12 | /// 13 | class ExpansionPanelListScreen extends StatefulWidget { 14 | @override 15 | _ExpansionPanelListScreenState createState() => 16 | _ExpansionPanelListScreenState(); 17 | } 18 | 19 | class _ExpansionPanelListScreenState extends State { 20 | var currentPanelIndex = -1; 21 | List mList; 22 | List expandStateList; 23 | 24 | _ExpansionPanelListScreenState() { 25 | mList = new List(); 26 | expandStateList = new List(); 27 | for (int i = 0; i < 10; i++) { 28 | mList.add(i); 29 | expandStateList.add(ExpandStateBean(i, false)); 30 | } 31 | } 32 | 33 | _setCurrentIndex(int index, isExpand) { 34 | setState(() { 35 | expandStateList.forEach((item) { 36 | if (item.index == index) { 37 | item.isOpen = !isExpand; 38 | } 39 | }); 40 | }); 41 | } 42 | 43 | @override 44 | void initState() { 45 | super.initState(); 46 | 47 | var text = ""; 48 | assert(text != null); 49 | } 50 | 51 | @override 52 | Widget build(BuildContext context) { 53 | return Scaffold( 54 | appBar: AppBar( 55 | title: Text("ExpansionPanelList Demo"), 56 | ), 57 | body: SingleChildScrollView( 58 | // child: MyExpansionPanelList.radio( 59 | // children: mList.map((index) { 60 | // return new ExpansionPanelRadio( 61 | // value: index, 62 | // headerBuilder: (context, isExpanded) { 63 | // return new ListTile( 64 | // title: new Text("我是第$index标题"), 65 | // ); 66 | // }, 67 | // body: new Text("$index")); 68 | // }).toList(), 69 | // expansionCallback: ((index, bol) { 70 | // _setCurrentIndex(index, bol); 71 | // }), 72 | //// initialOpenPanelValue: mList[0], 73 | // ), 74 | child: ExpansionPanelList( 75 | // animationDuration: new Duration(seconds: 0), 76 | children: mList.map((index) { 77 | return new ExpansionPanel( 78 | headerBuilder: (context, isExpanded) { 79 | return new ListTile( 80 | title: new Text('我是第$index个标题'), 81 | ); 82 | }, 83 | body: new Padding( 84 | padding: EdgeInsets.symmetric(horizontal: 5.0), 85 | child: Container( 86 | height: 100.0, 87 | color: Colors.blue, 88 | alignment: Alignment.center, 89 | child: Icon( 90 | Icons.security, 91 | size: 35.0, 92 | ), 93 | ), 94 | ), 95 | isExpanded: expandStateList[index].isOpen, 96 | ); 97 | }).toList(), 98 | expansionCallback: (index, bol) { 99 | _setCurrentIndex(index, bol); 100 | }, 101 | ), 102 | )); 103 | } 104 | } 105 | -------------------------------------------------------------------------------- /lib/widget_demo/ui/image_demo_screen.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/material.dart'; 2 | import 'package:flutter_app_demo/image/dragscale_screen.dart'; 3 | import 'package:flutter_app_demo/image/image_pick_demo_screen.dart'; 4 | import 'package:flutter_app_demo/utils/route_helper.dart'; 5 | import 'package:flutter_drag_scale/core/drag_scale_widget.dart'; 6 | 7 | class ImageDemoScreen extends StatefulWidget { 8 | @override 9 | _ImageDemoScreenState createState() { 10 | return _ImageDemoScreenState(); 11 | } 12 | } 13 | 14 | class _ImageDemoScreenState extends State { 15 | @override 16 | Widget build(BuildContext context) { 17 | return Scaffold( 18 | appBar: AppBar(title: Text("image的各种操作"),), 19 | body: ListView( 20 | children: [ 21 | FlatButton(child: Text("图片的放大和缩小"),onPressed: (){ 22 | RouteHelper.pushWidget(context, DragScaleDemoScreen()); 23 | },), 24 | 25 | FlatButton(child: Text("相册选择器"),onPressed: (){ 26 | RouteHelper.pushWidget(context, ImagePickDemoScreen()); 27 | },), 28 | 29 | ], 30 | ), 31 | );; 32 | } 33 | } -------------------------------------------------------------------------------- /lib/widget_demo/ui/inheritedwidget_screen.dart: -------------------------------------------------------------------------------- 1 | import 'dart:async'; 2 | 3 | import 'package:flutter/material.dart'; 4 | 5 | class InheritedWidgetScreen extends StatefulWidget { 6 | InheritedWidgetScreen({Key key}) : super(key: key); 7 | 8 | 9 | @override 10 | _InheritedWidgetScreenState createState() => _InheritedWidgetScreenState(); 11 | } 12 | 13 | class _InheritedWidgetScreenState extends State { 14 | int _counter = 0; 15 | 16 | @override 17 | Widget build(BuildContext context) { 18 | return Scaffold( 19 | appBar: AppBar( 20 | title: Text("inheritedWidget 使用"), 21 | ), 22 | body: Center( 23 | child: ShareWidget( //使用ShareWidget 24 | data: _counter, 25 | child: Column( 26 | mainAxisAlignment: MainAxisAlignment.center, 27 | children: [ 28 | Padding( 29 | padding: const EdgeInsets.only(bottom: 20.0), 30 | child: Text('You have clicked the button this many time:'), 31 | ), 32 | Padding( 33 | padding: const EdgeInsets.only(bottom: 20.0), 34 | child: _TextWidget(), //子widget中依赖ShareWidget 35 | ), 36 | RaisedButton( 37 | child: Text('Increment'), 38 | onPressed: () => setState(() => ++_counter), 39 | ), 40 | ], 41 | ), 42 | ), 43 | ), 44 | ); 45 | } 46 | } 47 | 48 | class ShareWidget extends InheritedWidget { 49 | 50 | final int data; 51 | 52 | ShareWidget({@required this.data, Widget child}) : super(child: child); 53 | 54 | //定义一个方法,方便子树中的widget获取这个widget,进而获得共享数据。 55 | static ShareWidget of(BuildContext context) { 56 | /** 57 | * 获取最近的给定类型的Widget,该widget必须是InheritedWidget的子类, 58 | * 并向该widget注册传入的context,当该widget改变时, 59 | * 这个context会重新构建以便从该widget获得新的值。 60 | * 这就是child向InheritedWidget注册的方法。 61 | */ 62 | return context.dependOnInheritedWidgetOfExactType(); 63 | } 64 | 65 | /** 66 | * framework通过使用以前占据树中的这个位置的小部件作为参数调用这个函数来区分这些情况。 67 | */ 68 | @override 69 | bool updateShouldNotify(ShareWidget oldWidget) { 70 | return oldWidget.data != data; 71 | } 72 | } 73 | 74 | class _TextWidget extends StatefulWidget { 75 | @override 76 | State createState() { 77 | return _TextWidgetState(); 78 | } 79 | } 80 | 81 | class _TextWidgetState extends State<_TextWidget> { 82 | @override 83 | Widget build(BuildContext context) { 84 | return Text( 85 | ShareWidget 86 | .of(context) 87 | .data 88 | .toString() 89 | ); 90 | } 91 | 92 | /** 93 | * 如果依赖的InheritedWidget改变了,framework将会调用这个方法来通知这个对象。 94 | * 在这个方法中调用BuildContext.inheritFromWidgetOfExactType是安全的。 95 | * 子类很少覆写这个方法,因为framework通常会在依赖的InheritedWidget改变后调用build方法, 96 | * 覆写这个方法通常用来做一些耗时的工作,比如网络请求 97 | */ 98 | @override 99 | void didChangeDependencies() { 100 | super.didChangeDependencies(); 101 | print("Dependencies change"); 102 | } 103 | } 104 | 105 | -------------------------------------------------------------------------------- /lib/widget_demo/ui/listview_demo_screen.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/cupertino.dart'; 2 | import 'package:flutter/material.dart'; 3 | 4 | class ListViewDemoScreen extends StatefulWidget { 5 | 6 | @override 7 | State createState() { 8 | // TODO: implement createState 9 | return ListViewDemoScreenState(); 10 | } 11 | } 12 | 13 | 14 | class ListViewDemoScreenState extends State{ 15 | List items= List(); 16 | 17 | 18 | @override 19 | void initState() { 20 | super.initState(); 21 | 22 | for(int i=0;i<20;i++){ 23 | items.add(i.toString()); 24 | } 25 | 26 | } 27 | 28 | 29 | Widget getItemView(int postion) { 30 | return new ListTile( 31 | onTap: () { 32 | Navigator.of(context).push(new MaterialPageRoute(builder: (context) { 33 | print("wilson 点击的数据"); 34 | print(postion); 35 | })); 36 | }, 37 | leading: new CircleAvatar( 38 | radius: 20.0, 39 | backgroundImage: new NetworkImage( 40 | 'https://upload.jianshu.io/users/upload_avatars/7700793/dbcf94ba-9e63-4fcf-aa77-361644dd5a87?imageMogr2/auto-orient/strip|imageView2/1/w/240/h/240'), 41 | ), 42 | title: new Text("班主任"), 43 | subtitle: new Text("你高考考了满分你知道吗?"), 44 | trailing: new Container( 45 | child: Column( 46 | children: [ 47 | new Container( 48 | margin: EdgeInsets.fromLTRB(0, 12, 5, 0), 49 | child: Text( 50 | 51 | "9:00", 52 | style: TextStyle(fontSize: 12), 53 | ), 54 | ), 55 | new Container( 56 | margin: EdgeInsets.fromLTRB(0, 2, 5, 0), 57 | width: 20, 58 | height: 20, 59 | decoration: BoxDecoration( 60 | borderRadius: BorderRadius.circular(10), //圆角 61 | color: Colors.red, //圆点背景颜色 62 | ), 63 | child: new Text( 64 | "1", 65 | textAlign: TextAlign.center, 66 | style: TextStyle( 67 | fontSize: 16, 68 | ), 69 | ), 70 | ) 71 | ], 72 | ), 73 | ), 74 | ); 75 | } 76 | 77 | @override 78 | Widget build(BuildContext context) { 79 | final title = "Dismissing Items"; 80 | return Scaffold( 81 | appBar: new AppBar( 82 | title: new Text(title), 83 | ), 84 | body: new ListView.builder( 85 | scrollDirection: Axis.horizontal, 86 | itemCount: items.length, 87 | itemBuilder: (context, index) { 88 | final item = items[index]; 89 | //通过拖动来删除小部件的widget 90 | return new Dismissible( 91 | //如果Dismissible是一个列表项 它必须有一个key 用来区别其他项 92 | key: new Key(item), 93 | //在child被取消时调用 94 | onDismissed: (direction) { 95 | items.removeAt(index); 96 | //这个和Android的SnackBar差不多 97 | Scaffold.of(context).showSnackBar( 98 | new SnackBar(content: new Text("$item dismissed"))); 99 | }, 100 | //如果指定了background 他将会堆叠在Dismissible child后面 并在child移除时暴露 101 | background: new Container( 102 | color: Colors.red, 103 | ), 104 | child: getItemView(index)); 105 | }, 106 | ), 107 | ); 108 | } 109 | 110 | } -------------------------------------------------------------------------------- /lib/widget_demo/ui/mergeable_material_item_screen.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/material.dart'; 2 | 3 | class MergeableMaterialItemScreen extends StatefulWidget { 4 | _MergeableMaterialItemState createState() => _MergeableMaterialItemState(); 5 | } 6 | 7 | class _MergeableMaterialItemState extends State { 8 | final List items = []; 9 | bool currIndex = false; 10 | int currIndexNum = 1; 11 | 12 | _isChildExpanded() { 13 | setState(() { 14 | currIndex ? currIndex = false : currIndex = true; 15 | currIndexNum++; 16 | }); 17 | } 18 | 19 | @override 20 | Widget build(BuildContext context) { 21 | items.add( 22 | 23 | //class MaterialSlice extends MergeableMaterialItem 24 | MaterialSlice( 25 | key: ValueKey(currIndexNum), 26 | child: Column(children: [ 27 | // header, 28 | AnimatedCrossFade( 29 | firstChild: Container( 30 | height: 20.0, 31 | width: 20.0, 32 | color: Colors.green, 33 | ), 34 | secondChild: Container( 35 | height: 20.0, 36 | width: 200.0, 37 | color: Colors.red, 38 | ), 39 | crossFadeState: currIndex 40 | ? CrossFadeState.showSecond 41 | : CrossFadeState.showFirst, 42 | firstCurve: 43 | const Interval(0.0, 0.6, curve: Curves.fastOutSlowIn), 44 | secondCurve: 45 | const Interval(0.4, 1.0, curve: Curves.fastOutSlowIn), 46 | sizeCurve: Curves.fastOutSlowIn, 47 | duration: Duration(microseconds: 6), 48 | ) 49 | ]))); 50 | 51 | return Column( 52 | children: [ 53 | MergeableMaterial(hasDividers: true, children: items), 54 | RaisedButton( 55 | child: Text("点击添加"), 56 | onPressed: () { 57 | _isChildExpanded(); 58 | }, 59 | ) 60 | ], 61 | ); 62 | } 63 | } 64 | -------------------------------------------------------------------------------- /lib/widget_demo/ui/multl_list_widget/EntryNew.dart: -------------------------------------------------------------------------------- 1 | class EntryNew { 2 | String groupName; 3 | int id; 4 | int parentId; 5 | int replyType; 6 | List children; 7 | List replys; 8 | int sortIndex; 9 | 10 | EntryNew( 11 | {this.children, 12 | this.groupName, 13 | this.id, 14 | this.parentId, 15 | this.replyType, 16 | this.replys, 17 | this.sortIndex}); 18 | 19 | factory EntryNew.fromJson(Map json) { 20 | return EntryNew( 21 | children: json['children'] != null 22 | ? (json['children'] as List).map((i) => EntryNew.fromJson(i)).toList() 23 | : null, 24 | groupName: json['groupName'], 25 | id: json['id'], 26 | parentId: json['parentId'], 27 | replyType: json['replyType'], 28 | replys: json['replys'] != null 29 | ? (json['replys'] as List).map((i) => Reply.fromJson(i)).toList() 30 | : null, 31 | sortIndex: json['sortIndex'], 32 | ); 33 | } 34 | 35 | Map toJson() { 36 | final Map data = new Map(); 37 | data['groupName'] = this.groupName; 38 | data['id'] = this.id; 39 | data['parentId'] = this.parentId; 40 | data['replyType'] = this.replyType; 41 | data['sortIndex'] = this.sortIndex; 42 | if (this.children != null) { 43 | data['children'] = this.children.map((v) => v.toJson()).toList(); 44 | } 45 | if (this.replys != null) { 46 | data['replys'] = this.replys.map((v) => v.toJson()).toList(); 47 | } 48 | return data; 49 | } 50 | } 51 | 52 | class Reply { 53 | int accountId; 54 | String content; 55 | String createTime; 56 | int groupId; 57 | int id; 58 | String lastUpdateTime; 59 | int msgType; 60 | int sortIndex; 61 | int tenantId; 62 | String title; 63 | 64 | Reply( 65 | {this.accountId, 66 | this.content, 67 | this.createTime, 68 | this.groupId, 69 | this.id, 70 | this.lastUpdateTime, 71 | this.msgType, 72 | this.sortIndex, 73 | this.tenantId, 74 | this.title}); 75 | 76 | factory Reply.fromJson(Map json) { 77 | return Reply( 78 | accountId: json['accountId'], 79 | content: json['content'], 80 | createTime: json['createTime'], 81 | groupId: json['groupId'], 82 | id: json['id'], 83 | lastUpdateTime: json['lastUpdateTime'], 84 | msgType: json['msgType'], 85 | sortIndex: json['sortIndex'], 86 | tenantId: json['tenantId'], 87 | title: json['title'], 88 | ); 89 | } 90 | 91 | Map toJson() { 92 | final Map data = new Map(); 93 | data['accountId'] = this.accountId; 94 | data['content'] = this.content; 95 | data['createTime'] = this.createTime; 96 | data['groupId'] = this.groupId; 97 | data['id'] = this.id; 98 | data['lastUpdateTime'] = this.lastUpdateTime; 99 | data['msgType'] = this.msgType; 100 | data['sortIndex'] = this.sortIndex; 101 | data['tenantId'] = this.tenantId; 102 | data['title'] = this.title; 103 | return data; 104 | } 105 | } 106 | -------------------------------------------------------------------------------- /lib/widget_demo/ui/notification_screen.dart: -------------------------------------------------------------------------------- 1 | import 'dart:math'; 2 | 3 | import 'package:flutter/material.dart'; 4 | import 'package:flutter_app_demo/utils/toast.dart'; 5 | 6 | class NotificationScreen extends StatefulWidget { 7 | NotificationScreen({Key key}) : super(key: key); 8 | 9 | @override 10 | _NotificationScreenState createState() => _NotificationScreenState(); 11 | } 12 | 13 | class _NotificationScreenState extends State { 14 | 15 | @override 16 | Widget build(BuildContext context) { 17 | return Scaffold( 18 | appBar: AppBar( 19 | title: Text("Notification 使用"), 20 | ), 21 | body: NotificationListener( 22 | onNotification: (notification) { 23 | setState(() { 24 | ToastUtil.showToast("上级接到了通知"); 25 | }); 26 | return true; 27 | }, 28 | child: new RaisedButton( 29 | textColor: Colors.black, 30 | child: new Center( 31 | child: new Text('点击传递随机数给上层Widget'), 32 | ), 33 | onPressed: () { 34 | new TestNotification(count: new Random().nextInt(100)) 35 | .dispatch(context); 36 | }), 37 | )); 38 | } 39 | } 40 | 41 | class TestNotification extends Notification { 42 | TestNotification({ 43 | @required this.count, 44 | }); 45 | 46 | final int count; 47 | } 48 | -------------------------------------------------------------------------------- /lib/widget_demo/ui/progress_dialog_demo_screen.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/material.dart'; 2 | import 'package:flutter_app_demo/widget/progress_dialog.dart'; 3 | 4 | class ProgressDialogDemoScreen extends StatefulWidget { 5 | 6 | 7 | static enter(BuildContext context) { 8 | return Navigator.push( 9 | context, 10 | MaterialPageRoute( 11 | builder: (BuildContext content) => ProgressDialogDemoScreen())); 12 | } 13 | 14 | ProgressDialogDemoScreen({Key key,}) : super(key: key); 15 | 16 | 17 | @override 18 | _ProgressDialogState createState() => _ProgressDialogState(); 19 | } 20 | 21 | class _ProgressDialogState extends State { 22 | bool _loading = false; 23 | 24 | @override 25 | Widget build(BuildContext context) { 26 | return Scaffold( 27 | appBar: AppBar( 28 | title: Text("ProgressDialogDemoScreen"), 29 | ), 30 | body: ProgressDialog( 31 | loading: _loading, 32 | // msg: '正在加载...', 33 | child: Center( 34 | child: RaisedButton( 35 | onPressed: () => _onRefresh(), 36 | child: Text('显示加载动画'), 37 | ), 38 | ), 39 | ), 40 | ); 41 | } 42 | 43 | 44 | 45 | Future _onRefresh() async { 46 | setState(() { 47 | _loading = !_loading; 48 | }); 49 | await Future.delayed(Duration(seconds: 3), () { 50 | setState(() { 51 | _loading = !_loading; 52 | // Toast.show(context, "加载完成"); 53 | }); 54 | }); 55 | } 56 | } 57 | 58 | -------------------------------------------------------------------------------- /lib/widget_demo/ui/refreshIndicator_demo_screen.dart: -------------------------------------------------------------------------------- 1 | import 'dart:async'; 2 | 3 | import 'package:flutter/material.dart'; 4 | 5 | class RefreshIndicatorDemoScreen extends StatefulWidget { 6 | static enter(BuildContext context) { 7 | return Navigator.push( 8 | context, 9 | MaterialPageRoute( 10 | builder: (BuildContext content) => RefreshIndicatorDemoScreen())); 11 | } 12 | @override 13 | State createState() { 14 | return new RefreshIndicatorDemoScreenState(); 15 | } 16 | } 17 | 18 | class RefreshIndicatorDemoScreenState extends State { 19 | 20 | ScrollController _controller = ScrollController(); 21 | List listData = new List(); 22 | bool isLoadMore = true; 23 | @override 24 | void initState() { 25 | // TODO: implement initState 26 | super.initState(); 27 | 28 | for(int i=0;i<=50;i++){ 29 | listData.add(i.toString()); 30 | } 31 | 32 | 33 | _controller.addListener((){ 34 | 35 | if (_controller.position.pixels == _controller.position.minScrollExtent) { 36 | print("滑动到顶部"); 37 | }else if(_controller.position.pixels == _controller.position.maxScrollExtent){ 38 | print("滑动到底部"); 39 | } 40 | 41 | }); 42 | } 43 | 44 | Widget buildListView() { 45 | return new ListView.builder( 46 | controller: _controller, 47 | padding: const EdgeInsets.all(16.0), 48 | itemCount: listData.length, 49 | itemBuilder: (context, i) { 50 | return Text(listData.elementAt(i) + i.toString()); 51 | }, 52 | ); 53 | } 54 | 55 | Future _handleRefresh() async { 56 | 57 | if(isLoadMore){ 58 | return ; 59 | } 60 | print("滑动到顶部"); 61 | // 延迟3秒后添加新数据, 模拟网络加载 62 | await Future.delayed(Duration(seconds: 3), () { 63 | isLoadMore = false; 64 | setState(() { 65 | 66 | listData.clear(); 67 | for (int i = 0; i < 60; i++) { 68 | listData.add("" + i.toString()); 69 | } 70 | _controller.jumpTo(_controller.position.maxScrollExtent); 71 | }); 72 | }); 73 | } 74 | 75 | @override 76 | Widget build(BuildContext context) { 77 | return Scaffold( 78 | appBar: AppBar(title: Text("下拉刷新"),), 79 | body: Container( 80 | child: RefreshIndicator(child: buildListView(), onRefresh: _handleRefresh),), 81 | ); 82 | // child: RefreshIndicator(child: buildListView(), onRefresh: _handleRefresh),); 83 | } 84 | } 85 | -------------------------------------------------------------------------------- /lib/widget_demo/ui/slider_screen.dart: -------------------------------------------------------------------------------- 1 | 2 | import 'package:flutter/material.dart'; 3 | 4 | class SliderScreen extends StatefulWidget { 5 | @override 6 | _SliderScreenState createState() => _SliderScreenState(); 7 | } 8 | 9 | class _SliderScreenState extends State { 10 | double _value = 0; 11 | int _dollars = 20; 12 | 13 | @override 14 | Widget build(BuildContext context) { 15 | return Scaffold( 16 | body: Column( 17 | mainAxisAlignment: MainAxisAlignment.center, 18 | children: [ 19 | Container( 20 | margin: EdgeInsets.fromLTRB(30, 35, 30, 0), 21 | decoration: BoxDecoration( 22 | gradient: LinearGradient(begin: Alignment.center,end: Alignment.center),// 渐变色 23 | borderRadius: BorderRadius.circular(25) 24 | ), 25 | child: Slider( 26 | value: _value, 27 | onChanged: (newValue) { 28 | print('onChanged:$newValue'); 29 | setState(() { 30 | _value = newValue; 31 | }); 32 | }, 33 | onChangeStart: (startValue) { 34 | print('onChangeStart:$startValue'); 35 | }, 36 | onChangeEnd: (endValue) { 37 | print('onChangeEnd:$endValue'); 38 | }, 39 | label: '$_value dollars', 40 | divisions: 10, 41 | semanticFormatterCallback: (newValue) { 42 | return '${newValue.round()} dollars'; 43 | }, 44 | ), 45 | ), 46 | Container( 47 | margin: EdgeInsets.fromLTRB(30, 35, 30, 0), 48 | decoration: BoxDecoration( 49 | gradient: LinearGradient(begin: Alignment.center,end: Alignment.center,),// 渐变色 50 | borderRadius: BorderRadius.circular(25) 51 | ), 52 | child: Slider( 53 | value: _dollars.toDouble(), 54 | min: 20.0, 55 | max: 330.0, 56 | label: '$_dollars dollars', 57 | onChanged: (double newValue) { 58 | setState(() { 59 | _dollars = newValue.round(); 60 | }); 61 | }, 62 | semanticFormatterCallback: (double newValue) { 63 | return '${newValue.round()} dollars'; 64 | }), 65 | ), 66 | 67 | ], 68 | ), 69 | ); 70 | } 71 | } 72 | -------------------------------------------------------------------------------- /lib/widget_demo/ui/stack_demo_screen.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/material.dart'; 2 | 3 | 4 | 5 | class StackDemoScreen extends StatefulWidget { 6 | 7 | 8 | @override 9 | StackDemoScreenState createState() => StackDemoScreenState(); 10 | } 11 | 12 | class StackDemoScreenState extends State { 13 | @override 14 | Widget build(BuildContext context) { 15 | return Scaffold( 16 | appBar: AppBar( 17 | title: Text("stack 控件使用"), 18 | ), 19 | body: Container( 20 | child: Stack( 21 | alignment: Alignment.center, 22 | children: [ 23 | new CircleAvatar( 24 | backgroundImage: AssetImage("assets/images/img.jpg"), 25 | ), 26 | Positioned( 27 | top: 0.0, 28 | right: 1, 29 | child: new Container( 30 | width: 15, 31 | height:15, 32 | decoration: BoxDecoration( 33 | color: Colors.red, 34 | border: new Border.all(width: 1.0,color: Colors.white), 35 | borderRadius: BorderRadius.all(Radius.circular(10))), 36 | 37 | child: Text( 38 | " ", 39 | ), 40 | )), 41 | ], 42 | ), 43 | ), 44 | ); 45 | } 46 | } 47 | -------------------------------------------------------------------------------- /lib/widget_demo/ui/tab_bar_view_demo_screen.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/material.dart'; 2 | 3 | class TabBarViewDemoScreen extends StatefulWidget { 4 | 5 | 6 | static enter(BuildContext context) { 7 | return Navigator.push( 8 | context, 9 | MaterialPageRoute( 10 | builder: (BuildContext content) => TabBarViewDemoScreen())); 11 | } 12 | @override 13 | _TabBarViewDemoScreenState createState() { 14 | return _TabBarViewDemoScreenState(); 15 | } 16 | } 17 | 18 | class _TabBarViewDemoScreenState extends State { 19 | final List tabTexts = [ 20 | new Text("eee", style: new TextStyle(fontSize: 20.0)), 21 | new Text("22", style: new TextStyle(fontSize: 20.0)), 22 | new Text("3", style: new TextStyle(fontSize: 20.0)), 23 | ]; 24 | 25 | List tabs = []; 26 | @override 27 | void initState() { 28 | for (int i = 0; i < tabTexts.length; i++) { 29 | tabs.add(new Tab( 30 | child: tabTexts[i], 31 | )); 32 | } 33 | 34 | super.initState(); 35 | } 36 | 37 | @override 38 | Widget build(BuildContext context) { 39 | return new DefaultTabController( 40 | length: tabs.length, 41 | child: new Scaffold( 42 | appBar: new AppBar( 43 | 44 | bottom: new TabBar( 45 | isScrollable: true, 46 | tabs: tabs, 47 | 48 | ), 49 | ), 50 | body: new TabBarView( 51 | children: tabTexts.map((Text tab) { 52 | return new Center(child: Text(tab.data)); 53 | }).toList()), 54 | )); 55 | } 56 | } 57 | -------------------------------------------------------------------------------- /lib/widget_demo/ui/webview_demo_screen.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/material.dart'; 2 | import 'package:webview_flutter/webview_flutter.dart'; 3 | class WebViewDemoScreen extends StatefulWidget { 4 | WebViewDemoScreen(); 5 | @override 6 | createState() => _WebViewDemoScreenState(); 7 | } 8 | class _WebViewDemoScreenState extends State { 9 | var _url; 10 | final _key = UniqueKey(); 11 | _WebViewDemoScreenState(); 12 | 13 | @override 14 | void initState() { 15 | super.initState(); 16 | 17 | _url = "https://baidu.com"; 18 | } 19 | @override 20 | Widget build(BuildContext context) { 21 | return Scaffold( 22 | appBar: AppBar(), 23 | body: Column( 24 | children: [ 25 | Expanded( 26 | child: WebView( 27 | key: _key, 28 | javascriptMode: JavascriptMode.unrestricted, 29 | initialUrl: _url)) 30 | ], 31 | )); 32 | } 33 | } -------------------------------------------------------------------------------- /res/values/strings_en.arb: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yxwandroid/Flutter-Study-Demo/1051f3ae861fdcc861d8185463d36a00fc3effc7/res/values/strings_en.arb -------------------------------------------------------------------------------- /test/widget_test.dart: -------------------------------------------------------------------------------- 1 | // This is a basic Flutter widget test. 2 | // 3 | // To perform an interaction with a widget in your test, use the WidgetTester 4 | // utility that Flutter provides. For example, you can send tap and scroll 5 | // gestures. You can also use WidgetTester to find child widgets in the widget 6 | // tree, read text, and verify that the values of widget properties are correct. 7 | 8 | import 'package:flutter/material.dart'; 9 | import 'package:flutter_test/flutter_test.dart'; 10 | 11 | import 'package:flutter_app_demo/main.dart'; 12 | 13 | void main() { 14 | testWidgets('Counter increments smoke test', (WidgetTester tester) async { 15 | // Build our app and trigger a frame. 16 | // await tester.pumpWidget(MyApp()); 17 | 18 | // Verify that our counter starts at 0. 19 | expect(find.text('0'), findsOneWidget); 20 | expect(find.text('1'), findsNothing); 21 | 22 | // Tap the '+' icon and trigger a frame. 23 | await tester.tap(find.byIcon(Icons.add)); 24 | await tester.pump(); 25 | 26 | // Verify that our counter has incremented. 27 | expect(find.text('0'), findsNothing); 28 | expect(find.text('1'), findsOneWidget); 29 | }); 30 | } 31 | --------------------------------------------------------------------------------