├── .gitignore
├── .metadata
├── README.md
├── android
├── .gitignore
├── app
│ ├── build.gradle
│ └── src
│ │ ├── debug
│ │ └── AndroidManifest.xml
│ │ ├── main
│ │ ├── AndroidManifest.xml
│ │ ├── kotlin
│ │ │ └── com
│ │ │ │ └── tao
│ │ │ │ └── flutter_wan
│ │ │ │ └── MainActivity.kt
│ │ └── res
│ │ │ ├── drawable
│ │ │ └── launch_background.xml
│ │ │ ├── mipmap-hdpi
│ │ │ └── ic_launcher.png
│ │ │ ├── mipmap-mdpi
│ │ │ └── ic_launcher.png
│ │ │ ├── mipmap-xhdpi
│ │ │ └── ic_launcher.png
│ │ │ ├── mipmap-xxhdpi
│ │ │ └── ic_launcher.png
│ │ │ ├── mipmap-xxxhdpi
│ │ │ └── ic_launcher.png
│ │ │ ├── values-night
│ │ │ └── styles.xml
│ │ │ └── values
│ │ │ └── styles.xml
│ │ └── profile
│ │ └── AndroidManifest.xml
├── build.gradle
├── gradle.properties
├── gradle
│ └── wrapper
│ │ └── gradle-wrapper.properties
├── key.properties
├── key_store.jks
└── settings.gradle
├── images
└── ttxs.jpg
├── ios
├── .gitignore
├── Flutter
│ ├── AppFrameworkInfo.plist
│ ├── Debug.xcconfig
│ └── Release.xcconfig
├── Podfile
├── Runner.xcodeproj
│ ├── project.pbxproj
│ ├── project.xcworkspace
│ │ ├── contents.xcworkspacedata
│ │ └── xcshareddata
│ │ │ ├── IDEWorkspaceChecks.plist
│ │ │ └── WorkspaceSettings.xcsettings
│ └── xcshareddata
│ │ └── xcschemes
│ │ └── Runner.xcscheme
├── Runner.xcworkspace
│ ├── contents.xcworkspacedata
│ └── xcshareddata
│ │ ├── IDEWorkspaceChecks.plist
│ │ └── WorkspaceSettings.xcsettings
└── Runner
│ ├── AppDelegate.swift
│ ├── Assets.xcassets
│ ├── AppIcon.appiconset
│ │ ├── Contents.json
│ │ ├── Icon-App-1024x1024@1x.png
│ │ ├── Icon-App-20x20@1x.png
│ │ ├── Icon-App-20x20@2x.png
│ │ ├── Icon-App-20x20@3x.png
│ │ ├── Icon-App-29x29@1x.png
│ │ ├── Icon-App-29x29@2x.png
│ │ ├── Icon-App-29x29@3x.png
│ │ ├── Icon-App-40x40@1x.png
│ │ ├── Icon-App-40x40@2x.png
│ │ ├── Icon-App-40x40@3x.png
│ │ ├── Icon-App-60x60@2x.png
│ │ ├── Icon-App-60x60@3x.png
│ │ ├── Icon-App-76x76@1x.png
│ │ ├── Icon-App-76x76@2x.png
│ │ └── Icon-App-83.5x83.5@2x.png
│ └── LaunchImage.imageset
│ │ ├── Contents.json
│ │ ├── LaunchImage.png
│ │ ├── LaunchImage@2x.png
│ │ ├── LaunchImage@3x.png
│ │ └── README.md
│ ├── Base.lproj
│ ├── LaunchScreen.storyboard
│ └── Main.storyboard
│ ├── Info.plist
│ └── Runner-Bridging-Header.h
├── lib
├── app
│ ├── config
│ │ └── route.dart
│ ├── init.dart
│ ├── typedef
│ │ └── function.dart
│ └── utils
│ │ ├── cache
│ │ └── sp_util.dart
│ │ ├── show
│ │ └── toast_util.dart
│ │ ├── tool
│ │ └── string_util.dart
│ │ └── ui
│ │ ├── future.dart
│ │ ├── keep_alive_page.dart
│ │ ├── ui_adapter.dart
│ │ └── view_util.dart
├── bean
│ ├── README.md
│ ├── common
│ │ ├── article_detail_bean.dart
│ │ └── btn_info.dart
│ ├── home
│ │ ├── banner_bean.dart
│ │ ├── banner_bean.g.dart
│ │ ├── home_article_bean.dart
│ │ └── home_article_bean.g.dart
│ ├── navi
│ │ ├── navi_info_bean.dart
│ │ └── navi_info_bean.g.dart
│ ├── project
│ │ ├── project_bean.dart
│ │ ├── project_bean.g.dart
│ │ ├── project_detail_bean.dart
│ │ └── project_detail_bean.g.dart
│ ├── tree
│ │ ├── tree_info_bean.dart
│ │ ├── tree_info_bean.g.dart
│ │ ├── tree_info_item_bean.dart
│ │ └── tree_info_item_bean.g.dart
│ └── user
│ │ ├── collect_list_bean.dart
│ │ ├── collect_list_bean.g.dart
│ │ ├── common_response.dart
│ │ ├── common_response.g.dart
│ │ ├── hot_word_bean.dart
│ │ ├── hot_word_bean.g.dart
│ │ ├── login_info_bean.dart
│ │ ├── login_info_bean.g.dart
│ │ ├── register_info_bean.dart
│ │ └── register_info_bean.g.dart
├── http
│ ├── api.dart
│ └── http.dart
├── main.dart
├── module
│ ├── home
│ │ ├── action.dart
│ │ ├── effect.dart
│ │ ├── page.dart
│ │ ├── reducer.dart
│ │ ├── state.dart
│ │ ├── view.dart
│ │ └── widget
│ │ │ └── home_banner.dart
│ ├── main
│ │ ├── action.dart
│ │ ├── collect
│ │ │ ├── action.dart
│ │ │ ├── adapter.dart
│ │ │ ├── collect_item
│ │ │ │ ├── action.dart
│ │ │ │ ├── component.dart
│ │ │ │ ├── effect.dart
│ │ │ │ ├── state.dart
│ │ │ │ ├── view.dart
│ │ │ │ └── widget
│ │ │ │ │ └── collect_item_view.dart
│ │ │ ├── effect.dart
│ │ │ ├── page.dart
│ │ │ ├── reducer.dart
│ │ │ ├── state.dart
│ │ │ └── view.dart
│ │ ├── effect.dart
│ │ ├── login
│ │ │ ├── action.dart
│ │ │ ├── effect.dart
│ │ │ ├── page.dart
│ │ │ ├── state.dart
│ │ │ ├── view.dart
│ │ │ └── widget
│ │ │ │ └── login_view.dart
│ │ ├── page.dart
│ │ ├── reducer.dart
│ │ ├── register
│ │ │ ├── action.dart
│ │ │ ├── effect.dart
│ │ │ ├── page.dart
│ │ │ ├── state.dart
│ │ │ ├── view.dart
│ │ │ └── widget
│ │ │ │ └── register_view.dart
│ │ ├── search
│ │ │ ├── action.dart
│ │ │ ├── effect.dart
│ │ │ ├── page.dart
│ │ │ ├── reducer.dart
│ │ │ ├── state.dart
│ │ │ ├── view.dart
│ │ │ └── widget
│ │ │ │ ├── search_app_bar.dart
│ │ │ │ └── search_hot_word.dart
│ │ ├── state.dart
│ │ ├── view.dart
│ │ └── widget
│ │ │ ├── main_app_bar.dart
│ │ │ ├── main_body.dart
│ │ │ ├── main_bottom_navigation.dart
│ │ │ └── main_drawer.dart
│ ├── navi
│ │ ├── action.dart
│ │ ├── adapter.dart
│ │ ├── effect.dart
│ │ ├── navi_item
│ │ │ ├── action.dart
│ │ │ ├── component.dart
│ │ │ ├── effect.dart
│ │ │ ├── state.dart
│ │ │ ├── view.dart
│ │ │ └── widget
│ │ │ │ └── navi_detail_Item_view.dart
│ │ ├── page.dart
│ │ ├── reducer.dart
│ │ ├── state.dart
│ │ └── view.dart
│ ├── project
│ │ ├── action.dart
│ │ ├── effect.dart
│ │ ├── page.dart
│ │ ├── project_tab
│ │ │ ├── action.dart
│ │ │ ├── adapter.dart
│ │ │ ├── effect.dart
│ │ │ ├── page.dart
│ │ │ ├── reducer.dart
│ │ │ ├── state.dart
│ │ │ └── view.dart
│ │ ├── project_tab_item
│ │ │ ├── action.dart
│ │ │ ├── component.dart
│ │ │ ├── effect.dart
│ │ │ ├── state.dart
│ │ │ ├── view.dart
│ │ │ └── widget
│ │ │ │ └── project_item_detail.dart
│ │ ├── reducer.dart
│ │ ├── state.dart
│ │ └── view.dart
│ ├── tree
│ │ ├── action.dart
│ │ ├── adapter.dart
│ │ ├── effect.dart
│ │ ├── page.dart
│ │ ├── reducer.dart
│ │ ├── state.dart
│ │ ├── tree_detail
│ │ │ ├── page.dart
│ │ │ ├── state.dart
│ │ │ ├── tree_detail_tab
│ │ │ │ ├── page.dart
│ │ │ │ ├── state.dart
│ │ │ │ └── view.dart
│ │ │ └── view.dart
│ │ ├── tree_item
│ │ │ ├── action.dart
│ │ │ ├── component.dart
│ │ │ ├── effect.dart
│ │ │ ├── state.dart
│ │ │ ├── view.dart
│ │ │ └── widget
│ │ │ │ └── tree_item_style.dart
│ │ └── view.dart
│ └── web
│ │ ├── action.dart
│ │ ├── effect.dart
│ │ ├── page.dart
│ │ ├── reducer.dart
│ │ ├── state.dart
│ │ ├── view.dart
│ │ └── widget
│ │ └── common_webview.dart
└── view
│ ├── component
│ └── article_list
│ │ ├── action.dart
│ │ ├── adapter.dart
│ │ ├── component.dart
│ │ ├── effect.dart
│ │ ├── item
│ │ ├── action.dart
│ │ ├── component.dart
│ │ ├── effect.dart
│ │ ├── state.dart
│ │ ├── view.dart
│ │ └── widget
│ │ │ └── article_item_detail.dart
│ │ ├── reducer.dart
│ │ ├── state.dart
│ │ └── view.dart
│ ├── dialog
│ └── easy
│ │ └── easy_dialog.dart
│ └── widget
│ ├── input
│ └── input_actions.dart
│ └── search
│ └── search_bar.dart
├── linux
├── .gitignore
├── CMakeLists.txt
├── flutter
│ ├── CMakeLists.txt
│ ├── generated_plugin_registrant.cc
│ ├── generated_plugin_registrant.h
│ └── generated_plugins.cmake
├── main.cc
├── my_application.cc
└── my_application.h
├── macos
├── .gitignore
├── Flutter
│ ├── Flutter-Debug.xcconfig
│ ├── Flutter-Release.xcconfig
│ └── GeneratedPluginRegistrant.swift
├── Podfile
├── Runner.xcodeproj
│ ├── project.pbxproj
│ ├── project.xcworkspace
│ │ └── xcshareddata
│ │ │ └── IDEWorkspaceChecks.plist
│ └── xcshareddata
│ │ └── xcschemes
│ │ └── Runner.xcscheme
├── Runner.xcworkspace
│ ├── contents.xcworkspacedata
│ └── xcshareddata
│ │ └── IDEWorkspaceChecks.plist
└── Runner
│ ├── AppDelegate.swift
│ ├── Assets.xcassets
│ └── AppIcon.appiconset
│ │ ├── Contents.json
│ │ ├── app_icon_1024.png
│ │ ├── app_icon_128.png
│ │ ├── app_icon_16.png
│ │ ├── app_icon_256.png
│ │ ├── app_icon_32.png
│ │ ├── app_icon_512.png
│ │ └── app_icon_64.png
│ ├── Base.lproj
│ └── MainMenu.xib
│ ├── Configs
│ ├── AppInfo.xcconfig
│ ├── Debug.xcconfig
│ ├── Release.xcconfig
│ └── Warnings.xcconfig
│ ├── DebugProfile.entitlements
│ ├── Info.plist
│ ├── MainFlutterWindow.swift
│ └── Release.entitlements
├── pubspec.lock
├── pubspec.yaml
├── test
└── widget_test.dart
├── web
├── favicon.png
├── icons
│ ├── Icon-192.png
│ └── Icon-512.png
├── index.html
└── manifest.json
└── windows
├── .gitignore
├── CMakeLists.txt
├── flutter
├── CMakeLists.txt
├── generated_plugin_registrant.cc
├── generated_plugin_registrant.h
└── generated_plugins.cmake
└── runner
├── CMakeLists.txt
├── Runner.rc
├── flutter_window.cpp
├── flutter_window.h
├── main.cpp
├── resource.h
├── resources
└── app_icon.ico
├── run_loop.cpp
├── run_loop.h
├── runner.exe.manifest
├── utils.cpp
├── utils.h
├── win32_window.cpp
└── win32_window.h
/.gitignore:
--------------------------------------------------------------------------------
1 | # Miscellaneous
2 | *.class
3 | *.log
4 | *.pyc
5 | *.swp
6 | .DS_Store
7 | .atom/
8 | .buildlog/
9 | .history
10 | .svn/
11 |
12 | # IntelliJ related
13 | *.iml
14 | *.ipr
15 | *.iws
16 | .idea/
17 |
18 | # The .vscode folder contains launch configuration and tasks you configure in
19 | # VS Code which you may wish to be included in version control, so this line
20 | # is commented out by default.
21 | #.vscode/
22 |
23 | # Flutter/Dart/Pub related
24 | **/doc/api/
25 | .dart_tool/
26 | .flutter-plugins
27 | .flutter-plugins-dependencies
28 | .packages
29 | .pub-cache/
30 | .pub/
31 | /build/
32 |
33 | # Web related
34 | lib/generated_plugin_registrant.dart
35 |
36 | # Exceptions to above rules.
37 | !/packages/flutter_tools/test/data/dart_dependencies_test/**/.packages
38 |
--------------------------------------------------------------------------------
/.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: 0b8abb4724aa590dd0f429683339b1e045a1594d
8 | channel: stable
9 |
10 | project_type: app
11 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | ## fish_redux使用
2 | - 注:该项目为Flutter + fish_redux,页面基本均是fish_redux搭建
3 | - fish-redux使用
4 | - 教程:[掘金:fish_redux使用详解---看完就会用!](https://juejin.im/post/6860029460524040199)
5 | - 备用:[博客园:fish_redux使用详解---看完就会用!](https://www.cnblogs.com/xdd666/p/13803224.html)
6 | - [代码demo地址](https://github.com/CNAD666/ExampleCode/tree/master/Flutter/fish_redux_demo)
7 |
8 | ## 说明
9 |
10 | **多谢铁子们给我点的小星星,为了对得起你们的支持,我重写了第一版所有模块,第二版的坑填完了**
11 |
12 | - 初版的fish_redux的玩Android是我刚学flutter时写的,代码写的比较混乱,重构代码,也是为了让大家更清晰了解fish_redux结构,也给出TabBar控制器在fish_redux初始化的解决方案,大家可以看看
13 | - 重构的所有模块,无限弱化了reducer层作用
14 | - 在日程使用fish_redux和flutter_bloc后,实际能深刻体会reducer实际上只是相当于bloc中yield或emit关键字的作用,职能完全可以弱化为,仅仅作为状态刷新;这样可以大大简化开发流程,只需要关注view -> action -> effect (reducer: 统一刷新事件)
15 | - view模块中,页面使用widget组合的方式去构造的,只传入必要的数据源和保留一些点击回调
16 | - 为什么用widget组合方式构造页面:非常复杂的界面,必须将页面分成一个个小模块,然后再将其组合,每个小模块Widget内部应当对自身的的职能,能逻辑自洽的处理
17 | - 组合widget关键点:一般来说,我们并不关注widget内部页面的实现,只需要关心的是widget需要的数据源,以及widget对交互的反馈;例如:我点击widget后,widget回调事件,并传达一些数据给我;至于内部怎么实现,外部并不关心,请勿将dispatch传递到封装的widget内部,这会使我们关注的事件被封装在内部
18 |
19 | ## 第一版
20 |
21 | - [x] ~~首页banner展示,首页文章分页加载,完成下拉刷新,上拉加载~~
22 | - [x] ~~完成知识体系和体系详情模块~~
23 | - [x] ~~完成导航模块~~
24 | - [x] ~~完成项目模块~~
25 | - [x] ~~侧栏布局完成,功能留坑,方便添加~~
26 |
27 |
28 |
29 | ## 第二版
30 |
31 | - [x] ~~搜索功能~~
32 | - [x] ~~热搜词~~
33 | - [x] ~~收藏,查看收藏功能~~
34 | - [x] ~~登录功能(这个实际就是登拿个参数,去请求收藏的信息等)~~
35 | - [x] ~~用户注册~~
36 | - [x] ~~侧栏的一列功能填坑~~
37 |
38 |
39 | ## 打包操作
40 |
41 | - android(关闭R8压缩)
42 | - flutter build apk --no-shrink
43 |
44 | - ios(生成 .app ,然后 在 XCode 执行 打包 操作)
45 | - flutter build ios --release --target=lib/app/main_dev.dart
46 |
47 |
48 | ## APP安装地址
49 |
50 | - android
51 |
52 | 
53 |
54 | - ios
55 |
56 | - 下载项目,直接跑吧
57 |
58 | ## app效果
59 |
60 | 
61 |
--------------------------------------------------------------------------------
/android/.gitignore:
--------------------------------------------------------------------------------
1 | gradle-wrapper.jar
2 | /.gradle
3 | /captures/
4 | /gradlew
5 | /gradlew.bat
6 | /local.properties
7 | GeneratedPluginRegistrant.java
8 |
--------------------------------------------------------------------------------
/android/app/build.gradle:
--------------------------------------------------------------------------------
1 | def localProperties = new Properties()
2 | def localPropertiesFile = rootProject.file('local.properties')
3 | if (localPropertiesFile.exists()) {
4 | localPropertiesFile.withReader('UTF-8') { reader ->
5 | localProperties.load(reader)
6 | }
7 | }
8 |
9 | def flutterRoot = localProperties.getProperty('flutter.sdk')
10 | if (flutterRoot == null) {
11 | throw new GradleException("Flutter SDK not found. Define location with flutter.sdk in the local.properties file.")
12 | }
13 |
14 | def flutterVersionCode = localProperties.getProperty('flutter.versionCode')
15 | if (flutterVersionCode == null) {
16 | flutterVersionCode = '1.0'
17 | }
18 |
19 | def flutterVersionName = localProperties.getProperty('flutter.versionName')
20 | if (flutterVersionName == null) {
21 | flutterVersionName = '1.0'
22 | }
23 |
24 | apply plugin: 'com.android.application'
25 | apply plugin: 'kotlin-android'
26 | apply from: "$flutterRoot/packages/flutter_tools/gradle/flutter.gradle"
27 |
28 | //处理打包
29 | def keystoreProperties = new Properties()
30 | keystoreProperties.load(new FileInputStream(rootProject.file("key.properties")))
31 |
32 | android {
33 | compileSdkVersion 28
34 |
35 | sourceSets {
36 | main.java.srcDirs += 'src/main/kotlin'
37 | }
38 |
39 | lintOptions {
40 | disable 'InvalidPackage'
41 | }
42 |
43 | defaultConfig {
44 | // TODO: Specify your own unique Application ID (https://developer.android.com/studio/build/application-id.html).
45 | applicationId "com.tao.flutter_wan"
46 | minSdkVersion 17
47 | targetSdkVersion 28
48 | versionCode flutterVersionCode.toInteger()
49 | versionName flutterVersionName
50 | testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
51 |
52 | ndk {
53 | //设置支持的SO库架构
54 | abiFilters 'arm64-v8a'//, 'x86', 'armeabi-v7a', 'x86_64'
55 | }
56 | }
57 |
58 | signingConfigs {
59 | release {
60 | keyAlias keystoreProperties['keyAlias']
61 | keyPassword keystoreProperties['keyPassword']
62 | storeFile file(keystoreProperties['storeFile'])
63 | storePassword keystoreProperties['storePassword']
64 | }
65 | }
66 |
67 | buildTypes {
68 | release {
69 | // TODO: Add your own signing config for the release build.
70 | // Signing with the debug keys for now, so `flutter run --release` works.
71 | signingConfig signingConfigs.debug
72 | }
73 | }
74 | }
75 |
76 | flutter {
77 | source '../..'
78 | }
79 |
80 | dependencies {
81 | implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version"
82 | testImplementation 'junit:junit:4.12'
83 | androidTestImplementation 'androidx.test:runner:1.1.1'
84 | androidTestImplementation 'androidx.test.espresso:espresso-core:3.1.1'
85 | }
86 |
--------------------------------------------------------------------------------
/android/app/src/debug/AndroidManifest.xml:
--------------------------------------------------------------------------------
1 |
3 |
6 |
7 |
8 |
9 |
10 |
11 |
--------------------------------------------------------------------------------
/android/app/src/main/AndroidManifest.xml:
--------------------------------------------------------------------------------
1 |
3 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
19 |
28 |
29 |
30 |
31 |
32 |
33 |
35 |
38 |
39 |
40 |
--------------------------------------------------------------------------------
/android/app/src/main/kotlin/com/tao/flutter_wan/MainActivity.kt:
--------------------------------------------------------------------------------
1 | package com.tao.flutter_wan
2 |
3 | import androidx.annotation.NonNull;
4 | import io.flutter.embedding.android.FlutterActivity
5 | import io.flutter.embedding.engine.FlutterEngine
6 | import io.flutter.plugins.GeneratedPluginRegistrant
7 |
8 | class MainActivity: FlutterActivity() {
9 | override fun configureFlutterEngine(@NonNull flutterEngine: FlutterEngine) {
10 | GeneratedPluginRegistrant.registerWith(flutterEngine);
11 | }
12 | }
13 |
--------------------------------------------------------------------------------
/android/app/src/main/res/drawable/launch_background.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
12 |
13 |
--------------------------------------------------------------------------------
/android/app/src/main/res/mipmap-hdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/xdd666t/flutter_wan/70fb16ee0b1af4394f6e59121efb4aa862715d3c/android/app/src/main/res/mipmap-hdpi/ic_launcher.png
--------------------------------------------------------------------------------
/android/app/src/main/res/mipmap-mdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/xdd666t/flutter_wan/70fb16ee0b1af4394f6e59121efb4aa862715d3c/android/app/src/main/res/mipmap-mdpi/ic_launcher.png
--------------------------------------------------------------------------------
/android/app/src/main/res/mipmap-xhdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/xdd666t/flutter_wan/70fb16ee0b1af4394f6e59121efb4aa862715d3c/android/app/src/main/res/mipmap-xhdpi/ic_launcher.png
--------------------------------------------------------------------------------
/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/xdd666t/flutter_wan/70fb16ee0b1af4394f6e59121efb4aa862715d3c/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png
--------------------------------------------------------------------------------
/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/xdd666t/flutter_wan/70fb16ee0b1af4394f6e59121efb4aa862715d3c/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png
--------------------------------------------------------------------------------
/android/app/src/main/res/values-night/styles.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
9 |
15 |
18 |
19 |
--------------------------------------------------------------------------------
/android/app/src/main/res/values/styles.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
8 |
9 |
--------------------------------------------------------------------------------
/android/app/src/profile/AndroidManifest.xml:
--------------------------------------------------------------------------------
1 |
3 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/android/build.gradle:
--------------------------------------------------------------------------------
1 | buildscript {
2 | ext.kotlin_version = '1.3.50'
3 | repositories {
4 | google()
5 | jcenter()
6 | }
7 |
8 | dependencies {
9 | classpath 'com.android.tools.build:gradle:3.6.1'
10 | classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
11 | }
12 | }
13 |
14 | allprojects {
15 | repositories {
16 | google()
17 | jcenter()
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.enableR8=true
3 | android.useAndroidX=true
4 | android.enableJetifier=true
5 |
--------------------------------------------------------------------------------
/android/gradle/wrapper/gradle-wrapper.properties:
--------------------------------------------------------------------------------
1 | #Sun Mar 22 15:08:17 CST 2020
2 | distributionBase=GRADLE_USER_HOME
3 | distributionPath=wrapper/dists
4 | zipStoreBase=GRADLE_USER_HOME
5 | zipStorePath=wrapper/dists
6 | distributionUrl=https\://services.gradle.org/distributions/gradle-5.6.4-all.zip
7 |
--------------------------------------------------------------------------------
/android/key.properties:
--------------------------------------------------------------------------------
1 | storePassword= 1q2w3e4r
2 | keyPassword= 1q2w3e4r
3 | keyAlias= key
4 | storeFile= ../key_store.jks
--------------------------------------------------------------------------------
/android/key_store.jks:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/xdd666t/flutter_wan/70fb16ee0b1af4394f6e59121efb4aa862715d3c/android/key_store.jks
--------------------------------------------------------------------------------
/android/settings.gradle:
--------------------------------------------------------------------------------
1 | include ':app'
2 |
3 | def flutterProjectRoot = rootProject.projectDir.parentFile.toPath()
4 |
5 | def plugins = new Properties()
6 | def pluginsFile = new File(flutterProjectRoot.toFile(), '.flutter-plugins')
7 | if (pluginsFile.exists()) {
8 | pluginsFile.withReader('UTF-8') { reader -> plugins.load(reader) }
9 | }
10 |
11 | plugins.each { name, path ->
12 | def pluginDirectory = flutterProjectRoot.resolve(path).resolve('android').toFile()
13 | include ":$name"
14 | project(":$name").projectDir = pluginDirectory
15 | }
16 |
--------------------------------------------------------------------------------
/images/ttxs.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/xdd666t/flutter_wan/70fb16ee0b1af4394f6e59121efb4aa862715d3c/images/ttxs.jpg
--------------------------------------------------------------------------------
/ios/.gitignore:
--------------------------------------------------------------------------------
1 | *.mode1v3
2 | *.mode2v3
3 | *.moved-aside
4 | *.pbxuser
5 | *.perspectivev3
6 | **/*sync/
7 | .sconsign.dblite
8 | .tags*
9 | **/.vagrant/
10 | **/DerivedData/
11 | Icon?
12 | **/Pods/
13 | **/.symlinks/
14 | profile
15 | xcuserdata
16 | **/.generated/
17 | Flutter/App.framework
18 | Flutter/Flutter.framework
19 | Flutter/Flutter.podspec
20 | Flutter/Generated.xcconfig
21 | Flutter/app.flx
22 | Flutter/app.zip
23 | Flutter/flutter_assets/
24 | Flutter/flutter_export_environment.sh
25 | ServiceDefinitions.json
26 | Runner/GeneratedPluginRegistrant.*
27 |
28 | # Exceptions to above rules.
29 | !default.mode1v3
30 | !default.mode2v3
31 | !default.pbxuser
32 | !default.perspectivev3
33 |
--------------------------------------------------------------------------------
/ios/Flutter/AppFrameworkInfo.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | CFBundleDevelopmentRegion
6 | $(DEVELOPMENT_LANGUAGE)
7 | CFBundleExecutable
8 | App
9 | CFBundleIdentifier
10 | io.flutter.flutter.app
11 | CFBundleInfoDictionaryVersion
12 | 6.0
13 | CFBundleName
14 | App
15 | CFBundlePackageType
16 | FMWK
17 | CFBundleShortVersionString
18 | 1.0
19 | CFBundleSignature
20 | ????
21 | CFBundleVersion
22 | 1.0
23 | MinimumOSVersion
24 | 8.0
25 |
26 |
27 |
--------------------------------------------------------------------------------
/ios/Flutter/Debug.xcconfig:
--------------------------------------------------------------------------------
1 | #include? "Pods/Target Support Files/Pods-Runner/Pods-Runner.debug.xcconfig"
2 | #include "Generated.xcconfig"
3 |
--------------------------------------------------------------------------------
/ios/Flutter/Release.xcconfig:
--------------------------------------------------------------------------------
1 | #include? "Pods/Target Support Files/Pods-Runner/Pods-Runner.release.xcconfig"
2 | #include "Generated.xcconfig"
3 |
--------------------------------------------------------------------------------
/ios/Podfile:
--------------------------------------------------------------------------------
1 | # Uncomment this line to define a global platform for your project
2 | # platform :ios, '9.0'
3 |
4 | # CocoaPods analytics sends network stats synchronously affecting flutter build latency.
5 | ENV['COCOAPODS_DISABLE_STATS'] = 'true'
6 |
7 | project 'Runner', {
8 | 'Debug' => :debug,
9 | 'Profile' => :release,
10 | 'Release' => :release,
11 | }
12 |
13 | def flutter_root
14 | generated_xcode_build_settings_path = File.expand_path(File.join('..', 'Flutter', 'Generated.xcconfig'), __FILE__)
15 | unless File.exist?(generated_xcode_build_settings_path)
16 | raise "#{generated_xcode_build_settings_path} must exist. If you're running pod install manually, make sure flutter pub get is executed first"
17 | end
18 |
19 | File.foreach(generated_xcode_build_settings_path) do |line|
20 | matches = line.match(/FLUTTER_ROOT\=(.*)/)
21 | return matches[1].strip if matches
22 | end
23 | raise "FLUTTER_ROOT not found in #{generated_xcode_build_settings_path}. Try deleting Generated.xcconfig, then run flutter pub get"
24 | end
25 |
26 | require File.expand_path(File.join('packages', 'flutter_tools', 'bin', 'podhelper'), flutter_root)
27 |
28 | flutter_ios_podfile_setup
29 |
30 | target 'Runner' do
31 | use_frameworks!
32 | use_modular_headers!
33 |
34 | flutter_install_all_ios_pods File.dirname(File.realpath(__FILE__))
35 | end
36 |
37 | post_install do |installer|
38 | installer.pods_project.targets.each do |target|
39 | flutter_additional_ios_build_settings(target)
40 | end
41 | end
42 |
--------------------------------------------------------------------------------
/ios/Runner.xcodeproj/project.xcworkspace/contents.xcworkspacedata:
--------------------------------------------------------------------------------
1 |
2 |
4 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/ios/Runner.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | IDEDidComputeMac32BitWarning
6 |
7 |
8 |
9 |
--------------------------------------------------------------------------------
/ios/Runner.xcodeproj/project.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | PreviewsEnabled
6 |
7 |
8 |
9 |
--------------------------------------------------------------------------------
/ios/Runner.xcworkspace/contents.xcworkspacedata:
--------------------------------------------------------------------------------
1 |
2 |
4 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/ios/Runner.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | IDEDidComputeMac32BitWarning
6 |
7 |
8 |
9 |
--------------------------------------------------------------------------------
/ios/Runner.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | PreviewsEnabled
6 |
7 |
8 |
9 |
--------------------------------------------------------------------------------
/ios/Runner/AppDelegate.swift:
--------------------------------------------------------------------------------
1 | import UIKit
2 | import Flutter
3 |
4 | @UIApplicationMain
5 | @objc class AppDelegate: FlutterAppDelegate {
6 | override func application(
7 | _ application: UIApplication,
8 | didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?
9 | ) -> Bool {
10 | GeneratedPluginRegistrant.register(with: self)
11 | return super.application(application, didFinishLaunchingWithOptions: launchOptions)
12 | }
13 | }
14 |
--------------------------------------------------------------------------------
/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-1024x1024@1x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/xdd666t/flutter_wan/70fb16ee0b1af4394f6e59121efb4aa862715d3c/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/xdd666t/flutter_wan/70fb16ee0b1af4394f6e59121efb4aa862715d3c/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/xdd666t/flutter_wan/70fb16ee0b1af4394f6e59121efb4aa862715d3c/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/xdd666t/flutter_wan/70fb16ee0b1af4394f6e59121efb4aa862715d3c/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/xdd666t/flutter_wan/70fb16ee0b1af4394f6e59121efb4aa862715d3c/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/xdd666t/flutter_wan/70fb16ee0b1af4394f6e59121efb4aa862715d3c/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/xdd666t/flutter_wan/70fb16ee0b1af4394f6e59121efb4aa862715d3c/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/xdd666t/flutter_wan/70fb16ee0b1af4394f6e59121efb4aa862715d3c/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/xdd666t/flutter_wan/70fb16ee0b1af4394f6e59121efb4aa862715d3c/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/xdd666t/flutter_wan/70fb16ee0b1af4394f6e59121efb4aa862715d3c/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/xdd666t/flutter_wan/70fb16ee0b1af4394f6e59121efb4aa862715d3c/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/xdd666t/flutter_wan/70fb16ee0b1af4394f6e59121efb4aa862715d3c/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/xdd666t/flutter_wan/70fb16ee0b1af4394f6e59121efb4aa862715d3c/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/xdd666t/flutter_wan/70fb16ee0b1af4394f6e59121efb4aa862715d3c/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/xdd666t/flutter_wan/70fb16ee0b1af4394f6e59121efb4aa862715d3c/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/xdd666t/flutter_wan/70fb16ee0b1af4394f6e59121efb4aa862715d3c/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage.png
--------------------------------------------------------------------------------
/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/xdd666t/flutter_wan/70fb16ee0b1af4394f6e59121efb4aa862715d3c/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@2x.png
--------------------------------------------------------------------------------
/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@3x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/xdd666t/flutter_wan/70fb16ee0b1af4394f6e59121efb4aa862715d3c/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 | NSAppTransportSecurity
6 |
7 | NSAllowsArbitraryLoads
8 |
9 |
10 | CFBundleDevelopmentRegion
11 | $(DEVELOPMENT_LANGUAGE)
12 | CFBundleExecutable
13 | $(EXECUTABLE_NAME)
14 | CFBundleIdentifier
15 | $(PRODUCT_BUNDLE_IDENTIFIER)
16 | CFBundleInfoDictionaryVersion
17 | 6.0
18 | CFBundleName
19 | flutter_wan
20 | CFBundlePackageType
21 | APPL
22 | CFBundleShortVersionString
23 | $(FLUTTER_BUILD_NAME)
24 | CFBundleSignature
25 | ????
26 | CFBundleVersion
27 | $(FLUTTER_BUILD_NUMBER)
28 | LSRequiresIPhoneOS
29 |
30 | UILaunchStoryboardName
31 | LaunchScreen
32 | UIMainStoryboardFile
33 | Main
34 | UISupportedInterfaceOrientations
35 |
36 | UIInterfaceOrientationPortrait
37 | UIInterfaceOrientationLandscapeLeft
38 | UIInterfaceOrientationLandscapeRight
39 |
40 | UISupportedInterfaceOrientations~ipad
41 |
42 | UIInterfaceOrientationPortrait
43 | UIInterfaceOrientationPortraitUpsideDown
44 | UIInterfaceOrientationLandscapeLeft
45 | UIInterfaceOrientationLandscapeRight
46 |
47 | UIViewControllerBasedStatusBarAppearance
48 |
49 |
50 |
51 |
--------------------------------------------------------------------------------
/ios/Runner/Runner-Bridging-Header.h:
--------------------------------------------------------------------------------
1 | #import "GeneratedPluginRegistrant.h"
--------------------------------------------------------------------------------
/lib/app/config/route.dart:
--------------------------------------------------------------------------------
1 | import 'package:fish_redux/fish_redux.dart';
2 | import 'package:flutter_wan/module/home/page.dart';
3 | import 'package:flutter_wan/module/main/collect/page.dart';
4 | import 'package:flutter_wan/module/main/login/page.dart';
5 | import 'package:flutter_wan/module/main/page.dart';
6 | import 'package:flutter_wan/module/main/register/page.dart';
7 | import 'package:flutter_wan/module/main/search/page.dart';
8 | import 'package:flutter_wan/module/navi/page.dart';
9 | import 'package:flutter_wan/module/project/page.dart';
10 | import 'package:flutter_wan/module/tree/page.dart';
11 | import 'package:flutter_wan/module/tree/tree_detail/page.dart';
12 | import 'package:flutter_wan/module/web/page.dart';
13 |
14 | ///路由管理
15 | class RouteConfig {
16 | ///定义你的路由名称比如 static final String routeHome = 'page/home';
17 | ///主模块
18 | static const String mainPage = 'page/main';
19 |
20 | ///登录
21 | static const String loginPage = 'page/main/login';
22 |
23 | ///注册
24 | static const String registerPage = 'page/main/login/register';
25 |
26 | ///新闻主页面
27 | static const String homePage = 'page/home';
28 |
29 | ///知识体系主页面
30 | static const String treePage = 'page/tree';
31 |
32 | ///知识体系细节
33 | static const String treeDetailPage = 'page/treeDetail';
34 |
35 | ///我的模块主页面
36 | static const String naviPage = 'page/navi';
37 |
38 | ///项目模块
39 | static const String projectPage = 'page/project';
40 |
41 | ///展示文章内容,统一的容器
42 | static const String webViewPage = 'page/webview';
43 |
44 | ///收藏主页
45 | static const String collectPage = 'page/main/collect';
46 |
47 | ///搜索页面
48 | static const String searchPage = 'page/main/search';
49 |
50 | ///将你的路由名称和页面映射在一起,比如:RouteConfig.homePage: HomePage(),
51 | static final AbstractRoutes routes = PageRoutes(
52 | pages: >{
53 | RouteConfig.mainPage: MainPage(),
54 | RouteConfig.homePage: HomePage(),
55 | RouteConfig.treePage: TreePage(),
56 | RouteConfig.treeDetailPage: TreeDetailPage(),
57 | RouteConfig.naviPage: NaviPage(),
58 | RouteConfig.projectPage: ProjectPage(),
59 | RouteConfig.webViewPage: WebViewPage(),
60 | RouteConfig.loginPage: LoginPage(),
61 | RouteConfig.registerPage: RegisterPage(),
62 | RouteConfig.collectPage: CollectPage(),
63 | RouteConfig.searchPage: SearchPage(),
64 | },
65 | );
66 | }
67 |
--------------------------------------------------------------------------------
/lib/app/init.dart:
--------------------------------------------------------------------------------
1 | //初始化一些必须的操作
2 | import 'package:flutter/cupertino.dart';
3 | import 'package:flutter_wan/app/utils/cache/sp_util.dart';
4 |
5 | void initApp(BuildContext context) {
6 | //初始化本地缓存
7 | SpUtil.init();
8 | }
9 |
--------------------------------------------------------------------------------
/lib/app/typedef/function.dart:
--------------------------------------------------------------------------------
1 | ///无参数请求回调
2 | typedef ParamVoidCallback = dynamic Function();
3 |
4 | ///回调一个参数
5 | typedef ParamSingleCallback = dynamic Function(D data);
6 |
7 | ///回到俩个参数
8 | typedef ParamTwiceCallback = dynamic Function(O dataOne, T dataTwo);
9 |
10 | ///回调三个参数
11 | typedef ParamThreeCallback = dynamic Function(
12 | O dataOne, T dataTwo, K threeData);
--------------------------------------------------------------------------------
/lib/app/utils/cache/sp_util.dart:
--------------------------------------------------------------------------------
1 | import 'package:shared_preferences/shared_preferences.dart';
2 |
3 | class SpUtil {
4 | static SharedPreferences _instance;
5 |
6 | ///使用前必须初始化
7 | static void init() async {
8 | _instance = await SharedPreferences.getInstance();
9 | }
10 |
11 | /// 保存数据
12 | static void put(String key, T value) async{
13 | SharedPreferences instance = await SharedPreferences.getInstance();
14 |
15 | switch (T) {
16 | case String:
17 | instance.setString(key, value as String);
18 | break;
19 | case int:
20 | instance.setInt(key, value as int);
21 | break;
22 | case bool:
23 | instance.setBool(key, value as bool);
24 | break;
25 | case double:
26 | instance.setDouble(key, value as double);
27 | break;
28 | }
29 | }
30 |
31 | /// 读取数据
32 | static Future get(String key) async {
33 | SharedPreferences instance = await SharedPreferences.getInstance();
34 |
35 | T res;
36 | switch (T) {
37 | case String:
38 | res = instance.getString(key) as T;
39 | break;
40 | case int:
41 | res = instance.getInt(key) as T;
42 | break;
43 | case bool:
44 | res = instance.getBool(key) as T;
45 | break;
46 | case double:
47 | res = instance.getDouble(key) as T;
48 | break;
49 | }
50 | return res;
51 | }
52 | }
53 |
--------------------------------------------------------------------------------
/lib/app/utils/show/toast_util.dart:
--------------------------------------------------------------------------------
1 | import 'package:flutter/material.dart';
2 | import 'package:flutter_wan/app/utils/ui/ui_adapter.dart';
3 | import 'package:fluttertoast/fluttertoast.dart';
4 |
5 | void showToast(msg) {
6 | Fluttertoast.showToast(
7 | msg: msg,
8 | toastLength: Toast.LENGTH_SHORT,
9 | gravity: ToastGravity.CENTER,
10 | timeInSecForIosWeb: 1,
11 | backgroundColor: Colors.grey,
12 | textColor: Colors.white,
13 | fontSize: setSp(32),
14 | );
15 | }
16 |
--------------------------------------------------------------------------------
/lib/app/utils/tool/string_util.dart:
--------------------------------------------------------------------------------
1 | class StringUtil {
2 | ///判断是否为空
3 | static bool isEmpty(String s) {
4 | if (s == null || s == '') {
5 | return true;
6 | }
7 |
8 | return false;
9 | }
10 | }
11 |
--------------------------------------------------------------------------------
/lib/app/utils/ui/future.dart:
--------------------------------------------------------------------------------
1 | import 'dart:async';
2 |
3 |
--------------------------------------------------------------------------------
/lib/app/utils/ui/keep_alive_page.dart:
--------------------------------------------------------------------------------
1 | import 'package:flutter/cupertino.dart';
2 |
3 | //页面保活方法
4 | Widget keepAlivePage(Widget child) => AliveWidget(child: child);
5 |
6 | class AliveWidget extends StatefulWidget {
7 | final Widget child;
8 |
9 | AliveWidget({this.child});
10 |
11 | @override
12 | State createState() {
13 | return _KeepAliveState();
14 | }
15 | }
16 |
17 | class _KeepAliveState extends State
18 | with AutomaticKeepAliveClientMixin {
19 | @override
20 | bool get wantKeepAlive => true;
21 |
22 | @override
23 | Widget build(BuildContext context) {
24 | super.build(context);
25 | return widget.child;
26 | }
27 | }
28 |
--------------------------------------------------------------------------------
/lib/app/utils/ui/ui_adapter.dart:
--------------------------------------------------------------------------------
1 | import 'dart:io';
2 |
3 | import 'package:flutter/cupertino.dart';
4 | import 'package:flutter_screenutil/flutter_screenutil.dart';
5 |
6 | //按照宽度适配
7 | double setWidth(double size) {
8 | return ScreenUtil().setWidth(size);
9 | }
10 |
11 | //按照高度适配
12 | double setHeight(double size) {
13 | return ScreenUtil().setHeight(size);
14 | }
15 |
16 | //适配文字
17 | double setSp(double size) {
18 | if (isMobile()) {
19 | return ScreenUtil().setSp(size);
20 | } else {
21 | return size.toDouble();
22 | }
23 | }
24 |
25 | //自动适配,方便调整
26 | double auto(double size) {
27 | if (isMobile()) {
28 | return ScreenUtil().setWidth(size);
29 | } else {
30 | return size.toDouble();
31 | }
32 | }
33 |
34 | //界面适配
35 | void initUiAdapter(BuildContext context) {
36 | //填入设计稿中设备的屏幕尺寸
37 | //默认 width : 1080px , height:1920px , allowFontScaling:false
38 | // ScreenUtil.init(context);
39 | //假如设计稿是按iPhone6的尺寸设计的(iPhone6 750*1334)
40 | // ScreenUtil.init(context, width: 750, height: 1334);
41 | //设置字体大小根据系统的“字体大小”辅助选项来进行缩放,默认为false
42 | // ScreenUtil.init(context, width: 750, height: 1334, allowFontScaling: true);
43 | if (!isMobile()) {
44 | return;
45 | }
46 | ScreenUtil.init(context, width: 750, height: 1334, allowFontScaling: true);
47 | }
48 |
49 |
50 | //判断是否是移动端平台
51 | bool isMobile() {
52 | if (Platform.isAndroid || Platform.isIOS) {
53 | return true;
54 | } else {
55 | return false;
56 | }
57 | }
58 |
59 |
60 | extension dimensionsNum on num {
61 | ///自动适配移动界面
62 | num get dp => auto(this);
63 |
64 | ///配置文字,文字适配请用sp单位
65 | num get sp => setSp(this);
66 | }
67 |
--------------------------------------------------------------------------------
/lib/app/utils/ui/view_util.dart:
--------------------------------------------------------------------------------
1 | import 'dart:async';
2 |
3 | import 'package:flutter/cupertino.dart';
4 |
5 | class ViewUtil {
6 | ///界面初始化完成好的
7 | static Future initFinish() async {
8 | Completer completer = new Completer();
9 |
10 | WidgetsBinding.instance.addPostFrameCallback((timeStamp) {
11 | completer.complete();
12 | });
13 |
14 | return completer.future;
15 | }
16 | }
17 |
--------------------------------------------------------------------------------
/lib/bean/README.md:
--------------------------------------------------------------------------------
1 | ## 实体命名生成
2 | json快捷生成bean文件网址:[https://caijinglong.github.io/json2dart/index_ch.html](https://caijinglong.github.io/json2dart/index_ch.html)
3 |
4 | ## 生成实体附属文件命令
5 |
6 | ### 使用 build_runner 生成 .g.dart 文件
7 | flutter packages pub run build_runner build
8 |
9 | ### 监控生成文件,如果有改动时自动生成/更新 .g.dart 文件
10 | flutter packages pub run build_runner watch
11 |
12 | ### 删除并重新创建.g.dart文件
13 | flutter packages pub run build_runner build --delete-conflicting-outputs
14 |
15 |
16 |
--------------------------------------------------------------------------------
/lib/bean/common/article_detail_bean.dart:
--------------------------------------------------------------------------------
1 | class ArticleDetailBean {
2 | ArticleDetailBean({
3 | this.title,
4 | this.url,
5 | this.id,
6 | this.isCollect,
7 | });
8 |
9 | ///文章id
10 | int id;
11 |
12 | ///标题
13 | String title;
14 |
15 | ///文章链接
16 | String url;
17 |
18 | ///是否被收藏
19 | bool isCollect;
20 | }
21 |
--------------------------------------------------------------------------------
/lib/bean/common/btn_info.dart:
--------------------------------------------------------------------------------
1 | import 'package:flutter/material.dart';
2 |
3 | ///按钮信息
4 | class BtnInfo {
5 | BtnInfo({
6 | this.title,
7 | this.tag,
8 | this.icon,
9 | });
10 |
11 | ///按钮名称
12 | String title;
13 |
14 | ///按钮标识
15 | String tag;
16 |
17 | ///正常情况图标
18 | Icon icon;
19 |
20 |
21 | /// jsonDecode(jsonStr) 方法中会调用实体类的这个方法。如果实体类中没有这个方法,会报错。
22 | Map toJson() {
23 | Map map = Map();
24 | map["title"] = this.title;
25 | map["tag"] = this.tag;
26 | map["icon"] = this.icon;
27 | return map;
28 | }
29 | }
30 |
--------------------------------------------------------------------------------
/lib/bean/home/banner_bean.dart:
--------------------------------------------------------------------------------
1 | import 'package:json_annotation/json_annotation.dart';
2 |
3 | part 'banner_bean.g.dart';
4 |
5 | @JsonSerializable()
6 | class BannerBean extends Object {
7 | @JsonKey(name: 'data')
8 | List data;
9 |
10 | @JsonKey(name: 'errorCode')
11 | int errorCode;
12 |
13 | @JsonKey(name: 'errorMsg')
14 | String errorMsg;
15 |
16 | BannerBean(
17 | this.data,
18 | this.errorCode,
19 | this.errorMsg,
20 | );
21 |
22 | factory BannerBean.fromJson(Map srcJson) =>
23 | _$BannerBeanFromJson(srcJson);
24 |
25 | Map toJson() => _$BannerBeanToJson(this);
26 | }
27 |
28 | @JsonSerializable()
29 | class Data extends Object {
30 | @JsonKey(name: 'desc')
31 | String desc;
32 |
33 | @JsonKey(name: 'id')
34 | int id;
35 |
36 | @JsonKey(name: 'imagePath')
37 | String imagePath;
38 |
39 | @JsonKey(name: 'isVisible')
40 | int isVisible;
41 |
42 | @JsonKey(name: 'order')
43 | int order;
44 |
45 | @JsonKey(name: 'title')
46 | String title;
47 |
48 | @JsonKey(name: 'type')
49 | int type;
50 |
51 | @JsonKey(name: 'url')
52 | String url;
53 |
54 | Data(
55 | this.desc,
56 | this.id,
57 | this.imagePath,
58 | this.isVisible,
59 | this.order,
60 | this.title,
61 | this.type,
62 | this.url,
63 | );
64 |
65 | factory Data.fromJson(Map srcJson) =>
66 | _$DataFromJson(srcJson);
67 |
68 | Map toJson() => _$DataToJson(this);
69 | }
70 |
--------------------------------------------------------------------------------
/lib/bean/home/banner_bean.g.dart:
--------------------------------------------------------------------------------
1 | // GENERATED CODE - DO NOT MODIFY BY HAND
2 |
3 | part of 'banner_bean.dart';
4 |
5 | // **************************************************************************
6 | // JsonSerializableGenerator
7 | // **************************************************************************
8 |
9 | BannerBean _$BannerBeanFromJson(Map json) {
10 | return BannerBean(
11 | (json['data'] as List)
12 | ?.map(
13 | (e) => e == null ? null : Data.fromJson(e as Map))
14 | ?.toList(),
15 | json['errorCode'] as int,
16 | json['errorMsg'] as String,
17 | );
18 | }
19 |
20 | Map _$BannerBeanToJson(BannerBean instance) =>
21 | {
22 | 'data': instance.data,
23 | 'errorCode': instance.errorCode,
24 | 'errorMsg': instance.errorMsg,
25 | };
26 |
27 | Data _$DataFromJson(Map json) {
28 | return Data(
29 | json['desc'] as String,
30 | json['id'] as int,
31 | json['imagePath'] as String,
32 | json['isVisible'] as int,
33 | json['order'] as int,
34 | json['title'] as String,
35 | json['type'] as int,
36 | json['url'] as String,
37 | );
38 | }
39 |
40 | Map _$DataToJson(Data instance) => {
41 | 'desc': instance.desc,
42 | 'id': instance.id,
43 | 'imagePath': instance.imagePath,
44 | 'isVisible': instance.isVisible,
45 | 'order': instance.order,
46 | 'title': instance.title,
47 | 'type': instance.type,
48 | 'url': instance.url,
49 | };
50 |
--------------------------------------------------------------------------------
/lib/bean/project/project_bean.dart:
--------------------------------------------------------------------------------
1 | import 'package:json_annotation/json_annotation.dart';
2 |
3 | part 'project_bean.g.dart';
4 |
5 |
6 | @JsonSerializable()
7 | class ProjectBean extends Object {
8 |
9 | @JsonKey(name: 'data')
10 | List data;
11 |
12 | @JsonKey(name: 'errorCode')
13 | int errorCode;
14 |
15 | @JsonKey(name: 'errorMsg')
16 | String errorMsg;
17 |
18 | ProjectBean(this.data,this.errorCode,this.errorMsg,);
19 |
20 | factory ProjectBean.fromJson(Map srcJson) => _$ProjectBeanFromJson(srcJson);
21 |
22 | Map toJson() => _$ProjectBeanToJson(this);
23 |
24 | }
25 |
26 |
27 | @JsonSerializable()
28 | class Data extends Object {
29 |
30 | @JsonKey(name: 'children')
31 | List children;
32 |
33 | @JsonKey(name: 'courseId')
34 | int courseId;
35 |
36 | @JsonKey(name: 'id')
37 | int id;
38 |
39 | @JsonKey(name: 'name')
40 | String name;
41 |
42 | @JsonKey(name: 'order')
43 | int order;
44 |
45 | @JsonKey(name: 'parentChapterId')
46 | int parentChapterId;
47 |
48 | @JsonKey(name: 'userControlSetTop')
49 | bool userControlSetTop;
50 |
51 | @JsonKey(name: 'visible')
52 | int visible;
53 |
54 | Data(this.children,this.courseId,this.id,this.name,this.order,this.parentChapterId,this.userControlSetTop,this.visible,);
55 |
56 | factory Data.fromJson(Map srcJson) => _$DataFromJson(srcJson);
57 |
58 | Map toJson() => _$DataToJson(this);
59 |
60 | }
61 |
62 |
63 |
--------------------------------------------------------------------------------
/lib/bean/project/project_bean.g.dart:
--------------------------------------------------------------------------------
1 | // GENERATED CODE - DO NOT MODIFY BY HAND
2 |
3 | part of 'project_bean.dart';
4 |
5 | // **************************************************************************
6 | // JsonSerializableGenerator
7 | // **************************************************************************
8 |
9 | ProjectBean _$ProjectBeanFromJson(Map json) {
10 | return ProjectBean(
11 | (json['data'] as List)
12 | ?.map(
13 | (e) => e == null ? null : Data.fromJson(e as Map))
14 | ?.toList(),
15 | json['errorCode'] as int,
16 | json['errorMsg'] as String,
17 | );
18 | }
19 |
20 | Map _$ProjectBeanToJson(ProjectBean instance) =>
21 | {
22 | 'data': instance.data,
23 | 'errorCode': instance.errorCode,
24 | 'errorMsg': instance.errorMsg,
25 | };
26 |
27 | Data _$DataFromJson(Map json) {
28 | return Data(
29 | json['children'] as List,
30 | json['courseId'] as int,
31 | json['id'] as int,
32 | json['name'] as String,
33 | json['order'] as int,
34 | json['parentChapterId'] as int,
35 | json['userControlSetTop'] as bool,
36 | json['visible'] as int,
37 | );
38 | }
39 |
40 | Map _$DataToJson(Data instance) => {
41 | 'children': instance.children,
42 | 'courseId': instance.courseId,
43 | 'id': instance.id,
44 | 'name': instance.name,
45 | 'order': instance.order,
46 | 'parentChapterId': instance.parentChapterId,
47 | 'userControlSetTop': instance.userControlSetTop,
48 | 'visible': instance.visible,
49 | };
50 |
--------------------------------------------------------------------------------
/lib/bean/tree/tree_info_bean.dart:
--------------------------------------------------------------------------------
1 | import 'package:json_annotation/json_annotation.dart';
2 |
3 | part 'tree_info_bean.g.dart';
4 |
5 | @JsonSerializable()
6 | class TreeInfoBean extends Object {
7 | @JsonKey(name: 'data')
8 | List data;
9 |
10 | @JsonKey(name: 'errorCode')
11 | int errorCode;
12 |
13 | @JsonKey(name: 'errorMsg')
14 | String errorMsg;
15 |
16 | TreeInfoBean(
17 | this.data,
18 | this.errorCode,
19 | this.errorMsg,
20 | );
21 |
22 | factory TreeInfoBean.fromJson(Map srcJson) =>
23 | _$TreeInfoBeanFromJson(srcJson);
24 |
25 | Map toJson() => _$TreeInfoBeanToJson(this);
26 | }
27 |
28 | @JsonSerializable()
29 | class Data extends Object {
30 | @JsonKey(name: 'children')
31 | List children;
32 |
33 | @JsonKey(name: 'courseId')
34 | int courseId;
35 |
36 | @JsonKey(name: 'id')
37 | int id;
38 |
39 | @JsonKey(name: 'name')
40 | String name;
41 |
42 | @JsonKey(name: 'order')
43 | int order;
44 |
45 | @JsonKey(name: 'parentChapterId')
46 | int parentChapterId;
47 |
48 | @JsonKey(name: 'userControlSetTop')
49 | bool userControlSetTop;
50 |
51 | @JsonKey(name: 'visible')
52 | int visible;
53 |
54 | Data(
55 | this.children,
56 | this.courseId,
57 | this.id,
58 | this.name,
59 | this.order,
60 | this.parentChapterId,
61 | this.userControlSetTop,
62 | this.visible,
63 | );
64 |
65 | factory Data.fromJson(Map srcJson) =>
66 | _$DataFromJson(srcJson);
67 |
68 | Map toJson() => _$DataToJson(this);
69 | }
70 |
71 | @JsonSerializable()
72 | class Children extends Object {
73 | @JsonKey(name: 'children')
74 | List children;
75 |
76 | @JsonKey(name: 'courseId')
77 | int courseId;
78 |
79 | @JsonKey(name: 'id')
80 | int id;
81 |
82 | @JsonKey(name: 'name')
83 | String name;
84 |
85 | @JsonKey(name: 'order')
86 | int order;
87 |
88 | @JsonKey(name: 'parentChapterId')
89 | int parentChapterId;
90 |
91 | @JsonKey(name: 'userControlSetTop')
92 | bool userControlSetTop;
93 |
94 | @JsonKey(name: 'visible')
95 | int visible;
96 |
97 | Children(
98 | this.children,
99 | this.courseId,
100 | this.id,
101 | this.name,
102 | this.order,
103 | this.parentChapterId,
104 | this.userControlSetTop,
105 | this.visible,
106 | );
107 |
108 | factory Children.fromJson(Map srcJson) =>
109 | _$ChildrenFromJson(srcJson);
110 |
111 | Map toJson() => _$ChildrenToJson(this);
112 | }
113 |
--------------------------------------------------------------------------------
/lib/bean/tree/tree_info_bean.g.dart:
--------------------------------------------------------------------------------
1 | // GENERATED CODE - DO NOT MODIFY BY HAND
2 |
3 | part of 'tree_info_bean.dart';
4 |
5 | // **************************************************************************
6 | // JsonSerializableGenerator
7 | // **************************************************************************
8 |
9 | TreeInfoBean _$TreeInfoBeanFromJson(Map json) {
10 | return TreeInfoBean(
11 | (json['data'] as List)
12 | ?.map(
13 | (e) => e == null ? null : Data.fromJson(e as Map))
14 | ?.toList(),
15 | json['errorCode'] as int,
16 | json['errorMsg'] as String,
17 | );
18 | }
19 |
20 | Map _$TreeInfoBeanToJson(TreeInfoBean instance) =>
21 | {
22 | 'data': instance.data,
23 | 'errorCode': instance.errorCode,
24 | 'errorMsg': instance.errorMsg,
25 | };
26 |
27 | Data _$DataFromJson(Map json) {
28 | return Data(
29 | (json['children'] as List)
30 | ?.map((e) =>
31 | e == null ? null : Children.fromJson(e as Map))
32 | ?.toList(),
33 | json['courseId'] as int,
34 | json['id'] as int,
35 | json['name'] as String,
36 | json['order'] as int,
37 | json['parentChapterId'] as int,
38 | json['userControlSetTop'] as bool,
39 | json['visible'] as int,
40 | );
41 | }
42 |
43 | Map _$DataToJson(Data instance) => {
44 | 'children': instance.children,
45 | 'courseId': instance.courseId,
46 | 'id': instance.id,
47 | 'name': instance.name,
48 | 'order': instance.order,
49 | 'parentChapterId': instance.parentChapterId,
50 | 'userControlSetTop': instance.userControlSetTop,
51 | 'visible': instance.visible,
52 | };
53 |
54 | Children _$ChildrenFromJson(Map json) {
55 | return Children(
56 | json['children'] as List,
57 | json['courseId'] as int,
58 | json['id'] as int,
59 | json['name'] as String,
60 | json['order'] as int,
61 | json['parentChapterId'] as int,
62 | json['userControlSetTop'] as bool,
63 | json['visible'] as int,
64 | );
65 | }
66 |
67 | Map _$ChildrenToJson(Children instance) => {
68 | 'children': instance.children,
69 | 'courseId': instance.courseId,
70 | 'id': instance.id,
71 | 'name': instance.name,
72 | 'order': instance.order,
73 | 'parentChapterId': instance.parentChapterId,
74 | 'userControlSetTop': instance.userControlSetTop,
75 | 'visible': instance.visible,
76 | };
77 |
--------------------------------------------------------------------------------
/lib/bean/user/collect_list_bean.dart:
--------------------------------------------------------------------------------
1 | import 'package:json_annotation/json_annotation.dart';
2 |
3 | part 'collect_list_bean.g.dart';
4 |
5 |
6 | @JsonSerializable()
7 | class CollectListBean extends Object {
8 |
9 | @JsonKey(name: 'data')
10 | Data data;
11 |
12 | @JsonKey(name: 'errorCode')
13 | int errorCode;
14 |
15 | @JsonKey(name: 'errorMsg')
16 | String errorMsg;
17 |
18 | CollectListBean(this.data,this.errorCode,this.errorMsg,);
19 |
20 | factory CollectListBean.fromJson(Map srcJson) => _$CollectListBeanFromJson(srcJson);
21 |
22 | Map toJson() => _$CollectListBeanToJson(this);
23 |
24 | }
25 |
26 |
27 | @JsonSerializable()
28 | class Data extends Object {
29 |
30 | @JsonKey(name: 'curPage')
31 | int curPage;
32 |
33 | @JsonKey(name: 'datas')
34 | List datas;
35 |
36 | @JsonKey(name: 'offset')
37 | int offset;
38 |
39 | @JsonKey(name: 'over')
40 | bool over;
41 |
42 | @JsonKey(name: 'pageCount')
43 | int pageCount;
44 |
45 | @JsonKey(name: 'size')
46 | int size;
47 |
48 | @JsonKey(name: 'total')
49 | int total;
50 |
51 | Data(this.curPage,this.datas,this.offset,this.over,this.pageCount,this.size,this.total,);
52 |
53 | factory Data.fromJson(Map srcJson) => _$DataFromJson(srcJson);
54 |
55 | Map toJson() => _$DataToJson(this);
56 |
57 | }
58 |
59 |
60 | @JsonSerializable()
61 | class Datas extends Object {
62 |
63 | @JsonKey(name: 'author')
64 | String author;
65 |
66 | @JsonKey(name: 'chapterId')
67 | int chapterId;
68 |
69 | @JsonKey(name: 'chapterName')
70 | String chapterName;
71 |
72 | @JsonKey(name: 'courseId')
73 | int courseId;
74 |
75 | @JsonKey(name: 'desc')
76 | String desc;
77 |
78 | @JsonKey(name: 'envelopePic')
79 | String envelopePic;
80 |
81 | @JsonKey(name: 'id')
82 | int id;
83 |
84 | @JsonKey(name: 'link')
85 | String link;
86 |
87 | @JsonKey(name: 'niceDate')
88 | String niceDate;
89 |
90 | @JsonKey(name: 'origin')
91 | String origin;
92 |
93 | @JsonKey(name: 'originId')
94 | int originId;
95 |
96 | @JsonKey(name: 'publishTime')
97 | int publishTime;
98 |
99 | @JsonKey(name: 'title')
100 | String title;
101 |
102 | @JsonKey(name: 'userId')
103 | int userId;
104 |
105 | @JsonKey(name: 'visible')
106 | int visible;
107 |
108 | @JsonKey(name: 'zan')
109 | int zan;
110 |
111 | Datas(this.author,this.chapterId,this.chapterName,this.courseId,this.desc,this.envelopePic,this.id,this.link,this.niceDate,this.origin,this.originId,this.publishTime,this.title,this.userId,this.visible,this.zan,);
112 |
113 | factory Datas.fromJson(Map srcJson) => _$DatasFromJson(srcJson);
114 |
115 | Map toJson() => _$DatasToJson(this);
116 |
117 | }
118 |
119 |
120 |
--------------------------------------------------------------------------------
/lib/bean/user/common_response.dart:
--------------------------------------------------------------------------------
1 | import 'package:json_annotation/json_annotation.dart';
2 |
3 | part 'common_response.g.dart';
4 |
5 |
6 | @JsonSerializable()
7 | class CommonResponse extends Object {
8 |
9 | @JsonKey(name: 'data')
10 | String data;
11 |
12 | @JsonKey(name: 'errorCode')
13 | int errorCode;
14 |
15 | @JsonKey(name: 'errorMsg')
16 | String errorMsg;
17 |
18 | CommonResponse(this.data,this.errorCode,this.errorMsg,);
19 |
20 | factory CommonResponse.fromJson(Map srcJson) => _$CommonResponseFromJson(srcJson);
21 |
22 | Map toJson() => _$CommonResponseToJson(this);
23 |
24 | }
25 |
26 |
27 |
--------------------------------------------------------------------------------
/lib/bean/user/common_response.g.dart:
--------------------------------------------------------------------------------
1 | // GENERATED CODE - DO NOT MODIFY BY HAND
2 |
3 | part of 'common_response.dart';
4 |
5 | // **************************************************************************
6 | // JsonSerializableGenerator
7 | // **************************************************************************
8 |
9 | CommonResponse _$CommonResponseFromJson(Map json) {
10 | return CommonResponse(
11 | json['data'] as String,
12 | json['errorCode'] as int,
13 | json['errorMsg'] as String,
14 | );
15 | }
16 |
17 | Map _$CommonResponseToJson(CommonResponse instance) =>
18 | {
19 | 'data': instance.data,
20 | 'errorCode': instance.errorCode,
21 | 'errorMsg': instance.errorMsg,
22 | };
23 |
--------------------------------------------------------------------------------
/lib/bean/user/hot_word_bean.dart:
--------------------------------------------------------------------------------
1 | import 'package:json_annotation/json_annotation.dart';
2 |
3 | part 'hot_word_bean.g.dart';
4 |
5 |
6 | @JsonSerializable()
7 | class HotWordBean extends Object {
8 |
9 | @JsonKey(name: 'data')
10 | List data;
11 |
12 | @JsonKey(name: 'errorCode')
13 | int errorCode;
14 |
15 | @JsonKey(name: 'errorMsg')
16 | String errorMsg;
17 |
18 | HotWordBean(this.data,this.errorCode,this.errorMsg,);
19 |
20 | factory HotWordBean.fromJson(Map srcJson) => _$HotWordBeanFromJson(srcJson);
21 |
22 | Map toJson() => _$HotWordBeanToJson(this);
23 |
24 | }
25 |
26 |
27 | @JsonSerializable()
28 | class Data extends Object {
29 |
30 | @JsonKey(name: 'id')
31 | int id;
32 |
33 | @JsonKey(name: 'link')
34 | String link;
35 |
36 | @JsonKey(name: 'name')
37 | String name;
38 |
39 | @JsonKey(name: 'order')
40 | int order;
41 |
42 | @JsonKey(name: 'visible')
43 | int visible;
44 |
45 | Data(this.id,this.link,this.name,this.order,this.visible,);
46 |
47 | factory Data.fromJson(Map srcJson) => _$DataFromJson(srcJson);
48 |
49 | Map toJson() => _$DataToJson(this);
50 |
51 | }
52 |
53 |
54 |
--------------------------------------------------------------------------------
/lib/bean/user/hot_word_bean.g.dart:
--------------------------------------------------------------------------------
1 | // GENERATED CODE - DO NOT MODIFY BY HAND
2 |
3 | part of 'hot_word_bean.dart';
4 |
5 | // **************************************************************************
6 | // JsonSerializableGenerator
7 | // **************************************************************************
8 |
9 | HotWordBean _$HotWordBeanFromJson(Map json) {
10 | return HotWordBean(
11 | (json['data'] as List)
12 | ?.map(
13 | (e) => e == null ? null : Data.fromJson(e as Map))
14 | ?.toList(),
15 | json['errorCode'] as int,
16 | json['errorMsg'] as String,
17 | );
18 | }
19 |
20 | Map _$HotWordBeanToJson(HotWordBean instance) =>
21 | {
22 | 'data': instance.data,
23 | 'errorCode': instance.errorCode,
24 | 'errorMsg': instance.errorMsg,
25 | };
26 |
27 | Data _$DataFromJson(Map json) {
28 | return Data(
29 | json['id'] as int,
30 | json['link'] as String,
31 | json['name'] as String,
32 | json['order'] as int,
33 | json['visible'] as int,
34 | );
35 | }
36 |
37 | Map _$DataToJson(Data instance) => {
38 | 'id': instance.id,
39 | 'link': instance.link,
40 | 'name': instance.name,
41 | 'order': instance.order,
42 | 'visible': instance.visible,
43 | };
44 |
--------------------------------------------------------------------------------
/lib/bean/user/login_info_bean.dart:
--------------------------------------------------------------------------------
1 | import 'package:json_annotation/json_annotation.dart';
2 |
3 | part 'login_info_bean.g.dart';
4 |
5 | @JsonSerializable()
6 | class LoginInfoBean extends Object {
7 | @JsonKey(name: 'data')
8 | Data data;
9 |
10 | @JsonKey(name: 'errorCode')
11 | int errorCode;
12 |
13 | @JsonKey(name: 'errorMsg')
14 | String errorMsg;
15 |
16 | LoginInfoBean(
17 | this.data,
18 | this.errorCode,
19 | this.errorMsg,
20 | );
21 |
22 | factory LoginInfoBean.fromJson(Map srcJson) =>
23 | _$LoginInfoBeanFromJson(srcJson);
24 |
25 | Map toJson() => _$LoginInfoBeanToJson(this);
26 | }
27 |
28 | @JsonSerializable()
29 | class Data extends Object {
30 | @JsonKey(name: 'admin')
31 | bool admin;
32 |
33 | @JsonKey(name: 'chapterTops')
34 | List chapterTops;
35 |
36 | @JsonKey(name: 'coinCount')
37 | int coinCount;
38 |
39 | @JsonKey(name: 'collectIds')
40 | List collectIds;
41 |
42 | @JsonKey(name: 'email')
43 | String email;
44 |
45 | @JsonKey(name: 'icon')
46 | String icon;
47 |
48 | @JsonKey(name: 'id')
49 | int id;
50 |
51 | @JsonKey(name: 'nickname')
52 | String nickname;
53 |
54 | @JsonKey(name: 'password')
55 | String password;
56 |
57 | @JsonKey(name: 'publicName')
58 | String publicName;
59 |
60 | @JsonKey(name: 'token')
61 | String token;
62 |
63 | @JsonKey(name: 'type')
64 | int type;
65 |
66 | @JsonKey(name: 'username')
67 | String username;
68 |
69 | Data(
70 | this.admin,
71 | this.chapterTops,
72 | this.coinCount,
73 | this.collectIds,
74 | this.email,
75 | this.icon,
76 | this.id,
77 | this.nickname,
78 | this.password,
79 | this.publicName,
80 | this.token,
81 | this.type,
82 | this.username,
83 | );
84 |
85 | factory Data.fromJson(Map srcJson) =>
86 | _$DataFromJson(srcJson);
87 |
88 | Map toJson() => _$DataToJson(this);
89 | }
90 |
--------------------------------------------------------------------------------
/lib/bean/user/login_info_bean.g.dart:
--------------------------------------------------------------------------------
1 | // GENERATED CODE - DO NOT MODIFY BY HAND
2 |
3 | part of 'login_info_bean.dart';
4 |
5 | // **************************************************************************
6 | // JsonSerializableGenerator
7 | // **************************************************************************
8 |
9 | LoginInfoBean _$LoginInfoBeanFromJson(Map json) {
10 | return LoginInfoBean(
11 | json['data'] == null
12 | ? null
13 | : Data.fromJson(json['data'] as Map),
14 | json['errorCode'] as int,
15 | json['errorMsg'] as String,
16 | );
17 | }
18 |
19 | Map _$LoginInfoBeanToJson(LoginInfoBean instance) =>
20 | {
21 | 'data': instance.data,
22 | 'errorCode': instance.errorCode,
23 | 'errorMsg': instance.errorMsg,
24 | };
25 |
26 | Data _$DataFromJson(Map json) {
27 | return Data(
28 | json['admin'] as bool,
29 | json['chapterTops'] as List,
30 | json['coinCount'] as int,
31 | json['collectIds'] as List,
32 | json['email'] as String,
33 | json['icon'] as String,
34 | json['id'] as int,
35 | json['nickname'] as String,
36 | json['password'] as String,
37 | json['publicName'] as String,
38 | json['token'] as String,
39 | json['type'] as int,
40 | json['username'] as String,
41 | );
42 | }
43 |
44 | Map _$DataToJson(Data instance) => {
45 | 'admin': instance.admin,
46 | 'chapterTops': instance.chapterTops,
47 | 'coinCount': instance.coinCount,
48 | 'collectIds': instance.collectIds,
49 | 'email': instance.email,
50 | 'icon': instance.icon,
51 | 'id': instance.id,
52 | 'nickname': instance.nickname,
53 | 'password': instance.password,
54 | 'publicName': instance.publicName,
55 | 'token': instance.token,
56 | 'type': instance.type,
57 | 'username': instance.username,
58 | };
59 |
--------------------------------------------------------------------------------
/lib/bean/user/register_info_bean.dart:
--------------------------------------------------------------------------------
1 | import 'package:json_annotation/json_annotation.dart';
2 |
3 | part 'register_info_bean.g.dart';
4 |
5 |
6 | @JsonSerializable()
7 | class RegisterInfoBean extends Object {
8 |
9 | @JsonKey(name: 'data')
10 | Data data;
11 |
12 | @JsonKey(name: 'errorCode')
13 | int errorCode;
14 |
15 | @JsonKey(name: 'errorMsg')
16 | String errorMsg;
17 |
18 | RegisterInfoBean(this.data,this.errorCode,this.errorMsg,);
19 |
20 | factory RegisterInfoBean.fromJson(Map srcJson) => _$RegisterInfoBeanFromJson(srcJson);
21 |
22 | Map toJson() => _$RegisterInfoBeanToJson(this);
23 |
24 | }
25 |
26 |
27 | @JsonSerializable()
28 | class Data extends Object {
29 |
30 | @JsonKey(name: 'admin')
31 | bool admin;
32 |
33 | @JsonKey(name: 'chapterTops')
34 | List chapterTops;
35 |
36 | @JsonKey(name: 'coinCount')
37 | int coinCount;
38 |
39 | @JsonKey(name: 'collectIds')
40 | List collectIds;
41 |
42 | @JsonKey(name: 'email')
43 | String email;
44 |
45 | @JsonKey(name: 'icon')
46 | String icon;
47 |
48 | @JsonKey(name: 'id')
49 | int id;
50 |
51 | @JsonKey(name: 'nickname')
52 | String nickname;
53 |
54 | @JsonKey(name: 'password')
55 | String password;
56 |
57 | @JsonKey(name: 'publicName')
58 | String publicName;
59 |
60 | @JsonKey(name: 'token')
61 | String token;
62 |
63 | @JsonKey(name: 'type')
64 | int type;
65 |
66 | @JsonKey(name: 'username')
67 | String username;
68 |
69 | Data(this.admin,this.chapterTops,this.coinCount,this.collectIds,this.email,this.icon,this.id,this.nickname,this.password,this.publicName,this.token,this.type,this.username,);
70 |
71 | factory Data.fromJson(Map srcJson) => _$DataFromJson(srcJson);
72 |
73 | Map toJson() => _$DataToJson(this);
74 |
75 | }
76 |
77 |
78 |
--------------------------------------------------------------------------------
/lib/bean/user/register_info_bean.g.dart:
--------------------------------------------------------------------------------
1 | // GENERATED CODE - DO NOT MODIFY BY HAND
2 |
3 | part of 'register_info_bean.dart';
4 |
5 | // **************************************************************************
6 | // JsonSerializableGenerator
7 | // **************************************************************************
8 |
9 | RegisterInfoBean _$RegisterInfoBeanFromJson(Map json) {
10 | return RegisterInfoBean(
11 | json['data'] == null
12 | ? null
13 | : Data.fromJson(json['data'] as Map),
14 | json['errorCode'] as int,
15 | json['errorMsg'] as String,
16 | );
17 | }
18 |
19 | Map _$RegisterInfoBeanToJson(RegisterInfoBean instance) =>
20 | {
21 | 'data': instance.data,
22 | 'errorCode': instance.errorCode,
23 | 'errorMsg': instance.errorMsg,
24 | };
25 |
26 | Data _$DataFromJson(Map json) {
27 | return Data(
28 | json['admin'] as bool,
29 | json['chapterTops'] as List,
30 | json['coinCount'] as int,
31 | json['collectIds'] as List,
32 | json['email'] as String,
33 | json['icon'] as String,
34 | json['id'] as int,
35 | json['nickname'] as String,
36 | json['password'] as String,
37 | json['publicName'] as String,
38 | json['token'] as String,
39 | json['type'] as int,
40 | json['username'] as String,
41 | );
42 | }
43 |
44 | Map _$DataToJson(Data instance) => {
45 | 'admin': instance.admin,
46 | 'chapterTops': instance.chapterTops,
47 | 'coinCount': instance.coinCount,
48 | 'collectIds': instance.collectIds,
49 | 'email': instance.email,
50 | 'icon': instance.icon,
51 | 'id': instance.id,
52 | 'nickname': instance.nickname,
53 | 'password': instance.password,
54 | 'publicName': instance.publicName,
55 | 'token': instance.token,
56 | 'type': instance.type,
57 | 'username': instance.username,
58 | };
59 |
--------------------------------------------------------------------------------
/lib/http/api.dart:
--------------------------------------------------------------------------------
1 | class ApiUrl {
2 | static const String _BASE_URL = "https://www.wanandroid.com";
3 |
4 | ///获取轮播信息 首页Banner
5 | static const String GET_BANNER_URL = "$_BASE_URL/banner/json";
6 |
7 | ///获取轮播信息 首页文章
8 | static const String GET_HOME_ARTICLE = "$_BASE_URL/article/list/";
9 |
10 | /// 获取体系数据
11 | static const String GET_TREE = "$_BASE_URL/tree/json";
12 |
13 | ///体系文章详情
14 | static const String GET_TREE_DETAIL = "$_BASE_URL/article/list/0/json";
15 |
16 | ///获取导航数据
17 | static const String GET_NAVI_INFO = "$_BASE_URL/navi/json";
18 |
19 | ///获取项目数据
20 | static const String GET_PROJECT_INFO = "$_BASE_URL/project/tree/json";
21 | static const String GET_PROJECT_DETAIL = "$_BASE_URL/project/list/1/json";
22 |
23 | ///登录
24 | static const String LOGIN = "$_BASE_URL/user/login";
25 |
26 | ///注册
27 | static const String REGISTER = "$_BASE_URL/user/register";
28 |
29 | ///收藏文章列表
30 | static const String COLLECT_ARTICLE_LIST = "$_BASE_URL/lg/collect/list/";
31 |
32 | ///收藏文章
33 | static const String COLLECT = "$_BASE_URL/lg/collect/";
34 |
35 | ///取消收藏文章
36 | static const String CANCEL_COLLECT = "$_BASE_URL/lg/uncollect_originId/";
37 |
38 | ///搜索热词
39 | static const String SEARCH_HOT_WORD = "$_BASE_URL/hotkey/json";
40 |
41 | ///搜索
42 | static const String SEARCH = "$_BASE_URL/article/query/";
43 | }
44 |
--------------------------------------------------------------------------------
/lib/http/http.dart:
--------------------------------------------------------------------------------
1 | import 'package:dio/dio.dart';
2 | import 'package:flutter_wan/app/utils/cache/sp_util.dart';
3 |
4 | ///获取dio设置
5 | Future getOptions() async {
6 | String userName = await SpUtil.get('userName');
7 | String password = await SpUtil.get('password');
8 |
9 | if (userName == null) {
10 | return null;
11 | }
12 |
13 | Map headers = Map();
14 | String cookie ="loginUserName=$userName;loginUserPassword=$password";
15 | headers['Cookie'] = cookie;
16 | Options options = Options(headers: headers);
17 |
18 | return options;
19 | }
20 |
--------------------------------------------------------------------------------
/lib/main.dart:
--------------------------------------------------------------------------------
1 | import 'package:flutter/cupertino.dart' hide Page;
2 | import 'package:flutter/material.dart' hide Page;
3 | import 'package:flutter_localizations/flutter_localizations.dart';
4 | import 'package:flutter_wan/app/init.dart';
5 |
6 | import 'app/config/route.dart';
7 |
8 | void main() {
9 | runApp(createApp());
10 | }
11 |
12 | Widget createApp() {
13 | return MyApp();
14 | }
15 |
16 |
17 | class _MyAppState extends State {
18 | @override
19 | void initState() {
20 | super.initState();
21 |
22 | initApp(context);
23 | }
24 |
25 | @override
26 | Widget build(BuildContext context) {
27 | return MaterialApp(
28 | title: '玩android',
29 | localizationsDelegates: [
30 | //国际化
31 | GlobalMaterialLocalizations.delegate,
32 | GlobalWidgetsLocalizations.delegate,
33 | ],
34 | home: RouteConfig.routes.buildPage(RouteConfig.mainPage, null), //作为默认页面
35 | onGenerateRoute: (RouteSettings settings) {
36 | //ios页面切换风格
37 | return CupertinoPageRoute(builder: (BuildContext context) {
38 | return RouteConfig.routes.buildPage(settings.name, settings.arguments);
39 | });
40 | },
41 | );
42 | }
43 | }
44 |
45 | class MyApp extends StatefulWidget {
46 | @override
47 | _MyAppState createState() => _MyAppState();
48 | }
49 |
--------------------------------------------------------------------------------
/lib/module/home/action.dart:
--------------------------------------------------------------------------------
1 | import 'package:fish_redux/fish_redux.dart';
2 |
3 | //TODO replace with your own action
4 | enum HomeAction {
5 | //切换banner数据
6 | switchBanner,
7 | //打开banner文章内容
8 | openBannerContent,
9 | //上拉加载
10 | onListLoad,
11 | //下拉刷新
12 | onListRefresh,
13 | //界面刷新
14 | onRefresh,
15 | }
16 |
17 | class HomeActionCreator {
18 | static Action onRefresh() {
19 | return Action(HomeAction.onRefresh);
20 | }
21 |
22 | static Action onListLoad() {
23 | return Action(HomeAction.onListLoad);
24 | }
25 |
26 | static Action onListRefresh() {
27 | return Action(HomeAction.onListRefresh);
28 | }
29 |
30 | static Action openBannerContent(int index) {
31 | return Action(HomeAction.openBannerContent, payload: index);
32 | }
33 |
34 | static Action switchBanner(int bannerImage) {
35 | return Action(HomeAction.switchBanner, payload: bannerImage);
36 | }
37 | }
38 |
--------------------------------------------------------------------------------
/lib/module/home/effect.dart:
--------------------------------------------------------------------------------
1 | import 'dart:convert';
2 |
3 | import 'package:dio/dio.dart';
4 | import 'package:fish_redux/fish_redux.dart';
5 | import 'package:flutter/material.dart' hide Action;
6 | import 'package:flutter_wan/app/config/route.dart';
7 | import 'package:flutter_wan/bean/common/article_detail_bean.dart';
8 | import 'package:flutter_wan/bean/home/banner_bean.dart';
9 | import 'package:flutter_wan/http/api.dart';
10 |
11 | import 'action.dart';
12 | import 'state.dart';
13 |
14 | Effect buildEffect() {
15 | return combineEffects(