├── .flutter-plugins-dependencies ├── .gitignore ├── .metadata ├── README.md ├── android ├── app │ ├── build.gradle │ └── src │ │ └── main │ │ ├── AndroidManifest.xml │ │ ├── gen │ │ └── com │ │ │ └── bhm │ │ │ └── flutter │ │ │ └── flutternb │ │ │ ├── BuildConfig.java │ │ │ ├── Manifest.java │ │ │ └── R.java │ │ ├── java │ │ └── com │ │ │ └── bhm │ │ │ └── flutter │ │ │ └── flutternb │ │ │ ├── FlutterNBApplication.java │ │ │ ├── interfaces │ │ │ └── CallBack.java │ │ │ ├── listeners │ │ │ ├── CallBackListener.java │ │ │ ├── ConnectionListener.java │ │ │ ├── ContactListener.java │ │ │ └── MessageListener.java │ │ │ ├── plugins │ │ │ ├── DealMethodCall.java │ │ │ └── FlutterPlugins.java │ │ │ ├── ui │ │ │ ├── MainActivity.java │ │ │ └── VideoRecordActivity.java │ │ │ └── util │ │ │ ├── CallBackData.java │ │ │ ├── EMClientUtils.java │ │ │ ├── MessageEntity.java │ │ │ └── Utils.java │ │ └── res │ │ ├── drawable │ │ ├── app_icon.png │ │ └── launch_background.xml │ │ ├── mipmap-hdpi │ │ └── ic_launcher.png │ │ ├── mipmap-mdpi │ │ └── ic_launcher.png │ │ ├── mipmap-xhdpi │ │ └── ic_launcher.png │ │ ├── mipmap-xxhdpi │ │ ├── ic_launcher.png │ │ ├── ic_launcher_new.png │ │ └── splash_bg.jpg │ │ ├── mipmap-xxxhdpi │ │ └── ic_launcher.png │ │ ├── values │ │ └── styles.xml │ │ └── xml │ │ └── network_security_config.xml ├── build.gradle ├── gradle.properties ├── gradle │ └── wrapper │ │ └── gradle-wrapper.properties ├── settings.gradle └── settings_aar.gradle ├── apk └── app-release.apk ├── assets ├── images │ ├── default │ │ ├── img_default.png │ │ └── img_fest.png │ ├── face │ │ ├── 0.gif │ │ ├── 1.gif │ │ ├── 10.gif │ │ ├── 11.gif │ │ ├── 12.gif │ │ ├── 13.gif │ │ ├── 14.gif │ │ ├── 15.gif │ │ ├── 16.gif │ │ ├── 17.gif │ │ ├── 18.gif │ │ ├── 19.gif │ │ ├── 2.gif │ │ ├── 20.gif │ │ ├── 21.gif │ │ ├── 22.gif │ │ ├── 23.gif │ │ ├── 24.gif │ │ ├── 25.gif │ │ ├── 26.gif │ │ ├── 27.gif │ │ ├── 28.gif │ │ ├── 29.gif │ │ ├── 3.gif │ │ ├── 30.gif │ │ ├── 31.gif │ │ ├── 32.gif │ │ ├── 33.gif │ │ ├── 34.gif │ │ ├── 35.gif │ │ ├── 36.gif │ │ ├── 37.gif │ │ ├── 38.gif │ │ ├── 39.gif │ │ ├── 4.gif │ │ ├── 40.gif │ │ ├── 41.gif │ │ ├── 42.gif │ │ ├── 43.gif │ │ ├── 44.gif │ │ ├── 45.gif │ │ ├── 46.gif │ │ ├── 47.gif │ │ ├── 48.gif │ │ ├── 49.gif │ │ ├── 5.gif │ │ ├── 50.gif │ │ ├── 51.gif │ │ ├── 52.gif │ │ ├── 53.gif │ │ ├── 54.gif │ │ ├── 55.gif │ │ ├── 56.gif │ │ ├── 57.gif │ │ ├── 58.gif │ │ ├── 59.gif │ │ ├── 6.gif │ │ ├── 60.gif │ │ ├── 61.gif │ │ ├── 62.gif │ │ ├── 63.gif │ │ ├── 64.gif │ │ ├── 65.gif │ │ ├── 66.gif │ │ ├── 67.gif │ │ ├── 68.gif │ │ ├── 69.gif │ │ ├── 7.gif │ │ ├── 70.gif │ │ ├── 71.gif │ │ ├── 72.gif │ │ ├── 73.gif │ │ ├── 74.gif │ │ ├── 75.gif │ │ ├── 76.gif │ │ ├── 77.gif │ │ ├── 78.gif │ │ ├── 79.gif │ │ ├── 8.gif │ │ ├── 80.gif │ │ ├── 81.gif │ │ ├── 82.gif │ │ ├── 83.gif │ │ ├── 84.gif │ │ ├── 85.gif │ │ ├── 86.gif │ │ ├── 87.gif │ │ ├── 88.gif │ │ ├── 89.gif │ │ ├── 9.gif │ │ ├── 90.png │ │ ├── 91.png │ │ ├── 92.png │ │ ├── 93.png │ │ ├── 94.png │ │ ├── 95.png │ │ ├── 96.png │ │ ├── 97.png │ │ ├── 98.png │ │ ├── 99.png │ │ └── face_delete.png │ ├── figure │ │ ├── 0.gif │ │ ├── 1.gif │ │ ├── 10.gif │ │ ├── 11.gif │ │ ├── 12.gif │ │ ├── 13.gif │ │ ├── 14.gif │ │ ├── 15.gif │ │ ├── 16.gif │ │ ├── 17.gif │ │ ├── 18.gif │ │ ├── 19.gif │ │ ├── 2.gif │ │ ├── 20.gif │ │ ├── 21.gif │ │ ├── 22.gif │ │ ├── 23.gif │ │ ├── 24.gif │ │ ├── 25.gif │ │ ├── 26.gif │ │ ├── 27.gif │ │ ├── 28.gif │ │ ├── 29.gif │ │ ├── 3.gif │ │ ├── 30.gif │ │ ├── 31.gif │ │ ├── 32.gif │ │ ├── 33.gif │ │ ├── 34.gif │ │ ├── 35.gif │ │ ├── 36.gif │ │ ├── 37.gif │ │ ├── 38.gif │ │ ├── 39.gif │ │ ├── 4.gif │ │ ├── 40.gif │ │ ├── 41.gif │ │ ├── 42.gif │ │ ├── 43.gif │ │ ├── 44.gif │ │ ├── 45.gif │ │ ├── 46.gif │ │ ├── 47.gif │ │ ├── 48.gif │ │ ├── 49.gif │ │ ├── 5.gif │ │ ├── 50.gif │ │ ├── 51.gif │ │ ├── 52.gif │ │ ├── 53.gif │ │ ├── 54.gif │ │ ├── 55.gif │ │ ├── 56.gif │ │ ├── 57.gif │ │ ├── 58.gif │ │ ├── 59.gif │ │ ├── 6.gif │ │ ├── 60.gif │ │ ├── 61.gif │ │ ├── 62.gif │ │ ├── 63.gif │ │ ├── 64.gif │ │ ├── 65.gif │ │ ├── 66.gif │ │ ├── 67.gif │ │ ├── 68.gif │ │ ├── 69.gif │ │ ├── 7.gif │ │ ├── 70.png │ │ ├── 71.gif │ │ ├── 72.gif │ │ ├── 73.gif │ │ ├── 74.png │ │ ├── 75.gif │ │ ├── 76.gif │ │ ├── 77.gif │ │ ├── 78.gif │ │ ├── 79.gif │ │ ├── 8.gif │ │ ├── 80.gif │ │ ├── 81.gif │ │ ├── 82.gif │ │ ├── 83.gif │ │ ├── 84.gif │ │ ├── 85.gif │ │ ├── 86.gif │ │ ├── 87.gif │ │ ├── 88.gif │ │ ├── 89.gif │ │ ├── 9.gif │ │ ├── 90.gif │ │ ├── 91.gif │ │ ├── 92.gif │ │ ├── 93.gif │ │ ├── 94.gif │ │ └── 95.gif │ ├── icon │ │ ├── audio_player_1.png │ │ ├── audio_player_2.png │ │ ├── audio_player_3.png │ │ ├── collection.png │ │ ├── group_chat.png │ │ ├── img_headportrait.png │ │ ├── official_accounts.png │ │ ├── search_friend.jpg │ │ └── system_message.png │ ├── main_page │ │ ├── friends.png │ │ ├── friends_c.png │ │ ├── message.png │ │ ├── message_c.png │ │ ├── mine.png │ │ ├── mine_c.png │ │ ├── more.png │ │ └── more_c.png │ └── splash │ │ ├── guide1.jpg │ │ ├── guide2.jpg │ │ ├── guide3.jpg │ │ ├── guide4.jpg │ │ ├── logo.png │ │ └── splash_bg.jpg └── sounds │ └── demo.mp3 ├── ios ├── Flutter │ ├── AppFrameworkInfo.plist │ ├── Debug.xcconfig │ ├── Release.xcconfig │ └── flutter_export_environment.sh ├── Runner.xcodeproj │ ├── project.pbxproj │ ├── project.xcworkspace │ │ └── contents.xcworkspacedata │ └── xcshareddata │ │ └── xcschemes │ │ └── Runner.xcscheme ├── Runner.xcworkspace │ └── contents.xcworkspacedata └── Runner │ ├── AppDelegate.h │ ├── AppDelegate.m │ ├── Assets.xcassets │ ├── AppIcon.appiconset │ │ ├── Contents.json │ │ ├── Icon-App-1024x1024@1x.png │ │ ├── Icon-App-20x20@1x.png │ │ ├── Icon-App-20x20@2x.png │ │ ├── Icon-App-20x20@3x.png │ │ ├── Icon-App-29x29@1x.png │ │ ├── Icon-App-29x29@2x.png │ │ ├── Icon-App-29x29@3x.png │ │ ├── Icon-App-40x40@1x.png │ │ ├── Icon-App-40x40@2x.png │ │ ├── Icon-App-40x40@3x.png │ │ ├── Icon-App-60x60@2x.png │ │ ├── Icon-App-60x60@3x.png │ │ ├── Icon-App-76x76@1x.png │ │ ├── Icon-App-76x76@2x.png │ │ └── Icon-App-83.5x83.5@2x.png │ └── LaunchImage.imageset │ │ ├── Contents.json │ │ ├── LaunchImage.png │ │ ├── LaunchImage@2x.png │ │ ├── LaunchImage@3x.png │ │ └── README.md │ ├── Base.lproj │ ├── LaunchScreen.storyboard │ └── Main.storyboard │ ├── Info.plist │ └── main.m ├── lib ├── constants │ ├── config.dart │ └── constants.dart ├── database │ ├── database_config.dart │ ├── database_control.dart │ └── message_database.dart ├── entity │ ├── message_body_eneity.dart │ └── message_entity.dart ├── interfaces │ └── call_back.dart ├── main.dart ├── resource │ └── colors.dart ├── ui │ ├── page │ │ ├── about_page.dart │ │ ├── base │ │ │ ├── default_texefield_page.dart │ │ │ ├── messag_state.dart │ │ │ ├── search_page.dart │ │ │ ├── theme_state.dart │ │ │ └── web_view_page.dart │ │ ├── change_theme_page.dart │ │ ├── chat_group_page.dart │ │ ├── chat_page.dart │ │ ├── chat_room_page.dart │ │ ├── circular_progress.dart │ │ ├── information_page.dart │ │ ├── login_page.dart │ │ ├── main │ │ │ ├── found_page.dart │ │ │ ├── friends_page.dart │ │ │ ├── main_page.dart │ │ │ ├── message_page.dart │ │ │ └── mine_page.dart │ │ ├── notification_settings_page.dart │ │ ├── pay_page.dart │ │ ├── photo_view_page.dart │ │ ├── project_page.dart │ │ ├── pyq_page.dart │ │ ├── quality_page.dart │ │ ├── register_page.dart │ │ ├── setting_page.dart │ │ ├── splash_page.dart │ │ ├── system_message_page.dart │ │ ├── system_page.dart │ │ └── video_player_page.dart │ └── widget │ │ ├── chat_item_widgets.dart │ │ ├── loading_widget.dart │ │ ├── more_widgets.dart │ │ ├── popupwindow_widget.dart │ │ └── search_appbar.dart └── utils │ ├── data_proxy.dart │ ├── date_util.dart │ ├── device_util.dart │ ├── dialog_util.dart │ ├── file_util.dart │ ├── functions.dart │ ├── image_util.dart │ ├── interact_vative.dart │ ├── notification_util.dart │ ├── object_util.dart │ ├── sp_util.dart │ ├── timeline_util.dart │ └── timer_util.dart ├── pubspec.yaml ├── screens ├── 1.png ├── 10.png ├── 11.png ├── 12.png ├── 13.png ├── 14.png ├── 15.png ├── 16.png ├── 17.png ├── 18.png ├── 19.png ├── 2.png ├── 20.png ├── 21.png ├── 22.png ├── 23.png ├── 24.png ├── 25.png ├── 26.png ├── 27.png ├── 28.png ├── 29.png ├── 3.png ├── 30.png ├── 31.png ├── 32.png ├── 33.png ├── 34.png ├── 35.png ├── 36.png ├── 37.png ├── 38.png ├── 39.png ├── 4.png ├── 40.png ├── 41.png ├── 42.png ├── 43.png ├── 44.png ├── 45.png ├── 46.png ├── 47.png ├── 48.png ├── 49.png ├── 5.png ├── 50.png ├── 51.png ├── 52.png ├── 53.png ├── 54.png ├── 55.png ├── 6.png ├── 7.png ├── 8.png ├── 9.png └── screen.md ├── test └── widget_test.dart └── 存在问题 /.flutter-plugins-dependencies: -------------------------------------------------------------------------------- 1 | {"_info":"// This is a generated file; do not edit or check into version control.","dependencyGraph":[{"name":"audioplayers","dependencies":["path_provider"]},{"name":"flutter_local_notifications","dependencies":[]},{"name":"flutter_record","dependencies":[]},{"name":"fluttertoast","dependencies":[]},{"name":"image_picker","dependencies":[]},{"name":"keyboard_visibility","dependencies":[]},{"name":"path_provider","dependencies":["path_provider_macos"]},{"name":"path_provider_macos","dependencies":[]},{"name":"permission_handler","dependencies":[]},{"name":"shared_preferences","dependencies":[]},{"name":"sqflite","dependencies":[]},{"name":"vibration","dependencies":[]},{"name":"video_player","dependencies":[]},{"name":"webview_flutter","dependencies":[]}]} -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Miscellaneous 2 | *.class 3 | *.lock 4 | *.log 5 | *.apk 6 | *.pyc 7 | *.swp 8 | .DS_Store 9 | .atom/ 10 | .buildlog/ 11 | .history 12 | .svn/ 13 | 14 | # IntelliJ related 15 | *.iml 16 | *.ipr 17 | *.iws 18 | .idea/ 19 | 20 | # Visual Studio Code related 21 | .vscode/ 22 | 23 | # Flutter/Dart/Pub related 24 | **/doc/api/ 25 | .dart_tool/ 26 | .flutter-plugins 27 | .packages 28 | .pub-cache/ 29 | .pub/ 30 | build/ 31 | 32 | # Android related 33 | **/android/**/gradle-wrapper.jar 34 | **/android/.gradle 35 | **/android/captures/ 36 | **/android/gradlew 37 | **/android/gradlew.bat 38 | **/android/local.properties 39 | **/android/**/GeneratedPluginRegistrant.java 40 | 41 | # iOS/XCode related 42 | **/ios/**/*.mode1v3 43 | **/ios/**/*.mode2v3 44 | **/ios/**/*.moved-aside 45 | **/ios/**/*.pbxuser 46 | **/ios/**/*.perspectivev3 47 | **/ios/**/*sync/ 48 | **/ios/**/.sconsign.dblite 49 | **/ios/**/.tags* 50 | **/ios/**/.vagrant/ 51 | **/ios/**/DerivedData/ 52 | **/ios/**/Icon? 53 | **/ios/**/Pods/ 54 | **/ios/**/.symlinks/ 55 | **/ios/**/profile 56 | **/ios/**/xcuserdata 57 | **/ios/.generated/ 58 | **/ios/Flutter/App.framework 59 | **/ios/Flutter/Flutter.framework 60 | **/ios/Flutter/Generated.xcconfig 61 | **/ios/Flutter/app.flx 62 | **/ios/Flutter/app.zip 63 | **/ios/Flutter/flutter_assets/ 64 | **/ios/ServiceDefinitions.json 65 | **/ios/Runner/GeneratedPluginRegistrant.* 66 | 67 | # Exceptions to above rules. 68 | !**/ios/**/default.mode1v3 69 | !**/ios/**/default.mode2v3 70 | !**/ios/**/default.pbxuser 71 | !**/ios/**/default.perspectivev3 72 | !/packages/flutter_tools/test/data/dart_dependencies_test/**/.packages 73 | -------------------------------------------------------------------------------- /.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: 5391447fae6209bb21a89e6a5a6583cac1af9b4b 8 | channel: stable 9 | 10 | project_type: app 11 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # flutter_nb ([Demo.apk,账号注册数量有限,公用账号(13800008888,123456)](https://github.com/buhuiming/flutter_nb/blob/master/apk/app-release.apk)) 暂停更新 2 | 3 | 一个集成环信IM的Flutter项目。目前只是Android与flutter双向交互, 4 | 已完成功能:注册、登录、退出登录、自动登录、切换头像、切换主题、消息推送开关、搜索、添加好友、 5 | 系统消息推送、系统消息列表、消息删除、数据库存储,通知栏提醒、加入黑名单、移出黑名单、 6 | 删除好友、发送文本消息、发送图片(表情)消息、发送语音消息、发送小视频等 7 | 8 | ## 现今环信已经推出sdk,http://www.easemob.com/download/im 9 | 10 | ## [TextField上显示自定义表情](https://www.jianshu.com/p/e9ccc4d7e01f) 11 | 12 | ## Getting Started([效果图](https://github.com/buhuiming/flutter_nb/tree/master/screens/screen.md),图片加载不出点[这里](https://www.jianshu.com/p/b1763de834a4)) 13 | 14 | ### 原理:原生集成环信IM SDK,利用MethodChannel和EventChannel,进行Flutter与原生的双向交互。 15 | 16 | ### 1、[Flutter自定义加载圈](https://www.jianshu.com/p/17e256bc6230) 17 | 18 | ### 2、[Flutter爬坑过程小总结](https://www.jianshu.com/p/08dded076f59) 19 | 20 | ### 3、[Flutter自定义带搜索框的AppBar](https://www.jianshu.com/p/03f5db68567b) 21 | 22 | ### 4、[Flutter与原生Android双向交互](https://www.jianshu.com/p/c19e2c12da2d) 23 | 24 | ### 5、[关于Flutter沉浸式状态栏](https://www.jianshu.com/p/0a74b134705b) 25 | 26 | ### 6、[Flutter优缺点](https://www.jianshu.com/p/b7f457e492c3) 27 | 28 | ### 7、[Flutter开发规范](https://www.jianshu.com/p/31ba91db2154) 29 | 30 | ## License 31 | 32 | ``` 33 | Copyright (c) 2018 Bekie 34 | 35 | Permission is hereby granted, free of charge, to any person obtaining a copy 36 | of this software and associated documentation files (the "Software"), to deal 37 | in the Software without restriction, including without limitation the rights 38 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 39 | copies of the Software, and to permit persons to whom the Software is 40 | furnished to do so, subject to the following conditions: 41 | 42 | The above copyright notice and this permission notice shall be included in all 43 | copies or substantial portions of the Software. 44 | 45 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 46 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 47 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 48 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 49 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 50 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 51 | SOFTWARE. 52 | ``` 53 | -------------------------------------------------------------------------------- /android/app/build.gradle: -------------------------------------------------------------------------------- 1 | def localProperties = new Properties() 2 | def localPropertiesFile = rootProject.file('local.properties') 3 | if (localPropertiesFile.exists()) { 4 | localPropertiesFile.withReader('UTF-8') { reader -> 5 | localProperties.load(reader) 6 | } 7 | } 8 | 9 | def flutterRoot = localProperties.getProperty('flutter.sdk') 10 | if (flutterRoot == null) { 11 | throw new GradleException("Flutter SDK not found. Define location with flutter.sdk in the local.properties file.") 12 | } 13 | 14 | def flutterVersionCode = localProperties.getProperty('flutter.versionCode') 15 | if (flutterVersionCode == null) { 16 | flutterVersionCode = '1' 17 | } 18 | 19 | def flutterVersionName = localProperties.getProperty('flutter.versionName') 20 | if (flutterVersionName == null) { 21 | flutterVersionName = '1.0' 22 | } 23 | 24 | apply plugin: 'com.android.application' 25 | apply from: "$flutterRoot/packages/flutter_tools/gradle/flutter.gradle" 26 | 27 | android { 28 | compileSdkVersion 28 29 | 30 | lintOptions { 31 | disable 'InvalidPackage' 32 | } 33 | 34 | defaultConfig { 35 | // TODO: Specify your own unique Application ID (https://developer.android.com/studio/build/application-id.html). 36 | applicationId "com.bhm.flutter.flutternb" 37 | minSdkVersion 19 38 | targetSdkVersion 28 39 | versionCode flutterVersionCode.toInteger() 40 | versionName flutterVersionName 41 | testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner" 42 | } 43 | 44 | buildTypes { 45 | //flutter在Android平台下会默认生成arm-v7架构的的so库 46 | //官方注释目前flutter只支持在debug模式下生成x86的so 47 | debug{ 48 | ndk { 49 | abiFilters 'x86', 'arm64-v8a' 50 | } 51 | } 52 | release { 53 | // TODO: Add your own signing config for the release build. 54 | // Signing with the debug keys for now, so `flutter run --release` works. 55 | signingConfig signingConfigs.debug 56 | ndk { 57 | abiFilters 'armeabi-v7a' 58 | } 59 | } 60 | } 61 | 62 | compileOptions { 63 | sourceCompatibility JavaVersion.VERSION_1_8 64 | targetCompatibility JavaVersion.VERSION_1_8 65 | } 66 | 67 | /*环信IM集成*/ 68 | //use legacy for android 6.0 69 | useLibrary 'org.apache.http.legacy' 70 | } 71 | 72 | flutter { 73 | source '../..' 74 | } 75 | 76 | dependencies { 77 | testImplementation 'junit:junit:4.12' 78 | //noinspection GradleCompatible 79 | androidTestImplementation 'com.android.support.test:runner:1.0.2' 80 | androidTestImplementation 'com.android.support.test.espresso:espresso-core:3.0.2' 81 | 82 | implementation 'io.reactivex.rxjava2:rxjava:2.1.16' 83 | /*环信IM集成*/ 84 | //Optional compile for GCM (Google Cloud Messaging). 85 | implementation 'com.google.android.gms:play-services-gcm:16.0.0' 86 | implementation 'com.hyphenate:hyphenate-sdk:3.3.0' 87 | implementation 'com.alibaba:fastjson:1.2.55' 88 | //轻触拍照,长按摄像 89 | implementation 'cjt.library.wheel:camera:1.1.9' 90 | //拒绝重写Activity或Fragment的onActivityResult方法 91 | implementation 'com.bhm.sdk.bhmlibrary:ActivityResult:1.0.3' 92 | implementation 'io.reactivex.rxjava2:rxandroid:2.0.1' 93 | } 94 | -------------------------------------------------------------------------------- /android/app/src/main/gen/com/bhm/flutter/flutternb/BuildConfig.java: -------------------------------------------------------------------------------- 1 | /*___Generated_by_IDEA___*/ 2 | 3 | package com.bhm.flutter.flutternb; 4 | 5 | /* This stub is only used by the IDE. It is NOT the BuildConfig class actually packed into the APK */ 6 | public final class BuildConfig { 7 | public final static boolean DEBUG = Boolean.parseBoolean(null); 8 | } -------------------------------------------------------------------------------- /android/app/src/main/gen/com/bhm/flutter/flutternb/Manifest.java: -------------------------------------------------------------------------------- 1 | /*___Generated_by_IDEA___*/ 2 | 3 | package com.bhm.flutter.flutternb; 4 | 5 | /* This stub is only used by the IDE. It is NOT the Manifest class actually packed into the APK */ 6 | public final class Manifest { 7 | } -------------------------------------------------------------------------------- /android/app/src/main/gen/com/bhm/flutter/flutternb/R.java: -------------------------------------------------------------------------------- 1 | /*___Generated_by_IDEA___*/ 2 | 3 | package com.bhm.flutter.flutternb; 4 | 5 | /* This stub is only used by the IDE. It is NOT the R class actually packed into the APK */ 6 | public final class R { 7 | } -------------------------------------------------------------------------------- /android/app/src/main/java/com/bhm/flutter/flutternb/FlutterNBApplication.java: -------------------------------------------------------------------------------- 1 | package com.bhm.flutter.flutternb; 2 | 3 | import android.app.Application; 4 | 5 | import com.hyphenate.chat.EMClient; 6 | import com.hyphenate.chat.EMOptions; 7 | 8 | public class FlutterNBApplication extends io.flutter.app.FlutterApplication { 9 | 10 | @Override 11 | public void onCreate() { 12 | super.onCreate(); 13 | initEMClient(); 14 | } 15 | 16 | /** 17 | * 环信IM集成 18 | */ 19 | private void initEMClient(){ 20 | EMOptions options = new EMOptions(); 21 | // 默认添加好友时,是不需要验证的,改成需要验证 22 | options.setAcceptInvitationAlways(false); 23 | // 是否自动将消息附件上传到环信服务器,默认为True是使用环信服务器上传下载, 24 | // 如果设为 false,需要开发者自己处理附件消息的上传和下载 25 | // options.setAutoTransferMessageAttachments(true); 26 | // 是否自动下载附件类消息的缩略图等,默认为 true 这里和上边这个参数相关联 27 | // options.setAutoDownloadThumbnail(true); 28 | //options.setAutoLogin(false);自动登录,默认为true 29 | 30 | 31 | Application appContext = FlutterNBApplication.this; 32 | /*int pid = android.os.Process.myPid(); 33 | String processAppName = Utils.getAppName(appContext, pid); 34 | // 如果APP启用了远程的service,此application:onCreate会被调用2次 35 | // 为了防止环信SDK被初始化2次,加此判断会保证SDK被初始化1次 36 | // 默认的APP会在以包名为默认的process name下运行,如果查到的process name不是APP的process name就立即返回 37 | 38 | if (processAppName == null ||!processAppName.equalsIgnoreCase(appContext.getPackageName())) { 39 | // 则此application::onCreate 是被service 调用的,直接返回 40 | return; 41 | }*/ 42 | //初始化 43 | EMClient.getInstance().init(appContext, options); 44 | //在做打包混淆时,关闭debug模式,避免消耗不必要的资源 45 | EMClient.getInstance().setDebugMode(true); 46 | } 47 | } 48 | -------------------------------------------------------------------------------- /android/app/src/main/java/com/bhm/flutter/flutternb/interfaces/CallBack.java: -------------------------------------------------------------------------------- 1 | package com.bhm.flutter.flutternb.interfaces; 2 | 3 | public interface CallBack { 4 | void call(Object o); 5 | } 6 | -------------------------------------------------------------------------------- /android/app/src/main/java/com/bhm/flutter/flutternb/listeners/CallBackListener.java: -------------------------------------------------------------------------------- 1 | package com.bhm.flutter.flutternb.listeners; 2 | 3 | import com.bhm.flutter.flutternb.interfaces.CallBack; 4 | import com.bhm.flutter.flutternb.util.CallBackData; 5 | import com.bhm.flutter.flutternb.util.Utils; 6 | 7 | import io.flutter.plugin.common.EventChannel; 8 | 9 | /** 10 | * APP原生主动调用Flutter 11 | */ 12 | public class CallBackListener implements CallBack { 13 | 14 | private EventChannel.EventSink mSink; 15 | 16 | public CallBackListener(EventChannel.EventSink sink){ 17 | mSink = sink; 18 | } 19 | 20 | @Override 21 | public void call(Object o) { 22 | Utils.doOnMainThread(mSink, CallBackData.setData(CallBackData.TYPE_OF_STRING, "onDestroy"));//APP onDestroy时调用 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /android/app/src/main/java/com/bhm/flutter/flutternb/listeners/ConnectionListener.java: -------------------------------------------------------------------------------- 1 | package com.bhm.flutter.flutternb.listeners; 2 | 3 | import com.bhm.flutter.flutternb.util.CallBackData; 4 | import com.bhm.flutter.flutternb.util.Utils; 5 | import com.hyphenate.EMConnectionListener; 6 | import com.hyphenate.EMError; 7 | import com.hyphenate.util.NetUtils; 8 | 9 | import io.flutter.app.FlutterActivity; 10 | import io.flutter.plugin.common.EventChannel; 11 | 12 | /** 13 | * 网络连接状态监听 14 | */ 15 | public class ConnectionListener implements EMConnectionListener { 16 | 17 | private FlutterActivity mActivity; 18 | private EventChannel.EventSink mSink; 19 | 20 | public ConnectionListener(FlutterActivity activity, EventChannel.EventSink sink){ 21 | mActivity = activity; 22 | mSink = sink; 23 | } 24 | 25 | @Override 26 | public void onConnected() { 27 | Utils.doOnMainThread(mSink, CallBackData.setData(CallBackData.TYPE_OF_STRING, "onConnected")); 28 | } 29 | @Override 30 | public void onDisconnected(final int error) { 31 | if(error == EMError.USER_REMOVED){ 32 | // 显示帐号已经被移除 33 | Utils.doOnMainThread(mSink, CallBackData.setData(CallBackData.TYPE_OF_STRING, "user_removed")); 34 | }else if (error == EMError.USER_LOGIN_ANOTHER_DEVICE) { 35 | // 显示帐号在其他设备登录 36 | Utils.doOnMainThread(mSink, CallBackData.setData(CallBackData.TYPE_OF_STRING, "user_login_another_device")); 37 | } else { 38 | if (NetUtils.hasNetwork(mActivity)) { 39 | //连接不到聊天服务器 40 | Utils.doOnMainThread(mSink, CallBackData.setData(CallBackData.TYPE_OF_STRING, "disconnected_to_service")); 41 | } else { 42 | //当前网络不可用,请检查网络设置 43 | Utils.doOnMainThread(mSink, CallBackData.setData(CallBackData.TYPE_OF_STRING, "no_net")); 44 | } 45 | } 46 | } 47 | } 48 | -------------------------------------------------------------------------------- /android/app/src/main/java/com/bhm/flutter/flutternb/listeners/ContactListener.java: -------------------------------------------------------------------------------- 1 | package com.bhm.flutter.flutternb.listeners; 2 | 3 | import com.alibaba.fastjson.JSON; 4 | import com.bhm.flutter.flutternb.util.CallBackData; 5 | import com.bhm.flutter.flutternb.util.MessageEntity; 6 | import com.bhm.flutter.flutternb.util.Utils; 7 | import com.hyphenate.EMContactListener; 8 | 9 | import io.flutter.plugin.common.EventChannel; 10 | 11 | public class ContactListener implements EMContactListener { 12 | 13 | private EventChannel.EventSink mSink; 14 | 15 | public ContactListener(EventChannel.EventSink sink){ 16 | mSink = sink; 17 | } 18 | 19 | @Override 20 | public void onContactAdded(String username) { 21 | //增加联系人时回调此方法 22 | Utils.doOnMainThread(mSink, CallBackData.setData(CallBackData.TYPE_OF_JSON, 23 | JSON.toJSONString(new MessageEntity("chat", "onContactAdded", username)))); 24 | } 25 | 26 | @Override 27 | public void onContactDeleted(String username) { 28 | //被删除时回调此方法 29 | Utils.doOnMainThread(mSink, CallBackData.setData(CallBackData.TYPE_OF_JSON, 30 | JSON.toJSONString(new MessageEntity("chat", "onContactDeleted", username)))); 31 | } 32 | 33 | @Override 34 | public void onContactInvited(String username, String reason) { 35 | //收到好友邀请 36 | Utils.doOnMainThread(mSink, CallBackData.setData(CallBackData.TYPE_OF_JSON, 37 | JSON.toJSONString(new MessageEntity("system", "onContactInvited", username, reason)))); 38 | } 39 | 40 | @Override 41 | public void onFriendRequestAccepted(String username) { 42 | //好友请求被同意 43 | Utils.doOnMainThread(mSink, CallBackData.setData(CallBackData.TYPE_OF_JSON, 44 | JSON.toJSONString(new MessageEntity("system", "onFriendRequestAccepted", username)))); 45 | } 46 | 47 | @Override 48 | public void onFriendRequestDeclined(String username) { 49 | //好友请求被拒绝 50 | Utils.doOnMainThread(mSink, CallBackData.setData(CallBackData.TYPE_OF_JSON, 51 | JSON.toJSONString(new MessageEntity("system", "onFriendRequestDeclined", username)))); 52 | } 53 | } 54 | -------------------------------------------------------------------------------- /android/app/src/main/java/com/bhm/flutter/flutternb/listeners/MessageListener.java: -------------------------------------------------------------------------------- 1 | package com.bhm.flutter.flutternb.listeners; 2 | 3 | import android.util.Log; 4 | 5 | import com.alibaba.fastjson.JSON; 6 | import com.bhm.flutter.flutternb.util.CallBackData; 7 | import com.bhm.flutter.flutternb.util.MessageEntity; 8 | import com.bhm.flutter.flutternb.util.Utils; 9 | import com.hyphenate.EMMessageListener; 10 | import com.hyphenate.chat.EMClient; 11 | import com.hyphenate.chat.EMMessage; 12 | 13 | import java.util.List; 14 | 15 | import io.flutter.plugin.common.EventChannel; 16 | 17 | public class MessageListener implements EMMessageListener { 18 | 19 | private EventChannel.EventSink mSink; 20 | private static final MessageListener LISTENER = new MessageListener(); 21 | public static MessageListener get(){ 22 | return LISTENER; 23 | } 24 | 25 | private MessageListener(){} 26 | 27 | public MessageListener register(EventChannel.EventSink sink){ 28 | mSink = sink; 29 | return LISTENER; 30 | } 31 | 32 | public void unRegister(){ 33 | EMClient.getInstance().chatManager().removeMessageListener(LISTENER); 34 | } 35 | 36 | @Override 37 | public void onMessageReceived(List messages) { 38 | //收到消息 39 | for(EMMessage message : messages) { 40 | //把消息主体body放在note字段 41 | MessageEntity entity = new MessageEntity(Utils.getChatType(message),"onMessageReceived", 42 | Utils.getType(message.getType()), message.getFrom(), String.valueOf(message.getMsgTime()), 43 | JSON.toJSONString(message.getBody())); 44 | Utils.doOnMainThread(mSink, CallBackData.setData(CallBackData.TYPE_OF_JSON, JSON.toJSONString(entity))); 45 | Log.i("MessageListener", "收到消息----> " + message.toString()); 46 | } 47 | } 48 | 49 | @Override 50 | public void onCmdMessageReceived(List messages) { 51 | //收到透传消息 52 | for(EMMessage message : messages) { 53 | //把消息主体body放在note字段 54 | 55 | Log.i("MessageListener", "收到透传消息----> " + message.toString()); 56 | } 57 | } 58 | 59 | @Override 60 | public void onMessageRead(List messages) { 61 | //收到已读回执 62 | for(EMMessage message : messages) { 63 | //把消息主体body放在note字段 64 | 65 | Log.i("MessageListener", "收到已读回执----> " + message.toString()); 66 | } 67 | } 68 | 69 | @Override 70 | public void onMessageDelivered(List messages) { 71 | //收到已送达回执 72 | for(EMMessage message : messages) { 73 | 74 | Log.i("MessageListener", "收到已送达回执----> " + message.toString()); 75 | } 76 | } 77 | 78 | @Override 79 | public void onMessageChanged(EMMessage message, Object change) { 80 | //消息状态变动 81 | 82 | Log.i("MessageListener", "消息状态变动----> " + message.toString()); 83 | } 84 | } 85 | -------------------------------------------------------------------------------- /android/app/src/main/java/com/bhm/flutter/flutternb/plugins/FlutterPlugins.java: -------------------------------------------------------------------------------- 1 | package com.bhm.flutter.flutternb.plugins; 2 | 3 | import io.flutter.app.FlutterActivity; 4 | import io.flutter.plugin.common.EventChannel; 5 | import io.flutter.plugin.common.MethodCall; 6 | import io.flutter.plugin.common.MethodChannel; 7 | 8 | /** 9 | * flutter与原生双向交互的插件 10 | */ 11 | public class FlutterPlugins implements MethodChannel.MethodCallHandler, EventChannel.StreamHandler{ 12 | 13 | private FlutterActivity activity; 14 | 15 | private FlutterPlugins(FlutterActivity activity) { 16 | this.activity = activity; 17 | } 18 | 19 | public static void registerWith(FlutterActivity activity) { 20 | FlutterPlugins instance = new FlutterPlugins(activity); 21 | //flutter调用原生 22 | MethodChannel channel = new MethodChannel(activity.registrarFor(DealMethodCall.channels_flutter_to_native) 23 | .messenger(), DealMethodCall.channels_flutter_to_native); 24 | //setMethodCallHandler在此通道上接收方法调用的回调 25 | channel.setMethodCallHandler(instance); 26 | 27 | //原生调用flutter 28 | EventChannel eventChannel = new EventChannel(activity.registrarFor(DealMethodCall.channels_native_to_flutter) 29 | .messenger(), DealMethodCall.channels_native_to_flutter); 30 | eventChannel.setStreamHandler(instance); 31 | } 32 | @Override 33 | public void onMethodCall(MethodCall methodCall, MethodChannel.Result result) { 34 | DealMethodCall.onMethodCall(activity, methodCall, result); 35 | } 36 | 37 | @Override 38 | public void onListen(Object o, EventChannel.EventSink eventSink) { 39 | DealMethodCall.onListen(activity, o, eventSink); 40 | } 41 | 42 | @Override 43 | public void onCancel(Object o) { 44 | DealMethodCall.onCancel(activity, o); 45 | } 46 | } 47 | -------------------------------------------------------------------------------- /android/app/src/main/java/com/bhm/flutter/flutternb/ui/MainActivity.java: -------------------------------------------------------------------------------- 1 | package com.bhm.flutter.flutternb.ui; 2 | 3 | import android.os.Bundle; 4 | 5 | import com.bhm.flutter.flutternb.plugins.FlutterPlugins; 6 | import com.bhm.flutter.flutternb.util.Utils; 7 | 8 | import io.flutter.app.FlutterActivity; 9 | import io.flutter.plugins.GeneratedPluginRegistrant; 10 | 11 | public class MainActivity extends FlutterActivity { 12 | @Override 13 | protected void onCreate(Bundle savedInstanceState) { 14 | Utils.setStatus(this); 15 | super.onCreate(savedInstanceState); 16 | GeneratedPluginRegistrant.registerWith(this); 17 | FlutterPlugins.registerWith(this); 18 | Utils.setFilePath(); 19 | } 20 | 21 | @Override 22 | protected void onDestroy() { 23 | Utils.setCallBack(null); 24 | super.onDestroy(); 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /android/app/src/main/java/com/bhm/flutter/flutternb/util/CallBackData.java: -------------------------------------------------------------------------------- 1 | package com.bhm.flutter.flutternb.util; 2 | 3 | import java.util.HashMap; 4 | import java.util.Map; 5 | 6 | public class CallBackData { 7 | public final static String TYPE_OF_STRING = "string"; 8 | public final static String TYPE_OF_JSON = "json"; 9 | 10 | public static Map res = new HashMap(); 11 | 12 | public static synchronized Map setData(String type, String content){ 13 | res.clear(); 14 | res.put(type, content); 15 | return res; 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /android/app/src/main/java/com/bhm/flutter/flutternb/util/MessageEntity.java: -------------------------------------------------------------------------------- 1 | package com.bhm.flutter.flutternb.util; 2 | 3 | public class MessageEntity { 4 | private String type; 5 | private String content_type; 6 | private String method; 7 | private String sender_account; 8 | private String note; 9 | private String time; 10 | 11 | public MessageEntity(String type, String method, String content_type, String username, String time, String reason){ 12 | this.type = type; 13 | this.content_type = content_type; 14 | this.method = method; 15 | this.sender_account = username; 16 | this.time = time; 17 | this.note = reason; 18 | } 19 | public MessageEntity(String type, String method, String username, String reason){ 20 | this.type = type; 21 | this.method = method; 22 | this.sender_account = username; 23 | this.note = reason; 24 | } 25 | public MessageEntity(String type, String method, String username){ 26 | this.type = type; 27 | this.method = method; 28 | this.sender_account = username; 29 | } 30 | 31 | public String getType() { 32 | return type; 33 | } 34 | 35 | public void setType(String type) { 36 | this.type = type; 37 | } 38 | 39 | public String getContent_type() { 40 | return content_type; 41 | } 42 | 43 | public void setContent_type(String content_type) { 44 | this.content_type = content_type; 45 | } 46 | 47 | public String getSender_account() { 48 | return sender_account; 49 | } 50 | 51 | public void setSender_account(String sender_account) { 52 | this.sender_account = sender_account; 53 | } 54 | 55 | public String getNote() { 56 | return note; 57 | } 58 | 59 | public void setNote(String note) { 60 | this.note = note; 61 | } 62 | 63 | public String getTime() { 64 | return time; 65 | } 66 | 67 | public void setTime(String time) { 68 | this.time = time; 69 | } 70 | 71 | public String getMethod() { 72 | return method; 73 | } 74 | 75 | public void setMethod(String method) { 76 | this.method = method; 77 | } 78 | } 79 | -------------------------------------------------------------------------------- /android/app/src/main/res/drawable/app_icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/buhuiming/flutter_nb/e2a3dcd27c72d1f9991da0d7446a7897bfcda424/android/app/src/main/res/drawable/app_icon.png -------------------------------------------------------------------------------- /android/app/src/main/res/drawable/launch_background.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 12 | 13 | 14 | -------------------------------------------------------------------------------- /android/app/src/main/res/mipmap-hdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/buhuiming/flutter_nb/e2a3dcd27c72d1f9991da0d7446a7897bfcda424/android/app/src/main/res/mipmap-hdpi/ic_launcher.png -------------------------------------------------------------------------------- /android/app/src/main/res/mipmap-mdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/buhuiming/flutter_nb/e2a3dcd27c72d1f9991da0d7446a7897bfcda424/android/app/src/main/res/mipmap-mdpi/ic_launcher.png -------------------------------------------------------------------------------- /android/app/src/main/res/mipmap-xhdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/buhuiming/flutter_nb/e2a3dcd27c72d1f9991da0d7446a7897bfcda424/android/app/src/main/res/mipmap-xhdpi/ic_launcher.png -------------------------------------------------------------------------------- /android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/buhuiming/flutter_nb/e2a3dcd27c72d1f9991da0d7446a7897bfcda424/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png -------------------------------------------------------------------------------- /android/app/src/main/res/mipmap-xxhdpi/ic_launcher_new.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/buhuiming/flutter_nb/e2a3dcd27c72d1f9991da0d7446a7897bfcda424/android/app/src/main/res/mipmap-xxhdpi/ic_launcher_new.png -------------------------------------------------------------------------------- /android/app/src/main/res/mipmap-xxhdpi/splash_bg.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/buhuiming/flutter_nb/e2a3dcd27c72d1f9991da0d7446a7897bfcda424/android/app/src/main/res/mipmap-xxhdpi/splash_bg.jpg -------------------------------------------------------------------------------- /android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/buhuiming/flutter_nb/e2a3dcd27c72d1f9991da0d7446a7897bfcda424/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png -------------------------------------------------------------------------------- /android/app/src/main/res/values/styles.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 8 | 9 | 16 | 17 | -------------------------------------------------------------------------------- /android/app/src/main/res/xml/network_security_config.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /android/build.gradle: -------------------------------------------------------------------------------- 1 | buildscript { 2 | repositories { 3 | google() 4 | jcenter() 5 | } 6 | 7 | dependencies { 8 | classpath 'com.android.tools.build:gradle:3.3.1' 9 | } 10 | } 11 | 12 | allprojects { 13 | repositories { 14 | google() 15 | jcenter() 16 | /*环信IM集成*/ 17 | maven { url "https://raw.githubusercontent.com/HyphenateInc/Hyphenate-SDK-Android/master/repository" } 18 | } 19 | } 20 | 21 | rootProject.buildDir = '../build' 22 | subprojects { 23 | project.buildDir = "${rootProject.buildDir}/${project.name}" 24 | } 25 | subprojects { 26 | project.evaluationDependsOn(':app') 27 | } 28 | 29 | task clean(type: Delete) { 30 | delete rootProject.buildDir 31 | } 32 | -------------------------------------------------------------------------------- /android/gradle.properties: -------------------------------------------------------------------------------- 1 | org.gradle.jvmargs=-Xmx1536M 2 | android.useAndroidX=true 3 | android.enableJetifier=true 4 | android.enableR8=true 5 | -------------------------------------------------------------------------------- /android/gradle/wrapper/gradle-wrapper.properties: -------------------------------------------------------------------------------- 1 | #Fri Jun 23 08:50:38 CEST 2017 2 | distributionBase=GRADLE_USER_HOME 3 | distributionPath=wrapper/dists 4 | zipStoreBase=GRADLE_USER_HOME 5 | zipStorePath=wrapper/dists 6 | distributionUrl=https\://services.gradle.org/distributions/gradle-4.10.2-all.zip 7 | -------------------------------------------------------------------------------- /android/settings.gradle: -------------------------------------------------------------------------------- 1 | include ':app' 2 | 3 | def flutterProjectRoot = rootProject.projectDir.parentFile.toPath() 4 | 5 | def plugins = new Properties() 6 | def pluginsFile = new File(flutterProjectRoot.toFile(), '.flutter-plugins') 7 | if (pluginsFile.exists()) { 8 | pluginsFile.withReader('UTF-8') { reader -> plugins.load(reader) } 9 | } 10 | 11 | plugins.each { name, path -> 12 | def pluginDirectory = flutterProjectRoot.resolve(path).resolve('android').toFile() 13 | include ":$name" 14 | project(":$name").projectDir = pluginDirectory 15 | } 16 | -------------------------------------------------------------------------------- /android/settings_aar.gradle: -------------------------------------------------------------------------------- 1 | include ':app' 2 | -------------------------------------------------------------------------------- /apk/app-release.apk: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/buhuiming/flutter_nb/e2a3dcd27c72d1f9991da0d7446a7897bfcda424/apk/app-release.apk -------------------------------------------------------------------------------- /assets/images/default/img_default.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/buhuiming/flutter_nb/e2a3dcd27c72d1f9991da0d7446a7897bfcda424/assets/images/default/img_default.png -------------------------------------------------------------------------------- /assets/images/default/img_fest.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/buhuiming/flutter_nb/e2a3dcd27c72d1f9991da0d7446a7897bfcda424/assets/images/default/img_fest.png -------------------------------------------------------------------------------- /assets/images/face/0.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/buhuiming/flutter_nb/e2a3dcd27c72d1f9991da0d7446a7897bfcda424/assets/images/face/0.gif -------------------------------------------------------------------------------- /assets/images/face/1.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/buhuiming/flutter_nb/e2a3dcd27c72d1f9991da0d7446a7897bfcda424/assets/images/face/1.gif -------------------------------------------------------------------------------- /assets/images/face/10.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/buhuiming/flutter_nb/e2a3dcd27c72d1f9991da0d7446a7897bfcda424/assets/images/face/10.gif -------------------------------------------------------------------------------- /assets/images/face/11.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/buhuiming/flutter_nb/e2a3dcd27c72d1f9991da0d7446a7897bfcda424/assets/images/face/11.gif -------------------------------------------------------------------------------- /assets/images/face/12.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/buhuiming/flutter_nb/e2a3dcd27c72d1f9991da0d7446a7897bfcda424/assets/images/face/12.gif -------------------------------------------------------------------------------- /assets/images/face/13.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/buhuiming/flutter_nb/e2a3dcd27c72d1f9991da0d7446a7897bfcda424/assets/images/face/13.gif -------------------------------------------------------------------------------- /assets/images/face/14.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/buhuiming/flutter_nb/e2a3dcd27c72d1f9991da0d7446a7897bfcda424/assets/images/face/14.gif -------------------------------------------------------------------------------- /assets/images/face/15.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/buhuiming/flutter_nb/e2a3dcd27c72d1f9991da0d7446a7897bfcda424/assets/images/face/15.gif -------------------------------------------------------------------------------- /assets/images/face/16.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/buhuiming/flutter_nb/e2a3dcd27c72d1f9991da0d7446a7897bfcda424/assets/images/face/16.gif -------------------------------------------------------------------------------- /assets/images/face/17.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/buhuiming/flutter_nb/e2a3dcd27c72d1f9991da0d7446a7897bfcda424/assets/images/face/17.gif -------------------------------------------------------------------------------- /assets/images/face/18.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/buhuiming/flutter_nb/e2a3dcd27c72d1f9991da0d7446a7897bfcda424/assets/images/face/18.gif -------------------------------------------------------------------------------- /assets/images/face/19.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/buhuiming/flutter_nb/e2a3dcd27c72d1f9991da0d7446a7897bfcda424/assets/images/face/19.gif -------------------------------------------------------------------------------- /assets/images/face/2.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/buhuiming/flutter_nb/e2a3dcd27c72d1f9991da0d7446a7897bfcda424/assets/images/face/2.gif -------------------------------------------------------------------------------- /assets/images/face/20.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/buhuiming/flutter_nb/e2a3dcd27c72d1f9991da0d7446a7897bfcda424/assets/images/face/20.gif -------------------------------------------------------------------------------- /assets/images/face/21.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/buhuiming/flutter_nb/e2a3dcd27c72d1f9991da0d7446a7897bfcda424/assets/images/face/21.gif -------------------------------------------------------------------------------- /assets/images/face/22.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/buhuiming/flutter_nb/e2a3dcd27c72d1f9991da0d7446a7897bfcda424/assets/images/face/22.gif -------------------------------------------------------------------------------- /assets/images/face/23.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/buhuiming/flutter_nb/e2a3dcd27c72d1f9991da0d7446a7897bfcda424/assets/images/face/23.gif -------------------------------------------------------------------------------- /assets/images/face/24.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/buhuiming/flutter_nb/e2a3dcd27c72d1f9991da0d7446a7897bfcda424/assets/images/face/24.gif -------------------------------------------------------------------------------- /assets/images/face/25.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/buhuiming/flutter_nb/e2a3dcd27c72d1f9991da0d7446a7897bfcda424/assets/images/face/25.gif -------------------------------------------------------------------------------- /assets/images/face/26.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/buhuiming/flutter_nb/e2a3dcd27c72d1f9991da0d7446a7897bfcda424/assets/images/face/26.gif -------------------------------------------------------------------------------- /assets/images/face/27.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/buhuiming/flutter_nb/e2a3dcd27c72d1f9991da0d7446a7897bfcda424/assets/images/face/27.gif -------------------------------------------------------------------------------- /assets/images/face/28.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/buhuiming/flutter_nb/e2a3dcd27c72d1f9991da0d7446a7897bfcda424/assets/images/face/28.gif -------------------------------------------------------------------------------- /assets/images/face/29.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/buhuiming/flutter_nb/e2a3dcd27c72d1f9991da0d7446a7897bfcda424/assets/images/face/29.gif -------------------------------------------------------------------------------- /assets/images/face/3.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/buhuiming/flutter_nb/e2a3dcd27c72d1f9991da0d7446a7897bfcda424/assets/images/face/3.gif -------------------------------------------------------------------------------- /assets/images/face/30.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/buhuiming/flutter_nb/e2a3dcd27c72d1f9991da0d7446a7897bfcda424/assets/images/face/30.gif -------------------------------------------------------------------------------- /assets/images/face/31.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/buhuiming/flutter_nb/e2a3dcd27c72d1f9991da0d7446a7897bfcda424/assets/images/face/31.gif -------------------------------------------------------------------------------- /assets/images/face/32.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/buhuiming/flutter_nb/e2a3dcd27c72d1f9991da0d7446a7897bfcda424/assets/images/face/32.gif -------------------------------------------------------------------------------- /assets/images/face/33.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/buhuiming/flutter_nb/e2a3dcd27c72d1f9991da0d7446a7897bfcda424/assets/images/face/33.gif -------------------------------------------------------------------------------- /assets/images/face/34.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/buhuiming/flutter_nb/e2a3dcd27c72d1f9991da0d7446a7897bfcda424/assets/images/face/34.gif -------------------------------------------------------------------------------- /assets/images/face/35.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/buhuiming/flutter_nb/e2a3dcd27c72d1f9991da0d7446a7897bfcda424/assets/images/face/35.gif -------------------------------------------------------------------------------- /assets/images/face/36.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/buhuiming/flutter_nb/e2a3dcd27c72d1f9991da0d7446a7897bfcda424/assets/images/face/36.gif -------------------------------------------------------------------------------- /assets/images/face/37.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/buhuiming/flutter_nb/e2a3dcd27c72d1f9991da0d7446a7897bfcda424/assets/images/face/37.gif -------------------------------------------------------------------------------- /assets/images/face/38.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/buhuiming/flutter_nb/e2a3dcd27c72d1f9991da0d7446a7897bfcda424/assets/images/face/38.gif -------------------------------------------------------------------------------- /assets/images/face/39.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/buhuiming/flutter_nb/e2a3dcd27c72d1f9991da0d7446a7897bfcda424/assets/images/face/39.gif -------------------------------------------------------------------------------- /assets/images/face/4.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/buhuiming/flutter_nb/e2a3dcd27c72d1f9991da0d7446a7897bfcda424/assets/images/face/4.gif -------------------------------------------------------------------------------- /assets/images/face/40.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/buhuiming/flutter_nb/e2a3dcd27c72d1f9991da0d7446a7897bfcda424/assets/images/face/40.gif -------------------------------------------------------------------------------- /assets/images/face/41.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/buhuiming/flutter_nb/e2a3dcd27c72d1f9991da0d7446a7897bfcda424/assets/images/face/41.gif -------------------------------------------------------------------------------- /assets/images/face/42.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/buhuiming/flutter_nb/e2a3dcd27c72d1f9991da0d7446a7897bfcda424/assets/images/face/42.gif -------------------------------------------------------------------------------- /assets/images/face/43.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/buhuiming/flutter_nb/e2a3dcd27c72d1f9991da0d7446a7897bfcda424/assets/images/face/43.gif -------------------------------------------------------------------------------- /assets/images/face/44.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/buhuiming/flutter_nb/e2a3dcd27c72d1f9991da0d7446a7897bfcda424/assets/images/face/44.gif -------------------------------------------------------------------------------- /assets/images/face/45.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/buhuiming/flutter_nb/e2a3dcd27c72d1f9991da0d7446a7897bfcda424/assets/images/face/45.gif -------------------------------------------------------------------------------- /assets/images/face/46.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/buhuiming/flutter_nb/e2a3dcd27c72d1f9991da0d7446a7897bfcda424/assets/images/face/46.gif -------------------------------------------------------------------------------- /assets/images/face/47.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/buhuiming/flutter_nb/e2a3dcd27c72d1f9991da0d7446a7897bfcda424/assets/images/face/47.gif -------------------------------------------------------------------------------- /assets/images/face/48.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/buhuiming/flutter_nb/e2a3dcd27c72d1f9991da0d7446a7897bfcda424/assets/images/face/48.gif -------------------------------------------------------------------------------- /assets/images/face/49.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/buhuiming/flutter_nb/e2a3dcd27c72d1f9991da0d7446a7897bfcda424/assets/images/face/49.gif -------------------------------------------------------------------------------- /assets/images/face/5.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/buhuiming/flutter_nb/e2a3dcd27c72d1f9991da0d7446a7897bfcda424/assets/images/face/5.gif -------------------------------------------------------------------------------- /assets/images/face/50.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/buhuiming/flutter_nb/e2a3dcd27c72d1f9991da0d7446a7897bfcda424/assets/images/face/50.gif -------------------------------------------------------------------------------- /assets/images/face/51.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/buhuiming/flutter_nb/e2a3dcd27c72d1f9991da0d7446a7897bfcda424/assets/images/face/51.gif -------------------------------------------------------------------------------- /assets/images/face/52.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/buhuiming/flutter_nb/e2a3dcd27c72d1f9991da0d7446a7897bfcda424/assets/images/face/52.gif -------------------------------------------------------------------------------- /assets/images/face/53.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/buhuiming/flutter_nb/e2a3dcd27c72d1f9991da0d7446a7897bfcda424/assets/images/face/53.gif -------------------------------------------------------------------------------- /assets/images/face/54.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/buhuiming/flutter_nb/e2a3dcd27c72d1f9991da0d7446a7897bfcda424/assets/images/face/54.gif -------------------------------------------------------------------------------- /assets/images/face/55.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/buhuiming/flutter_nb/e2a3dcd27c72d1f9991da0d7446a7897bfcda424/assets/images/face/55.gif -------------------------------------------------------------------------------- /assets/images/face/56.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/buhuiming/flutter_nb/e2a3dcd27c72d1f9991da0d7446a7897bfcda424/assets/images/face/56.gif -------------------------------------------------------------------------------- /assets/images/face/57.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/buhuiming/flutter_nb/e2a3dcd27c72d1f9991da0d7446a7897bfcda424/assets/images/face/57.gif -------------------------------------------------------------------------------- /assets/images/face/58.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/buhuiming/flutter_nb/e2a3dcd27c72d1f9991da0d7446a7897bfcda424/assets/images/face/58.gif -------------------------------------------------------------------------------- /assets/images/face/59.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/buhuiming/flutter_nb/e2a3dcd27c72d1f9991da0d7446a7897bfcda424/assets/images/face/59.gif -------------------------------------------------------------------------------- /assets/images/face/6.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/buhuiming/flutter_nb/e2a3dcd27c72d1f9991da0d7446a7897bfcda424/assets/images/face/6.gif -------------------------------------------------------------------------------- /assets/images/face/60.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/buhuiming/flutter_nb/e2a3dcd27c72d1f9991da0d7446a7897bfcda424/assets/images/face/60.gif -------------------------------------------------------------------------------- /assets/images/face/61.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/buhuiming/flutter_nb/e2a3dcd27c72d1f9991da0d7446a7897bfcda424/assets/images/face/61.gif -------------------------------------------------------------------------------- /assets/images/face/62.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/buhuiming/flutter_nb/e2a3dcd27c72d1f9991da0d7446a7897bfcda424/assets/images/face/62.gif -------------------------------------------------------------------------------- /assets/images/face/63.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/buhuiming/flutter_nb/e2a3dcd27c72d1f9991da0d7446a7897bfcda424/assets/images/face/63.gif -------------------------------------------------------------------------------- /assets/images/face/64.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/buhuiming/flutter_nb/e2a3dcd27c72d1f9991da0d7446a7897bfcda424/assets/images/face/64.gif -------------------------------------------------------------------------------- /assets/images/face/65.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/buhuiming/flutter_nb/e2a3dcd27c72d1f9991da0d7446a7897bfcda424/assets/images/face/65.gif -------------------------------------------------------------------------------- /assets/images/face/66.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/buhuiming/flutter_nb/e2a3dcd27c72d1f9991da0d7446a7897bfcda424/assets/images/face/66.gif -------------------------------------------------------------------------------- /assets/images/face/67.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/buhuiming/flutter_nb/e2a3dcd27c72d1f9991da0d7446a7897bfcda424/assets/images/face/67.gif -------------------------------------------------------------------------------- /assets/images/face/68.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/buhuiming/flutter_nb/e2a3dcd27c72d1f9991da0d7446a7897bfcda424/assets/images/face/68.gif -------------------------------------------------------------------------------- /assets/images/face/69.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/buhuiming/flutter_nb/e2a3dcd27c72d1f9991da0d7446a7897bfcda424/assets/images/face/69.gif -------------------------------------------------------------------------------- /assets/images/face/7.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/buhuiming/flutter_nb/e2a3dcd27c72d1f9991da0d7446a7897bfcda424/assets/images/face/7.gif -------------------------------------------------------------------------------- /assets/images/face/70.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/buhuiming/flutter_nb/e2a3dcd27c72d1f9991da0d7446a7897bfcda424/assets/images/face/70.gif -------------------------------------------------------------------------------- /assets/images/face/71.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/buhuiming/flutter_nb/e2a3dcd27c72d1f9991da0d7446a7897bfcda424/assets/images/face/71.gif -------------------------------------------------------------------------------- /assets/images/face/72.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/buhuiming/flutter_nb/e2a3dcd27c72d1f9991da0d7446a7897bfcda424/assets/images/face/72.gif -------------------------------------------------------------------------------- /assets/images/face/73.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/buhuiming/flutter_nb/e2a3dcd27c72d1f9991da0d7446a7897bfcda424/assets/images/face/73.gif -------------------------------------------------------------------------------- /assets/images/face/74.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/buhuiming/flutter_nb/e2a3dcd27c72d1f9991da0d7446a7897bfcda424/assets/images/face/74.gif -------------------------------------------------------------------------------- /assets/images/face/75.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/buhuiming/flutter_nb/e2a3dcd27c72d1f9991da0d7446a7897bfcda424/assets/images/face/75.gif -------------------------------------------------------------------------------- /assets/images/face/76.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/buhuiming/flutter_nb/e2a3dcd27c72d1f9991da0d7446a7897bfcda424/assets/images/face/76.gif -------------------------------------------------------------------------------- /assets/images/face/77.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/buhuiming/flutter_nb/e2a3dcd27c72d1f9991da0d7446a7897bfcda424/assets/images/face/77.gif -------------------------------------------------------------------------------- /assets/images/face/78.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/buhuiming/flutter_nb/e2a3dcd27c72d1f9991da0d7446a7897bfcda424/assets/images/face/78.gif -------------------------------------------------------------------------------- /assets/images/face/79.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/buhuiming/flutter_nb/e2a3dcd27c72d1f9991da0d7446a7897bfcda424/assets/images/face/79.gif -------------------------------------------------------------------------------- /assets/images/face/8.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/buhuiming/flutter_nb/e2a3dcd27c72d1f9991da0d7446a7897bfcda424/assets/images/face/8.gif -------------------------------------------------------------------------------- /assets/images/face/80.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/buhuiming/flutter_nb/e2a3dcd27c72d1f9991da0d7446a7897bfcda424/assets/images/face/80.gif -------------------------------------------------------------------------------- /assets/images/face/81.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/buhuiming/flutter_nb/e2a3dcd27c72d1f9991da0d7446a7897bfcda424/assets/images/face/81.gif -------------------------------------------------------------------------------- /assets/images/face/82.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/buhuiming/flutter_nb/e2a3dcd27c72d1f9991da0d7446a7897bfcda424/assets/images/face/82.gif -------------------------------------------------------------------------------- /assets/images/face/83.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/buhuiming/flutter_nb/e2a3dcd27c72d1f9991da0d7446a7897bfcda424/assets/images/face/83.gif -------------------------------------------------------------------------------- /assets/images/face/84.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/buhuiming/flutter_nb/e2a3dcd27c72d1f9991da0d7446a7897bfcda424/assets/images/face/84.gif -------------------------------------------------------------------------------- /assets/images/face/85.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/buhuiming/flutter_nb/e2a3dcd27c72d1f9991da0d7446a7897bfcda424/assets/images/face/85.gif -------------------------------------------------------------------------------- /assets/images/face/86.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/buhuiming/flutter_nb/e2a3dcd27c72d1f9991da0d7446a7897bfcda424/assets/images/face/86.gif -------------------------------------------------------------------------------- /assets/images/face/87.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/buhuiming/flutter_nb/e2a3dcd27c72d1f9991da0d7446a7897bfcda424/assets/images/face/87.gif -------------------------------------------------------------------------------- /assets/images/face/88.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/buhuiming/flutter_nb/e2a3dcd27c72d1f9991da0d7446a7897bfcda424/assets/images/face/88.gif -------------------------------------------------------------------------------- /assets/images/face/89.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/buhuiming/flutter_nb/e2a3dcd27c72d1f9991da0d7446a7897bfcda424/assets/images/face/89.gif -------------------------------------------------------------------------------- /assets/images/face/9.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/buhuiming/flutter_nb/e2a3dcd27c72d1f9991da0d7446a7897bfcda424/assets/images/face/9.gif -------------------------------------------------------------------------------- /assets/images/face/90.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/buhuiming/flutter_nb/e2a3dcd27c72d1f9991da0d7446a7897bfcda424/assets/images/face/90.png -------------------------------------------------------------------------------- /assets/images/face/91.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/buhuiming/flutter_nb/e2a3dcd27c72d1f9991da0d7446a7897bfcda424/assets/images/face/91.png -------------------------------------------------------------------------------- /assets/images/face/92.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/buhuiming/flutter_nb/e2a3dcd27c72d1f9991da0d7446a7897bfcda424/assets/images/face/92.png -------------------------------------------------------------------------------- /assets/images/face/93.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/buhuiming/flutter_nb/e2a3dcd27c72d1f9991da0d7446a7897bfcda424/assets/images/face/93.png -------------------------------------------------------------------------------- /assets/images/face/94.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/buhuiming/flutter_nb/e2a3dcd27c72d1f9991da0d7446a7897bfcda424/assets/images/face/94.png -------------------------------------------------------------------------------- /assets/images/face/95.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/buhuiming/flutter_nb/e2a3dcd27c72d1f9991da0d7446a7897bfcda424/assets/images/face/95.png -------------------------------------------------------------------------------- /assets/images/face/96.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/buhuiming/flutter_nb/e2a3dcd27c72d1f9991da0d7446a7897bfcda424/assets/images/face/96.png -------------------------------------------------------------------------------- /assets/images/face/97.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/buhuiming/flutter_nb/e2a3dcd27c72d1f9991da0d7446a7897bfcda424/assets/images/face/97.png -------------------------------------------------------------------------------- /assets/images/face/98.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/buhuiming/flutter_nb/e2a3dcd27c72d1f9991da0d7446a7897bfcda424/assets/images/face/98.png -------------------------------------------------------------------------------- /assets/images/face/99.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/buhuiming/flutter_nb/e2a3dcd27c72d1f9991da0d7446a7897bfcda424/assets/images/face/99.png -------------------------------------------------------------------------------- /assets/images/face/face_delete.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/buhuiming/flutter_nb/e2a3dcd27c72d1f9991da0d7446a7897bfcda424/assets/images/face/face_delete.png -------------------------------------------------------------------------------- /assets/images/figure/0.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/buhuiming/flutter_nb/e2a3dcd27c72d1f9991da0d7446a7897bfcda424/assets/images/figure/0.gif -------------------------------------------------------------------------------- /assets/images/figure/1.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/buhuiming/flutter_nb/e2a3dcd27c72d1f9991da0d7446a7897bfcda424/assets/images/figure/1.gif -------------------------------------------------------------------------------- /assets/images/figure/10.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/buhuiming/flutter_nb/e2a3dcd27c72d1f9991da0d7446a7897bfcda424/assets/images/figure/10.gif -------------------------------------------------------------------------------- /assets/images/figure/11.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/buhuiming/flutter_nb/e2a3dcd27c72d1f9991da0d7446a7897bfcda424/assets/images/figure/11.gif -------------------------------------------------------------------------------- /assets/images/figure/12.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/buhuiming/flutter_nb/e2a3dcd27c72d1f9991da0d7446a7897bfcda424/assets/images/figure/12.gif -------------------------------------------------------------------------------- /assets/images/figure/13.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/buhuiming/flutter_nb/e2a3dcd27c72d1f9991da0d7446a7897bfcda424/assets/images/figure/13.gif -------------------------------------------------------------------------------- /assets/images/figure/14.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/buhuiming/flutter_nb/e2a3dcd27c72d1f9991da0d7446a7897bfcda424/assets/images/figure/14.gif -------------------------------------------------------------------------------- /assets/images/figure/15.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/buhuiming/flutter_nb/e2a3dcd27c72d1f9991da0d7446a7897bfcda424/assets/images/figure/15.gif -------------------------------------------------------------------------------- /assets/images/figure/16.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/buhuiming/flutter_nb/e2a3dcd27c72d1f9991da0d7446a7897bfcda424/assets/images/figure/16.gif -------------------------------------------------------------------------------- /assets/images/figure/17.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/buhuiming/flutter_nb/e2a3dcd27c72d1f9991da0d7446a7897bfcda424/assets/images/figure/17.gif -------------------------------------------------------------------------------- /assets/images/figure/18.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/buhuiming/flutter_nb/e2a3dcd27c72d1f9991da0d7446a7897bfcda424/assets/images/figure/18.gif -------------------------------------------------------------------------------- /assets/images/figure/19.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/buhuiming/flutter_nb/e2a3dcd27c72d1f9991da0d7446a7897bfcda424/assets/images/figure/19.gif -------------------------------------------------------------------------------- /assets/images/figure/2.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/buhuiming/flutter_nb/e2a3dcd27c72d1f9991da0d7446a7897bfcda424/assets/images/figure/2.gif -------------------------------------------------------------------------------- /assets/images/figure/20.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/buhuiming/flutter_nb/e2a3dcd27c72d1f9991da0d7446a7897bfcda424/assets/images/figure/20.gif -------------------------------------------------------------------------------- /assets/images/figure/21.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/buhuiming/flutter_nb/e2a3dcd27c72d1f9991da0d7446a7897bfcda424/assets/images/figure/21.gif -------------------------------------------------------------------------------- /assets/images/figure/22.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/buhuiming/flutter_nb/e2a3dcd27c72d1f9991da0d7446a7897bfcda424/assets/images/figure/22.gif -------------------------------------------------------------------------------- /assets/images/figure/23.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/buhuiming/flutter_nb/e2a3dcd27c72d1f9991da0d7446a7897bfcda424/assets/images/figure/23.gif -------------------------------------------------------------------------------- /assets/images/figure/24.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/buhuiming/flutter_nb/e2a3dcd27c72d1f9991da0d7446a7897bfcda424/assets/images/figure/24.gif -------------------------------------------------------------------------------- /assets/images/figure/25.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/buhuiming/flutter_nb/e2a3dcd27c72d1f9991da0d7446a7897bfcda424/assets/images/figure/25.gif -------------------------------------------------------------------------------- /assets/images/figure/26.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/buhuiming/flutter_nb/e2a3dcd27c72d1f9991da0d7446a7897bfcda424/assets/images/figure/26.gif -------------------------------------------------------------------------------- /assets/images/figure/27.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/buhuiming/flutter_nb/e2a3dcd27c72d1f9991da0d7446a7897bfcda424/assets/images/figure/27.gif -------------------------------------------------------------------------------- /assets/images/figure/28.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/buhuiming/flutter_nb/e2a3dcd27c72d1f9991da0d7446a7897bfcda424/assets/images/figure/28.gif -------------------------------------------------------------------------------- /assets/images/figure/29.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/buhuiming/flutter_nb/e2a3dcd27c72d1f9991da0d7446a7897bfcda424/assets/images/figure/29.gif -------------------------------------------------------------------------------- /assets/images/figure/3.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/buhuiming/flutter_nb/e2a3dcd27c72d1f9991da0d7446a7897bfcda424/assets/images/figure/3.gif -------------------------------------------------------------------------------- /assets/images/figure/30.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/buhuiming/flutter_nb/e2a3dcd27c72d1f9991da0d7446a7897bfcda424/assets/images/figure/30.gif -------------------------------------------------------------------------------- /assets/images/figure/31.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/buhuiming/flutter_nb/e2a3dcd27c72d1f9991da0d7446a7897bfcda424/assets/images/figure/31.gif -------------------------------------------------------------------------------- /assets/images/figure/32.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/buhuiming/flutter_nb/e2a3dcd27c72d1f9991da0d7446a7897bfcda424/assets/images/figure/32.gif -------------------------------------------------------------------------------- /assets/images/figure/33.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/buhuiming/flutter_nb/e2a3dcd27c72d1f9991da0d7446a7897bfcda424/assets/images/figure/33.gif -------------------------------------------------------------------------------- /assets/images/figure/34.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/buhuiming/flutter_nb/e2a3dcd27c72d1f9991da0d7446a7897bfcda424/assets/images/figure/34.gif -------------------------------------------------------------------------------- /assets/images/figure/35.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/buhuiming/flutter_nb/e2a3dcd27c72d1f9991da0d7446a7897bfcda424/assets/images/figure/35.gif -------------------------------------------------------------------------------- /assets/images/figure/36.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/buhuiming/flutter_nb/e2a3dcd27c72d1f9991da0d7446a7897bfcda424/assets/images/figure/36.gif -------------------------------------------------------------------------------- /assets/images/figure/37.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/buhuiming/flutter_nb/e2a3dcd27c72d1f9991da0d7446a7897bfcda424/assets/images/figure/37.gif -------------------------------------------------------------------------------- /assets/images/figure/38.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/buhuiming/flutter_nb/e2a3dcd27c72d1f9991da0d7446a7897bfcda424/assets/images/figure/38.gif -------------------------------------------------------------------------------- /assets/images/figure/39.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/buhuiming/flutter_nb/e2a3dcd27c72d1f9991da0d7446a7897bfcda424/assets/images/figure/39.gif -------------------------------------------------------------------------------- /assets/images/figure/4.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/buhuiming/flutter_nb/e2a3dcd27c72d1f9991da0d7446a7897bfcda424/assets/images/figure/4.gif -------------------------------------------------------------------------------- /assets/images/figure/40.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/buhuiming/flutter_nb/e2a3dcd27c72d1f9991da0d7446a7897bfcda424/assets/images/figure/40.gif -------------------------------------------------------------------------------- /assets/images/figure/41.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/buhuiming/flutter_nb/e2a3dcd27c72d1f9991da0d7446a7897bfcda424/assets/images/figure/41.gif -------------------------------------------------------------------------------- /assets/images/figure/42.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/buhuiming/flutter_nb/e2a3dcd27c72d1f9991da0d7446a7897bfcda424/assets/images/figure/42.gif -------------------------------------------------------------------------------- /assets/images/figure/43.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/buhuiming/flutter_nb/e2a3dcd27c72d1f9991da0d7446a7897bfcda424/assets/images/figure/43.gif -------------------------------------------------------------------------------- /assets/images/figure/44.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/buhuiming/flutter_nb/e2a3dcd27c72d1f9991da0d7446a7897bfcda424/assets/images/figure/44.gif -------------------------------------------------------------------------------- /assets/images/figure/45.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/buhuiming/flutter_nb/e2a3dcd27c72d1f9991da0d7446a7897bfcda424/assets/images/figure/45.gif -------------------------------------------------------------------------------- /assets/images/figure/46.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/buhuiming/flutter_nb/e2a3dcd27c72d1f9991da0d7446a7897bfcda424/assets/images/figure/46.gif -------------------------------------------------------------------------------- /assets/images/figure/47.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/buhuiming/flutter_nb/e2a3dcd27c72d1f9991da0d7446a7897bfcda424/assets/images/figure/47.gif -------------------------------------------------------------------------------- /assets/images/figure/48.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/buhuiming/flutter_nb/e2a3dcd27c72d1f9991da0d7446a7897bfcda424/assets/images/figure/48.gif -------------------------------------------------------------------------------- /assets/images/figure/49.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/buhuiming/flutter_nb/e2a3dcd27c72d1f9991da0d7446a7897bfcda424/assets/images/figure/49.gif -------------------------------------------------------------------------------- /assets/images/figure/5.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/buhuiming/flutter_nb/e2a3dcd27c72d1f9991da0d7446a7897bfcda424/assets/images/figure/5.gif -------------------------------------------------------------------------------- /assets/images/figure/50.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/buhuiming/flutter_nb/e2a3dcd27c72d1f9991da0d7446a7897bfcda424/assets/images/figure/50.gif -------------------------------------------------------------------------------- /assets/images/figure/51.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/buhuiming/flutter_nb/e2a3dcd27c72d1f9991da0d7446a7897bfcda424/assets/images/figure/51.gif -------------------------------------------------------------------------------- /assets/images/figure/52.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/buhuiming/flutter_nb/e2a3dcd27c72d1f9991da0d7446a7897bfcda424/assets/images/figure/52.gif -------------------------------------------------------------------------------- /assets/images/figure/53.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/buhuiming/flutter_nb/e2a3dcd27c72d1f9991da0d7446a7897bfcda424/assets/images/figure/53.gif -------------------------------------------------------------------------------- /assets/images/figure/54.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/buhuiming/flutter_nb/e2a3dcd27c72d1f9991da0d7446a7897bfcda424/assets/images/figure/54.gif -------------------------------------------------------------------------------- /assets/images/figure/55.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/buhuiming/flutter_nb/e2a3dcd27c72d1f9991da0d7446a7897bfcda424/assets/images/figure/55.gif -------------------------------------------------------------------------------- /assets/images/figure/56.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/buhuiming/flutter_nb/e2a3dcd27c72d1f9991da0d7446a7897bfcda424/assets/images/figure/56.gif -------------------------------------------------------------------------------- /assets/images/figure/57.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/buhuiming/flutter_nb/e2a3dcd27c72d1f9991da0d7446a7897bfcda424/assets/images/figure/57.gif -------------------------------------------------------------------------------- /assets/images/figure/58.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/buhuiming/flutter_nb/e2a3dcd27c72d1f9991da0d7446a7897bfcda424/assets/images/figure/58.gif -------------------------------------------------------------------------------- /assets/images/figure/59.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/buhuiming/flutter_nb/e2a3dcd27c72d1f9991da0d7446a7897bfcda424/assets/images/figure/59.gif -------------------------------------------------------------------------------- /assets/images/figure/6.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/buhuiming/flutter_nb/e2a3dcd27c72d1f9991da0d7446a7897bfcda424/assets/images/figure/6.gif -------------------------------------------------------------------------------- /assets/images/figure/60.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/buhuiming/flutter_nb/e2a3dcd27c72d1f9991da0d7446a7897bfcda424/assets/images/figure/60.gif -------------------------------------------------------------------------------- /assets/images/figure/61.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/buhuiming/flutter_nb/e2a3dcd27c72d1f9991da0d7446a7897bfcda424/assets/images/figure/61.gif -------------------------------------------------------------------------------- /assets/images/figure/62.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/buhuiming/flutter_nb/e2a3dcd27c72d1f9991da0d7446a7897bfcda424/assets/images/figure/62.gif -------------------------------------------------------------------------------- /assets/images/figure/63.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/buhuiming/flutter_nb/e2a3dcd27c72d1f9991da0d7446a7897bfcda424/assets/images/figure/63.gif -------------------------------------------------------------------------------- /assets/images/figure/64.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/buhuiming/flutter_nb/e2a3dcd27c72d1f9991da0d7446a7897bfcda424/assets/images/figure/64.gif -------------------------------------------------------------------------------- /assets/images/figure/65.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/buhuiming/flutter_nb/e2a3dcd27c72d1f9991da0d7446a7897bfcda424/assets/images/figure/65.gif -------------------------------------------------------------------------------- /assets/images/figure/66.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/buhuiming/flutter_nb/e2a3dcd27c72d1f9991da0d7446a7897bfcda424/assets/images/figure/66.gif -------------------------------------------------------------------------------- /assets/images/figure/67.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/buhuiming/flutter_nb/e2a3dcd27c72d1f9991da0d7446a7897bfcda424/assets/images/figure/67.gif -------------------------------------------------------------------------------- /assets/images/figure/68.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/buhuiming/flutter_nb/e2a3dcd27c72d1f9991da0d7446a7897bfcda424/assets/images/figure/68.gif -------------------------------------------------------------------------------- /assets/images/figure/69.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/buhuiming/flutter_nb/e2a3dcd27c72d1f9991da0d7446a7897bfcda424/assets/images/figure/69.gif -------------------------------------------------------------------------------- /assets/images/figure/7.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/buhuiming/flutter_nb/e2a3dcd27c72d1f9991da0d7446a7897bfcda424/assets/images/figure/7.gif -------------------------------------------------------------------------------- /assets/images/figure/70.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/buhuiming/flutter_nb/e2a3dcd27c72d1f9991da0d7446a7897bfcda424/assets/images/figure/70.png -------------------------------------------------------------------------------- /assets/images/figure/71.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/buhuiming/flutter_nb/e2a3dcd27c72d1f9991da0d7446a7897bfcda424/assets/images/figure/71.gif -------------------------------------------------------------------------------- /assets/images/figure/72.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/buhuiming/flutter_nb/e2a3dcd27c72d1f9991da0d7446a7897bfcda424/assets/images/figure/72.gif -------------------------------------------------------------------------------- /assets/images/figure/73.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/buhuiming/flutter_nb/e2a3dcd27c72d1f9991da0d7446a7897bfcda424/assets/images/figure/73.gif -------------------------------------------------------------------------------- /assets/images/figure/74.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/buhuiming/flutter_nb/e2a3dcd27c72d1f9991da0d7446a7897bfcda424/assets/images/figure/74.png -------------------------------------------------------------------------------- /assets/images/figure/75.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/buhuiming/flutter_nb/e2a3dcd27c72d1f9991da0d7446a7897bfcda424/assets/images/figure/75.gif -------------------------------------------------------------------------------- /assets/images/figure/76.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/buhuiming/flutter_nb/e2a3dcd27c72d1f9991da0d7446a7897bfcda424/assets/images/figure/76.gif -------------------------------------------------------------------------------- /assets/images/figure/77.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/buhuiming/flutter_nb/e2a3dcd27c72d1f9991da0d7446a7897bfcda424/assets/images/figure/77.gif -------------------------------------------------------------------------------- /assets/images/figure/78.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/buhuiming/flutter_nb/e2a3dcd27c72d1f9991da0d7446a7897bfcda424/assets/images/figure/78.gif -------------------------------------------------------------------------------- /assets/images/figure/79.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/buhuiming/flutter_nb/e2a3dcd27c72d1f9991da0d7446a7897bfcda424/assets/images/figure/79.gif -------------------------------------------------------------------------------- /assets/images/figure/8.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/buhuiming/flutter_nb/e2a3dcd27c72d1f9991da0d7446a7897bfcda424/assets/images/figure/8.gif -------------------------------------------------------------------------------- /assets/images/figure/80.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/buhuiming/flutter_nb/e2a3dcd27c72d1f9991da0d7446a7897bfcda424/assets/images/figure/80.gif -------------------------------------------------------------------------------- /assets/images/figure/81.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/buhuiming/flutter_nb/e2a3dcd27c72d1f9991da0d7446a7897bfcda424/assets/images/figure/81.gif -------------------------------------------------------------------------------- /assets/images/figure/82.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/buhuiming/flutter_nb/e2a3dcd27c72d1f9991da0d7446a7897bfcda424/assets/images/figure/82.gif -------------------------------------------------------------------------------- /assets/images/figure/83.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/buhuiming/flutter_nb/e2a3dcd27c72d1f9991da0d7446a7897bfcda424/assets/images/figure/83.gif -------------------------------------------------------------------------------- /assets/images/figure/84.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/buhuiming/flutter_nb/e2a3dcd27c72d1f9991da0d7446a7897bfcda424/assets/images/figure/84.gif -------------------------------------------------------------------------------- /assets/images/figure/85.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/buhuiming/flutter_nb/e2a3dcd27c72d1f9991da0d7446a7897bfcda424/assets/images/figure/85.gif -------------------------------------------------------------------------------- /assets/images/figure/86.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/buhuiming/flutter_nb/e2a3dcd27c72d1f9991da0d7446a7897bfcda424/assets/images/figure/86.gif -------------------------------------------------------------------------------- /assets/images/figure/87.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/buhuiming/flutter_nb/e2a3dcd27c72d1f9991da0d7446a7897bfcda424/assets/images/figure/87.gif -------------------------------------------------------------------------------- /assets/images/figure/88.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/buhuiming/flutter_nb/e2a3dcd27c72d1f9991da0d7446a7897bfcda424/assets/images/figure/88.gif -------------------------------------------------------------------------------- /assets/images/figure/89.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/buhuiming/flutter_nb/e2a3dcd27c72d1f9991da0d7446a7897bfcda424/assets/images/figure/89.gif -------------------------------------------------------------------------------- /assets/images/figure/9.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/buhuiming/flutter_nb/e2a3dcd27c72d1f9991da0d7446a7897bfcda424/assets/images/figure/9.gif -------------------------------------------------------------------------------- /assets/images/figure/90.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/buhuiming/flutter_nb/e2a3dcd27c72d1f9991da0d7446a7897bfcda424/assets/images/figure/90.gif -------------------------------------------------------------------------------- /assets/images/figure/91.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/buhuiming/flutter_nb/e2a3dcd27c72d1f9991da0d7446a7897bfcda424/assets/images/figure/91.gif -------------------------------------------------------------------------------- /assets/images/figure/92.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/buhuiming/flutter_nb/e2a3dcd27c72d1f9991da0d7446a7897bfcda424/assets/images/figure/92.gif -------------------------------------------------------------------------------- /assets/images/figure/93.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/buhuiming/flutter_nb/e2a3dcd27c72d1f9991da0d7446a7897bfcda424/assets/images/figure/93.gif -------------------------------------------------------------------------------- /assets/images/figure/94.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/buhuiming/flutter_nb/e2a3dcd27c72d1f9991da0d7446a7897bfcda424/assets/images/figure/94.gif -------------------------------------------------------------------------------- /assets/images/figure/95.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/buhuiming/flutter_nb/e2a3dcd27c72d1f9991da0d7446a7897bfcda424/assets/images/figure/95.gif -------------------------------------------------------------------------------- /assets/images/icon/audio_player_1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/buhuiming/flutter_nb/e2a3dcd27c72d1f9991da0d7446a7897bfcda424/assets/images/icon/audio_player_1.png -------------------------------------------------------------------------------- /assets/images/icon/audio_player_2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/buhuiming/flutter_nb/e2a3dcd27c72d1f9991da0d7446a7897bfcda424/assets/images/icon/audio_player_2.png -------------------------------------------------------------------------------- /assets/images/icon/audio_player_3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/buhuiming/flutter_nb/e2a3dcd27c72d1f9991da0d7446a7897bfcda424/assets/images/icon/audio_player_3.png -------------------------------------------------------------------------------- /assets/images/icon/collection.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/buhuiming/flutter_nb/e2a3dcd27c72d1f9991da0d7446a7897bfcda424/assets/images/icon/collection.png -------------------------------------------------------------------------------- /assets/images/icon/group_chat.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/buhuiming/flutter_nb/e2a3dcd27c72d1f9991da0d7446a7897bfcda424/assets/images/icon/group_chat.png -------------------------------------------------------------------------------- /assets/images/icon/img_headportrait.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/buhuiming/flutter_nb/e2a3dcd27c72d1f9991da0d7446a7897bfcda424/assets/images/icon/img_headportrait.png -------------------------------------------------------------------------------- /assets/images/icon/official_accounts.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/buhuiming/flutter_nb/e2a3dcd27c72d1f9991da0d7446a7897bfcda424/assets/images/icon/official_accounts.png -------------------------------------------------------------------------------- /assets/images/icon/search_friend.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/buhuiming/flutter_nb/e2a3dcd27c72d1f9991da0d7446a7897bfcda424/assets/images/icon/search_friend.jpg -------------------------------------------------------------------------------- /assets/images/icon/system_message.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/buhuiming/flutter_nb/e2a3dcd27c72d1f9991da0d7446a7897bfcda424/assets/images/icon/system_message.png -------------------------------------------------------------------------------- /assets/images/main_page/friends.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/buhuiming/flutter_nb/e2a3dcd27c72d1f9991da0d7446a7897bfcda424/assets/images/main_page/friends.png -------------------------------------------------------------------------------- /assets/images/main_page/friends_c.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/buhuiming/flutter_nb/e2a3dcd27c72d1f9991da0d7446a7897bfcda424/assets/images/main_page/friends_c.png -------------------------------------------------------------------------------- /assets/images/main_page/message.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/buhuiming/flutter_nb/e2a3dcd27c72d1f9991da0d7446a7897bfcda424/assets/images/main_page/message.png -------------------------------------------------------------------------------- /assets/images/main_page/message_c.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/buhuiming/flutter_nb/e2a3dcd27c72d1f9991da0d7446a7897bfcda424/assets/images/main_page/message_c.png -------------------------------------------------------------------------------- /assets/images/main_page/mine.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/buhuiming/flutter_nb/e2a3dcd27c72d1f9991da0d7446a7897bfcda424/assets/images/main_page/mine.png -------------------------------------------------------------------------------- /assets/images/main_page/mine_c.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/buhuiming/flutter_nb/e2a3dcd27c72d1f9991da0d7446a7897bfcda424/assets/images/main_page/mine_c.png -------------------------------------------------------------------------------- /assets/images/main_page/more.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/buhuiming/flutter_nb/e2a3dcd27c72d1f9991da0d7446a7897bfcda424/assets/images/main_page/more.png -------------------------------------------------------------------------------- /assets/images/main_page/more_c.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/buhuiming/flutter_nb/e2a3dcd27c72d1f9991da0d7446a7897bfcda424/assets/images/main_page/more_c.png -------------------------------------------------------------------------------- /assets/images/splash/guide1.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/buhuiming/flutter_nb/e2a3dcd27c72d1f9991da0d7446a7897bfcda424/assets/images/splash/guide1.jpg -------------------------------------------------------------------------------- /assets/images/splash/guide2.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/buhuiming/flutter_nb/e2a3dcd27c72d1f9991da0d7446a7897bfcda424/assets/images/splash/guide2.jpg -------------------------------------------------------------------------------- /assets/images/splash/guide3.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/buhuiming/flutter_nb/e2a3dcd27c72d1f9991da0d7446a7897bfcda424/assets/images/splash/guide3.jpg -------------------------------------------------------------------------------- /assets/images/splash/guide4.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/buhuiming/flutter_nb/e2a3dcd27c72d1f9991da0d7446a7897bfcda424/assets/images/splash/guide4.jpg -------------------------------------------------------------------------------- /assets/images/splash/logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/buhuiming/flutter_nb/e2a3dcd27c72d1f9991da0d7446a7897bfcda424/assets/images/splash/logo.png -------------------------------------------------------------------------------- /assets/images/splash/splash_bg.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/buhuiming/flutter_nb/e2a3dcd27c72d1f9991da0d7446a7897bfcda424/assets/images/splash/splash_bg.jpg -------------------------------------------------------------------------------- /assets/sounds/demo.mp3: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/buhuiming/flutter_nb/e2a3dcd27c72d1f9991da0d7446a7897bfcda424/assets/sounds/demo.mp3 -------------------------------------------------------------------------------- /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 "Generated.xcconfig" 2 | -------------------------------------------------------------------------------- /ios/Flutter/Release.xcconfig: -------------------------------------------------------------------------------- 1 | #include "Generated.xcconfig" 2 | -------------------------------------------------------------------------------- /ios/Flutter/flutter_export_environment.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | # This is a generated file; do not edit or check into version control. 3 | export "FLUTTER_ROOT=E:\flutter\flutter" 4 | export "FLUTTER_APPLICATION_PATH=F:\FlutterProject\flutter_nb" 5 | export "FLUTTER_TARGET=lib\main.dart" 6 | export "FLUTTER_BUILD_DIR=build" 7 | export "SYMROOT=${SOURCE_ROOT}/../build\ios" 8 | export "FLUTTER_FRAMEWORK_DIR=E:\flutter\flutter\bin\cache\artifacts\engine\ios" 9 | export "FLUTTER_BUILD_NAME=1.0.0" 10 | export "FLUTTER_BUILD_NUMBER=1" 11 | -------------------------------------------------------------------------------- /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 | 8 | -------------------------------------------------------------------------------- /ios/Runner/AppDelegate.h: -------------------------------------------------------------------------------- 1 | #import 2 | #import 3 | 4 | @interface AppDelegate : FlutterAppDelegate 5 | 6 | @end 7 | -------------------------------------------------------------------------------- /ios/Runner/AppDelegate.m: -------------------------------------------------------------------------------- 1 | #include "AppDelegate.h" 2 | #include "GeneratedPluginRegistrant.h" 3 | 4 | @implementation AppDelegate 5 | 6 | - (BOOL)application:(UIApplication *)application 7 | didFinishLaunchingWithOptions:(NSDictionary *)launchOptions { 8 | [GeneratedPluginRegistrant registerWithRegistry:self]; 9 | // Override point for customization after application launch. 10 | return [super application:application didFinishLaunchingWithOptions:launchOptions]; 11 | } 12 | 13 | @end 14 | -------------------------------------------------------------------------------- /ios/Runner/Assets.xcassets/AppIcon.appiconset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "size" : "20x20", 5 | "idiom" : "iphone", 6 | "filename" : "Icon-App-20x20@2x.png", 7 | "scale" : "2x" 8 | }, 9 | { 10 | "size" : "20x20", 11 | "idiom" : "iphone", 12 | "filename" : "Icon-App-20x20@3x.png", 13 | "scale" : "3x" 14 | }, 15 | { 16 | "size" : "29x29", 17 | "idiom" : "iphone", 18 | "filename" : "Icon-App-29x29@1x.png", 19 | "scale" : "1x" 20 | }, 21 | { 22 | "size" : "29x29", 23 | "idiom" : "iphone", 24 | "filename" : "Icon-App-29x29@2x.png", 25 | "scale" : "2x" 26 | }, 27 | { 28 | "size" : "29x29", 29 | "idiom" : "iphone", 30 | "filename" : "Icon-App-29x29@3x.png", 31 | "scale" : "3x" 32 | }, 33 | { 34 | "size" : "40x40", 35 | "idiom" : "iphone", 36 | "filename" : "Icon-App-40x40@2x.png", 37 | "scale" : "2x" 38 | }, 39 | { 40 | "size" : "40x40", 41 | "idiom" : "iphone", 42 | "filename" : "Icon-App-40x40@3x.png", 43 | "scale" : "3x" 44 | }, 45 | { 46 | "size" : "60x60", 47 | "idiom" : "iphone", 48 | "filename" : "Icon-App-60x60@2x.png", 49 | "scale" : "2x" 50 | }, 51 | { 52 | "size" : "60x60", 53 | "idiom" : "iphone", 54 | "filename" : "Icon-App-60x60@3x.png", 55 | "scale" : "3x" 56 | }, 57 | { 58 | "size" : "20x20", 59 | "idiom" : "ipad", 60 | "filename" : "Icon-App-20x20@1x.png", 61 | "scale" : "1x" 62 | }, 63 | { 64 | "size" : "20x20", 65 | "idiom" : "ipad", 66 | "filename" : "Icon-App-20x20@2x.png", 67 | "scale" : "2x" 68 | }, 69 | { 70 | "size" : "29x29", 71 | "idiom" : "ipad", 72 | "filename" : "Icon-App-29x29@1x.png", 73 | "scale" : "1x" 74 | }, 75 | { 76 | "size" : "29x29", 77 | "idiom" : "ipad", 78 | "filename" : "Icon-App-29x29@2x.png", 79 | "scale" : "2x" 80 | }, 81 | { 82 | "size" : "40x40", 83 | "idiom" : "ipad", 84 | "filename" : "Icon-App-40x40@1x.png", 85 | "scale" : "1x" 86 | }, 87 | { 88 | "size" : "40x40", 89 | "idiom" : "ipad", 90 | "filename" : "Icon-App-40x40@2x.png", 91 | "scale" : "2x" 92 | }, 93 | { 94 | "size" : "76x76", 95 | "idiom" : "ipad", 96 | "filename" : "Icon-App-76x76@1x.png", 97 | "scale" : "1x" 98 | }, 99 | { 100 | "size" : "76x76", 101 | "idiom" : "ipad", 102 | "filename" : "Icon-App-76x76@2x.png", 103 | "scale" : "2x" 104 | }, 105 | { 106 | "size" : "83.5x83.5", 107 | "idiom" : "ipad", 108 | "filename" : "Icon-App-83.5x83.5@2x.png", 109 | "scale" : "2x" 110 | }, 111 | { 112 | "size" : "1024x1024", 113 | "idiom" : "ios-marketing", 114 | "filename" : "Icon-App-1024x1024@1x.png", 115 | "scale" : "1x" 116 | } 117 | ], 118 | "info" : { 119 | "version" : 1, 120 | "author" : "xcode" 121 | } 122 | } 123 | -------------------------------------------------------------------------------- /ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-1024x1024@1x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/buhuiming/flutter_nb/e2a3dcd27c72d1f9991da0d7446a7897bfcda424/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/buhuiming/flutter_nb/e2a3dcd27c72d1f9991da0d7446a7897bfcda424/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/buhuiming/flutter_nb/e2a3dcd27c72d1f9991da0d7446a7897bfcda424/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/buhuiming/flutter_nb/e2a3dcd27c72d1f9991da0d7446a7897bfcda424/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/buhuiming/flutter_nb/e2a3dcd27c72d1f9991da0d7446a7897bfcda424/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/buhuiming/flutter_nb/e2a3dcd27c72d1f9991da0d7446a7897bfcda424/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/buhuiming/flutter_nb/e2a3dcd27c72d1f9991da0d7446a7897bfcda424/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/buhuiming/flutter_nb/e2a3dcd27c72d1f9991da0d7446a7897bfcda424/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/buhuiming/flutter_nb/e2a3dcd27c72d1f9991da0d7446a7897bfcda424/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/buhuiming/flutter_nb/e2a3dcd27c72d1f9991da0d7446a7897bfcda424/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/buhuiming/flutter_nb/e2a3dcd27c72d1f9991da0d7446a7897bfcda424/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/buhuiming/flutter_nb/e2a3dcd27c72d1f9991da0d7446a7897bfcda424/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/buhuiming/flutter_nb/e2a3dcd27c72d1f9991da0d7446a7897bfcda424/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/buhuiming/flutter_nb/e2a3dcd27c72d1f9991da0d7446a7897bfcda424/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/buhuiming/flutter_nb/e2a3dcd27c72d1f9991da0d7446a7897bfcda424/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/buhuiming/flutter_nb/e2a3dcd27c72d1f9991da0d7446a7897bfcda424/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage.png -------------------------------------------------------------------------------- /ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/buhuiming/flutter_nb/e2a3dcd27c72d1f9991da0d7446a7897bfcda424/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@2x.png -------------------------------------------------------------------------------- /ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/buhuiming/flutter_nb/e2a3dcd27c72d1f9991da0d7446a7897bfcda424/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@3x.png -------------------------------------------------------------------------------- /ios/Runner/Assets.xcassets/LaunchImage.imageset/README.md: -------------------------------------------------------------------------------- 1 | # Launch Screen Assets 2 | 3 | You can customize the launch screen with your own desired assets by replacing the image files in this directory. 4 | 5 | You can also do it by opening your Flutter project's Xcode project with `open ios/Runner.xcworkspace`, selecting `Runner/Assets.xcassets` in the Project Navigator and dropping in the desired images. -------------------------------------------------------------------------------- /ios/Runner/Base.lproj/LaunchScreen.storyboard: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | -------------------------------------------------------------------------------- /ios/Runner/Base.lproj/Main.storyboard: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | -------------------------------------------------------------------------------- /ios/Runner/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | en 7 | CFBundleExecutable 8 | $(EXECUTABLE_NAME) 9 | CFBundleIdentifier 10 | $(PRODUCT_BUNDLE_IDENTIFIER) 11 | CFBundleInfoDictionaryVersion 12 | 6.0 13 | CFBundleName 14 | flutter_nb 15 | CFBundlePackageType 16 | APPL 17 | CFBundleShortVersionString 18 | $(FLUTTER_BUILD_NAME) 19 | CFBundleSignature 20 | ???? 21 | CFBundleVersion 22 | $(FLUTTER_BUILD_NUMBER) 23 | LSRequiresIPhoneOS 24 | 25 | UILaunchStoryboardName 26 | LaunchScreen 27 | UIMainStoryboardFile 28 | Main 29 | UISupportedInterfaceOrientations 30 | 31 | UIInterfaceOrientationPortrait 32 | UIInterfaceOrientationLandscapeLeft 33 | UIInterfaceOrientationLandscapeRight 34 | 35 | UISupportedInterfaceOrientations~ipad 36 | 37 | UIInterfaceOrientationPortrait 38 | UIInterfaceOrientationPortraitUpsideDown 39 | UIInterfaceOrientationLandscapeLeft 40 | UIInterfaceOrientationLandscapeRight 41 | 42 | UIViewControllerBasedStatusBarAppearance 43 | 44 | 45 | 46 | -------------------------------------------------------------------------------- /ios/Runner/main.m: -------------------------------------------------------------------------------- 1 | #import 2 | #import 3 | #import "AppDelegate.h" 4 | 5 | int main(int argc, char* argv[]) { 6 | @autoreleasepool { 7 | return UIApplicationMain(argc, argv, nil, NSStringFromClass([AppDelegate class])); 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /lib/constants/config.dart: -------------------------------------------------------------------------------- 1 | class Config { 2 | static const String VERSION = '1.0.0'; 3 | } 4 | -------------------------------------------------------------------------------- /lib/constants/constants.dart: -------------------------------------------------------------------------------- 1 | class Constants { 2 | static const String GITHUB_URL = 'https://github.com/buhuiming'; 3 | static const String JIANSHU_URL = 'https://www.jianshu.com/u/99bbcff7c8a1'; 4 | static const String KEY_GUIDE = 'key_guide'; //false: show guide page; 5 | static const String KEY_LOGIN = 'key_login'; //false: show login page; 6 | static const String KEY_LOGIN_ACCOUNT = 'key_login_account'; 7 | static const String URL_ADVERTISING = 8 | 'https://raw.githubusercontent.com/Sky24n/LDocuments/master/AppImgs/flutter_common_utils_a.png'; 9 | static const String INPUTFORMATTERS = '[a-zA-Z0-9!.?,~@#%^&*()]'; 10 | static const String FUNCTION_SEARCH_FRIENDS = 11 | "function_Search_friends"; //搜索功能-查找朋友 12 | 13 | static const String MESSAGE_TYPE_SYSTEM_ZH = "系统消息"; //系统消息 14 | static const String MESSAGE_TYPE_SYSTEM = "system"; //消息类型:系统消息 15 | static const String MESSAGE_TYPE_CHAT = "chat"; //消息类型:聊天消息 16 | static const String MESSAGE_TYPE_GROUP_CHAT = "chatGroup"; //消息类型:群聊消息 17 | static const String MESSAGE_TYPE_ROOM_CHAT = "chatRoom"; //消息类型:聊天室消息 18 | static const String MESSAGE_TYPE_OTHERS = "others"; //消息类型:其他消息 19 | static const String CONTENT_TYPE_SYSTEM = "text"; //消息内容类型:文本 20 | static const String CONTENT_TYPE_VOICE = "voice"; //消息内容类型:语音 21 | static const String CONTENT_TYPE_VIDEO = "video"; //消息内容类型:视频 22 | static const String CONTENT_TYPE_IMAGE = "image"; //消息内容类型:图像 23 | static const String CONTENT_TYPE_LOCATION = "location"; //消息内容类型:位置 24 | static const String CONTENT_TYPE_FILE = "file"; //消息内容类型:文件 25 | static const String CONTENT_TYPE_DEFINED = "defined"; //消息内容类型:拓展(自定义)消息 26 | static const String CONTENT_TYPE_CMD = "cmd"; //消息内容类型:其他(透传)消息 27 | 28 | static const String KET_THEME_COLOR = "ket_theme_color"; //主题色 29 | 30 | static int currentPage = 0; 31 | 32 | static const String NOTIFICATION_KEY_ALL = "notification_key_all"; //新消息提醒总开关 33 | static const String NOTIFICATION_KEY_SYSTEM = 34 | "notification_key_system"; //系统消息提醒开关 35 | static const String NOTIFICATION_KEY_CHAT = 36 | "notification_key_chat"; //聊天消息提醒开关 37 | static const String NOTIFICATION_KEY_OTHERS = 38 | "notification_key_others"; //其他消息提醒开关 39 | } 40 | -------------------------------------------------------------------------------- /lib/database/database_config.dart: -------------------------------------------------------------------------------- 1 | /* 2 | * 数据库相关配置 3 | */ 4 | class DataBaseConfig { 5 | static const String DATABASE_NAME = 'nb_db'; 6 | static const String MESSAGE_TABLE = 'message_type_table'; 7 | static const String VERSION = '1.0.0'; 8 | static const int VERSION_CODE = 1; 9 | static const bool DEBUG = false; 10 | } 11 | -------------------------------------------------------------------------------- /lib/entity/message_body_eneity.dart: -------------------------------------------------------------------------------- 1 | class MessageBodyEntity { 2 | /*文本*/ 3 | String message; //文本 4 | /*图像*/ 5 | String fileName; 6 | int height; 7 | int width; 8 | int length; 9 | int duration; 10 | int videoFileLength; 11 | String remoteUrl; //远程图、远程视频 12 | String thumbnailUrl; //缩略图 13 | bool sendOriginalImage; 14 | MessageBodyEntity( 15 | {this.message, 16 | this.fileName, 17 | this.height, 18 | this.width, 19 | this.length, 20 | this.videoFileLength, 21 | this.duration, 22 | this.remoteUrl, 23 | this.thumbnailUrl, 24 | this.sendOriginalImage}); 25 | 26 | MessageBodyEntity.fromMap(Map map) 27 | : this( 28 | message: map['message'], 29 | fileName: map['fileName'], 30 | height: map['height'], 31 | width: map['width'], 32 | length: map['length'], 33 | duration: map['duration'], 34 | videoFileLength: map['videoFileLength'], 35 | remoteUrl: map['remoteUrl'], 36 | thumbnailUrl: map['thumbnailUrl'], 37 | sendOriginalImage: map['sendOriginalImage'], 38 | ); 39 | } 40 | -------------------------------------------------------------------------------- /lib/interfaces/call_back.dart: -------------------------------------------------------------------------------- 1 | class CallBack { 2 | T call(Object o) {} 3 | } 4 | -------------------------------------------------------------------------------- /lib/main.dart: -------------------------------------------------------------------------------- 1 | import 'dart:async'; 2 | 3 | import 'package:flutter/material.dart'; 4 | import 'package:flutter_nb/ui/page/main/main_page.dart'; 5 | import 'package:flutter_nb/ui/page/splash_page.dart'; 6 | import 'package:flutter_nb/utils/data_proxy.dart'; 7 | import 'package:flutter_nb/utils/device_util.dart'; 8 | 9 | //void main() => runApp(MyApp()); 10 | 11 | void collectLog(String line) { 12 | //收集日志 13 | } 14 | void reportErrorAndLog(FlutterErrorDetails details) { 15 | //上报错误和日志逻辑 16 | } 17 | 18 | FlutterErrorDetails makeDetails(Object obj, StackTrace stack) { 19 | // 构建错误信息 20 | } 21 | 22 | void main() { 23 | FlutterError.onError = (FlutterErrorDetails details) { 24 | reportErrorAndLog(details); 25 | }; 26 | runZoned( 27 | () => runApp(MyApp()), 28 | zoneSpecification: ZoneSpecification( 29 | print: (Zone self, ZoneDelegate parent, Zone zone, String line) { 30 | collectLog(line); // 收集日志 31 | }, 32 | ), 33 | onError: (Object obj, StackTrace stack) { 34 | var details = makeDetails(obj, stack); 35 | reportErrorAndLog(details); 36 | }, 37 | ); 38 | } 39 | 40 | class MyApp extends StatelessWidget { 41 | @override 42 | Widget build(BuildContext context) { 43 | DeviceUtil.setBarStatus(true); 44 | DataProxy.build().connect(context); //启动APP时,就建立与原生的交互 45 | return MaterialApp(home: new SplashPage(), routes: { 46 | '/MainPage': (ctx) => MainPage(), 47 | }); 48 | } 49 | } 50 | -------------------------------------------------------------------------------- /lib/resource/colors.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/material.dart'; 2 | 3 | /* 4 | 1.colorPrimary 应用的主要色调,actionBar默认使用该颜色,Toolbar导航栏的底色 5 | 2.colorPrimaryDark 应用的主要暗色调,statusBarColor默认使用该颜色 6 | 3.statusBarColor 状态栏颜色,默认使用colorPrimaryDark 7 | 4.windowBackground 窗口背景颜色 8 | 5.navigationBarColor 底部栏颜色 9 | 6.colorForeground 应用的前景色,ListView的分割线,switch滑动区默认使用该颜色 10 | 7.colorBackground 应用的背景色,popMenu的背景默认使用该颜色 11 | 8.colorAccent CheckBox,RadioButton,SwitchCompat等一般控件的选中效果默认采用该颜色 12 | 9.colorControlNormal CheckBox,RadioButton,SwitchCompat等默认状态的颜色。 13 | 10.colorControlHighlight 控件按压时的色调 14 | 11.colorControlActivated 控件选中时的颜色,默认使用colorAccent 15 | 12.colorButtonNormal 默认按钮的背景颜色 16 | 13.editTextColor:默认EditView输入框字体的颜色。 17 | 14.textColor Button,textView的文字颜色 18 | 15.textColorPrimaryDisableOnly RadioButton checkbox等控件的文字 19 | 16.textColorPrimary 应用的主要文字颜色,actionBar的标题文字默认使用该颜色 20 | 17.colorSwitchThumbNormal: switch thumbs 默认状态的颜色. (switch off) 21 | */ 22 | class ColorT { 23 | static const Color app_main = Color(0xFF666666); 24 | static const Color transparent_80 = Color(0x80000000); //204 25 | static const Color transparent_50 = Color(0x50000000); //204 26 | 27 | static const Color text_dark = Color(0xFF333333); 28 | static const Color text_normal = Color(0xFF666666); 29 | static const Color text_gray = Color(0xFF999999); 30 | 31 | static const Color divider = Color(0xffe5e5e5); 32 | 33 | static const Color gray_33 = Color(0xFF333333); //51 34 | static const Color gray_66 = Color(0xFF666666); //102 35 | static const Color gray_99 = Color(0xFF999999); //153 36 | static const Color common_orange = Color(0XFFFC9153); //252 145 83 37 | static const Color gray_ef = Color(0XFFEFEFEF); //153 38 | 39 | static const Color gray_f0 = Color(0xfff0f0f0); //204 40 | static const Color gray_f5 = Color(0xfff5f5f5); //204 41 | static const Color gray_cc = Color(0xffcccccc); //204 42 | static const Color gray_ce = Color(0xffcecece); //206 43 | static const Color green_1 = Color(0xff009688); //204 44 | static const Color green_62 = Color(0xff626262); //204 45 | static const Color green_e5 = Color(0xffe5e5e5); //204 46 | } 47 | 48 | Map circleAvatarMap = { 49 | 'A': Colors.blueAccent, 50 | 'B': Colors.blue, 51 | 'C': Colors.cyan, 52 | 'D': Colors.deepPurple, 53 | 'E': Colors.deepPurpleAccent, 54 | 'F': Colors.blue, 55 | 'G': Colors.green, 56 | 'H': Colors.lightBlue, 57 | 'I': Colors.indigo, 58 | 'J': Colors.blue, 59 | 'K': Colors.blue, 60 | 'L': Colors.lightGreen, 61 | 'M': Colors.blue, 62 | 'N': Colors.brown, 63 | 'O': Colors.orange, 64 | 'P': Colors.purple, 65 | 'Q': Colors.black, 66 | 'R': Colors.red, 67 | 'S': Colors.blue, 68 | 'T': Colors.teal, 69 | 'U': Colors.purpleAccent, 70 | 'V': Colors.black, 71 | 'W': Colors.brown, 72 | 'X': Colors.blue, 73 | 'Y': Colors.yellow, 74 | 'Z': Colors.grey, 75 | '#': Colors.blue, 76 | }; 77 | 78 | Map themeColorMap = { 79 | 'red': Colors.red, 80 | 'pink': Colors.pink, 81 | 'purple': Colors.purple, 82 | 'deepPurple': Colors.deepPurple, 83 | 'indigo': Colors.indigo, 84 | 'blue': Colors.blue, 85 | 'lightBlue': Colors.lightBlue, 86 | 'cyan': Colors.cyan, 87 | 'teal': Colors.teal, 88 | 'green': Colors.green, 89 | 'lightGreen': Colors.lightGreen, 90 | 'lime': Colors.lime, 91 | 'yellow': Colors.yellow, 92 | 'amber': Colors.amber, 93 | 'orange': Colors.orange, 94 | 'deepOrange': Colors.deepOrange, 95 | 'brown': Colors.brown, 96 | 'blueGrey': Colors.blueGrey, 97 | 'white': Colors.white, 98 | 'black': Colors.black, 99 | }; 100 | Map themeSwatchColorMap = { 101 | 'red': Colors.red, 102 | 'pink': Colors.pink, 103 | 'purple': Colors.purple, 104 | 'deepPurple': Colors.deepPurple, 105 | 'indigo': Colors.indigo, 106 | 'blue': Colors.blue, 107 | 'lightBlue': Colors.lightBlue, 108 | 'cyan': Colors.cyan, 109 | 'teal': Colors.teal, 110 | 'green': Colors.green, 111 | 'lightGreen': Colors.lightGreen, 112 | 'lime': Colors.lime, 113 | 'yellow': Colors.yellow, 114 | 'amber': Colors.amber, 115 | 'orange': Colors.orange, 116 | 'deepOrange': Colors.deepOrange, 117 | 'brown': Colors.brown, 118 | 'blueGrey': Colors.blueGrey, 119 | 'white': Colors.red, //白色不是MaterialColor 120 | 'black': Colors.blue, //黑色不是MaterialColor 121 | }; 122 | -------------------------------------------------------------------------------- /lib/ui/page/about_page.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/cupertino.dart'; 2 | import 'package:flutter/material.dart'; 3 | import 'package:flutter_nb/constants/config.dart'; 4 | import 'package:flutter_nb/constants/constants.dart'; 5 | import 'package:flutter_nb/ui/page/base/web_view_page.dart'; 6 | import 'package:flutter_nb/ui/widget/more_widgets.dart'; 7 | import 'package:flutter_nb/utils/device_util.dart'; 8 | import 'package:flutter_nb/utils/dialog_util.dart'; 9 | import 'package:flutter_nb/utils/file_util.dart'; 10 | import 'package:flutter_nb/utils/object_util.dart'; 11 | 12 | /* 13 | * 关于页面 14 | */ 15 | class AboutPage extends StatelessWidget { 16 | @override 17 | Widget build(BuildContext context) { 18 | // TODO: implement build 19 | DeviceUtil.setBarStatus(true); 20 | return new About(); 21 | } 22 | } 23 | 24 | class About extends StatefulWidget { 25 | @override 26 | State createState() { 27 | // TODO: implement createState 28 | return new _AboutState(); 29 | } 30 | } 31 | 32 | class _AboutState extends State { 33 | GlobalKey _key = new GlobalKey(); 34 | 35 | @override 36 | Widget build(BuildContext context) { 37 | // TODO: implement build 38 | return new MaterialApp( 39 | theme: ThemeData( 40 | primaryColor: ObjectUtil.getThemeColor(), 41 | platform: TargetPlatform.iOS), 42 | home: new Scaffold( 43 | key: _key, 44 | backgroundColor: Colors.white, 45 | primary: true, 46 | body: SafeArea( 47 | child: ListView( 48 | children: [ 49 | SizedBox(height: 40.0), 50 | new Center( 51 | child: ClipRRect( 52 | borderRadius: BorderRadius.circular(12.0), 53 | child: new Image.asset( 54 | FileUtil.getImagePath('logo', 55 | dir: 'splash', format: 'png'), 56 | height: 120.0, 57 | width: 120.0), 58 | ), 59 | ), 60 | SizedBox(height: 10), 61 | new Center( 62 | child: Text( 63 | '版本号 ' + Config.VERSION, 64 | maxLines: 1, 65 | softWrap: true, 66 | overflow: TextOverflow.ellipsis, 67 | style: TextStyle( 68 | fontSize: 15.0, color: ObjectUtil.getThemeColor()), 69 | )), 70 | SizedBox(height: 66.0), 71 | MoreWidgets.defaultListViewItem(null, 'github', 72 | textColor: Colors.black, onItemClick: (res) { 73 | Navigator.push( 74 | context, 75 | new CupertinoPageRoute( 76 | builder: (ctx) => new WebViewPage( 77 | title: 'Github', 78 | url: Constants.GITHUB_URL, 79 | ))); 80 | }), 81 | MoreWidgets.defaultListViewItem(null, '简书', 82 | textColor: Colors.black, onItemClick: (res) { 83 | Navigator.push( 84 | context, 85 | new CupertinoPageRoute( 86 | builder: (ctx) => new WebViewPage( 87 | title: 'Github', 88 | url: Constants.JIANSHU_URL, 89 | ))); 90 | }), 91 | MoreWidgets.defaultListViewItem(null, '版本更新', 92 | textColor: Colors.black, onItemClick: (res) { 93 | DialogUtil.buildSnakeBarByKey('已经是最新版本', _key); 94 | }), 95 | MoreWidgets.defaultListViewItem(null, '其他', 96 | textColor: Colors.black, onItemClick: (res) { 97 | DialogUtil.buildSnakeBarByKey('暂时没有了', _key); 98 | }), 99 | ], 100 | )), 101 | appBar: MoreWidgets.buildAppBar( 102 | context, 103 | '关于', 104 | centerTitle: true, 105 | elevation: 2.0, 106 | leading: IconButton( 107 | icon: Icon(Icons.arrow_back), 108 | onPressed: () { 109 | Navigator.pop(context); 110 | }), 111 | ), 112 | )); 113 | } 114 | } 115 | -------------------------------------------------------------------------------- /lib/ui/page/base/messag_state.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/material.dart'; 2 | import 'package:flutter_nb/entity/message_entity.dart'; 3 | import 'package:flutter_nb/utils/interact_vative.dart'; 4 | 5 | /* 6 | * 消息类State基类,监听原生的回调,更新页面 7 | */ 8 | abstract class MessageState extends State { 9 | @override 10 | void initState() { 11 | // TODO: implement initState 12 | super.initState(); 13 | _addListener(); 14 | } 15 | 16 | _addListener() { 17 | InteractNative.initMessageEvent(); 18 | InteractNative.getMessageEventStream().listen((value) { 19 | updateData(value); 20 | }); 21 | } 22 | 23 | @protected 24 | void updateData(MessageEntity entity); 25 | } 26 | -------------------------------------------------------------------------------- /lib/ui/page/base/theme_state.dart: -------------------------------------------------------------------------------- 1 | /* 2 | * State基类,更新页面用 3 | */ 4 | import 'package:flutter/material.dart'; 5 | import 'package:flutter_nb/utils/interact_vative.dart'; 6 | import 'package:flutter_nb/utils/object_util.dart'; 7 | 8 | abstract class ThemeState extends State { 9 | Color primaryColor; 10 | MaterialColor primarySwatch; 11 | Color themeLightColor; 12 | 13 | @override 14 | void initState() { 15 | // TODO: implement initState 16 | super.initState(); 17 | init(); 18 | _addListener(); //添加监听 19 | } 20 | 21 | init() { 22 | primaryColor = ObjectUtil.getThemeColor(); 23 | primarySwatch = ObjectUtil.getThemeSwatchColor(); 24 | themeLightColor = ObjectUtil.getThemeLightColor(); 25 | } 26 | 27 | _addListener() { 28 | InteractNative.initAppEvent(); 29 | InteractNative.getAppEventStream().listen((value) { 30 | notify(value); 31 | }); 32 | } 33 | 34 | @protected 35 | void notify(Object o); 36 | 37 | } 38 | -------------------------------------------------------------------------------- /lib/ui/page/change_theme_page.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/material.dart'; 2 | import 'package:flutter_nb/constants/constants.dart'; 3 | import 'package:flutter_nb/resource/colors.dart'; 4 | import 'package:flutter_nb/ui/page/base/theme_state.dart'; 5 | import 'package:flutter_nb/ui/widget/more_widgets.dart'; 6 | import 'package:flutter_nb/utils/device_util.dart'; 7 | import 'package:flutter_nb/utils/interact_vative.dart'; 8 | import 'package:flutter_nb/utils/object_util.dart'; 9 | import 'package:flutter_nb/utils/sp_util.dart'; 10 | 11 | /* 12 | * 改变主题 13 | */ 14 | class ChangeThemePage extends StatelessWidget { 15 | @override 16 | Widget build(BuildContext context) { 17 | // TODO: implement build 18 | DeviceUtil.setBarStatus(true); 19 | return new ChangeTheme(); 20 | } 21 | } 22 | 23 | class ChangeTheme extends StatefulWidget { 24 | @override 25 | State createState() { 26 | // TODO: implement createState 27 | return new _ChangeThemeState(); 28 | } 29 | } 30 | 31 | class _ChangeThemeState extends ThemeState { 32 | @override 33 | Widget build(BuildContext context) { 34 | // TODO: implement build 35 | return new MaterialApp( 36 | theme: ThemeData( 37 | primaryColor: ObjectUtil.getThemeColor(), 38 | platform: TargetPlatform.iOS), 39 | home: new Scaffold( 40 | backgroundColor: Colors.white, 41 | primary: true, 42 | body: SafeArea( 43 | child: GridView.count( 44 | crossAxisCount: 5, 45 | padding: EdgeInsets.all(10.0), 46 | children: themeColorMap.keys.map((String key) { 47 | Color value = themeColorMap[key]; 48 | return new InkWell( 49 | onTap: () { 50 | SPUtil.putString(Constants.KET_THEME_COLOR, key); 51 | InteractNative.getAppEventSink() 52 | .add(InteractNative.RESET_THEME_COLOR); 53 | }, 54 | child: new Container( 55 | margin: EdgeInsets.all(13.0), 56 | width: 34.0, 57 | height: 34.0, 58 | color: value, 59 | ), 60 | ); 61 | }).toList()), 62 | ), 63 | appBar: MoreWidgets.buildAppBar( 64 | context, 65 | '切换主题', 66 | centerTitle: true, 67 | elevation: 2.0, 68 | leading: IconButton( 69 | icon: Icon(Icons.arrow_back), 70 | onPressed: () { 71 | Navigator.pop(context); 72 | }), 73 | ), 74 | )); 75 | } 76 | 77 | @override 78 | void notify(Object o) { 79 | // TODO: implement notify 80 | setState(() { 81 | if (o == InteractNative.RESET_THEME_COLOR) { 82 | init(); 83 | } 84 | }); 85 | } 86 | } 87 | -------------------------------------------------------------------------------- /lib/ui/page/chat_group_page.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/material.dart'; 2 | import 'package:flutter_nb/entity/message_entity.dart'; 3 | import 'package:flutter_nb/ui/page/base/messag_state.dart'; 4 | import 'package:flutter_nb/ui/widget/more_widgets.dart'; 5 | import 'package:flutter_nb/utils/object_util.dart'; 6 | /* 7 | * 群聊 8 | */ 9 | class ChatGroupPage extends StatefulWidget { 10 | @override 11 | State createState() { 12 | // TODO: implement createState 13 | return ChatGroupState(); 14 | } 15 | } 16 | 17 | class ChatGroupState extends MessageState { 18 | @override 19 | Widget build(BuildContext context) { 20 | // TODO: implement build 21 | return MaterialApp( 22 | theme: ThemeData( 23 | primaryColor: ObjectUtil.getThemeColor(), 24 | primarySwatch: ObjectUtil.getThemeSwatchColor(), 25 | platform: TargetPlatform.iOS), 26 | home: Scaffold( 27 | appBar: MoreWidgets.buildAppBar( 28 | context, 29 | '', 30 | centerTitle: true, 31 | elevation: 2.0, 32 | leading: IconButton( 33 | icon: Icon(Icons.arrow_back), 34 | onPressed: () { 35 | Navigator.pop(context); 36 | }), 37 | actions: [ 38 | InkWell( 39 | child: Container( 40 | padding: EdgeInsets.only(right: 15, left: 15), 41 | child: Icon( 42 | Icons.delete, 43 | size: 22, 44 | )), 45 | onTap: () {}) 46 | ], 47 | ), 48 | body: ListView(), 49 | )); 50 | } 51 | 52 | @override 53 | void updateData(MessageEntity entity) { 54 | // TODO: implement updateData 55 | } 56 | } 57 | -------------------------------------------------------------------------------- /lib/ui/page/chat_room_page.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/material.dart'; 2 | import 'package:flutter_nb/entity/message_entity.dart'; 3 | import 'package:flutter_nb/ui/page/base/messag_state.dart'; 4 | import 'package:flutter_nb/ui/widget/more_widgets.dart'; 5 | import 'package:flutter_nb/utils/object_util.dart'; 6 | /* 7 | * 聊天室 8 | */ 9 | class ChatRoomPage extends StatefulWidget { 10 | @override 11 | State createState() { 12 | // TODO: implement createState 13 | return ChatRoomState(); 14 | } 15 | } 16 | 17 | class ChatRoomState extends MessageState { 18 | @override 19 | Widget build(BuildContext context) { 20 | // TODO: implement build 21 | return MaterialApp( 22 | theme: ThemeData( 23 | primaryColor: ObjectUtil.getThemeColor(), 24 | primarySwatch: ObjectUtil.getThemeSwatchColor(), 25 | platform: TargetPlatform.iOS), 26 | home: Scaffold( 27 | appBar: MoreWidgets.buildAppBar( 28 | context, 29 | '', 30 | centerTitle: true, 31 | elevation: 2.0, 32 | leading: IconButton( 33 | icon: Icon(Icons.arrow_back), 34 | onPressed: () { 35 | Navigator.pop(context); 36 | }), 37 | actions: [ 38 | InkWell( 39 | child: Container( 40 | padding: EdgeInsets.only(right: 15, left: 15), 41 | child: Icon( 42 | Icons.delete, 43 | size: 22, 44 | )), 45 | onTap: () {}) 46 | ], 47 | ), 48 | body: ListView(), 49 | )); 50 | } 51 | 52 | @override 53 | void updateData(MessageEntity entity) { 54 | // TODO: implement updateData 55 | } 56 | } 57 | -------------------------------------------------------------------------------- /lib/ui/page/information_page.dart: -------------------------------------------------------------------------------- 1 | import 'dart:math'; 2 | import 'dart:ui'; 3 | 4 | import 'package:flutter/material.dart'; 5 | import 'package:flutter_nb/resource/colors.dart'; 6 | import 'package:flutter_nb/ui/widget/more_widgets.dart'; 7 | import 'package:flutter_nb/utils/object_util.dart'; 8 | import 'package:flutter_staggered_grid_view/flutter_staggered_grid_view.dart'; 9 | 10 | class InformationPage extends StatefulWidget { 11 | @override 12 | State createState() { 13 | // TODO: implement createState 14 | return InformationPageState(); 15 | } 16 | } 17 | 18 | class InformationPageState extends State { 19 | @override 20 | Widget build(BuildContext context) { 21 | // TODO: implement build 22 | return layout(context); 23 | } 24 | 25 | Widget layout(BuildContext context) { 26 | return Scaffold( 27 | appBar: MoreWidgets.buildAppBar( 28 | context, 29 | '资讯', 30 | centerTitle: true, 31 | elevation: 2.0, 32 | leading: IconButton( 33 | icon: Icon(Icons.arrow_back), 34 | onPressed: () { 35 | Navigator.pop(context); 36 | }), 37 | ), 38 | body: StaggeredGridView.countBuilder( 39 | crossAxisCount: 4, 40 | itemCount: 100, 41 | padding: EdgeInsets.all(12), 42 | itemBuilder: (BuildContext context, int index) => new Container( 43 | color: ObjectUtil.getRandomColor(), 44 | child: new Center( 45 | child: new CircleAvatar( 46 | backgroundColor: Colors.white, 47 | child: new Text('$index'), 48 | ), 49 | )), 50 | staggeredTileBuilder: (int index) => 51 | new StaggeredTile.count(2, index.isEven ? 2 : 1), 52 | mainAxisSpacing: 12.0, 53 | crossAxisSpacing: 12.0, 54 | )); 55 | } 56 | } 57 | -------------------------------------------------------------------------------- /lib/ui/page/main/mine_page.dart: -------------------------------------------------------------------------------- 1 | import 'dart:io'; 2 | 3 | import 'package:flutter/cupertino.dart'; 4 | import 'package:flutter/material.dart'; 5 | import 'package:flutter_nb/constants/constants.dart'; 6 | import 'package:flutter_nb/ui/page/setting_page.dart'; 7 | import 'package:flutter_nb/ui/widget/loading_widget.dart'; 8 | import 'package:flutter_nb/ui/widget/more_widgets.dart'; 9 | import 'package:flutter_nb/ui/widget/popupwindow_widget.dart'; 10 | import 'package:flutter_nb/utils/dialog_util.dart'; 11 | import 'package:flutter_nb/utils/file_util.dart'; 12 | import 'package:flutter_nb/utils/interact_vative.dart'; 13 | import 'package:flutter_nb/utils/object_util.dart'; 14 | import 'package:flutter_nb/utils/sp_util.dart'; 15 | 16 | /* 17 | * 我的 18 | */ 19 | class MinePage extends StatefulWidget { 20 | MinePage({Key key, this.title, this.operation, this.rootContext}) 21 | : super(key: key); 22 | final String title; 23 | final Operation operation; 24 | final BuildContext rootContext; 25 | 26 | @override 27 | State createState() { 28 | // TODO: implement createState 29 | return _MineState(); 30 | } 31 | } 32 | 33 | class _MineState extends State with AutomaticKeepAliveClientMixin { 34 | File imageChild; 35 | 36 | @override 37 | Widget build(BuildContext context) { 38 | return Scaffold( 39 | appBar: MoreWidgets.buildAppBar(context, '', 40 | elevation: 0.0, actions: _actions(context)), 41 | body: ListView( 42 | children: [ 43 | MoreWidgets.mineListViewItem1( 44 | SPUtil.getString(Constants.KEY_LOGIN_ACCOUNT), 45 | content: '萍水相逢,尽是他乡之客', 46 | imageChild: _getHeadPortrait(), onImageClick: (res) { 47 | PopupWindowUtil.showPhotoChosen(context, onCallBack: (image) { 48 | setState(() { 49 | imageChild = image; 50 | }); 51 | }); 52 | }), 53 | MoreWidgets.buildDivider(), 54 | MoreWidgets.defaultListViewItem(Icons.add_shopping_cart, '支付', 55 | textColor: Colors.black), 56 | MoreWidgets.defaultListViewItem(Icons.favorite, '收藏', 57 | textColor: Colors.black), 58 | MoreWidgets.defaultListViewItem(Icons.photo, '相册', 59 | textColor: Colors.black, onItemClick: (res) {}), 60 | MoreWidgets.defaultListViewItem(Icons.content_copy, '卡包', 61 | textColor: Colors.black, onItemClick: (res) {}), 62 | MoreWidgets.defaultListViewItem(Icons.face, '表情', 63 | textColor: Colors.black, onItemClick: (res) {}), 64 | MoreWidgets.defaultListViewItem(Icons.settings, '设置', 65 | textColor: Colors.black, isDivider: false, onItemClick: (res) { 66 | Navigator.push( 67 | context, 68 | new CupertinoPageRoute( 69 | builder: (ctx) => SettingPage())); 70 | }), 71 | MoreWidgets.buildDivider(), 72 | MoreWidgets.defaultListViewItem(Icons.exit_to_app, '退出', 73 | textColor: Colors.black, isDivider: false, onItemClick: (res) { 74 | DialogUtil.showBaseDialog(context, '确定退出登录吗?', rightClick: (res) { 75 | _logOut(); 76 | }); 77 | }), 78 | MoreWidgets.buildDivider(), 79 | ], 80 | ) 81 | // This trailing comma makes auto-formatting nicer for build methods. 82 | ); 83 | } 84 | 85 | List _actions(BuildContext context) { 86 | List actions = new List(); 87 | Widget widget = InkWell( 88 | child: Container( 89 | padding: EdgeInsets.only(right: 20, left: 20), 90 | child: Icon( 91 | Icons.add_a_photo, 92 | size: 22, 93 | )), 94 | onTap: () { 95 | PopupWindowUtil.showPhotoChosen(context); 96 | }); 97 | actions.add(widget); 98 | return actions; 99 | } 100 | 101 | Widget _getHeadPortrait() { 102 | if (null != imageChild) { 103 | return Image.file(imageChild, width: 62, height: 62, fit: BoxFit.fill); 104 | } 105 | return Image.asset( 106 | FileUtil.getImagePath('logo', dir: 'splash', format: 'png'), 107 | fit: BoxFit.fill, 108 | width: 62, 109 | height: 62); 110 | } 111 | 112 | _logOut() { 113 | widget.operation.setShowLoading(true); 114 | InteractNative.goNativeWithValue(InteractNative.methodNames['logout']) 115 | .then((success) { 116 | widget.operation.setShowLoading(false); 117 | if (success == true) { 118 | DialogUtil.buildToast('登出成功'); 119 | ObjectUtil.doExit(widget.rootContext); 120 | } else if (success is String) { 121 | DialogUtil.buildToast(success); 122 | } else { 123 | DialogUtil.buildToast('登出失败'); 124 | } 125 | }); 126 | } 127 | 128 | @override 129 | // TODO: implement wantKeepAlive 130 | bool get wantKeepAlive => true; 131 | } 132 | -------------------------------------------------------------------------------- /lib/ui/page/notification_settings_page.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/material.dart'; 2 | import 'package:flutter_nb/constants/constants.dart'; 3 | import 'package:flutter_nb/ui/widget/more_widgets.dart'; 4 | import 'package:flutter_nb/utils/device_util.dart'; 5 | import 'package:flutter_nb/utils/object_util.dart'; 6 | import 'package:flutter_nb/utils/sp_util.dart'; 7 | 8 | /* 9 | * 通知设置 10 | */ 11 | class NotificationSettingsPage extends StatelessWidget { 12 | @override 13 | Widget build(BuildContext context) { 14 | // TODO: implement build 15 | DeviceUtil.setBarStatus(true); 16 | return new NotificationSettings(); 17 | } 18 | } 19 | 20 | class NotificationSettings extends StatefulWidget { 21 | @override 22 | State createState() { 23 | // TODO: implement createState 24 | return new _NotificationSettingsState(); 25 | } 26 | } 27 | 28 | class _NotificationSettingsState extends State { 29 | @override 30 | Widget build(BuildContext buildContext) { 31 | // TODO: implement build 32 | return new MaterialApp( 33 | theme: ThemeData( 34 | primaryColor: ObjectUtil.getThemeColor(), 35 | platform: TargetPlatform.iOS), 36 | home: new Scaffold( 37 | backgroundColor: Colors.white, 38 | primary: true, 39 | body: SafeArea( 40 | child: Column( 41 | children: [ 42 | MoreWidgets.switchListViewItem(null, '接收新消息通知', 43 | value: SPUtil.getBool(Constants.NOTIFICATION_KEY_ALL) != 44 | false, onSwitch: (isCheck) { 45 | setState(() { 46 | print(isCheck); 47 | SPUtil.putBool(Constants.NOTIFICATION_KEY_ALL, isCheck); 48 | }); 49 | }), 50 | SPUtil.getBool(Constants.NOTIFICATION_KEY_ALL) != false 51 | ? Row( 52 | children: [ 53 | SizedBox( 54 | width: 20, 55 | ), 56 | Expanded( 57 | flex: 1, 58 | child: Column( 59 | children: [ 60 | MoreWidgets.switchListViewItem(null, '系统消息通知', 61 | value: SPUtil.getBool(Constants 62 | .NOTIFICATION_KEY_SYSTEM) != 63 | false, onSwitch: (isCheck) { 64 | setState(() { 65 | print(isCheck); 66 | SPUtil.putBool( 67 | Constants.NOTIFICATION_KEY_SYSTEM, 68 | isCheck); 69 | }); 70 | }), 71 | MoreWidgets.switchListViewItem(null, '聊天消息通知', 72 | value: SPUtil.getBool(Constants 73 | .NOTIFICATION_KEY_CHAT) != 74 | false, onSwitch: (isCheck) { 75 | setState(() { 76 | print(isCheck); 77 | SPUtil.putBool( 78 | Constants.NOTIFICATION_KEY_CHAT, 79 | isCheck); 80 | }); 81 | }), 82 | MoreWidgets.switchListViewItem(null, '其他消息通知', 83 | value: SPUtil.getBool(Constants 84 | .NOTIFICATION_KEY_OTHERS) != 85 | false, onSwitch: (isCheck) { 86 | setState(() { 87 | print(isCheck); 88 | SPUtil.putBool( 89 | Constants.NOTIFICATION_KEY_OTHERS, 90 | isCheck); 91 | }); 92 | }), 93 | ], 94 | )) 95 | ], 96 | ) 97 | : Text('') 98 | ], 99 | ), 100 | ), 101 | appBar: MoreWidgets.buildAppBar( 102 | buildContext, 103 | '新消息提醒', 104 | centerTitle: true, 105 | elevation: 2.0, 106 | leading: IconButton( 107 | icon: Icon(Icons.arrow_back), 108 | onPressed: () { 109 | Navigator.pop(context); 110 | }), 111 | ), 112 | )); 113 | } 114 | } 115 | -------------------------------------------------------------------------------- /lib/ui/page/pay_page.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/cupertino.dart'; 2 | import 'package:flutter/material.dart'; 3 | import 'package:flutter_nb/ui/widget/more_widgets.dart'; 4 | import 'package:flutter_nb/utils/object_util.dart'; 5 | 6 | class PayPage extends StatefulWidget { 7 | final title; 8 | 9 | PayPage(this.title); 10 | 11 | @override 12 | State createState() { 13 | // TODO: implement createState 14 | return PayState(); 15 | } 16 | } 17 | 18 | class PayState extends State { 19 | @override 20 | Widget build(BuildContext context) { 21 | // TODO: implement build 22 | return new Scaffold( 23 | appBar: MoreWidgets.buildAppBar(context, widget.title), 24 | body: Center( 25 | child: RaisedButton( 26 | textColor: Colors.white, 27 | color: ObjectUtil.getThemeSwatchColor(), 28 | padding: EdgeInsets.all(12.0), 29 | shape: new StadiumBorder( 30 | side: new BorderSide( 31 | style: BorderStyle.solid, 32 | color: ObjectUtil.getThemeSwatchColor(), 33 | )), 34 | child: 35 | Text(widget.title + "页面按钮", style: new TextStyle(fontSize: 16.0)), 36 | onPressed: () { 37 | var name = widget.title; 38 | switch (name) { 39 | case "A": 40 | name = "B"; 41 | break; 42 | case "B": 43 | name = "C"; 44 | break; 45 | case "C": 46 | name = "D"; 47 | break; 48 | case "D": 49 | name = "E"; 50 | break; 51 | case "E": 52 | name = "F"; 53 | break; 54 | case "F": 55 | Navigator.popUntil(context, ModalRoute.withName("C")); 56 | return; 57 | } 58 | Navigator.push( 59 | context, 60 | new CupertinoPageRoute( 61 | builder: (ctx) => PayPage(name), 62 | settings: RouteSettings(name: name))); 63 | }, 64 | ), 65 | ), 66 | ); 67 | } 68 | } 69 | -------------------------------------------------------------------------------- /lib/ui/page/photo_view_page.dart: -------------------------------------------------------------------------------- 1 | import 'dart:io'; 2 | 3 | import 'package:flukit/flukit.dart'; 4 | import 'package:flutter/material.dart'; 5 | import 'package:flutter_nb/resource/colors.dart'; 6 | import 'package:flutter_nb/utils/object_util.dart'; 7 | import 'package:photo_view/photo_view.dart'; 8 | 9 | /* 10 | * 图片查看 11 | */ 12 | class PhotoViewPage extends StatelessWidget { 13 | final List images; 14 | 15 | PhotoViewPage({Key key, this.images}) : super(key: key); 16 | 17 | @override 18 | Widget build(BuildContext context) { 19 | // TODO: implement build 20 | return _buildWidget(context); 21 | } 22 | 23 | Widget _buildWidget(BuildContext context) { 24 | List _listWidget = new List(); 25 | for (String url in images) { 26 | _listWidget.add(_itemWidget(url)); 27 | } 28 | return Container( 29 | child: GestureDetector( 30 | child: Swiper( 31 | autoStart: false, 32 | circular: false, 33 | indicator: CircleSwiperIndicator( 34 | radius: 4.0, 35 | padding: EdgeInsets.only(bottom: 20.0), 36 | itemColor: ColorT.gray_99, 37 | itemActiveColor: ObjectUtil.getThemeSwatchColor()), 38 | children: _listWidget), 39 | onTap: () { 40 | Navigator.pop(context); 41 | }, 42 | )); 43 | } 44 | 45 | Widget _itemWidget(String url) { 46 | return PhotoView( 47 | imageProvider: 48 | url.startsWith("http") ? NetworkImage(url) : FileImage(File(url)), 49 | ); 50 | } 51 | } 52 | -------------------------------------------------------------------------------- /lib/ui/page/quality_page.dart: -------------------------------------------------------------------------------- 1 | import 'dart:math'; 2 | import 'dart:ui'; 3 | 4 | import 'package:flutter/material.dart'; 5 | import 'package:flutter_nb/resource/colors.dart'; 6 | import 'package:flutter_nb/ui/widget/more_widgets.dart'; 7 | import 'package:flutter_nb/utils/dialog_util.dart'; 8 | import 'package:flutter_nb/utils/file_util.dart'; 9 | import 'package:flutter_nb/utils/object_util.dart'; 10 | import 'package:flutter_staggered_grid_view/flutter_staggered_grid_view.dart'; 11 | 12 | class QualityPage extends StatefulWidget { 13 | @override 14 | State createState() { 15 | // TODO: implement createState 16 | return QualityPageState(); 17 | } 18 | } 19 | 20 | class QualityPageState extends State { 21 | @override 22 | Widget build(BuildContext context) { 23 | // TODO: implement build 24 | return layout(context); 25 | } 26 | 27 | Widget layout(BuildContext context) { 28 | return Material( 29 | child: CustomScrollView( 30 | slivers: [ 31 | //AppBar,包含一个导航栏 32 | SliverAppBar( 33 | pinned: true, 34 | expandedHeight: 250.0, 35 | flexibleSpace: FlexibleSpaceBar( 36 | title: const Text('干货'), 37 | background: Image.asset( 38 | FileUtil.getImagePath('img_fest', format: 'png'), 39 | fit: BoxFit.cover, 40 | ), 41 | ), 42 | ), 43 | 44 | SliverPadding( 45 | padding: const EdgeInsets.all(8.0), 46 | sliver: new SliverGrid( 47 | //Grid 48 | gridDelegate: new SliverGridDelegateWithFixedCrossAxisCount( 49 | crossAxisCount: 2, //Grid按两列显示 50 | mainAxisSpacing: 10.0, 51 | crossAxisSpacing: 10.0, 52 | childAspectRatio: 4.0, 53 | ), 54 | delegate: new SliverChildBuilderDelegate( 55 | (BuildContext context, int index) { 56 | //创建子widget 57 | return new Container( 58 | alignment: Alignment.center, 59 | color: Colors.cyan[100 * (index % 9)], 60 | child: new Text('grid item $index'), 61 | ); 62 | }, 63 | childCount: 20, 64 | ), 65 | ), 66 | ), 67 | //List 68 | new SliverFixedExtentList( 69 | itemExtent: 50.0, 70 | delegate: new SliverChildBuilderDelegate( 71 | (BuildContext context, int index) { 72 | //创建列表项 73 | return new Container( 74 | alignment: Alignment.center, 75 | color: Colors.lightBlue[100 * (index % 9)], 76 | child: new Text('list item $index'), 77 | ); 78 | }, childCount: 50 //50个列表项 79 | ), 80 | ), 81 | ], 82 | ), 83 | ); 84 | } 85 | } 86 | -------------------------------------------------------------------------------- /lib/ui/page/setting_page.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/cupertino.dart'; 2 | import 'package:flutter/material.dart'; 3 | import 'package:flutter_nb/ui/page/about_page.dart'; 4 | import 'package:flutter_nb/ui/page/base/theme_state.dart'; 5 | import 'package:flutter_nb/ui/page/change_theme_page.dart'; 6 | import 'package:flutter_nb/ui/page/notification_settings_page.dart'; 7 | import 'package:flutter_nb/ui/widget/more_widgets.dart'; 8 | import 'package:flutter_nb/utils/device_util.dart'; 9 | import 'package:flutter_nb/utils/dialog_util.dart'; 10 | import 'package:flutter_nb/utils/interact_vative.dart'; 11 | import 'package:flutter_nb/utils/object_util.dart'; 12 | 13 | /* 14 | * 设置页面 15 | */ 16 | class SettingPage extends StatelessWidget { 17 | @override 18 | Widget build(BuildContext context) { 19 | // TODO: implement build 20 | DeviceUtil.setBarStatus(true); 21 | return new Setting(); 22 | } 23 | } 24 | 25 | class Setting extends StatefulWidget { 26 | @override 27 | State createState() { 28 | // TODO: implement createState 29 | return new _SettingState(); 30 | } 31 | } 32 | 33 | class _SettingState extends ThemeState { 34 | @override 35 | Widget build(BuildContext context) { 36 | // TODO: implement build 37 | return new MaterialApp( 38 | theme: ThemeData( 39 | primaryColor: ObjectUtil.getThemeColor(), 40 | platform: TargetPlatform.iOS), 41 | home: new Scaffold( 42 | backgroundColor: Colors.white, 43 | primary: true, 44 | body: SafeArea( 45 | child: ListView( 46 | children: [ 47 | MoreWidgets.defaultListViewItem(null, '切换主题', 48 | textColor: Colors.black, onItemClick: (res) { 49 | Navigator.push( 50 | context, 51 | new CupertinoPageRoute( 52 | builder: (ctx) => ChangeThemePage())); 53 | }), 54 | MoreWidgets.defaultListViewItem(null, '清理缓存', 55 | textColor: Colors.black, onItemClick: (res) { 56 | DialogUtil.buildToast('清理完成'); 57 | }), 58 | MoreWidgets.defaultListViewItem(null, '新消息提醒', 59 | textColor: Colors.black, onItemClick: (res) { 60 | Navigator.push( 61 | context, 62 | new CupertinoPageRoute( 63 | builder: (ctx) => NotificationSettingsPage())); 64 | }), 65 | MoreWidgets.defaultListViewItem(null, '关于', 66 | textColor: Colors.black, onItemClick: (res) { 67 | Navigator.push( 68 | context, 69 | new CupertinoPageRoute( 70 | builder: (ctx) => AboutPage())); 71 | }), 72 | ], 73 | )), 74 | appBar: MoreWidgets.buildAppBar( 75 | context, 76 | '设置', 77 | centerTitle: true, 78 | elevation: 2.0, 79 | leading: IconButton( 80 | icon: Icon(Icons.arrow_back), 81 | onPressed: () { 82 | Navigator.pop(context); 83 | }), 84 | ), 85 | )); 86 | } 87 | 88 | @override 89 | void notify(Object type) { 90 | // TODO: implement notify 91 | setState(() { 92 | if (type == InteractNative.RESET_THEME_COLOR) { 93 | init(); 94 | } 95 | }); 96 | } 97 | } 98 | -------------------------------------------------------------------------------- /lib/ui/widget/loading_widget.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/material.dart'; 2 | import 'package:flutter_nb/resource/colors.dart'; 3 | import 'package:flutter_nb/utils/functions.dart'; 4 | 5 | /* 6 | * loading page 7 | */ 8 | class LoadingScaffold extends StatefulWidget { 9 | final bool isShowLoadingAtNow; 10 | final BackPressType backPressType; 11 | final BackPressCallback backPressCallback; 12 | final Operation operation; 13 | final Widget child; 14 | 15 | const LoadingScaffold( 16 | {Key key, 17 | this.isShowLoadingAtNow: false, 18 | this.backPressType: BackPressType.CLOSE_CURRENT, 19 | this.backPressCallback, 20 | @required this.operation, 21 | @required this.child}) 22 | : super(key: key); 23 | 24 | @override 25 | State createState() { 26 | // TODO: implement createState 27 | return new LoadingState(); 28 | } 29 | } 30 | 31 | class LoadingState extends State { 32 | VoidCallback listener; 33 | Future _onWillPop() => new Future.value(false); //禁掉返回按钮和右滑关闭 34 | 35 | @override 36 | void initState() { 37 | // TODO: implement initState 38 | super.initState(); 39 | widget.operation._notifier = ValueNotifier(false); 40 | if (widget.isShowLoadingAtNow != true) { 41 | widget.operation._notifier.value = false; 42 | } else { 43 | widget.operation._notifier.value = true; 44 | } 45 | listener = () { 46 | setState(() { 47 | _hideKeyBord(); 48 | }); 49 | }; 50 | widget.operation._notifier.addListener(listener); 51 | } 52 | 53 | void _hideKeyBord() { 54 | FocusScope.of(context).requestFocus(FocusNode()); 55 | } 56 | 57 | @override 58 | void dispose() { 59 | // TODO: implement dispose 60 | super.dispose(); 61 | if (null != listener) { 62 | widget.operation._notifier.removeListener(listener); 63 | } 64 | } 65 | 66 | @override 67 | Widget build(BuildContext context) { 68 | // TODO: implement build 69 | return new Stack( 70 | children: [ 71 | new Offstage( 72 | offstage: false, 73 | child: widget.child, 74 | ), 75 | new Offstage( 76 | offstage: widget.operation._notifier.value != true, 77 | child: widget.operation._notifier.value != true 78 | ? _loadingWidget() 79 | : _WillPopScopeWidget(), //显示loading,则禁掉返回按钮和右滑关闭 80 | ) 81 | ], 82 | ); 83 | } 84 | 85 | Widget _WillPopScopeWidget() { 86 | return new WillPopScope( 87 | onWillPop: () { 88 | if (null != widget.backPressCallback) { 89 | widget.backPressCallback(widget.backPressType); 90 | } 91 | if (widget.backPressType == BackPressType.SBLOCK) { 92 | _onWillPop(); //阻止返回 93 | } else if (widget.backPressType == BackPressType.CLOSE_CURRENT) { 94 | widget.operation.setShowLoading(false); //关闭当前页 95 | } else if (widget.backPressType == BackPressType.CLOSE_PARENT) { 96 | Navigator.pop(context); //关闭当前页及当前页的父页 97 | } 98 | }, 99 | child: _loadingWidget()); 100 | } 101 | 102 | Widget _loadingWidget() { 103 | return new Container( 104 | alignment: Alignment.center, 105 | color: ColorT.transparent_50, 106 | width: double.infinity, 107 | height: double.infinity, 108 | child: ClipRRect( 109 | borderRadius: BorderRadius.circular(10.0), 110 | child: new Container( 111 | alignment: Alignment.center, 112 | color: ColorT.transparent_80, 113 | width: 220.0, 114 | height: 90.0, 115 | child: Row( 116 | mainAxisAlignment: MainAxisAlignment.center, 117 | children: [ 118 | SizedBox( 119 | width: 28.0, 120 | height: 28.0, 121 | child: CircularProgressIndicator( 122 | valueColor: AlwaysStoppedAnimation(Colors.white), 123 | strokeWidth: 2.5, 124 | ), 125 | ), 126 | SizedBox(width: 15.0), 127 | Text( 128 | '玩命加载中...', 129 | style: new TextStyle( 130 | fontSize: 17.0, 131 | color: Colors.white, 132 | letterSpacing: 0.8, 133 | fontWeight: FontWeight.normal, 134 | decoration: TextDecoration.none, 135 | ), 136 | ) 137 | ], 138 | ), 139 | ))); 140 | } 141 | } 142 | 143 | enum BackPressType { 144 | SBLOCK, //阻止返回 145 | CLOSE_CURRENT, //关闭当前页 146 | CLOSE_PARENT //关闭当前页及当前页的父页 147 | } 148 | 149 | class Operation { 150 | ValueNotifier _notifier; 151 | 152 | void setShowLoading(bool isShow) { 153 | _notifier.value = isShow; 154 | } 155 | 156 | bool get isShow => _notifier.value; 157 | } 158 | -------------------------------------------------------------------------------- /lib/ui/widget/popupwindow_widget.dart: -------------------------------------------------------------------------------- 1 | import 'dart:io'; 2 | 3 | import 'package:flutter/material.dart'; 4 | import 'package:flutter_nb/ui/widget/more_widgets.dart'; 5 | import 'package:flutter_nb/utils/dialog_util.dart'; 6 | import 'package:flutter_nb/utils/functions.dart'; 7 | import 'package:flutter_nb/utils/image_util.dart'; 8 | import 'package:flutter_nb/utils/interact_vative.dart'; 9 | 10 | class PopupWindowUtil { 11 | /* 12 | * 选择相机相册 13 | */ 14 | static Future showPhotoChosen(BuildContext context, {OnCallBack onCallBack}) { 15 | return showModalBottomSheet( 16 | context: context, 17 | builder: (BuildContext context) { 18 | return new Column( 19 | mainAxisSize: MainAxisSize.min, 20 | children: [ 21 | new ListTile( 22 | leading: new Icon(Icons.photo_camera), 23 | title: new Text("拍照"), 24 | onTap: () async { 25 | Navigator.pop(context); 26 | ImageUtil.getCameraImage().then((image) { 27 | if (onCallBack != null) { 28 | onCallBack(image); 29 | } 30 | }); 31 | }, 32 | ), 33 | MoreWidgets.buildDivider(height: 0), 34 | new ListTile( 35 | leading: new Icon(Icons.photo_library), 36 | title: new Text("相册"), 37 | onTap: () async { 38 | Navigator.pop(context); 39 | ImageUtil.getGalleryImage().then((image) { 40 | if (onCallBack != null) { 41 | onCallBack(image); 42 | } 43 | }); 44 | }, 45 | ), 46 | ], 47 | ); 48 | }); 49 | } 50 | 51 | /* 52 | * 选择拍照片、拍视频 53 | */ 54 | static Future showCameraChosen(BuildContext context, {OnCallBackWithType onCallBack}) { 55 | return showModalBottomSheet( 56 | context: context, 57 | builder: (BuildContext context) { 58 | return new Column( 59 | mainAxisSize: MainAxisSize.min, 60 | children: [ 61 | new ListTile( 62 | leading: new Icon(Icons.photo_camera), 63 | title: new Text("拍照片"), 64 | onTap: () async { 65 | Navigator.pop(context); 66 | ImageUtil.getCameraImage().then((image) { 67 | if (onCallBack != null) { 68 | onCallBack(1, image); 69 | } 70 | }); 71 | }, 72 | ), 73 | MoreWidgets.buildDivider(height: 0), 74 | new ListTile( 75 | leading: new Icon(Icons.photo_library), 76 | title: new Text("拍视频"), 77 | onTap: () async { 78 | Navigator.pop(context); 79 | InteractNative.goNativeWithValue( 80 | InteractNative.methodNames['shootVideo'], null) 81 | .then((success) { 82 | if (success != null && success is Map) { 83 | if (onCallBack != null) { 84 | onCallBack(2, success); 85 | } 86 | } else { 87 | DialogUtil.buildToast(success.toString()); 88 | } 89 | }); 90 | }, 91 | ), 92 | ], 93 | ); 94 | }); 95 | } 96 | } 97 | -------------------------------------------------------------------------------- /lib/utils/data_proxy.dart: -------------------------------------------------------------------------------- 1 | /* 2 | * 数据传输代理 3 | */ 4 | import 'package:flutter/widgets.dart'; 5 | import 'package:flutter_nb/database/database_control.dart'; 6 | import 'package:flutter_nb/ui/widget/loading_widget.dart'; 7 | import 'package:flutter_nb/utils/dialog_util.dart'; 8 | import 'package:flutter_nb/utils/interact_vative.dart'; 9 | import 'package:flutter_nb/utils/object_util.dart'; 10 | 11 | class DataProxy { 12 | static final DataProxy _dataProxy = new DataProxy._init(); 13 | BuildContext _context; 14 | Operation _operation; 15 | 16 | static DataProxy build() { 17 | return _dataProxy; 18 | } 19 | 20 | DataProxy._init(); 21 | 22 | void setContext(BuildContext context, Operation operation) { 23 | _context = context; 24 | _operation = operation; 25 | } 26 | 27 | /* 28 | * 启动与原生的交互 29 | */ 30 | void connect(BuildContext context) { 31 | _context = context; 32 | InteractNative.dealNativeWithValue(_onEvent, onError: _onError); 33 | } 34 | 35 | /* 36 | * 断开与原生的交互 37 | */ 38 | void unConnect() { 39 | if (null != InteractNative.streamSubscription) { 40 | InteractNative.streamSubscription.cancel(); 41 | } 42 | } 43 | 44 | void _onEvent(Object event) { 45 | if (event == null || !(event is Map)) { 46 | return; 47 | } 48 | Map res = event; 49 | if (res.containsKey('string')) { 50 | if (res.containsValue('onConnected')) { 51 | //已连接 52 | } else if (res.containsValue('user_removed')) { 53 | //显示帐号已经被移除 54 | DialogUtil.buildToast('flutter帐号已经被移除'); 55 | ObjectUtil.doExit(_context); 56 | } else if (res.containsValue('user_login_another_device')) { 57 | //显示帐号在其他设备登录 58 | DialogUtil.buildToast('flutter帐号在其他设备登录'); 59 | ObjectUtil.doExit(_context); 60 | } else if (res.containsValue('disconnected_to_service')) { 61 | //连接不到聊天服务器 62 | // DialogUtil.buildToast('连接不到聊天服务器'); 63 | } else if (res.containsValue('no_net')) { 64 | //当前网络不可用,请检查网络设置 65 | DialogUtil.buildToast('当前网络不可用,请检查网络设置'); 66 | } else if (res.containsValue('onDestroy')) { 67 | //APP执行onDestroy 68 | unConnect(); 69 | } 70 | } else if (res.containsKey('json')) { 71 | DataBaseControl.decodeData(res.values.elementAt(0), 72 | context: _context, 73 | operation: _operation, callBack: (type, unReadCount, entity) async{ 74 | entity.isUnreadCount = unReadCount; 75 | //触发点MessageState 76 | InteractNative.getMessageEventSink().add(entity); 77 | }); //解析数据保存数据库 78 | } 79 | } 80 | 81 | void _onError(Object error) { 82 | DialogUtil.buildToast(error.toString()); 83 | } 84 | } 85 | -------------------------------------------------------------------------------- /lib/utils/device_util.dart: -------------------------------------------------------------------------------- 1 | import 'dart:io'; 2 | 3 | import 'package:flutter/material.dart'; 4 | import 'package:flutter/services.dart'; 5 | 6 | class DeviceUtil { 7 | /* 8 | * 以下两行设置android状态栏为透明的沉浸。写在组件渲染之后,是为了在渲染后进行set赋值, 9 | * 覆盖状态栏,写在渲染之前MaterialApp组件会覆盖掉这个值。 10 | */ 11 | static setBarStatus(bool isDarkIcon, {Color color: Colors.transparent}) async{ 12 | if (Platform.isAndroid) { 13 | if (isDarkIcon) { 14 | SystemUiOverlayStyle systemUiOverlayStyle = SystemUiOverlayStyle( 15 | statusBarColor: color, statusBarIconBrightness: Brightness.dark); 16 | SystemChrome.setSystemUIOverlayStyle(systemUiOverlayStyle); 17 | } else { 18 | SystemUiOverlayStyle systemUiOverlayStyle = SystemUiOverlayStyle( 19 | statusBarColor: color, statusBarIconBrightness: Brightness.light); 20 | SystemChrome.setSystemUIOverlayStyle(systemUiOverlayStyle); 21 | } 22 | } 23 | } 24 | 25 | /* 26 | *获取屏幕宽度 27 | */ 28 | static double getScreenWidth(BuildContext context) { 29 | return MediaQuery.of(context).size.width; 30 | } 31 | 32 | /* 33 | * 获取屏幕高度 34 | */ 35 | static double getScreenHeight(BuildContext context) { 36 | return MediaQuery.of(context).size.height; 37 | } 38 | 39 | /* 40 | *获取系统状态栏高度 41 | */ 42 | static double getSysStatsHeight(BuildContext context) { 43 | return MediaQuery.of(context).padding.top; 44 | } 45 | } 46 | -------------------------------------------------------------------------------- /lib/utils/dialog_util.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/material.dart'; 2 | import 'package:flutter_nb/resource/colors.dart'; 3 | import 'package:flutter_nb/utils/functions.dart'; 4 | import 'package:flutter_nb/utils/object_util.dart'; 5 | import 'package:fluttertoast/fluttertoast.dart'; 6 | 7 | class DialogUtil { 8 | static buildToast(String str) { 9 | Fluttertoast.showToast( 10 | msg: str, 11 | toastLength: Toast.LENGTH_SHORT, 12 | gravity: ToastGravity.CENTER, 13 | timeInSecForIos: 1, 14 | backgroundColor: ObjectUtil.getThemeSwatchColor(), 15 | textColor: Colors.white); 16 | } 17 | 18 | static buildSnakeBar(BuildContext context, String str) { 19 | final snackBar = new SnackBar( 20 | content: new Text(str), 21 | duration: Duration(milliseconds: 1500), 22 | backgroundColor: ObjectUtil.getThemeSwatchColor()); 23 | Scaffold.of(context).showSnackBar( 24 | snackBar); //Scaffold.of(context)是一个state,context对应的state必须的暴露的 25 | } 26 | 27 | //如果context在Scaffold之前,弹不出请用这个 28 | //使用GlobalKey开销较大,如果有其他可选方案,应尽量避免使用它 29 | static buildSnakeBarByKey(String str, GlobalKey key) { 30 | final snackBar = new SnackBar( 31 | content: new Text(str), 32 | duration: Duration(milliseconds: 1500), 33 | backgroundColor: ObjectUtil.getThemeSwatchColor()); 34 | key.currentState.showSnackBar(snackBar); 35 | } 36 | 37 | /* 38 | * 普通dialog 39 | */ 40 | static showBaseDialog(BuildContext context, String content, 41 | {String title = '提示', 42 | String left = '取消', 43 | String right = '确认', 44 | OnItemClick leftClick, 45 | OnItemClick rightClick}) { 46 | showDialog( 47 | context: context, 48 | barrierDismissible: true, //点击对话框barrier(遮罩)时是否关闭它 49 | builder: (BuildContext context) => new AlertDialog( 50 | shape: RoundedRectangleBorder( 51 | side: BorderSide.none, 52 | borderRadius: BorderRadius.all(Radius.circular(10))), 53 | title: ObjectUtil.isEmpty(title) 54 | ? SizedBox( 55 | width: 0, 56 | height: 10, 57 | ) 58 | : new Text(title), 59 | titlePadding: EdgeInsets.fromLTRB(20, 10, 20, 0), 60 | contentPadding: EdgeInsets.fromLTRB(20, 10, 20, 0), 61 | content: new Text(content), 62 | actions: [ 63 | ObjectUtil.isEmpty(left) 64 | ? SizedBox( 65 | width: 0, 66 | height: 15, 67 | ) 68 | : FlatButton( 69 | child: new Text( 70 | left, 71 | style: TextStyle(color: ColorT.app_main), 72 | ), 73 | onPressed: () { 74 | Navigator.of(context).pop(); 75 | if (null != leftClick) { 76 | leftClick(null); 77 | } 78 | }, 79 | ), 80 | ObjectUtil.isEmpty(right) 81 | ? SizedBox( 82 | width: 0, 83 | height: 15, 84 | ) 85 | : FlatButton( 86 | child: new Text( 87 | right, 88 | style: TextStyle(color: ObjectUtil.getThemeColor()), 89 | ), 90 | onPressed: () { 91 | Navigator.of(context).pop(); 92 | if (null != rightClick) { 93 | rightClick(null); 94 | } 95 | }, 96 | ) 97 | ])); 98 | } 99 | } 100 | -------------------------------------------------------------------------------- /lib/utils/file_util.dart: -------------------------------------------------------------------------------- 1 | class FileUtil { 2 | static String getImagePath(String name, 3 | {String dir: 'default', String format: 'jpg'}) { 4 | return 'assets/images/$dir/$name.$format'; 5 | } 6 | } 7 | -------------------------------------------------------------------------------- /lib/utils/functions.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/material.dart'; 2 | import 'package:flutter_nb/entity/message_entity.dart'; 3 | import 'package:flutter_nb/ui/widget/loading_widget.dart'; 4 | 5 | class Functions {} 6 | 7 | typedef BackPressCallback = Future Function(BackPressType); //按返回键时触发 8 | 9 | typedef OnChangedCallback = Future Function(); //输入内容变化时触发 10 | 11 | typedef OnSubmitCallback = Future Function( 12 | Object, Operation, BuildContext); //输入完成时触发 13 | 14 | typedef OnItemClick = Future Function(Object); //控件点击时触发 15 | 16 | typedef OnItemDoubleClick = Future Function(Object); //控件点击时触发 17 | 18 | typedef OnItemLongClick = Future Function(Object); //控件点击时触发 19 | 20 | typedef OnCallBack = Future Function(Object); 21 | 22 | typedef OnCallBackWithType = Future Function(int, Object); 23 | 24 | typedef OnUpdateCallback = Future Function( 25 | Object, int, MessageEntity); //数据更新时触发 26 | -------------------------------------------------------------------------------- /lib/utils/image_util.dart: -------------------------------------------------------------------------------- 1 | import 'package:image_picker/image_picker.dart'; 2 | 3 | class ImageUtil { 4 | /* 5 | * 从相机取图片 6 | */ 7 | static Future getCameraImage() async { 8 | return await ImagePicker.pickImage(source: ImageSource.camera); 9 | } 10 | 11 | /* 12 | * 从相册取图片 13 | */ 14 | static Future getGalleryImage() async { 15 | return await ImagePicker.pickImage(source: ImageSource.gallery); 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /lib/utils/interact_vative.dart: -------------------------------------------------------------------------------- 1 | import 'dart:async'; 2 | 3 | import 'package:flutter/services.dart'; 4 | import 'package:flutter_nb/entity/message_entity.dart'; 5 | import 'package:rxdart/rxdart.dart'; 6 | 7 | class InteractNative { 8 | /* 通道名称,必须与原生注册的一致*/ 9 | static const flutter_to_native = const MethodChannel( 10 | 'com.bhm.flutter.flutternb.plugins/flutter_to_native'); 11 | static const native_to_flutter = 12 | const EventChannel('com.bhm.flutter.flutternb.plugins/native_to_flutter'); 13 | 14 | static StreamSubscription streamSubscription; 15 | 16 | static BehaviorSubject _appEvent = 17 | BehaviorSubject(); //APP内部通信对象 18 | static BehaviorSubject _messageEvent = 19 | BehaviorSubject(); //APP内部通信对象 20 | 21 | static const int RESET_THEME_COLOR = 1; 22 | static const int CHANGE_PAGE_TO_MAIN = 2; 23 | static const int CHANGE_PAGE_TO_LOGIN = 3; 24 | static const String SYSTEM_MESSAGE_HAS_READ = 'system_message_has_read'; 25 | static const String SYSTEM_MESSAGE_DELETE_ALL = 'system_message_delete_all'; 26 | static const String SYSTEM_MESSAGE_DELETE = 'system_message_delete'; 27 | /* 28 | * 方法名称,必须与flutter注册的一致 29 | */ 30 | static final Map methodNames = const { 31 | 'register': 'register', //注册 32 | 'login': 'login', //登录 33 | 'logout': 'logout', //退出登录 34 | 'autoLogin': 'autoLogin', //自动登录 35 | 'backPress': 'backPress', //物理返回键触发,主要是让应用返回桌面,而不是关闭应用 36 | 'addFriends': 'addFriends', //添加好友 37 | 'refusedFriends': 'refusedFriends', //拒绝好友添加邀请 38 | 'acceptedFriends': 'acceptedFriends', //同意好友添加邀请 39 | 'getAllContacts': 'getAllContacts', //获取好友列表 40 | 'addUserToBlackList': 'addUserToBlackList', //拉入黑名单 41 | 'getBlackListUsernames': 'getBlackListUsernames', //黑名单列表 42 | 'getBlackListUsernamesFromDataBase': 43 | 'getBlackListUsernamesFromDataBase', //黑名单列表(数据库) 44 | 'removeUserFromBlackList': 'removeUserFromBlackList', //移出黑名单 45 | 'deleteContact': 'deleteContact', //删除好友 46 | 'sendMessage': 'sendMessage', //发送聊天消息 47 | 'createFiles': 'createFiles', //创建APP文件夹 48 | 'shootVideo': 'shootVideo', //拍摄小视频 49 | }; 50 | 51 | /* 52 | * 调用原生的方法(带参) 53 | */ 54 | static Future goNativeWithValue(String methodName, 55 | [Map map]) async { 56 | dynamic future; 57 | try { 58 | if (null == map) { 59 | future = await flutter_to_native.invokeMethod(methodName); 60 | } else { 61 | future = await flutter_to_native.invokeMethod(methodName, map); 62 | } 63 | } on PlatformException catch (e) { 64 | future = false; 65 | } 66 | return future; 67 | } 68 | 69 | /* 70 | * 原生回调的方法(带参) 71 | */ 72 | static StreamSubscription dealNativeWithValue(Function event, 73 | {Function onError, void onDone(), bool cancelOnError}) { 74 | streamSubscription = native_to_flutter 75 | .receiveBroadcastStream() 76 | .listen(event, onError: onError); 77 | return streamSubscription; 78 | } 79 | 80 | /* 81 | * 自定义通信 82 | */ 83 | static BehaviorSubject initAppEvent() { 84 | if (null == _appEvent || _appEvent.isClosed) { 85 | _appEvent = BehaviorSubject(); 86 | } 87 | return _appEvent; 88 | } 89 | 90 | /* 91 | * 自定义通信 92 | */ 93 | static BehaviorSubject initMessageEvent() { 94 | if (null == _messageEvent || _messageEvent.isClosed) { 95 | _messageEvent = BehaviorSubject(); 96 | } 97 | return _messageEvent; 98 | } 99 | 100 | /*发送*/ 101 | static Sink getMessageEventSink() { 102 | initMessageEvent(); 103 | return _messageEvent.sink; 104 | } 105 | 106 | /*发送*/ 107 | static Sink getAppEventSink() { 108 | initAppEvent(); 109 | return _appEvent.sink; 110 | } 111 | 112 | /*接收*/ 113 | static Stream getAppEventStream() { 114 | initAppEvent(); 115 | return _appEvent.stream; 116 | } 117 | 118 | /*接收*/ 119 | static Stream getMessageEventStream() { 120 | initMessageEvent(); 121 | return _messageEvent.stream; 122 | } 123 | 124 | /* 125 | * 退出登录时,需要关闭 126 | */ 127 | static void closeMessageStream() { 128 | if (null != _messageEvent) { 129 | _messageEvent.close(); 130 | } 131 | } 132 | 133 | static void closeAppStream() { 134 | if (null != _appEvent) { 135 | _appEvent.close(); 136 | } 137 | } 138 | } 139 | -------------------------------------------------------------------------------- /lib/utils/sp_util.dart: -------------------------------------------------------------------------------- 1 | import 'dart:async'; 2 | import 'dart:convert'; 3 | import 'package:shared_preferences/shared_preferences.dart'; 4 | import 'package:synchronized/synchronized.dart'; 5 | 6 | class SPUtil { 7 | static SPUtil _spUtil; 8 | static SharedPreferences _prefs; 9 | static Lock _lock = new Lock(); 10 | 11 | SPUtil._(); 12 | 13 | Future _init() async { 14 | _prefs = await SharedPreferences.getInstance(); 15 | } 16 | 17 | static Future getInstance() async { 18 | if (null == _spUtil) { 19 | await _lock.synchronized(() async { 20 | if (null == _spUtil) { 21 | var spUtil = SPUtil._(); 22 | await spUtil._init(); 23 | _spUtil = spUtil; 24 | } 25 | }); 26 | } 27 | return _spUtil; 28 | } 29 | 30 | static String getString(String key) { 31 | if (_prefs == null) return null; 32 | return _prefs.getString(key); 33 | } 34 | 35 | static Future putString(String key, String value) { 36 | if (_prefs == null) return null; 37 | return _prefs.setString(key, value); 38 | } 39 | 40 | static bool getBool(String key) { 41 | if (_prefs == null) return null; 42 | return _prefs.getBool(key); 43 | } 44 | 45 | static Future putBool(String key, bool value) { 46 | if (_prefs == null) return null; 47 | return _prefs.setBool(key, value); 48 | } 49 | 50 | static int getInt(String key) { 51 | if (_prefs == null) return null; 52 | return _prefs.getInt(key); 53 | } 54 | 55 | static Future putInt(String key, int value) { 56 | if (_prefs == null) return null; 57 | return _prefs.setInt(key, value); 58 | } 59 | 60 | static double getDouble(String key) { 61 | if (_prefs == null) return null; 62 | return _prefs.getDouble(key); 63 | } 64 | 65 | static Future putDouble(String key, double value) { 66 | if (_prefs == null) return null; 67 | return _prefs.setDouble(key, value); 68 | } 69 | 70 | static List getStringList(String key) { 71 | return _prefs.getStringList(key); 72 | } 73 | 74 | static Future putStringList(String key, List value) { 75 | if (_prefs == null) return null; 76 | return _prefs.setStringList(key, value); 77 | } 78 | 79 | static dynamic getDynamic(String key) { 80 | if (_prefs == null) return null; 81 | return _prefs.get(key); 82 | } 83 | 84 | static Set getKeys() { 85 | if (_prefs == null) return null; 86 | return _prefs.getKeys(); 87 | } 88 | 89 | static Future remove(String key) { 90 | if (_prefs == null) return null; 91 | return _prefs.remove(key); 92 | } 93 | 94 | static Future clear() { 95 | if (_prefs == null) return null; 96 | return _prefs.clear(); 97 | } 98 | 99 | static void putObject(String key, Object value) { 100 | switch (T) { 101 | case int: 102 | putInt(key, value); 103 | break; 104 | case double: 105 | putDouble(key, value); 106 | break; 107 | case bool: 108 | putBool(key, value); 109 | break; 110 | case String: 111 | putString(key, value); 112 | break; 113 | case List: 114 | putStringList(key, value); 115 | break; 116 | default: 117 | putString(key, value == null ? "" : json.encode(value)); 118 | break; 119 | } 120 | } 121 | } 122 | 123 | -------------------------------------------------------------------------------- /lib/utils/timer_util.dart: -------------------------------------------------------------------------------- 1 | import 'dart:async'; 2 | 3 | import 'dart:math'; 4 | 5 | ///timer callback.(millisUntilFinished 毫秒). 6 | typedef void OnTimerTickCallback(int millisUntilFinished); 7 | 8 | class TimerUtil { 9 | TimerUtil({this.mInterval: Duration.millisecondsPerSecond, this.mTotalTime}); 10 | 11 | ///Timer. 12 | Timer _mTimer; 13 | 14 | ///Is Timer active. 15 | ///Timer是否启动. 16 | bool _isActive = false; 17 | 18 | ///Timer interval (unit millisecond,def: 1000 millisecond). 19 | ///Timer间隔 单位毫秒,默认1000毫秒(1秒). 20 | int mInterval; 21 | 22 | ///countdown totalTime. 23 | ///倒计时总时间 24 | int mTotalTime; //单位毫秒 25 | 26 | OnTimerTickCallback _onTimerTickCallback; 27 | 28 | ///set Timer interval. (unit millisecond). 29 | ///设置Timer间隔. 30 | void setInterval(int interval) { 31 | if (interval <= 0) interval = Duration.millisecondsPerSecond; 32 | mInterval = interval; 33 | } 34 | 35 | ///set countdown totalTime. (unit millisecond). 36 | ///设置倒计时总时间. 37 | void setTotalTime(int totalTime) { 38 | if (totalTime <= 0) return; 39 | mTotalTime = totalTime; 40 | } 41 | 42 | ///start Timer. 43 | ///启动定时Timer. 44 | void startTimer() { 45 | if (_isActive || mInterval <= 0) return; 46 | _isActive = true; 47 | Duration duration = Duration(milliseconds: mInterval); 48 | _doCallback(0); 49 | _mTimer = Timer.periodic(duration, (Timer timer) { 50 | _doCallback(timer.tick); 51 | }); 52 | } 53 | 54 | ///start countdown Timer. 55 | ///启动倒计时Timer. 56 | void startCountDown() { 57 | if (_isActive || mInterval <= 0 || mTotalTime <= 0) return; 58 | _isActive = true; 59 | Duration duration = Duration(milliseconds: mInterval); 60 | _doCallback(mTotalTime); 61 | _mTimer = Timer.periodic(duration, (Timer timer) { 62 | int time = mTotalTime - mInterval; 63 | mTotalTime = time; 64 | if (time >= mInterval) { 65 | _doCallback(time); 66 | } else if (time == 0) { 67 | _doCallback(time); 68 | cancel(); 69 | } else { 70 | timer.cancel(); 71 | Future.delayed(Duration(milliseconds: time), () { 72 | mTotalTime = 0; 73 | _doCallback(0); 74 | cancel(); 75 | }); 76 | } 77 | }); 78 | } 79 | 80 | void _doCallback(int time) { 81 | if (_onTimerTickCallback != null) { 82 | _onTimerTickCallback(time); 83 | } 84 | } 85 | 86 | ///update countdown totalTime. 87 | ///重设倒计时总时间. 88 | void updateTotalTime(int totalTime) { 89 | cancel(); 90 | mTotalTime = totalTime; 91 | startCountDown(); 92 | } 93 | 94 | ///timer is Active. 95 | ///Timer是否启动. 96 | bool isActive() { 97 | return _isActive; 98 | } 99 | 100 | ///Cancels the timer. 101 | ///取消计时器. 102 | void cancel() { 103 | if (_mTimer != null) { 104 | _mTimer.cancel(); 105 | _mTimer = null; 106 | } 107 | _isActive = false; 108 | } 109 | 110 | ///set timer callback. 111 | void setOnTimerTickCallback(OnTimerTickCallback callback) { 112 | _onTimerTickCallback = callback; 113 | } 114 | 115 | static Map getAuthCode(){ 116 | Map map = new Map(); 117 | int d = Random.secure().nextInt(2); 118 | int a = Random.secure().nextInt(999); 119 | int b = Random.secure().nextInt(99); 120 | int c = Random.secure().nextInt(9999); 121 | if(d == 1){ 122 | int value = a * b + c; 123 | String key = '$a × $b + $c = ?'; 124 | map[key] = value.toString(); 125 | }else{ 126 | int value = a + b + c; 127 | String key = '$a + $b + $c = ?'; 128 | map[key] = value.toString(); 129 | } 130 | return map; 131 | } 132 | 133 | } 134 | -------------------------------------------------------------------------------- /pubspec.yaml: -------------------------------------------------------------------------------- 1 | name: flutter_nb 2 | description: A new Flutter application. 3 | 4 | # The following defines the version and build number for your application. 5 | # A version number is three numbers separated by dots, like 1.2.43 6 | # followed by an optional build number separated by a +. 7 | # Both the version and the builder number may be overridden in flutter 8 | # build by specifying --build-name and --build-number, respectively. 9 | # Read more about versioning at semver.org. 10 | version: 1.0.0+1 11 | 12 | environment: 13 | sdk: ">=2.1.0 <3.0.0" 14 | 15 | dependencies: 16 | flutter: 17 | sdk: flutter 18 | 19 | # The following adds the Cupertino Icons font to your application. 20 | # Use with the CupertinoIcons class for iOS style icons. 21 | cupertino_icons: ^0.1.2 #图标资源 22 | shared_preferences: ^0.4.3 #存储 23 | synchronized: ^2.0.2+1 #异步相关 24 | rxdart: ^0.24.0 #Rx 25 | cached_network_image: ^2.2.0+1 #网络图片 26 | fluttertoast: ^3.0.1 #提示 27 | sqflite: ^1.1.1 #数据库 28 | flutter_local_notifications: ^0.5.2 #通知栏 29 | image_picker: ^0.6.1+8 #相机相册 30 | #webview_flutter: ^0.3.4 #WebView 31 | keyboard_visibility: ^0.5.2 #软键盘 32 | flutter_record: ^0.3.5 #录音、播放(播放的地址作者写死了,不支持http) 33 | vibration: ^1.0.1 #震动 34 | permission_handler: ^3.0.0 #权限申请 35 | audioplayers: ^0.15.1 #播放器 36 | photo_view: ^0.7.0 #图片预览 37 | video_player: ^0.10.0+5 # 视频播放器 38 | flutter_staggered_grid_view: ^0.3.0 #支持交错排列的GridView 39 | 40 | flukit: 41 | git: 42 | url: git://github.com/flutterchina/flukit.git 43 | path: package_src/ 44 | webview_flutter: 45 | git: 46 | url: git://github.com/Sky24n/plugins.git 47 | ref: newDev 48 | path: packages/webview_flutter/ 49 | 50 | dev_dependencies: 51 | flutter_test: 52 | sdk: flutter 53 | 54 | # For information on the generic Dart part of this file, see the 55 | # following page: https://www.dartlang.org/tools/pub/pubspec 56 | 57 | # The following section is specific to Flutter. 58 | flutter: 59 | 60 | # The following line ensures that the Material Icons font is 61 | # included with your application, so that you can use the icons in 62 | # the material Icons class. 63 | uses-material-design: true 64 | assets: 65 | - assets/ 66 | - assets/images/ 67 | - assets/images/default/ 68 | - assets/images/main_page/ 69 | - assets/images/splash/ 70 | - assets/images/icon/ 71 | - assets/images/face/ 72 | - assets/images/figure/ 73 | 74 | - assets/sounds/ 75 | # To add assets to your application, add an assets section, like this: 76 | # assets: 77 | # - images/a_dot_burr.jpeg 78 | # - images/a_dot_ham.jpeg 79 | 80 | # An image asset can refer to one or more resolution-specific "variants", see 81 | # https://flutter.io/assets-and-images/#resolution-aware. 82 | 83 | # For details regarding adding assets from package dependencies, see 84 | # https://flutter.io/assets-and-images/#from-packages 85 | 86 | # To add custom fonts to your application, add a fonts section here, 87 | # in this "flutter" section. Each entry in this list should have a 88 | # "family" key with the font family name, and a "fonts" key with a 89 | # list giving the asset and other descriptors for the font. For 90 | # example: 91 | # fonts: 92 | # - family: Schyler 93 | # fonts: 94 | # - asset: fonts/Schyler-Regular.ttf 95 | # - asset: fonts/Schyler-Italic.ttf 96 | # style: italic 97 | # - family: Trajan Pro 98 | # fonts: 99 | # - asset: fonts/TrajanPro.ttf 100 | # - asset: fonts/TrajanPro_Bold.ttf 101 | # weight: 700 102 | # 103 | # For details regarding fonts from package dependencies, 104 | # see https://flutter.io/custom-fonts/#from-packages 105 | -------------------------------------------------------------------------------- /screens/1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/buhuiming/flutter_nb/e2a3dcd27c72d1f9991da0d7446a7897bfcda424/screens/1.png -------------------------------------------------------------------------------- /screens/10.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/buhuiming/flutter_nb/e2a3dcd27c72d1f9991da0d7446a7897bfcda424/screens/10.png -------------------------------------------------------------------------------- /screens/11.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/buhuiming/flutter_nb/e2a3dcd27c72d1f9991da0d7446a7897bfcda424/screens/11.png -------------------------------------------------------------------------------- /screens/12.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/buhuiming/flutter_nb/e2a3dcd27c72d1f9991da0d7446a7897bfcda424/screens/12.png -------------------------------------------------------------------------------- /screens/13.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/buhuiming/flutter_nb/e2a3dcd27c72d1f9991da0d7446a7897bfcda424/screens/13.png -------------------------------------------------------------------------------- /screens/14.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/buhuiming/flutter_nb/e2a3dcd27c72d1f9991da0d7446a7897bfcda424/screens/14.png -------------------------------------------------------------------------------- /screens/15.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/buhuiming/flutter_nb/e2a3dcd27c72d1f9991da0d7446a7897bfcda424/screens/15.png -------------------------------------------------------------------------------- /screens/16.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/buhuiming/flutter_nb/e2a3dcd27c72d1f9991da0d7446a7897bfcda424/screens/16.png -------------------------------------------------------------------------------- /screens/17.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/buhuiming/flutter_nb/e2a3dcd27c72d1f9991da0d7446a7897bfcda424/screens/17.png -------------------------------------------------------------------------------- /screens/18.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/buhuiming/flutter_nb/e2a3dcd27c72d1f9991da0d7446a7897bfcda424/screens/18.png -------------------------------------------------------------------------------- /screens/19.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/buhuiming/flutter_nb/e2a3dcd27c72d1f9991da0d7446a7897bfcda424/screens/19.png -------------------------------------------------------------------------------- /screens/2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/buhuiming/flutter_nb/e2a3dcd27c72d1f9991da0d7446a7897bfcda424/screens/2.png -------------------------------------------------------------------------------- /screens/20.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/buhuiming/flutter_nb/e2a3dcd27c72d1f9991da0d7446a7897bfcda424/screens/20.png -------------------------------------------------------------------------------- /screens/21.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/buhuiming/flutter_nb/e2a3dcd27c72d1f9991da0d7446a7897bfcda424/screens/21.png -------------------------------------------------------------------------------- /screens/22.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/buhuiming/flutter_nb/e2a3dcd27c72d1f9991da0d7446a7897bfcda424/screens/22.png -------------------------------------------------------------------------------- /screens/23.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/buhuiming/flutter_nb/e2a3dcd27c72d1f9991da0d7446a7897bfcda424/screens/23.png -------------------------------------------------------------------------------- /screens/24.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/buhuiming/flutter_nb/e2a3dcd27c72d1f9991da0d7446a7897bfcda424/screens/24.png -------------------------------------------------------------------------------- /screens/25.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/buhuiming/flutter_nb/e2a3dcd27c72d1f9991da0d7446a7897bfcda424/screens/25.png -------------------------------------------------------------------------------- /screens/26.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/buhuiming/flutter_nb/e2a3dcd27c72d1f9991da0d7446a7897bfcda424/screens/26.png -------------------------------------------------------------------------------- /screens/27.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/buhuiming/flutter_nb/e2a3dcd27c72d1f9991da0d7446a7897bfcda424/screens/27.png -------------------------------------------------------------------------------- /screens/28.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/buhuiming/flutter_nb/e2a3dcd27c72d1f9991da0d7446a7897bfcda424/screens/28.png -------------------------------------------------------------------------------- /screens/29.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/buhuiming/flutter_nb/e2a3dcd27c72d1f9991da0d7446a7897bfcda424/screens/29.png -------------------------------------------------------------------------------- /screens/3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/buhuiming/flutter_nb/e2a3dcd27c72d1f9991da0d7446a7897bfcda424/screens/3.png -------------------------------------------------------------------------------- /screens/30.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/buhuiming/flutter_nb/e2a3dcd27c72d1f9991da0d7446a7897bfcda424/screens/30.png -------------------------------------------------------------------------------- /screens/31.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/buhuiming/flutter_nb/e2a3dcd27c72d1f9991da0d7446a7897bfcda424/screens/31.png -------------------------------------------------------------------------------- /screens/32.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/buhuiming/flutter_nb/e2a3dcd27c72d1f9991da0d7446a7897bfcda424/screens/32.png -------------------------------------------------------------------------------- /screens/33.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/buhuiming/flutter_nb/e2a3dcd27c72d1f9991da0d7446a7897bfcda424/screens/33.png -------------------------------------------------------------------------------- /screens/34.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/buhuiming/flutter_nb/e2a3dcd27c72d1f9991da0d7446a7897bfcda424/screens/34.png -------------------------------------------------------------------------------- /screens/35.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/buhuiming/flutter_nb/e2a3dcd27c72d1f9991da0d7446a7897bfcda424/screens/35.png -------------------------------------------------------------------------------- /screens/36.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/buhuiming/flutter_nb/e2a3dcd27c72d1f9991da0d7446a7897bfcda424/screens/36.png -------------------------------------------------------------------------------- /screens/37.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/buhuiming/flutter_nb/e2a3dcd27c72d1f9991da0d7446a7897bfcda424/screens/37.png -------------------------------------------------------------------------------- /screens/38.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/buhuiming/flutter_nb/e2a3dcd27c72d1f9991da0d7446a7897bfcda424/screens/38.png -------------------------------------------------------------------------------- /screens/39.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/buhuiming/flutter_nb/e2a3dcd27c72d1f9991da0d7446a7897bfcda424/screens/39.png -------------------------------------------------------------------------------- /screens/4.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/buhuiming/flutter_nb/e2a3dcd27c72d1f9991da0d7446a7897bfcda424/screens/4.png -------------------------------------------------------------------------------- /screens/40.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/buhuiming/flutter_nb/e2a3dcd27c72d1f9991da0d7446a7897bfcda424/screens/40.png -------------------------------------------------------------------------------- /screens/41.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/buhuiming/flutter_nb/e2a3dcd27c72d1f9991da0d7446a7897bfcda424/screens/41.png -------------------------------------------------------------------------------- /screens/42.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/buhuiming/flutter_nb/e2a3dcd27c72d1f9991da0d7446a7897bfcda424/screens/42.png -------------------------------------------------------------------------------- /screens/43.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/buhuiming/flutter_nb/e2a3dcd27c72d1f9991da0d7446a7897bfcda424/screens/43.png -------------------------------------------------------------------------------- /screens/44.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/buhuiming/flutter_nb/e2a3dcd27c72d1f9991da0d7446a7897bfcda424/screens/44.png -------------------------------------------------------------------------------- /screens/45.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/buhuiming/flutter_nb/e2a3dcd27c72d1f9991da0d7446a7897bfcda424/screens/45.png -------------------------------------------------------------------------------- /screens/46.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/buhuiming/flutter_nb/e2a3dcd27c72d1f9991da0d7446a7897bfcda424/screens/46.png -------------------------------------------------------------------------------- /screens/47.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/buhuiming/flutter_nb/e2a3dcd27c72d1f9991da0d7446a7897bfcda424/screens/47.png -------------------------------------------------------------------------------- /screens/48.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/buhuiming/flutter_nb/e2a3dcd27c72d1f9991da0d7446a7897bfcda424/screens/48.png -------------------------------------------------------------------------------- /screens/49.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/buhuiming/flutter_nb/e2a3dcd27c72d1f9991da0d7446a7897bfcda424/screens/49.png -------------------------------------------------------------------------------- /screens/5.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/buhuiming/flutter_nb/e2a3dcd27c72d1f9991da0d7446a7897bfcda424/screens/5.png -------------------------------------------------------------------------------- /screens/50.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/buhuiming/flutter_nb/e2a3dcd27c72d1f9991da0d7446a7897bfcda424/screens/50.png -------------------------------------------------------------------------------- /screens/51.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/buhuiming/flutter_nb/e2a3dcd27c72d1f9991da0d7446a7897bfcda424/screens/51.png -------------------------------------------------------------------------------- /screens/52.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/buhuiming/flutter_nb/e2a3dcd27c72d1f9991da0d7446a7897bfcda424/screens/52.png -------------------------------------------------------------------------------- /screens/53.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/buhuiming/flutter_nb/e2a3dcd27c72d1f9991da0d7446a7897bfcda424/screens/53.png -------------------------------------------------------------------------------- /screens/54.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/buhuiming/flutter_nb/e2a3dcd27c72d1f9991da0d7446a7897bfcda424/screens/54.png -------------------------------------------------------------------------------- /screens/55.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/buhuiming/flutter_nb/e2a3dcd27c72d1f9991da0d7446a7897bfcda424/screens/55.png -------------------------------------------------------------------------------- /screens/6.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/buhuiming/flutter_nb/e2a3dcd27c72d1f9991da0d7446a7897bfcda424/screens/6.png -------------------------------------------------------------------------------- /screens/7.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/buhuiming/flutter_nb/e2a3dcd27c72d1f9991da0d7446a7897bfcda424/screens/7.png -------------------------------------------------------------------------------- /screens/8.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/buhuiming/flutter_nb/e2a3dcd27c72d1f9991da0d7446a7897bfcda424/screens/8.png -------------------------------------------------------------------------------- /screens/9.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/buhuiming/flutter_nb/e2a3dcd27c72d1f9991da0d7446a7897bfcda424/screens/9.png -------------------------------------------------------------------------------- /screens/screen.md: -------------------------------------------------------------------------------- 1 | # flutter_nb 2 | 3 | 一个集成环信IM的Flutter项目。 4 | 5 | ## Getting Started 6 | ------ 7 | ![image](https://github.com/buhuiming/flutter_nb/blob/master/screens/1.png)![image](https://github.com/buhuiming/flutter_nb/blob/master/screens/2.png)![image](https://github.com/buhuiming/flutter_nb/blob/master/screens/3.png)![image](https://github.com/buhuiming/flutter_nb/blob/master/screens/4.png)![image](https://github.com/buhuiming/flutter_nb/blob/master/screens/5.png)![image](https://github.com/buhuiming/flutter_nb/blob/master/screens/6.png)![image](https://github.com/buhuiming/flutter_nb/blob/master/screens/7.png)![image](https://github.com/buhuiming/flutter_nb/blob/master/screens/8.png)![image](https://github.com/buhuiming/flutter_nb/blob/master/screens/9.png)![image](https://github.com/buhuiming/flutter_nb/blob/master/screens/10.png)![image](https://github.com/buhuiming/flutter_nb/blob/master/screens/11.png)![image](https://github.com/buhuiming/flutter_nb/blob/master/screens/12.png)![image](https://github.com/buhuiming/flutter_nb/blob/master/screens/13.png)![image](https://github.com/buhuiming/flutter_nb/blob/master/screens/14.png)![image](https://github.com/buhuiming/flutter_nb/blob/master/screens/15.png)![image](https://github.com/buhuiming/flutter_nb/blob/master/screens/16.png)![image](https://github.com/buhuiming/flutter_nb/blob/master/screens/17.png)![image](https://github.com/buhuiming/flutter_nb/blob/master/screens/18.png)![image](https://github.com/buhuiming/flutter_nb/blob/master/screens/19.png)![image](https://github.com/buhuiming/flutter_nb/blob/master/screens/20.png)![image](https://github.com/buhuiming/flutter_nb/blob/master/screens/21.png)![image](https://github.com/buhuiming/flutter_nb/blob/master/screens/22.png)![image](https://github.com/buhuiming/flutter_nb/blob/master/screens/23.png)![image](https://github.com/buhuiming/flutter_nb/blob/master/screens/24.png)![image](https://github.com/buhuiming/flutter_nb/blob/master/screens/25.png)![image](https://github.com/buhuiming/flutter_nb/blob/master/screens/26.png)![image](https://github.com/buhuiming/flutter_nb/blob/master/screens/27.png)![image](https://github.com/buhuiming/flutter_nb/blob/master/screens/28.png)![image](https://github.com/buhuiming/flutter_nb/blob/master/screens/29.png)![image](https://github.com/buhuiming/flutter_nb/blob/master/screens/30.png)![image](https://github.com/buhuiming/flutter_nb/blob/master/screens/31.png)![image](https://github.com/buhuiming/flutter_nb/blob/master/screens/32.png)![image](https://github.com/buhuiming/flutter_nb/blob/master/screens/33.png)![image](https://github.com/buhuiming/flutter_nb/blob/master/screens/34.png)![image](https://github.com/buhuiming/flutter_nb/blob/master/screens/35.png)![image](https://github.com/buhuiming/flutter_nb/blob/master/screens/36.png)![image](https://github.com/buhuiming/flutter_nb/blob/master/screens/37.png)![image](https://github.com/buhuiming/flutter_nb/blob/master/screens/38.png)![image](https://github.com/buhuiming/flutter_nb/blob/master/screens/39.png)![image](https://github.com/buhuiming/flutter_nb/blob/master/screens/40.png)![image](https://github.com/buhuiming/flutter_nb/blob/master/screens/41.png)![image](https://github.com/buhuiming/flutter_nb/blob/master/screens/42.png)![image](https://github.com/buhuiming/flutter_nb/blob/master/screens/43.png)![image](https://github.com/buhuiming/flutter_nb/blob/master/screens/44.png)![image](https://github.com/buhuiming/flutter_nb/blob/master/screens/45.png)![image](https://github.com/buhuiming/flutter_nb/blob/master/screens/46.png)![image](https://github.com/buhuiming/flutter_nb/blob/master/screens/47.png)![image](https://github.com/buhuiming/flutter_nb/blob/master/screens/48.png)![image](https://github.com/buhuiming/flutter_nb/blob/master/screens/49.png)![image](https://github.com/buhuiming/flutter_nb/blob/master/screens/50.png)![image](https://github.com/buhuiming/flutter_nb/blob/master/screens/51.png)![image](https://github.com/buhuiming/flutter_nb/blob/master/screens/52.png)![image](https://github.com/buhuiming/flutter_nb/blob/master/screens/53.png)![image](https://github.com/buhuiming/flutter_nb/blob/master/screens/54.png)![image](https://github.com/buhuiming/flutter_nb/blob/master/screens/55.png) 8 | -------------------------------------------------------------------------------- /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_nb/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 | -------------------------------------------------------------------------------- /存在问题: -------------------------------------------------------------------------------- 1 | 目前存在的问题: 2 | 1.退出登录或者杀死进程后,期间收到的信息,登录后,消息处理过程中,消息概率性不保存或不展示在消息列表。(主要原因:登录后,环信IM下发消息比初始化页面快) 3 | 2.setState问题 4 | 3.聊天列表消息时间显示存在缺陷,由于listView暂时找不到滚动到顶部位置的方法,所以把listView倒置显示,以滚动到顶部的方式实现。但是导致数据添加必须 5 | 是反的,每一条数据时间对比不能如愿。 6 | 4.发送语音时,有时因为录音时间太短,导致再录音就失败。需要重新进入页面。 7 | 5.本地录音删除后,点击播放,播放不了。 8 | 6.有些手机相册的图片地址,取不到图片。 9 | 7.切换账号登录后,“朋友”页面没刷新 --------------------------------------------------------------------------------