├── README.md ├── flutter 笔记.txt ├── flutter_mfw ├── .gitignore ├── .metadata ├── README.md ├── android │ ├── app │ │ ├── build.gradle │ │ └── src │ │ │ ├── debug │ │ │ └── AndroidManifest.xml │ │ │ ├── main │ │ │ ├── AndroidManifest.xml │ │ │ ├── kotlin │ │ │ │ └── com │ │ │ │ │ └── yi │ │ │ │ │ └── jia │ │ │ │ │ └── dong │ │ │ │ │ └── flutter_mfw │ │ │ │ │ └── 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 │ │ │ │ └── styles.xml │ │ │ └── profile │ │ │ └── AndroidManifest.xml │ ├── build.gradle │ ├── gradle.properties │ ├── gradle │ │ └── wrapper │ │ │ └── gradle-wrapper.properties │ └── settings.gradle ├── assets │ ├── icon_favourite.png │ ├── icon_fengye.png │ ├── icon_gonglve.png │ ├── icon_hote.png │ ├── icon_huxian.png │ ├── icon_jipiao.png │ ├── icon_message.png │ ├── icon_right.png │ ├── icon_travel.png │ ├── icon_youji.png │ ├── images │ │ ├── 2.0x │ │ │ ├── icon_favourite.png │ │ │ ├── icon_fengye.png │ │ │ ├── icon_gonglve.png │ │ │ ├── icon_hote.png │ │ │ ├── icon_huxian.png │ │ │ ├── icon_jipiao.png │ │ │ ├── icon_message.png │ │ │ ├── icon_right.png │ │ │ ├── icon_travel.png │ │ │ ├── icon_youji.png │ │ │ ├── lishi.png │ │ │ ├── order.png │ │ │ ├── qianbi.png │ │ │ ├── saoma.png │ │ │ ├── setting.png │ │ │ ├── start.png │ │ │ ├── tab_default_mall.png │ │ │ ├── tab_destination_normal.png │ │ │ ├── tab_destination_selected.png │ │ │ ├── tab_focused_mall.png │ │ │ ├── tab_homepage_normal.png │ │ │ ├── tab_homepage_refresh.png │ │ │ ├── tab_homepage_selected.png │ │ │ ├── tab_hotel_normal.png │ │ │ ├── tab_hotel_selected.png │ │ │ ├── tab_mine_normal.png │ │ │ ├── tab_mine_selected.png │ │ │ └── topic.png │ │ └── 3.0x │ │ │ ├── icon_favourite.png │ │ │ ├── icon_fengye.png │ │ │ ├── icon_gonglve.png │ │ │ ├── icon_hote.png │ │ │ ├── icon_huxian.png │ │ │ ├── icon_jipiao.png │ │ │ ├── icon_message.png │ │ │ ├── icon_right.png │ │ │ ├── icon_travel.png │ │ │ ├── icon_youji.png │ │ │ ├── lishi.png │ │ │ ├── order.png │ │ │ ├── qianbi.png │ │ │ ├── saoma.png │ │ │ ├── setting.png │ │ │ ├── start.png │ │ │ ├── tab_default_mall.png │ │ │ ├── tab_destination_normal.png │ │ │ ├── tab_destination_selected.png │ │ │ ├── tab_focused_mall.png │ │ │ ├── tab_homepage_normal.png │ │ │ ├── tab_homepage_refresh.png │ │ │ ├── tab_homepage_selected.png │ │ │ ├── tab_hotel_normal.png │ │ │ ├── tab_hotel_selected.png │ │ │ ├── tab_mine_normal.png │ │ │ ├── tab_mine_selected.png │ │ │ └── topic.png │ ├── lishi.png │ ├── order.png │ ├── qianbi.png │ ├── saoma.png │ ├── setting.png │ ├── start.png │ ├── tab_default_mall.png │ ├── tab_destination_normal.png │ ├── tab_destination_selected.png │ ├── tab_focused_mall.png │ ├── tab_homepage_normal.png │ ├── tab_homepage_refresh.png │ ├── tab_homepage_selected.png │ ├── tab_hotel_normal.png │ ├── tab_hotel_selected.png │ ├── tab_mine_normal.png │ ├── tab_mine_selected.png │ └── topic.png ├── ios │ ├── Flutter │ │ ├── AppFrameworkInfo.plist │ │ ├── Debug.xcconfig │ │ ├── Flutter.podspec │ │ └── Release.xcconfig │ ├── Runner.xcodeproj │ │ ├── project.pbxproj │ │ ├── project.xcworkspace │ │ │ └── contents.xcworkspacedata │ │ └── xcshareddata │ │ │ └── xcschemes │ │ │ └── Runner.xcscheme │ ├── Runner.xcworkspace │ │ ├── contents.xcworkspacedata │ │ └── xcshareddata │ │ │ └── IDEWorkspaceChecks.plist │ └── Runner │ │ ├── AppDelegate.swift │ │ ├── Assets.xcassets │ │ ├── AppIcon.appiconset │ │ │ ├── Contents.json │ │ │ ├── Icon-App-1024x1024@1x.png │ │ │ ├── Icon-App-20x20@1x.png │ │ │ ├── Icon-App-20x20@2x.png │ │ │ ├── Icon-App-20x20@3x.png │ │ │ ├── Icon-App-29x29@1x.png │ │ │ ├── Icon-App-29x29@2x.png │ │ │ ├── Icon-App-29x29@3x.png │ │ │ ├── Icon-App-40x40@1x.png │ │ │ ├── Icon-App-40x40@2x.png │ │ │ ├── Icon-App-40x40@3x.png │ │ │ ├── Icon-App-60x60@2x.png │ │ │ ├── Icon-App-60x60@3x.png │ │ │ ├── Icon-App-76x76@1x.png │ │ │ ├── Icon-App-76x76@2x.png │ │ │ └── Icon-App-83.5x83.5@2x.png │ │ └── LaunchImage.imageset │ │ │ ├── Contents.json │ │ │ ├── LaunchImage.png │ │ │ ├── LaunchImage@2x.png │ │ │ ├── LaunchImage@3x.png │ │ │ └── README.md │ │ ├── Base.lproj │ │ ├── LaunchScreen.storyboard │ │ └── Main.storyboard │ │ ├── Info.plist │ │ └── Runner-Bridging-Header.h ├── lib │ ├── dao │ │ ├── home_dao.dart │ │ ├── location_dao.dart │ │ ├── my_dao.dart │ │ ├── travel_dao.dart │ │ └── travel_detail_dao.dart │ ├── main.dart │ ├── model │ │ ├── home_main_icon_model.dart │ │ ├── home_model.dart │ │ ├── hote_model.dart │ │ ├── location_model.dart │ │ ├── location_tababr_model.dart │ │ ├── location_where_model.dart │ │ ├── my_channel_model.dart │ │ ├── tabar_model.dart │ │ ├── travel_detail_model.dart │ │ ├── travel_header_model.dart │ │ ├── travel_list_model.dart │ │ └── waterfall_model.dart │ ├── pages │ │ ├── detail │ │ │ ├── detail_appbar_widget.dart │ │ │ ├── detail_bottom_bar_widget.dart │ │ │ ├── detail_carousel_widget.dart │ │ │ ├── detail_content_widget.dart │ │ │ ├── detail_recommend_title_widget.dart │ │ │ ├── detail_remind_widget.dart │ │ │ ├── detail_reply_widget.dart │ │ │ ├── detail_title_widget.dart │ │ │ └── travel_detail_widget.dart │ │ ├── home │ │ │ ├── home_page.dart │ │ │ ├── home_waterfall_page.dart │ │ │ ├── waterfall_widget │ │ │ │ └── water_fallItem_widget.dart │ │ │ └── widget │ │ │ │ ├── home_adv_widget.dart │ │ │ │ ├── home_hote_topic_widget.dart │ │ │ │ ├── home_navbar_widget.dart │ │ │ │ ├── home_tabbar_widget.dart │ │ │ │ └── home_top_nav.widget.dart │ │ ├── location │ │ │ ├── location_page.dart │ │ │ ├── page │ │ │ │ ├── location_recommend_page.dart │ │ │ │ └── location_reserve_page.dart │ │ │ └── widget │ │ │ │ ├── location_adv_widget.dart │ │ │ │ ├── location_navbar_widget.dart │ │ │ │ ├── location_nearly_widget.dart │ │ │ │ ├── location_sticky_category_widget.dart │ │ │ │ ├── location_stycky_widget.dart │ │ │ │ ├── location_synthesize_widget.dart │ │ │ │ ├── location_top_nav_widget.dart │ │ │ │ ├── location_what_grid_widget.dart │ │ │ │ ├── location_what_widget.dart │ │ │ │ └── location_where_live_widget.dart │ │ ├── my │ │ │ ├── my_page.dart │ │ │ └── widget │ │ │ │ ├── my_get_honey_widget.dart │ │ │ │ ├── my_items_widget.dart │ │ │ │ ├── my_logout_widget.dart │ │ │ │ ├── my_navbar_widget.dart │ │ │ │ ├── my_service_card_widget.dart │ │ │ │ └── my_travel_widget.dart │ │ └── travel │ │ │ ├── travel_page.dart │ │ │ └── widget │ │ │ ├── travel_banner_widget.dart │ │ │ ├── travel_calendar_widget.dart │ │ │ ├── travel_destination_widget.dart │ │ │ ├── travel_everyday_widget.dart │ │ │ ├── travel_grid_widget.dart │ │ │ ├── travel_navsearch_widget.dart │ │ │ ├── travel_recommend_widget.dart │ │ │ ├── travel_tab_control_widget.dart │ │ │ └── travel_waterfall_widget.dart │ ├── routers │ │ └── router.dart │ ├── screen_adapter.dart │ └── tabbar │ │ └── tabbar_page.dart ├── pubspec.lock ├── pubspec.yaml └── test │ └── widget_test.dart └── img ├── 01.jpg ├── 02.jpg └── 03.jpg /README.md: -------------------------------------------------------------------------------- 1 | # Flutter 项目实战(高仿马蜂窝) 2 | 3 | ## 持续更新中 4 | 视频演示地址:https://www.bilibili.com/video/av79760801 5 | 6 | ## 效果图 7 | 8 | ![avatar](https://github.com/SHIMLY-GitHub/fluter_mfw/blob/master/img/01.jpg)![avatar](https://github.com/SHIMLY-GitHub/fluter_mfw/blob/master/img/02.jpg)![avatar](https://github.com/SHIMLY-GitHub/fluter_mfw/blob/master/img/03.jpg) 9 | 10 | -------------------------------------------------------------------------------- /flutter 笔记.txt: -------------------------------------------------------------------------------- 1 | 2 | state 的生命周期 3 | 4 | created 这个阶段initState 方法会被调动 此时的widget 还没有被创建 5 | 6 | initialize initState 方法执行完毕 调用 didChangeDependencies 此时的widget 依然没有被创建完成 7 | 8 | 9 | ready widget 已经被创建完成 10 | 11 | defunct dispose方法被调用 widget 被销毁 12 | 13 | element 的生命周期 14 | initial, 15 | 16 | active, 17 | 18 | inactive, 19 | 20 | defunct, 21 | 22 | 23 | BuildOwner 是什么 24 | 25 | 1. 判断当前的状态的声明周期 26 | 如果当前state 已经销毁 则抛出异常 27 | 28 | 如果state 已经被创建 但是对应的element 不存在的话 抛出异常 29 | 30 | 2. 判断 31 | setState(() { 32 | 33 | }); 方法是否为异步 如果为异步 则直接抛出异常 34 | 3.调用 _element.markNeedsBuild(); 35 | _dirty = true; 36 | 将这个元素标记为dirty 并且添加到下一帧需要重建的全局的 widgets列表中 (全局列表在哪) 37 | 4.调用 scheduleBuildFor() 38 | 把这个标记为dirty 的元素 添加到列表中 以便重新生成 39 | 40 | _dirtyElements.add(element); 41 | element._inDirtyList = true; 42 | -------------------------------------------------------------------------------- /flutter_mfw/.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 | .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/Flutter/flutter_export_environment.sh 65 | **/ios/ServiceDefinitions.json 66 | **/ios/Runner/GeneratedPluginRegistrant.* 67 | 68 | # Exceptions to above rules. 69 | !**/ios/**/default.mode1v3 70 | !**/ios/**/default.mode2v3 71 | !**/ios/**/default.pbxuser 72 | !**/ios/**/default.perspectivev3 73 | !/packages/flutter_tools/test/data/dart_dependencies_test/**/.packages 74 | -------------------------------------------------------------------------------- /flutter_mfw/.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: 2d2a1ffec95cc70a3218872a2cd3f8de4933c42f 8 | channel: stable 9 | 10 | project_type: app 11 | -------------------------------------------------------------------------------- /flutter_mfw/README.md: -------------------------------------------------------------------------------- 1 | # flutter_mfw 2 | 3 | A new Flutter application. 4 | 5 | ## Getting Started 6 | 7 | This project is a starting point for a Flutter application. 8 | 9 | A few resources to get you started if this is your first Flutter project: 10 | 11 | - [Lab: Write your first Flutter app](https://flutter.dev/docs/get-started/codelab) 12 | - [Cookbook: Useful Flutter samples](https://flutter.dev/docs/cookbook) 13 | 14 | For help getting started with Flutter, view our 15 | [online documentation](https://flutter.dev/docs), which offers tutorials, 16 | samples, guidance on mobile development, and a full API reference. 17 | -------------------------------------------------------------------------------- /flutter_mfw/android/app/build.gradle: -------------------------------------------------------------------------------- 1 | def localProperties = new Properties() 2 | def localPropertiesFile = rootProject.file('local.properties') 3 | if (localPropertiesFile.exists()) { 4 | localPropertiesFile.withReader('UTF-8') { reader -> 5 | localProperties.load(reader) 6 | } 7 | } 8 | 9 | def flutterRoot = localProperties.getProperty('flutter.sdk') 10 | if (flutterRoot == null) { 11 | throw new GradleException("Flutter SDK not found. Define location with flutter.sdk in the local.properties file.") 12 | } 13 | 14 | def flutterVersionCode = localProperties.getProperty('flutter.versionCode') 15 | if (flutterVersionCode == null) { 16 | flutterVersionCode = '1' 17 | } 18 | 19 | def flutterVersionName = localProperties.getProperty('flutter.versionName') 20 | if (flutterVersionName == null) { 21 | flutterVersionName = '1.0' 22 | } 23 | 24 | apply plugin: 'com.android.application' 25 | apply plugin: 'kotlin-android' 26 | apply from: "$flutterRoot/packages/flutter_tools/gradle/flutter.gradle" 27 | 28 | android { 29 | compileSdkVersion 28 30 | 31 | sourceSets { 32 | main.java.srcDirs += 'src/main/kotlin' 33 | } 34 | 35 | lintOptions { 36 | disable 'InvalidPackage' 37 | } 38 | 39 | defaultConfig { 40 | // TODO: Specify your own unique Application ID (https://developer.android.com/studio/build/application-id.html). 41 | applicationId "com.yi.jia.dong.flutter_mfw" 42 | minSdkVersion 16 43 | targetSdkVersion 28 44 | versionCode flutterVersionCode.toInteger() 45 | versionName flutterVersionName 46 | testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner" 47 | } 48 | 49 | buildTypes { 50 | release { 51 | // TODO: Add your own signing config for the release build. 52 | // Signing with the debug keys for now, so `flutter run --release` works. 53 | signingConfig signingConfigs.debug 54 | } 55 | } 56 | } 57 | 58 | flutter { 59 | source '../..' 60 | } 61 | 62 | dependencies { 63 | implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version" 64 | testImplementation 'junit:junit:4.12' 65 | androidTestImplementation 'com.android.support.test:runner:1.0.2' 66 | androidTestImplementation 'com.android.support.test.espresso:espresso-core:3.0.2' 67 | } 68 | -------------------------------------------------------------------------------- /flutter_mfw/android/app/src/debug/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 3 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /flutter_mfw/android/app/src/main/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 3 | 4 | 9 | 13 | 20 | 24 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | -------------------------------------------------------------------------------- /flutter_mfw/android/app/src/main/kotlin/com/yi/jia/dong/flutter_mfw/MainActivity.kt: -------------------------------------------------------------------------------- 1 | package com.yi.jia.dong.flutter_mfw 2 | 3 | import android.os.Bundle 4 | 5 | import io.flutter.app.FlutterActivity 6 | import io.flutter.plugins.GeneratedPluginRegistrant 7 | 8 | class MainActivity: FlutterActivity() { 9 | override fun onCreate(savedInstanceState: Bundle?) { 10 | super.onCreate(savedInstanceState) 11 | GeneratedPluginRegistrant.registerWith(this) 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /flutter_mfw/android/app/src/main/res/drawable/launch_background.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 12 | 13 | -------------------------------------------------------------------------------- /flutter_mfw/android/app/src/main/res/mipmap-hdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/coder-dongjiayi/fluter_mfw/87a25f1335b4137f9c5ee780853d38053a4456eb/flutter_mfw/android/app/src/main/res/mipmap-hdpi/ic_launcher.png -------------------------------------------------------------------------------- /flutter_mfw/android/app/src/main/res/mipmap-mdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/coder-dongjiayi/fluter_mfw/87a25f1335b4137f9c5ee780853d38053a4456eb/flutter_mfw/android/app/src/main/res/mipmap-mdpi/ic_launcher.png -------------------------------------------------------------------------------- /flutter_mfw/android/app/src/main/res/mipmap-xhdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/coder-dongjiayi/fluter_mfw/87a25f1335b4137f9c5ee780853d38053a4456eb/flutter_mfw/android/app/src/main/res/mipmap-xhdpi/ic_launcher.png -------------------------------------------------------------------------------- /flutter_mfw/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/coder-dongjiayi/fluter_mfw/87a25f1335b4137f9c5ee780853d38053a4456eb/flutter_mfw/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png -------------------------------------------------------------------------------- /flutter_mfw/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/coder-dongjiayi/fluter_mfw/87a25f1335b4137f9c5ee780853d38053a4456eb/flutter_mfw/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png -------------------------------------------------------------------------------- /flutter_mfw/android/app/src/main/res/values/styles.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 8 | 9 | -------------------------------------------------------------------------------- /flutter_mfw/android/app/src/profile/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 3 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /flutter_mfw/android/build.gradle: -------------------------------------------------------------------------------- 1 | buildscript { 2 | ext.kotlin_version = '1.2.71' 3 | repositories { 4 | google() 5 | jcenter() 6 | } 7 | 8 | dependencies { 9 | classpath 'com.android.tools.build:gradle:3.2.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 | -------------------------------------------------------------------------------- /flutter_mfw/android/gradle.properties: -------------------------------------------------------------------------------- 1 | org.gradle.jvmargs=-Xmx1536M 2 | 3 | -------------------------------------------------------------------------------- /flutter_mfw/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 | -------------------------------------------------------------------------------- /flutter_mfw/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 | -------------------------------------------------------------------------------- /flutter_mfw/assets/icon_favourite.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/coder-dongjiayi/fluter_mfw/87a25f1335b4137f9c5ee780853d38053a4456eb/flutter_mfw/assets/icon_favourite.png -------------------------------------------------------------------------------- /flutter_mfw/assets/icon_fengye.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/coder-dongjiayi/fluter_mfw/87a25f1335b4137f9c5ee780853d38053a4456eb/flutter_mfw/assets/icon_fengye.png -------------------------------------------------------------------------------- /flutter_mfw/assets/icon_gonglve.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/coder-dongjiayi/fluter_mfw/87a25f1335b4137f9c5ee780853d38053a4456eb/flutter_mfw/assets/icon_gonglve.png -------------------------------------------------------------------------------- /flutter_mfw/assets/icon_hote.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/coder-dongjiayi/fluter_mfw/87a25f1335b4137f9c5ee780853d38053a4456eb/flutter_mfw/assets/icon_hote.png -------------------------------------------------------------------------------- /flutter_mfw/assets/icon_huxian.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/coder-dongjiayi/fluter_mfw/87a25f1335b4137f9c5ee780853d38053a4456eb/flutter_mfw/assets/icon_huxian.png -------------------------------------------------------------------------------- /flutter_mfw/assets/icon_jipiao.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/coder-dongjiayi/fluter_mfw/87a25f1335b4137f9c5ee780853d38053a4456eb/flutter_mfw/assets/icon_jipiao.png -------------------------------------------------------------------------------- /flutter_mfw/assets/icon_message.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/coder-dongjiayi/fluter_mfw/87a25f1335b4137f9c5ee780853d38053a4456eb/flutter_mfw/assets/icon_message.png -------------------------------------------------------------------------------- /flutter_mfw/assets/icon_right.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/coder-dongjiayi/fluter_mfw/87a25f1335b4137f9c5ee780853d38053a4456eb/flutter_mfw/assets/icon_right.png -------------------------------------------------------------------------------- /flutter_mfw/assets/icon_travel.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/coder-dongjiayi/fluter_mfw/87a25f1335b4137f9c5ee780853d38053a4456eb/flutter_mfw/assets/icon_travel.png -------------------------------------------------------------------------------- /flutter_mfw/assets/icon_youji.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/coder-dongjiayi/fluter_mfw/87a25f1335b4137f9c5ee780853d38053a4456eb/flutter_mfw/assets/icon_youji.png -------------------------------------------------------------------------------- /flutter_mfw/assets/images/2.0x/icon_favourite.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/coder-dongjiayi/fluter_mfw/87a25f1335b4137f9c5ee780853d38053a4456eb/flutter_mfw/assets/images/2.0x/icon_favourite.png -------------------------------------------------------------------------------- /flutter_mfw/assets/images/2.0x/icon_fengye.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/coder-dongjiayi/fluter_mfw/87a25f1335b4137f9c5ee780853d38053a4456eb/flutter_mfw/assets/images/2.0x/icon_fengye.png -------------------------------------------------------------------------------- /flutter_mfw/assets/images/2.0x/icon_gonglve.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/coder-dongjiayi/fluter_mfw/87a25f1335b4137f9c5ee780853d38053a4456eb/flutter_mfw/assets/images/2.0x/icon_gonglve.png -------------------------------------------------------------------------------- /flutter_mfw/assets/images/2.0x/icon_hote.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/coder-dongjiayi/fluter_mfw/87a25f1335b4137f9c5ee780853d38053a4456eb/flutter_mfw/assets/images/2.0x/icon_hote.png -------------------------------------------------------------------------------- /flutter_mfw/assets/images/2.0x/icon_huxian.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/coder-dongjiayi/fluter_mfw/87a25f1335b4137f9c5ee780853d38053a4456eb/flutter_mfw/assets/images/2.0x/icon_huxian.png -------------------------------------------------------------------------------- /flutter_mfw/assets/images/2.0x/icon_jipiao.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/coder-dongjiayi/fluter_mfw/87a25f1335b4137f9c5ee780853d38053a4456eb/flutter_mfw/assets/images/2.0x/icon_jipiao.png -------------------------------------------------------------------------------- /flutter_mfw/assets/images/2.0x/icon_message.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/coder-dongjiayi/fluter_mfw/87a25f1335b4137f9c5ee780853d38053a4456eb/flutter_mfw/assets/images/2.0x/icon_message.png -------------------------------------------------------------------------------- /flutter_mfw/assets/images/2.0x/icon_right.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/coder-dongjiayi/fluter_mfw/87a25f1335b4137f9c5ee780853d38053a4456eb/flutter_mfw/assets/images/2.0x/icon_right.png -------------------------------------------------------------------------------- /flutter_mfw/assets/images/2.0x/icon_travel.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/coder-dongjiayi/fluter_mfw/87a25f1335b4137f9c5ee780853d38053a4456eb/flutter_mfw/assets/images/2.0x/icon_travel.png -------------------------------------------------------------------------------- /flutter_mfw/assets/images/2.0x/icon_youji.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/coder-dongjiayi/fluter_mfw/87a25f1335b4137f9c5ee780853d38053a4456eb/flutter_mfw/assets/images/2.0x/icon_youji.png -------------------------------------------------------------------------------- /flutter_mfw/assets/images/2.0x/lishi.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/coder-dongjiayi/fluter_mfw/87a25f1335b4137f9c5ee780853d38053a4456eb/flutter_mfw/assets/images/2.0x/lishi.png -------------------------------------------------------------------------------- /flutter_mfw/assets/images/2.0x/order.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/coder-dongjiayi/fluter_mfw/87a25f1335b4137f9c5ee780853d38053a4456eb/flutter_mfw/assets/images/2.0x/order.png -------------------------------------------------------------------------------- /flutter_mfw/assets/images/2.0x/qianbi.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/coder-dongjiayi/fluter_mfw/87a25f1335b4137f9c5ee780853d38053a4456eb/flutter_mfw/assets/images/2.0x/qianbi.png -------------------------------------------------------------------------------- /flutter_mfw/assets/images/2.0x/saoma.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/coder-dongjiayi/fluter_mfw/87a25f1335b4137f9c5ee780853d38053a4456eb/flutter_mfw/assets/images/2.0x/saoma.png -------------------------------------------------------------------------------- /flutter_mfw/assets/images/2.0x/setting.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/coder-dongjiayi/fluter_mfw/87a25f1335b4137f9c5ee780853d38053a4456eb/flutter_mfw/assets/images/2.0x/setting.png -------------------------------------------------------------------------------- /flutter_mfw/assets/images/2.0x/start.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/coder-dongjiayi/fluter_mfw/87a25f1335b4137f9c5ee780853d38053a4456eb/flutter_mfw/assets/images/2.0x/start.png -------------------------------------------------------------------------------- /flutter_mfw/assets/images/2.0x/tab_default_mall.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/coder-dongjiayi/fluter_mfw/87a25f1335b4137f9c5ee780853d38053a4456eb/flutter_mfw/assets/images/2.0x/tab_default_mall.png -------------------------------------------------------------------------------- /flutter_mfw/assets/images/2.0x/tab_destination_normal.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/coder-dongjiayi/fluter_mfw/87a25f1335b4137f9c5ee780853d38053a4456eb/flutter_mfw/assets/images/2.0x/tab_destination_normal.png -------------------------------------------------------------------------------- /flutter_mfw/assets/images/2.0x/tab_destination_selected.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/coder-dongjiayi/fluter_mfw/87a25f1335b4137f9c5ee780853d38053a4456eb/flutter_mfw/assets/images/2.0x/tab_destination_selected.png -------------------------------------------------------------------------------- /flutter_mfw/assets/images/2.0x/tab_focused_mall.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/coder-dongjiayi/fluter_mfw/87a25f1335b4137f9c5ee780853d38053a4456eb/flutter_mfw/assets/images/2.0x/tab_focused_mall.png -------------------------------------------------------------------------------- /flutter_mfw/assets/images/2.0x/tab_homepage_normal.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/coder-dongjiayi/fluter_mfw/87a25f1335b4137f9c5ee780853d38053a4456eb/flutter_mfw/assets/images/2.0x/tab_homepage_normal.png -------------------------------------------------------------------------------- /flutter_mfw/assets/images/2.0x/tab_homepage_refresh.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/coder-dongjiayi/fluter_mfw/87a25f1335b4137f9c5ee780853d38053a4456eb/flutter_mfw/assets/images/2.0x/tab_homepage_refresh.png -------------------------------------------------------------------------------- /flutter_mfw/assets/images/2.0x/tab_homepage_selected.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/coder-dongjiayi/fluter_mfw/87a25f1335b4137f9c5ee780853d38053a4456eb/flutter_mfw/assets/images/2.0x/tab_homepage_selected.png -------------------------------------------------------------------------------- /flutter_mfw/assets/images/2.0x/tab_hotel_normal.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/coder-dongjiayi/fluter_mfw/87a25f1335b4137f9c5ee780853d38053a4456eb/flutter_mfw/assets/images/2.0x/tab_hotel_normal.png -------------------------------------------------------------------------------- /flutter_mfw/assets/images/2.0x/tab_hotel_selected.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/coder-dongjiayi/fluter_mfw/87a25f1335b4137f9c5ee780853d38053a4456eb/flutter_mfw/assets/images/2.0x/tab_hotel_selected.png -------------------------------------------------------------------------------- /flutter_mfw/assets/images/2.0x/tab_mine_normal.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/coder-dongjiayi/fluter_mfw/87a25f1335b4137f9c5ee780853d38053a4456eb/flutter_mfw/assets/images/2.0x/tab_mine_normal.png -------------------------------------------------------------------------------- /flutter_mfw/assets/images/2.0x/tab_mine_selected.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/coder-dongjiayi/fluter_mfw/87a25f1335b4137f9c5ee780853d38053a4456eb/flutter_mfw/assets/images/2.0x/tab_mine_selected.png -------------------------------------------------------------------------------- /flutter_mfw/assets/images/2.0x/topic.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/coder-dongjiayi/fluter_mfw/87a25f1335b4137f9c5ee780853d38053a4456eb/flutter_mfw/assets/images/2.0x/topic.png -------------------------------------------------------------------------------- /flutter_mfw/assets/images/3.0x/icon_favourite.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/coder-dongjiayi/fluter_mfw/87a25f1335b4137f9c5ee780853d38053a4456eb/flutter_mfw/assets/images/3.0x/icon_favourite.png -------------------------------------------------------------------------------- /flutter_mfw/assets/images/3.0x/icon_fengye.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/coder-dongjiayi/fluter_mfw/87a25f1335b4137f9c5ee780853d38053a4456eb/flutter_mfw/assets/images/3.0x/icon_fengye.png -------------------------------------------------------------------------------- /flutter_mfw/assets/images/3.0x/icon_gonglve.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/coder-dongjiayi/fluter_mfw/87a25f1335b4137f9c5ee780853d38053a4456eb/flutter_mfw/assets/images/3.0x/icon_gonglve.png -------------------------------------------------------------------------------- /flutter_mfw/assets/images/3.0x/icon_hote.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/coder-dongjiayi/fluter_mfw/87a25f1335b4137f9c5ee780853d38053a4456eb/flutter_mfw/assets/images/3.0x/icon_hote.png -------------------------------------------------------------------------------- /flutter_mfw/assets/images/3.0x/icon_huxian.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/coder-dongjiayi/fluter_mfw/87a25f1335b4137f9c5ee780853d38053a4456eb/flutter_mfw/assets/images/3.0x/icon_huxian.png -------------------------------------------------------------------------------- /flutter_mfw/assets/images/3.0x/icon_jipiao.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/coder-dongjiayi/fluter_mfw/87a25f1335b4137f9c5ee780853d38053a4456eb/flutter_mfw/assets/images/3.0x/icon_jipiao.png -------------------------------------------------------------------------------- /flutter_mfw/assets/images/3.0x/icon_message.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/coder-dongjiayi/fluter_mfw/87a25f1335b4137f9c5ee780853d38053a4456eb/flutter_mfw/assets/images/3.0x/icon_message.png -------------------------------------------------------------------------------- /flutter_mfw/assets/images/3.0x/icon_right.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/coder-dongjiayi/fluter_mfw/87a25f1335b4137f9c5ee780853d38053a4456eb/flutter_mfw/assets/images/3.0x/icon_right.png -------------------------------------------------------------------------------- /flutter_mfw/assets/images/3.0x/icon_travel.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/coder-dongjiayi/fluter_mfw/87a25f1335b4137f9c5ee780853d38053a4456eb/flutter_mfw/assets/images/3.0x/icon_travel.png -------------------------------------------------------------------------------- /flutter_mfw/assets/images/3.0x/icon_youji.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/coder-dongjiayi/fluter_mfw/87a25f1335b4137f9c5ee780853d38053a4456eb/flutter_mfw/assets/images/3.0x/icon_youji.png -------------------------------------------------------------------------------- /flutter_mfw/assets/images/3.0x/lishi.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/coder-dongjiayi/fluter_mfw/87a25f1335b4137f9c5ee780853d38053a4456eb/flutter_mfw/assets/images/3.0x/lishi.png -------------------------------------------------------------------------------- /flutter_mfw/assets/images/3.0x/order.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/coder-dongjiayi/fluter_mfw/87a25f1335b4137f9c5ee780853d38053a4456eb/flutter_mfw/assets/images/3.0x/order.png -------------------------------------------------------------------------------- /flutter_mfw/assets/images/3.0x/qianbi.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/coder-dongjiayi/fluter_mfw/87a25f1335b4137f9c5ee780853d38053a4456eb/flutter_mfw/assets/images/3.0x/qianbi.png -------------------------------------------------------------------------------- /flutter_mfw/assets/images/3.0x/saoma.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/coder-dongjiayi/fluter_mfw/87a25f1335b4137f9c5ee780853d38053a4456eb/flutter_mfw/assets/images/3.0x/saoma.png -------------------------------------------------------------------------------- /flutter_mfw/assets/images/3.0x/setting.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/coder-dongjiayi/fluter_mfw/87a25f1335b4137f9c5ee780853d38053a4456eb/flutter_mfw/assets/images/3.0x/setting.png -------------------------------------------------------------------------------- /flutter_mfw/assets/images/3.0x/start.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/coder-dongjiayi/fluter_mfw/87a25f1335b4137f9c5ee780853d38053a4456eb/flutter_mfw/assets/images/3.0x/start.png -------------------------------------------------------------------------------- /flutter_mfw/assets/images/3.0x/tab_default_mall.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/coder-dongjiayi/fluter_mfw/87a25f1335b4137f9c5ee780853d38053a4456eb/flutter_mfw/assets/images/3.0x/tab_default_mall.png -------------------------------------------------------------------------------- /flutter_mfw/assets/images/3.0x/tab_destination_normal.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/coder-dongjiayi/fluter_mfw/87a25f1335b4137f9c5ee780853d38053a4456eb/flutter_mfw/assets/images/3.0x/tab_destination_normal.png -------------------------------------------------------------------------------- /flutter_mfw/assets/images/3.0x/tab_destination_selected.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/coder-dongjiayi/fluter_mfw/87a25f1335b4137f9c5ee780853d38053a4456eb/flutter_mfw/assets/images/3.0x/tab_destination_selected.png -------------------------------------------------------------------------------- /flutter_mfw/assets/images/3.0x/tab_focused_mall.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/coder-dongjiayi/fluter_mfw/87a25f1335b4137f9c5ee780853d38053a4456eb/flutter_mfw/assets/images/3.0x/tab_focused_mall.png -------------------------------------------------------------------------------- /flutter_mfw/assets/images/3.0x/tab_homepage_normal.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/coder-dongjiayi/fluter_mfw/87a25f1335b4137f9c5ee780853d38053a4456eb/flutter_mfw/assets/images/3.0x/tab_homepage_normal.png -------------------------------------------------------------------------------- /flutter_mfw/assets/images/3.0x/tab_homepage_refresh.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/coder-dongjiayi/fluter_mfw/87a25f1335b4137f9c5ee780853d38053a4456eb/flutter_mfw/assets/images/3.0x/tab_homepage_refresh.png -------------------------------------------------------------------------------- /flutter_mfw/assets/images/3.0x/tab_homepage_selected.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/coder-dongjiayi/fluter_mfw/87a25f1335b4137f9c5ee780853d38053a4456eb/flutter_mfw/assets/images/3.0x/tab_homepage_selected.png -------------------------------------------------------------------------------- /flutter_mfw/assets/images/3.0x/tab_hotel_normal.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/coder-dongjiayi/fluter_mfw/87a25f1335b4137f9c5ee780853d38053a4456eb/flutter_mfw/assets/images/3.0x/tab_hotel_normal.png -------------------------------------------------------------------------------- /flutter_mfw/assets/images/3.0x/tab_hotel_selected.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/coder-dongjiayi/fluter_mfw/87a25f1335b4137f9c5ee780853d38053a4456eb/flutter_mfw/assets/images/3.0x/tab_hotel_selected.png -------------------------------------------------------------------------------- /flutter_mfw/assets/images/3.0x/tab_mine_normal.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/coder-dongjiayi/fluter_mfw/87a25f1335b4137f9c5ee780853d38053a4456eb/flutter_mfw/assets/images/3.0x/tab_mine_normal.png -------------------------------------------------------------------------------- /flutter_mfw/assets/images/3.0x/tab_mine_selected.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/coder-dongjiayi/fluter_mfw/87a25f1335b4137f9c5ee780853d38053a4456eb/flutter_mfw/assets/images/3.0x/tab_mine_selected.png -------------------------------------------------------------------------------- /flutter_mfw/assets/images/3.0x/topic.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/coder-dongjiayi/fluter_mfw/87a25f1335b4137f9c5ee780853d38053a4456eb/flutter_mfw/assets/images/3.0x/topic.png -------------------------------------------------------------------------------- /flutter_mfw/assets/lishi.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/coder-dongjiayi/fluter_mfw/87a25f1335b4137f9c5ee780853d38053a4456eb/flutter_mfw/assets/lishi.png -------------------------------------------------------------------------------- /flutter_mfw/assets/order.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/coder-dongjiayi/fluter_mfw/87a25f1335b4137f9c5ee780853d38053a4456eb/flutter_mfw/assets/order.png -------------------------------------------------------------------------------- /flutter_mfw/assets/qianbi.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/coder-dongjiayi/fluter_mfw/87a25f1335b4137f9c5ee780853d38053a4456eb/flutter_mfw/assets/qianbi.png -------------------------------------------------------------------------------- /flutter_mfw/assets/saoma.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/coder-dongjiayi/fluter_mfw/87a25f1335b4137f9c5ee780853d38053a4456eb/flutter_mfw/assets/saoma.png -------------------------------------------------------------------------------- /flutter_mfw/assets/setting.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/coder-dongjiayi/fluter_mfw/87a25f1335b4137f9c5ee780853d38053a4456eb/flutter_mfw/assets/setting.png -------------------------------------------------------------------------------- /flutter_mfw/assets/start.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/coder-dongjiayi/fluter_mfw/87a25f1335b4137f9c5ee780853d38053a4456eb/flutter_mfw/assets/start.png -------------------------------------------------------------------------------- /flutter_mfw/assets/tab_default_mall.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/coder-dongjiayi/fluter_mfw/87a25f1335b4137f9c5ee780853d38053a4456eb/flutter_mfw/assets/tab_default_mall.png -------------------------------------------------------------------------------- /flutter_mfw/assets/tab_destination_normal.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/coder-dongjiayi/fluter_mfw/87a25f1335b4137f9c5ee780853d38053a4456eb/flutter_mfw/assets/tab_destination_normal.png -------------------------------------------------------------------------------- /flutter_mfw/assets/tab_destination_selected.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/coder-dongjiayi/fluter_mfw/87a25f1335b4137f9c5ee780853d38053a4456eb/flutter_mfw/assets/tab_destination_selected.png -------------------------------------------------------------------------------- /flutter_mfw/assets/tab_focused_mall.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/coder-dongjiayi/fluter_mfw/87a25f1335b4137f9c5ee780853d38053a4456eb/flutter_mfw/assets/tab_focused_mall.png -------------------------------------------------------------------------------- /flutter_mfw/assets/tab_homepage_normal.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/coder-dongjiayi/fluter_mfw/87a25f1335b4137f9c5ee780853d38053a4456eb/flutter_mfw/assets/tab_homepage_normal.png -------------------------------------------------------------------------------- /flutter_mfw/assets/tab_homepage_refresh.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/coder-dongjiayi/fluter_mfw/87a25f1335b4137f9c5ee780853d38053a4456eb/flutter_mfw/assets/tab_homepage_refresh.png -------------------------------------------------------------------------------- /flutter_mfw/assets/tab_homepage_selected.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/coder-dongjiayi/fluter_mfw/87a25f1335b4137f9c5ee780853d38053a4456eb/flutter_mfw/assets/tab_homepage_selected.png -------------------------------------------------------------------------------- /flutter_mfw/assets/tab_hotel_normal.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/coder-dongjiayi/fluter_mfw/87a25f1335b4137f9c5ee780853d38053a4456eb/flutter_mfw/assets/tab_hotel_normal.png -------------------------------------------------------------------------------- /flutter_mfw/assets/tab_hotel_selected.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/coder-dongjiayi/fluter_mfw/87a25f1335b4137f9c5ee780853d38053a4456eb/flutter_mfw/assets/tab_hotel_selected.png -------------------------------------------------------------------------------- /flutter_mfw/assets/tab_mine_normal.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/coder-dongjiayi/fluter_mfw/87a25f1335b4137f9c5ee780853d38053a4456eb/flutter_mfw/assets/tab_mine_normal.png -------------------------------------------------------------------------------- /flutter_mfw/assets/tab_mine_selected.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/coder-dongjiayi/fluter_mfw/87a25f1335b4137f9c5ee780853d38053a4456eb/flutter_mfw/assets/tab_mine_selected.png -------------------------------------------------------------------------------- /flutter_mfw/assets/topic.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/coder-dongjiayi/fluter_mfw/87a25f1335b4137f9c5ee780853d38053a4456eb/flutter_mfw/assets/topic.png -------------------------------------------------------------------------------- /flutter_mfw/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 | -------------------------------------------------------------------------------- /flutter_mfw/ios/Flutter/Debug.xcconfig: -------------------------------------------------------------------------------- 1 | #include "Generated.xcconfig" 2 | -------------------------------------------------------------------------------- /flutter_mfw/ios/Flutter/Flutter.podspec: -------------------------------------------------------------------------------- 1 | # 2 | # NOTE: This podspec is NOT to be published. It is only used as a local source! 3 | # 4 | 5 | Pod::Spec.new do |s| 6 | s.name = 'Flutter' 7 | s.version = '1.0.0' 8 | s.summary = 'High-performance, high-fidelity mobile apps.' 9 | s.description = <<-DESC 10 | Flutter provides an easy and productive way to build and deploy high-performance mobile apps for Android and iOS. 11 | DESC 12 | s.homepage = 'https://flutter.io' 13 | s.license = { :type => 'MIT' } 14 | s.author = { 'Flutter Dev Team' => 'flutter-dev@googlegroups.com' } 15 | s.source = { :git => 'https://github.com/flutter/engine', :tag => s.version.to_s } 16 | s.ios.deployment_target = '8.0' 17 | s.vendored_frameworks = 'Flutter.framework' 18 | end 19 | -------------------------------------------------------------------------------- /flutter_mfw/ios/Flutter/Release.xcconfig: -------------------------------------------------------------------------------- 1 | #include "Generated.xcconfig" 2 | -------------------------------------------------------------------------------- /flutter_mfw/ios/Runner.xcodeproj/project.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /flutter_mfw/ios/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme: -------------------------------------------------------------------------------- 1 | 2 | 5 | 8 | 9 | 15 | 21 | 22 | 23 | 24 | 25 | 30 | 31 | 32 | 33 | 39 | 40 | 41 | 42 | 43 | 44 | 54 | 56 | 62 | 63 | 64 | 65 | 66 | 67 | 73 | 75 | 81 | 82 | 83 | 84 | 86 | 87 | 90 | 91 | 92 | -------------------------------------------------------------------------------- /flutter_mfw/ios/Runner.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /flutter_mfw/ios/Runner.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | IDEDidComputeMac32BitWarning 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /flutter_mfw/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 | -------------------------------------------------------------------------------- /flutter_mfw/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 | -------------------------------------------------------------------------------- /flutter_mfw/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-1024x1024@1x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/coder-dongjiayi/fluter_mfw/87a25f1335b4137f9c5ee780853d38053a4456eb/flutter_mfw/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-1024x1024@1x.png -------------------------------------------------------------------------------- /flutter_mfw/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@1x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/coder-dongjiayi/fluter_mfw/87a25f1335b4137f9c5ee780853d38053a4456eb/flutter_mfw/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@1x.png -------------------------------------------------------------------------------- /flutter_mfw/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/coder-dongjiayi/fluter_mfw/87a25f1335b4137f9c5ee780853d38053a4456eb/flutter_mfw/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@2x.png -------------------------------------------------------------------------------- /flutter_mfw/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/coder-dongjiayi/fluter_mfw/87a25f1335b4137f9c5ee780853d38053a4456eb/flutter_mfw/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@3x.png -------------------------------------------------------------------------------- /flutter_mfw/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@1x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/coder-dongjiayi/fluter_mfw/87a25f1335b4137f9c5ee780853d38053a4456eb/flutter_mfw/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@1x.png -------------------------------------------------------------------------------- /flutter_mfw/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/coder-dongjiayi/fluter_mfw/87a25f1335b4137f9c5ee780853d38053a4456eb/flutter_mfw/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@2x.png -------------------------------------------------------------------------------- /flutter_mfw/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/coder-dongjiayi/fluter_mfw/87a25f1335b4137f9c5ee780853d38053a4456eb/flutter_mfw/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@3x.png -------------------------------------------------------------------------------- /flutter_mfw/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@1x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/coder-dongjiayi/fluter_mfw/87a25f1335b4137f9c5ee780853d38053a4456eb/flutter_mfw/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@1x.png -------------------------------------------------------------------------------- /flutter_mfw/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/coder-dongjiayi/fluter_mfw/87a25f1335b4137f9c5ee780853d38053a4456eb/flutter_mfw/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@2x.png -------------------------------------------------------------------------------- /flutter_mfw/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/coder-dongjiayi/fluter_mfw/87a25f1335b4137f9c5ee780853d38053a4456eb/flutter_mfw/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@3x.png -------------------------------------------------------------------------------- /flutter_mfw/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/coder-dongjiayi/fluter_mfw/87a25f1335b4137f9c5ee780853d38053a4456eb/flutter_mfw/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@2x.png -------------------------------------------------------------------------------- /flutter_mfw/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/coder-dongjiayi/fluter_mfw/87a25f1335b4137f9c5ee780853d38053a4456eb/flutter_mfw/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@3x.png -------------------------------------------------------------------------------- /flutter_mfw/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@1x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/coder-dongjiayi/fluter_mfw/87a25f1335b4137f9c5ee780853d38053a4456eb/flutter_mfw/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@1x.png -------------------------------------------------------------------------------- /flutter_mfw/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/coder-dongjiayi/fluter_mfw/87a25f1335b4137f9c5ee780853d38053a4456eb/flutter_mfw/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@2x.png -------------------------------------------------------------------------------- /flutter_mfw/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-83.5x83.5@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/coder-dongjiayi/fluter_mfw/87a25f1335b4137f9c5ee780853d38053a4456eb/flutter_mfw/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-83.5x83.5@2x.png -------------------------------------------------------------------------------- /flutter_mfw/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 | -------------------------------------------------------------------------------- /flutter_mfw/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/coder-dongjiayi/fluter_mfw/87a25f1335b4137f9c5ee780853d38053a4456eb/flutter_mfw/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage.png -------------------------------------------------------------------------------- /flutter_mfw/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/coder-dongjiayi/fluter_mfw/87a25f1335b4137f9c5ee780853d38053a4456eb/flutter_mfw/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@2x.png -------------------------------------------------------------------------------- /flutter_mfw/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/coder-dongjiayi/fluter_mfw/87a25f1335b4137f9c5ee780853d38053a4456eb/flutter_mfw/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@3x.png -------------------------------------------------------------------------------- /flutter_mfw/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. -------------------------------------------------------------------------------- /flutter_mfw/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 | -------------------------------------------------------------------------------- /flutter_mfw/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 | -------------------------------------------------------------------------------- /flutter_mfw/ios/Runner/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | $(DEVELOPMENT_LANGUAGE) 7 | CFBundleExecutable 8 | $(EXECUTABLE_NAME) 9 | CFBundleIdentifier 10 | $(PRODUCT_BUNDLE_IDENTIFIER) 11 | CFBundleInfoDictionaryVersion 12 | 6.0 13 | CFBundleName 14 | flutter_mfw 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 | -------------------------------------------------------------------------------- /flutter_mfw/ios/Runner/Runner-Bridging-Header.h: -------------------------------------------------------------------------------- 1 | #import "GeneratedPluginRegistrant.h" -------------------------------------------------------------------------------- /flutter_mfw/lib/dao/home_dao.dart: -------------------------------------------------------------------------------- 1 | 2 | import 'package:flutter_mfw/model/tabar_model.dart'; 3 | import 'package:flutter_mfw/model/hote_model.dart'; 4 | import 'package:flutter_mfw/model/waterfall_model.dart'; 5 | import 'package:flutter_mfw/model/home_main_icon_model.dart'; 6 | 7 | 8 | import 'package:dio/dio.dart'; 9 | const HOME_URL = "https://mapi.mafengwo.cn/discovery/get_index/v2?jsondata=%7B%22tab_id%22%3A%2255%22%2C%22top_refresh%22%3A%221%22%2C%22by_user%22%3A%221%22%7D&o_lat=39.903648&device_type=android&device_mid=867674040394714&dev_ver=D1926.0&oauth_version=1.0&oauth_signature_method=HMAC-SHA1&screen_height=2210&open_udid=A4%3A50%3A46%3A36%3AA8%3A43&app_version_code=800&x_auth_mode=client_auth&oauth_token=0_0969044fd4edf59957f4a39bce9200c6&sys_ver=9&o_lng=116.444529&brand=Xiaomi&zzzghostsigh=d54f6b842f09f103c3685c61601e2122b8943e7a&app_code=com.mfw.roadbook&screen_scale=2.88&screen_width=1080&time_offset=480&device_id=A4%3A50%3A46%3A36%3AA8%3A43&oauth_signature=SqmRPsyjvjaLrG2MEKPUGFWs8ik%3D&oauth_consumer_key=5&oauth_timestamp=1568794690&oauth_nonce=89dbcb85-fe39-4e44-9de6-6f38892c41c0&mfwsdk_ver=20140507&app_ver=9.3.28&has_notch=0&hardware_model=MIX+3&channel_id=XiaoMi&"; 10 | 11 | 12 | const HOME_TOP_URL = "https://mapi.mafengwo.cn/rest/app/theme/index/?jsondata=%7B%7D&o_lat=39.904539&device_type=android&dev_ver=D1932.0&oauth_version=1.0&oauth_signature_method=HMAC-SHA1&screen_height=2029&open_udid=64774894b98b2cc4&app_version_code=815&x_auth_mode=client_auth&oauth_token=0_0969044fd4edf59957f4a39bce9200c6&sys_ver=9&o_lng=116.443433&brand=Xiaomi&zzzghostsigh=81a906256b31880f397afe8f06407f4b218c8892&app_code=com.mfw.roadbook&android_oaid=1bb9aee3d819ec37&screen_scale=2.88&screen_width=1080&time_offset=480&device_id=64774894b98b2cc4&oauth_signature=baDgBZ%2BgAfg6S7TPje6NcoCi%2F7w%3D&oauth_consumer_key=5&oauth_timestamp=1573696461&oauth_nonce=436dd227-da3f-4e74-a803-8aef9b20f22c&mfwsdk_ver=20140507&app_ver=9.3.34&has_notch=1&hardware_model=MI+8+SE&channel_id=XiaoMi&"; 13 | 14 | 15 | class TabbarListDao{ 16 | static Future fetch() async{ 17 | 18 | final response = await Dio().get(HOME_URL); 19 | if(response.statusCode == 200){ 20 | 21 | var result = TabarListModel.fromJson(response.data["data"]["ex"]); 22 | var item = TabItemModel(); 23 | item.id = "0"; 24 | item.name = "关注"; 25 | result.tabList.insert(0, item); 26 | return result; 27 | }else{ 28 | throw Exception("首页请求失败"); 29 | } 30 | } 31 | 32 | } 33 | 34 | class HoteListDao{ 35 | static Future fetch() async { 36 | final response = await Dio().get(HOME_URL); 37 | if(response.statusCode == 200){ 38 | 39 | var result = HoteModel.fromJson(response.data["data"]["list"][0]["data"]); 40 | 41 | return result; 42 | }else{ 43 | throw Exception("首页请求失败"); 44 | } 45 | } 46 | } 47 | 48 | //请求icon 49 | class MainIconDao{ 50 | static Future fetch() async{ 51 | final resonse = await Dio().get(HOME_TOP_URL); 52 | 53 | if(resonse.statusCode == 200){ 54 | 55 | var result = HomeMainIconModel.fromJson(resonse.data); 56 | 57 | return result; 58 | 59 | }else{ 60 | throw Exception("icon请求失败"); 61 | } 62 | 63 | } 64 | } 65 | 66 | class WaterFallDao{ 67 | static Future fetch() async { 68 | final response = await Dio().get(HOME_URL); 69 | if(response.statusCode == 200){ 70 | 71 | 72 | var result = WaterFallListModel.fromJson(response.data["data"]); 73 | var list = []; 74 | for(var item in result.list){ 75 | if(item.data.user != null){ 76 | list.add(item); 77 | } 78 | } 79 | result.list = list; 80 | 81 | return result; 82 | }else{ 83 | throw Exception("首页请求失败"); 84 | } 85 | } 86 | } -------------------------------------------------------------------------------- /flutter_mfw/lib/dao/location_dao.dart: -------------------------------------------------------------------------------- 1 | 2 | import 'package:dio/dio.dart'; 3 | import 'package:flutter_mfw/model/location_model.dart'; 4 | import 'package:flutter_mfw/model/location_tababr_model.dart'; 5 | import 'package:flutter_mfw/model/location_where_model.dart'; 6 | 7 | const LOCATION_URL = "https://mapi.mafengwo.cn/mdd/item/get_mdd_item/v4?o_lat=39.903649&device_type=android&device_mid=867674040394714&dev_ver=D1926.0&oauth_version=1.0&oauth_signature_method=HMAC-SHA1&screen_height=2210&open_udid=A4%3A50%3A46%3A36%3AA8%3A43&app_version_code=800&x_auth_mode=client_auth&oauth_token=0_0969044fd4edf59957f4a39bce9200c6&sys_ver=9&o_lng=116.444673&mdd_id=10065&brand=Xiaomi&zzzghostsigh=55a5f3b2071dc13c6e96ae390d579bbbc93f2393&app_code=com.mfw.roadbook&screen_scale=2.88&screen_width=1080&time_offset=480&device_id=A4%3A50%3A46%3A36%3AA8%3A43&oauth_signature=vTxQ9Y%2FKJ5hi1wQpqDGwZx2Wwzs%3D&oauth_consumer_key=5&oauth_timestamp=1571296894&oauth_nonce=0756096c-c16f-4004-84c8-e50a3a84485a&mfwsdk_ver=20140507&app_ver=9.3.28&has_notch=0&hardware_model=MIX+3&by_user=1&channel_id=XiaoMi&"; 8 | 9 | const WETHER_URL = "https://m.mafengwo.cn/nb/public/weather.php?o_lat=39.903649&device_type=android&type=1&dev_ver=D1926.0&oauth_version=1.0&oauth_signature_method=HMAC-SHA1&screen_height=2210&open_udid=A4%3A50%3A46%3A36%3AA8%3A43&app_version_code=800&x_auth_mode=client_auth&oauth_token=0_0969044fd4edf59957f4a39bce9200c6&sys_ver=9&o_lng=116.444673&brand=Xiaomi&zzzghostsigh=f5837b55528c424ffe27aabf14d0a42ae0a924d8&app_code=com.mfw.roadbook&screen_scale=2.88&screen_width=1080&time_offset=480&device_id=A4%3A50%3A46%3A36%3AA8%3A43&oauth_signature=6Yt5oV0Ng%2BjkdXDJ5Q3miiJ97aI%3D&mddid=10065&oauth_consumer_key=5&oauth_timestamp=1571296894&oauth_nonce=33165392-050c-4f00-9e49-e7ad7e950c59&mfwsdk_ver=20140507&app_ver=9.3.28&has_notch=0&hardware_model=MIX+3&channel_id=XiaoMi&"; 10 | 11 | const LOCATION_TABAR_URL = "https://mapi.mafengwo.cn/mdd/feed/get_index/v1?jsondata=%7B%22device_mid%22%3A%22867674040394714%22%2C%22mdd_id%22%3A%2210065%22%2C%22by_user%22%3A%221%22%7D&o_lat=39.903649&device_type=android&dev_ver=D1926.0&oauth_version=1.0&oauth_signature_method=HMAC-SHA1&screen_height=2210&open_udid=A4%3A50%3A46%3A36%3AA8%3A43&app_version_code=800&x_auth_mode=client_auth&oauth_token=0_0969044fd4edf59957f4a39bce9200c6&sys_ver=9&o_lng=116.444673&brand=Xiaomi&zzzghostsigh=bcc14775fcb823740a1ad52fb1dd72842098abe2&app_code=com.mfw.roadbook&screen_scale=2.88&screen_width=1080&time_offset=480&device_id=A4%3A50%3A46%3A36%3AA8%3A43&oauth_signature=RG54frpqaPt7zPfxq4kjUTafbZU%3D&oauth_consumer_key=5&oauth_timestamp=1571296894&oauth_nonce=3acaaaae-1f9e-4e0e-acf1-3dc817c1c916&mfwsdk_ver=20140507&app_ver=9.3.28&has_notch=0&hardware_model=MIX+3&channel_id=XiaoMi&"; 12 | 13 | const LOCATION_WHERE_URL = "https://mapi.mafengwo.cn/mdd/feed/get_index/v1?jsondata=%7B%22tab_id%22%3A%22book_list%22%2C%22device_mid%22%3A%22868936038181299%22%2C%22mdd_id%22%3A%2210065%22%2C%22by_user%22%3A%221%22%7D&o_lat=39.904546&patch_ver=1.0&device_type=android&dev_ver=D1931.0&oauth_version=1.0&oauth_signature_method=HMAC-SHA1&screen_height=2029&open_udid=64774894b98b2cc4&app_version_code=812&x_auth_mode=client_auth&oauth_token=0_0969044fd4edf59957f4a39bce9200c6&sys_ver=9&o_lng=116.443446&brand=Xiaomi&zzzghostsigh=a21bb64b221fe2115f8f9316dd21c217e2afa228&app_code=com.mfw.roadbook&android_oaid=1bb9aee3d819ec37&screen_scale=2.88&screen_width=1080&time_offset=480&device_id=64774894b98b2cc4&oauth_signature=SJ60dO%2F%2BW19l%2BpXR1ruD%2FBmAR9U%3D&oauth_consumer_key=5&oauth_timestamp=1573108886&oauth_nonce=6b8feb27-d937-45a5-9732-89477149da3a&mfwsdk_ver=20140507&app_ver=9.3.33&has_notch=1&hardware_model=MI+8+SE&channel_id=XiaoMi&"; 14 | 15 | class LocationDao{ 16 | 17 | static Future fetch()async{ 18 | final response = await Dio().get(LOCATION_URL); 19 | if(response.statusCode == 200){ 20 | var result = LocationModel.fromJson(response.data); 21 | 22 | 23 | return result; 24 | }else{ 25 | throw Exception("location信息请求失败"); 26 | } 27 | } 28 | 29 | } 30 | 31 | class LocationTabbarDao{ 32 | static Future fetch() async { 33 | 34 | final response = await Dio().get(LOCATION_TABAR_URL); 35 | if(response.statusCode == 200){ 36 | 37 | 38 | var result = LocationTababrModel.fromJson(response.data); 39 | 40 | return result; 41 | }else{ 42 | throw Exception("首页tabbar请求失败"); 43 | } 44 | } 45 | } 46 | 47 | class LocationWhereDao{ 48 | static Future fetch() async{ 49 | 50 | final response = await Dio().get(LOCATION_WHERE_URL); 51 | if(response.statusCode == 200){ 52 | 53 | var result = LocationWhereModel.fromJson(response.data); 54 | 55 | 56 | return result; 57 | 58 | }else{ 59 | throw Exception("预定请求失败"); 60 | } 61 | } 62 | } 63 | 64 | -------------------------------------------------------------------------------- /flutter_mfw/lib/dao/my_dao.dart: -------------------------------------------------------------------------------- 1 | import 'package:dio/dio.dart'; 2 | import 'package:flutter_mfw/model/my_channel_model.dart'; 3 | const MY_URL = "https://mapi.mafengwo.cn/system/config/get_mine_channel_list/v2?o_lat=39.904542&device_type=android&dev_ver=D1930.0&oauth_version=1.0&oauth_signature_method=HMAC-SHA1&screen_height=2029&open_udid=64774894b98b2cc4&app_version_code=808&x_auth_mode=client_auth&oauth_token=0_0969044fd4edf59957f4a39bce9200c6&sys_ver=9&o_lng=116.443435&brand=Xiaomi&zzzghostsigh=9ce12a2caaf2eadf6f91c00081858578b4e56dbd&app_code=com.mfw.roadbook&android_oaid=1bb9aee3d819ec37&screen_scale=2.88&screen_width=1080&time_offset=480&device_id=64774894b98b2cc4&oauth_signature=csENOl67%2BKUlvGOT2gwarBkYqyI%3D&oauth_consumer_key=5&oauth_timestamp=1572846980&oauth_nonce=7cabcaea-6274-4d62-a7f8-4d97bad174cf&mfwsdk_ver=20140507&app_ver=9.3.32&has_notch=0&hardware_model=MI+8+SE&channel_id=XiaoMi&"; 4 | 5 | class MyChannelDao{ 6 | static Future fetch() async{ 7 | final response = await Dio().get(MY_URL); 8 | 9 | if(response.statusCode == 200){ 10 | 11 | var model = MyChannelModel.fromJson(response.data); 12 | return model; 13 | 14 | }else{ 15 | Exception("请求失败"); 16 | } 17 | 18 | } 19 | } -------------------------------------------------------------------------------- /flutter_mfw/lib/dao/travel_dao.dart: -------------------------------------------------------------------------------- 1 | import 'package:dio/dio.dart'; 2 | import 'package:flutter_mfw/model/travel_header_model.dart'; 3 | import 'package:flutter_mfw/model/travel_list_model.dart'; 4 | 5 | const TRAVEL_HEADER_URL = "https://mapi.mafengwo.cn/sales/home/get_index/v2?jsondata=%7B%22top_refresh%22%3A%220%22%2C%22page%22%3A%7B%22num%22%3A15%7D%7D&o_lat=39.904542&device_type=android&dev_ver=D1932.0&oauth_version=1.0&oauth_signature_method=HMAC-SHA1&screen_height=2029&open_udid=64774894b98b2cc4&app_version_code=815&x_auth_mode=client_auth&oauth_token=0_0969044fd4edf59957f4a39bce9200c6&sys_ver=9&o_lng=116.443449&brand=Xiaomi&zzzghostsigh=d07df9f817a222975d5cbc377cf2a86cee5140ea&app_code=com.mfw.roadbook&android_oaid=1bb9aee3d819ec37&screen_scale=2.88&screen_width=1080&time_offset=480&device_id=64774894b98b2cc4&oauth_signature=ZOPvqgFKYMMq4sAW3XsGCg6kYeI%3D&oauth_consumer_key=5&oauth_timestamp=1573707737&oauth_nonce=68a4f45c-1c41-44be-80d7-210da6b116f9&mfwsdk_ver=20140507&app_ver=9.3.34&has_notch=1&hardware_model=MI+8+SE&channel_id=XiaoMi&"; 6 | 7 | const TRAVEL_LIST_URL = "https://mapi.mafengwo.cn/sales/home/get_index/v2?jsondata=%7B%22page%22%3A%7B%22num%22%3A15%2C%22boundary%22%3A%221%22%7D%7D&o_lat=39.904542&device_type=android&dev_ver=D1932.0&oauth_version=1.0&oauth_signature_method=HMAC-SHA1&screen_height=2029&open_udid=64774894b98b2cc4&app_version_code=815&x_auth_mode=client_auth&oauth_token=0_0969044fd4edf59957f4a39bce9200c6&sys_ver=9&o_lng=116.443449&brand=Xiaomi&zzzghostsigh=521deb149b9e7d14de0029a4c0f9ed977b9b7d0a&app_code=com.mfw.roadbook&android_oaid=1bb9aee3d819ec37&screen_scale=2.88&screen_width=1080&time_offset=480&device_id=64774894b98b2cc4&oauth_signature=ZHFSuE7TVZR3C1adlOeiWEeqM3o%3D&oauth_consumer_key=5&oauth_timestamp=1573707738&oauth_nonce=a2b32230-f138-4db8-bacc-11995a9ddd35&mfwsdk_ver=20140507&app_ver=9.3.34&has_notch=1&hardware_model=MI+8+SE&channel_id=XiaoMi&"; 8 | 9 | class TravelHeaderDao{ 10 | 11 | static Future fetch() async{ 12 | final response = await Dio().get(TRAVEL_HEADER_URL); 13 | if(response.statusCode == 200){ 14 | 15 | var model = TravelHeaderModel.fromJson(response.data); 16 | 17 | 18 | return model; 19 | 20 | }else{ 21 | Exception("请求失败"); 22 | } 23 | } 24 | } 25 | 26 | class TravelListDao{ 27 | static Future fetch() async{ 28 | 29 | final response = await Dio().get(TRAVEL_LIST_URL); 30 | if(response.statusCode == 200){ 31 | var model = TravelListModel.fromJson(response.data); 32 | 33 | return model; 34 | 35 | }else{ 36 | Exception("请求失败"); 37 | } 38 | 39 | } 40 | } -------------------------------------------------------------------------------- /flutter_mfw/lib/dao/travel_detail_dao.dart: -------------------------------------------------------------------------------- 1 | import 'package:dio/dio.dart'; 2 | 3 | import 'package:flutter_mfw/model/travel_detail_model.dart'; 4 | const TRAVEL_DETAIL_URL = "https://mapi.mafengwo.cn/weng_exp/detail/get_detail/v4?o_lat=39.904569&device_type=android&dev_ver=D1935.0&weng_id=1645476439947365&oauth_version=1.0&oauth_signature_method=HMAC-SHA1&is_show_near_wengs=0&screen_height=2029&open_udid=64774894b98b2cc4&app_version_code=820&x_auth_mode=client_auth&oauth_token=0_0969044fd4edf59957f4a39bce9200c6&sys_ver=9&o_lng=116.443473&brand=Xiaomi&zzzghostsigh=2fd0966d8f173ff358adaea2c31f9b9522a368de&app_code=com.mfw.roadbook&android_oaid=1bb9aee3d819ec37&screen_scale=2.88&screen_width=1080&time_offset=480&device_id=64774894b98b2cc4&oauth_signature=%2BBoDrj%2FRGIh8Ex4Ms0ZYoRkJKhg%3D&oauth_consumer_key=5&oauth_timestamp=1576825984&is_full_version=1&oauth_nonce=e1e16b25-d7fc-400d-ae0b-516c6646dbe1&mfwsdk_ver=20140507&app_ver=9.3.37&has_notch=1&hardware_model=MI+8+SE&channel_id=XiaoMi&"; 5 | 6 | 7 | class TravelDetailDao{ 8 | 9 | static Future fetch() async{ 10 | final response = await Dio().get(TRAVEL_DETAIL_URL); 11 | if(response.statusCode == 200){ 12 | 13 | 14 | var model = TravelDetailModel.fromJson(response.data["data"]); 15 | 16 | return model; 17 | 18 | }else{ 19 | Exception("请求失败"); 20 | } 21 | } 22 | } -------------------------------------------------------------------------------- /flutter_mfw/lib/main.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/material.dart'; 2 | import 'package:flutter_mfw/routers/router.dart'; 3 | void main() => runApp(MyApp()); 4 | 5 | class MyApp extends StatelessWidget { 6 | // This widget is the root of your application. 7 | @override 8 | Widget build(BuildContext context) { 9 | return MaterialApp( 10 | initialRoute:"/", 11 | onGenerateRoute: onGenerateRoute, 12 | theme: ThemeData(primaryColor: Colors.white), 13 | ); 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /flutter_mfw/lib/model/home_main_icon_model.dart: -------------------------------------------------------------------------------- 1 | class HomeMainIconModel { 2 | int rc; 3 | String rm; 4 | Data data; 5 | 6 | HomeMainIconModel({this.rc, this.rm, this.data}); 7 | 8 | HomeMainIconModel.fromJson(Map json) { 9 | rc = json['rc']; 10 | rm = json['rm']; 11 | data = json['data'] != null ? new Data.fromJson(json['data']) : null; 12 | } 13 | 14 | Map toJson() { 15 | final Map data = new Map(); 16 | data['rc'] = this.rc; 17 | data['rm'] = this.rm; 18 | if (this.data != null) { 19 | data['data'] = this.data.toJson(); 20 | } 21 | return data; 22 | } 23 | } 24 | 25 | class Data { 26 | MainIcons mainIcons; 27 | 28 | Data({this.mainIcons}); 29 | 30 | Data.fromJson(Map json) { 31 | mainIcons = json['main_icons'] != null 32 | ? new MainIcons.fromJson(json['main_icons']) 33 | : null; 34 | } 35 | 36 | Map toJson() { 37 | final Map data = new Map(); 38 | if (this.mainIcons != null) { 39 | data['main_icons'] = this.mainIcons.toJson(); 40 | } 41 | return data; 42 | } 43 | } 44 | 45 | class MainIcons { 46 | List listWithColor; 47 | 48 | MainIcons({this.listWithColor}); 49 | 50 | MainIcons.fromJson(Map json) { 51 | if (json['list_with_color'] != null) { 52 | listWithColor = new List(); 53 | json['list_with_color'].forEach((v) { 54 | listWithColor.add(new ListWithColor.fromJson(v)); 55 | }); 56 | } 57 | } 58 | 59 | Map toJson() { 60 | final Map data = new Map(); 61 | if (this.listWithColor != null) { 62 | data['list_with_color'] = 63 | this.listWithColor.map((v) => v.toJson()).toList(); 64 | } 65 | return data; 66 | } 67 | } 68 | 69 | class ListWithColor { 70 | String icon; 71 | String title; 72 | String titleColor; 73 | BusinessItem businessItem; 74 | 75 | ListWithColor({this.icon, this.title, this.titleColor, this.businessItem}); 76 | 77 | ListWithColor.fromJson(Map json) { 78 | icon = json['icon']; 79 | title = json['title']; 80 | titleColor = json['title_color']; 81 | businessItem = json['business_item'] != null 82 | ? new BusinessItem.fromJson(json['business_item']) 83 | : null; 84 | } 85 | 86 | Map toJson() { 87 | final Map data = new Map(); 88 | data['icon'] = this.icon; 89 | data['title'] = this.title; 90 | data['title_color'] = this.titleColor; 91 | if (this.businessItem != null) { 92 | data['business_item'] = this.businessItem.toJson(); 93 | } 94 | return data; 95 | } 96 | } 97 | 98 | class BusinessItem { 99 | String itemId; 100 | String itemType; 101 | String itemName; 102 | String itemInfo; 103 | 104 | BusinessItem({this.itemId, this.itemType, this.itemName, this.itemInfo}); 105 | 106 | BusinessItem.fromJson(Map json) { 107 | itemId = json['item_id']; 108 | itemType = json['item_type']; 109 | itemName = json['item_name']; 110 | itemInfo = json['item_info']; 111 | } 112 | 113 | Map toJson() { 114 | final Map data = new Map(); 115 | data['item_id'] = this.itemId; 116 | data['item_type'] = this.itemType; 117 | data['item_name'] = this.itemName; 118 | data['item_info'] = this.itemInfo; 119 | return data; 120 | } 121 | } 122 | -------------------------------------------------------------------------------- /flutter_mfw/lib/model/home_model.dart: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/coder-dongjiayi/fluter_mfw/87a25f1335b4137f9c5ee780853d38053a4456eb/flutter_mfw/lib/model/home_model.dart -------------------------------------------------------------------------------- /flutter_mfw/lib/model/hote_model.dart: -------------------------------------------------------------------------------- 1 | class HoteModel { 2 | List list; 3 | 4 | HoteModel({this.list}); 5 | 6 | HoteModel.fromJson(Map json) { 7 | if (json['list'] != null) { 8 | list = new List(); 9 | json['list'].forEach((v) { 10 | list.add(new HoteItemModel.fromJson(v)); 11 | }); 12 | } 13 | } 14 | 15 | Map toJson() { 16 | final Map data = new Map(); 17 | if (this.list != null) { 18 | data['list'] = this.list.map((v) => v.toJson()).toList(); 19 | } 20 | return data; 21 | } 22 | } 23 | 24 | class HoteItemModel { 25 | String title; 26 | Tag tag; 27 | String jumpUrl; 28 | int isHotTopic; 29 | String subTitle; 30 | String image; 31 | BusinessItem businessItem; 32 | 33 | HoteItemModel( 34 | {this.title, 35 | this.tag, 36 | this.jumpUrl, 37 | this.isHotTopic, 38 | this.subTitle, 39 | this.image, 40 | this.businessItem}); 41 | 42 | HoteItemModel.fromJson(Map json) { 43 | title = json['title']; 44 | tag = json['tag'] != null ? new Tag.fromJson(json['tag']) : null; 45 | jumpUrl = json['jump_url']; 46 | isHotTopic = json['is_hot_topic']; 47 | subTitle = json['sub_title']; 48 | image = json['image']; 49 | businessItem = json['business_item'] != null 50 | ? new BusinessItem.fromJson(json['business_item']) 51 | : null; 52 | } 53 | 54 | Map toJson() { 55 | final Map data = new Map(); 56 | data['title'] = this.title; 57 | if (this.tag != null) { 58 | data['tag'] = this.tag.toJson(); 59 | } 60 | data['jump_url'] = this.jumpUrl; 61 | data['is_hot_topic'] = this.isHotTopic; 62 | data['sub_title'] = this.subTitle; 63 | data['image'] = this.image; 64 | if (this.businessItem != null) { 65 | data['business_item'] = this.businessItem.toJson(); 66 | } 67 | return data; 68 | } 69 | } 70 | 71 | class Tag { 72 | String text; 73 | String textColor; 74 | String borderColor; 75 | 76 | Tag({this.text, this.textColor, this.borderColor}); 77 | 78 | Tag.fromJson(Map json) { 79 | text = json['text']; 80 | textColor = json['text_color']; 81 | borderColor = json['border_color']; 82 | } 83 | 84 | Map toJson() { 85 | final Map data = new Map(); 86 | data['text'] = this.text; 87 | data['text_color'] = this.textColor; 88 | data['border_color'] = this.borderColor; 89 | return data; 90 | } 91 | } 92 | 93 | class BusinessItem { 94 | String itemId; 95 | String itemType; 96 | String abtest; 97 | String prmId; 98 | Extra extra; 99 | 100 | BusinessItem( 101 | {this.itemId, this.itemType, this.abtest, this.prmId, this.extra}); 102 | 103 | BusinessItem.fromJson(Map json) { 104 | itemId = json['item_id']; 105 | itemType = json['item_type']; 106 | abtest = json['abtest']; 107 | prmId = json['prm_id']; 108 | extra = json['extra'] != null ? new Extra.fromJson(json['extra']) : null; 109 | } 110 | 111 | Map toJson() { 112 | final Map data = new Map(); 113 | data['item_id'] = this.itemId; 114 | data['item_type'] = this.itemType; 115 | data['abtest'] = this.abtest; 116 | data['prm_id'] = this.prmId; 117 | if (this.extra != null) { 118 | data['extra'] = this.extra.toJson(); 119 | } 120 | return data; 121 | } 122 | } 123 | 124 | class Extra { 125 | String typeInfo; 126 | int isTraveling; 127 | int travelingMdd; 128 | int userStrategy; 129 | 130 | Extra( 131 | {this.typeInfo, this.isTraveling, this.travelingMdd, this.userStrategy}); 132 | 133 | Extra.fromJson(Map json) { 134 | typeInfo = json['type_info']; 135 | isTraveling = json['is_traveling']; 136 | travelingMdd = json['traveling_mdd']; 137 | userStrategy = json['user_strategy']; 138 | } 139 | 140 | Map toJson() { 141 | final Map data = new Map(); 142 | data['type_info'] = this.typeInfo; 143 | data['is_traveling'] = this.isTraveling; 144 | data['traveling_mdd'] = this.travelingMdd; 145 | data['user_strategy'] = this.userStrategy; 146 | return data; 147 | } 148 | } 149 | -------------------------------------------------------------------------------- /flutter_mfw/lib/model/my_channel_model.dart: -------------------------------------------------------------------------------- 1 | class MyChannelModel { 2 | int rc; 3 | MyChannelModelData data; 4 | String rm; 5 | 6 | MyChannelModel({this.rc, this.data, this.rm}); 7 | 8 | MyChannelModel.fromJson(Map json) { 9 | rc = json['rc']; 10 | data = json['data'] != null ? new MyChannelModelData.fromJson(json['data']) : null; 11 | rm = json['rm']; 12 | } 13 | 14 | Map toJson() { 15 | final Map data = new Map(); 16 | data['rc'] = this.rc; 17 | if (this.data != null) { 18 | data['data'] = this.data.toJson(); 19 | } 20 | data['rm'] = this.rm; 21 | return data; 22 | } 23 | } 24 | 25 | class MyChannelModelData { 26 | List normalChannels; 27 | List recommendChannels; 28 | 29 | MyChannelModelData({this.normalChannels, this.recommendChannels}); 30 | 31 | MyChannelModelData.fromJson(Map json) { 32 | if (json['normal_channels'] != null) { 33 | normalChannels = new List();(json['normal_channels'] as List).forEach((v) { normalChannels.add(new MyChannelModelDataNormalChannel.fromJson(v)); }); 34 | } 35 | if (json['recommend_channels'] != null) { 36 | recommendChannels = new List();(json['recommend_channels'] as List).forEach((v) { recommendChannels.add(new MyChannelModelDataRecommandChannels.fromJson(v)); }); 37 | } 38 | } 39 | 40 | Map toJson() { 41 | final Map data = new Map(); 42 | if (this.normalChannels != null) { 43 | data['normal_channels'] = this.normalChannels.map((v) => v.toJson()).toList(); 44 | } 45 | if (this.recommendChannels != null) { 46 | data['recommend_channels'] = this.recommendChannels.map((v) => v.toJson()).toList(); 47 | } 48 | return data; 49 | } 50 | } 51 | 52 | class MyChannelModelDataNormalChannel { 53 | String jumpUrl; 54 | String icon; 55 | int isNeedLogin; 56 | MyChannelModelDataNormalChannelsTip tip; 57 | String id; 58 | String title; 59 | int isTipDisappear; 60 | 61 | MyChannelModelDataNormalChannel({this.jumpUrl, this.icon, this.isNeedLogin, this.tip, this.id, this.title, this.isTipDisappear}); 62 | 63 | MyChannelModelDataNormalChannel.fromJson(Map json) { 64 | jumpUrl = json['jump_url']; 65 | icon = json['icon']; 66 | isNeedLogin = json['is_need_login']; 67 | tip = json['tip'] != null ? new MyChannelModelDataNormalChannelsTip.fromJson(json['tip']) : null; 68 | id = json['id']; 69 | title = json['title']; 70 | isTipDisappear = json['is_tip_disappear']; 71 | } 72 | 73 | Map toJson() { 74 | final Map data = new Map(); 75 | data['jump_url'] = this.jumpUrl; 76 | data['icon'] = this.icon; 77 | data['is_need_login'] = this.isNeedLogin; 78 | if (this.tip != null) { 79 | data['tip'] = this.tip.toJson(); 80 | } 81 | data['id'] = this.id; 82 | data['title'] = this.title; 83 | data['is_tip_disappear'] = this.isTipDisappear; 84 | return data; 85 | } 86 | } 87 | 88 | class MyChannelModelDataNormalChannelsTip { 89 | 90 | 91 | 92 | 93 | MyChannelModelDataNormalChannelsTip.fromJson(Map json) { 94 | } 95 | 96 | Map toJson() { 97 | final Map data = new Map(); 98 | return data; 99 | } 100 | } 101 | 102 | class MyChannelModelDataRecommandChannels { 103 | String jumpUrl; 104 | String icon; 105 | int isNeedLogin; 106 | MyChannelModelDataRecommendChannelsTip tip; 107 | String id; 108 | String title; 109 | int isTipDisappear; 110 | 111 | MyChannelModelDataRecommandChannels({this.jumpUrl, this.icon, this.isNeedLogin, this.tip, this.id, this.title, this.isTipDisappear}); 112 | 113 | MyChannelModelDataRecommandChannels.fromJson(Map json) { 114 | jumpUrl = json['jump_url']; 115 | icon = json['icon']; 116 | isNeedLogin = json['is_need_login']; 117 | tip = json['tip'] != null ? new MyChannelModelDataRecommendChannelsTip.fromJson(json['tip']) : null; 118 | id = json['id']; 119 | title = json['title']; 120 | isTipDisappear = json['is_tip_disappear']; 121 | } 122 | 123 | Map toJson() { 124 | final Map data = new Map(); 125 | data['jump_url'] = this.jumpUrl; 126 | data['icon'] = this.icon; 127 | data['is_need_login'] = this.isNeedLogin; 128 | if (this.tip != null) { 129 | data['tip'] = this.tip.toJson(); 130 | } 131 | data['id'] = this.id; 132 | data['title'] = this.title; 133 | data['is_tip_disappear'] = this.isTipDisappear; 134 | return data; 135 | } 136 | } 137 | 138 | class MyChannelModelDataRecommendChannelsTip { 139 | 140 | 141 | 142 | 143 | MyChannelModelDataRecommendChannelsTip.fromJson(Map json) { 144 | } 145 | 146 | Map toJson() { 147 | final Map data = new Map(); 148 | return data; 149 | } 150 | } 151 | -------------------------------------------------------------------------------- /flutter_mfw/lib/model/tabar_model.dart: -------------------------------------------------------------------------------- 1 | class TabarListModel { 2 | List tabList; 3 | 4 | TabarListModel({this.tabList}); 5 | 6 | TabarListModel.fromJson(Map json) { 7 | if (json['tab_list'] != null) { 8 | tabList = new List(); 9 | json['tab_list'].forEach((v) { 10 | tabList.add(new TabItemModel.fromJson(v)); 11 | }); 12 | } 13 | } 14 | 15 | Map toJson() { 16 | final Map data = new Map(); 17 | if (this.tabList != null) { 18 | data['tab_list'] = this.tabList.map((v) => v.toJson()).toList(); 19 | } 20 | return data; 21 | } 22 | } 23 | 24 | class TabItemModel { 25 | String id; 26 | String name; 27 | 28 | TabItemModel({this.id, this.name}); 29 | 30 | TabItemModel.fromJson(Map json) { 31 | id = json['id']; 32 | name = json['name']; 33 | } 34 | 35 | Map toJson() { 36 | final Map data = new Map(); 37 | data['id'] = this.id; 38 | data['name'] = this.name; 39 | return data; 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /flutter_mfw/lib/model/travel_detail_model.dart: -------------------------------------------------------------------------------- 1 | class TravelDetailModel{ 2 | 3 | WengModel weng; 4 | 5 | RelateStyleItems relateItems; 6 | 7 | 8 | 9 | TravelDetailModel({this.weng}); 10 | TravelDetailModel.fromJson(Map json) { 11 | 12 | 13 | weng = json['weng'] != null ? WengModel.fromJson(json["weng"]) : null; 14 | 15 | 16 | 17 | } 18 | 19 | } 20 | 21 | //replies 22 | class RepliesItemModel{ 23 | 24 | String content; 25 | 26 | OwnerModel owner; 27 | 28 | int num_like; 29 | 30 | RepliesItemModel.fromJson(Map json) { 31 | 32 | content = json["content"]; 33 | num_like = json["num_like"]; 34 | owner = json["owner"] !=null ? OwnerModel.fromJson(json["owner"]) : null; 35 | 36 | } 37 | 38 | } 39 | 40 | class FavouriteItem{ 41 | String logo; 42 | 43 | FavouriteItem(this.logo); 44 | FavouriteItem.fromJson(Map json){ 45 | logo = json["logo"]; 46 | } 47 | } 48 | 49 | //related_style_items 50 | class RelateStyleItems{ 51 | 52 | String type; 53 | String type_tag_background_color; 54 | String name; 55 | 56 | 57 | } 58 | 59 | class MediaModel{ 60 | 61 | int width; 62 | int height; 63 | String bimg; 64 | MediaModel({this.width,this.height,this.bimg}); 65 | 66 | MediaModel.fromJson(Map json){ 67 | width = json["width"]; 68 | height = json["height"]; 69 | bimg = json["bimg"]; 70 | 71 | } 72 | 73 | } 74 | 75 | class WengModel{ 76 | String content_edit; 77 | String content; 78 | String title_edit; 79 | int num_like; 80 | int num_reply; 81 | 82 | List replies; 83 | 84 | OwnerModel owner; 85 | List media; 86 | List favUsers; 87 | 88 | WengModel({ 89 | 90 | this.content_edit, 91 | this.content, 92 | 93 | this.owner, 94 | this.media, 95 | this.title_edit 96 | }); 97 | 98 | WengModel.fromJson(Map json) { 99 | content_edit = json['content_edit']; 100 | content = json['content_edit']; 101 | title_edit = json['title_edit']; 102 | num_like = json['num_like']; 103 | num_reply = json['num_reply']; 104 | 105 | owner = json['owner'] != null ? OwnerModel.fromJson(json['owner']) : null; 106 | 107 | if(json['media'] != null){ 108 | media = List(); 109 | 110 | json["media"].forEach((v){ 111 | 112 | 113 | media.add(MediaModel.fromJson(v["data"])); 114 | }); 115 | } 116 | 117 | if(json["replies"] != null){ 118 | replies = List(); 119 | json["replies"].forEach((v){ 120 | replies.add(RepliesItemModel.fromJson(v)); 121 | 122 | }); 123 | } 124 | 125 | if(json["fav_users"] != null){ 126 | 127 | favUsers = List(); 128 | 129 | json["fav_users"].forEach((v){ 130 | favUsers.add(FavouriteItem.fromJson(v)); 131 | 132 | }); 133 | } 134 | } 135 | 136 | } 137 | 138 | class OwnerModel{ 139 | String name; 140 | String logo; 141 | String jump_url; 142 | 143 | 144 | FootprintAssetTag footprint_asset_tag; 145 | 146 | OwnerModel({this.name,this.logo,this.jump_url,this.footprint_asset_tag}); 147 | 148 | 149 | OwnerModel.fromJson(Map json){ 150 | name = json["name"]; 151 | logo = json["logo"]; 152 | jump_url = json['jump_url']; 153 | 154 | footprint_asset_tag = json['footprint_asset_tag'] != null ? FootprintAssetTag.fromJson(json["footprint_asset_tag"]) : null; 155 | } 156 | 157 | } 158 | 159 | class FootprintAssetTag{ 160 | String icon; 161 | String text; 162 | String jump_url; 163 | 164 | 165 | FootprintAssetTag({this.icon,this.text,this.jump_url}); 166 | 167 | FootprintAssetTag.fromJson(Map json){ 168 | icon = json["icon"]; 169 | text = json["text"]; 170 | jump_url = json["jump_url"]; 171 | } 172 | } -------------------------------------------------------------------------------- /flutter_mfw/lib/pages/detail/detail_appbar_widget.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/material.dart'; 2 | import 'package:flutter_mfw/screen_adapter.dart'; 3 | import 'package:flutter_mfw/model/travel_detail_model.dart'; 4 | class DetailAppbarWidget extends StatefulWidget { 5 | 6 | 7 | OwnerModel owner; 8 | DetailAppbarWidget({Key key,this.owner}) : super(key:key); 9 | @override 10 | _DetailAppbarWidgetState createState() => _DetailAppbarWidgetState(); 11 | } 12 | 13 | class _DetailAppbarWidgetState extends State { 14 | @override 15 | Widget build(BuildContext context) { 16 | if(widget.owner == null){ 17 | return Text(""); 18 | } 19 | ScreenAdapter.init(context); 20 | 21 | 22 | return Row( 23 | children: [ 24 | ClipRRect( 25 | borderRadius: BorderRadius.circular(ScreenAdapter.setWidth(30)), 26 | child: Image.network( 27 | "${widget.owner.logo}", 28 | width: ScreenAdapter.setWidth(60), 29 | height: ScreenAdapter.setHeight(60), 30 | )), 31 | Padding( 32 | padding: EdgeInsets.only(left: 10), 33 | child: Text( 34 | "${widget.owner.name}", 35 | style: TextStyle(fontSize: 16), 36 | ), 37 | ), 38 | Container( 39 | margin: EdgeInsets.only(left: 10), 40 | padding: EdgeInsets.only(right: 5), 41 | decoration: BoxDecoration( 42 | color: Color.fromRGBO(221, 224, 243, 1.0), 43 | borderRadius: BorderRadius.circular(10)), 44 | child: Row( 45 | children: [ 46 | Image.network( 47 | "${widget.owner.footprint_asset_tag.icon}", 48 | width: ScreenAdapter.setWidth(40), 49 | height: ScreenAdapter.setHeight(40), 50 | ), 51 | Text("${widget.owner.footprint_asset_tag.text}", 52 | style: TextStyle( 53 | fontSize: 12, color: Color.fromRGBO(99, 100, 159, 1.0))) 54 | ], 55 | ), 56 | ) 57 | ], 58 | ); 59 | } 60 | } 61 | -------------------------------------------------------------------------------- /flutter_mfw/lib/pages/detail/detail_bottom_bar_widget.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/material.dart'; 2 | import 'package:flutter_mfw/screen_adapter.dart'; 3 | 4 | class DetailBottomBarWidget extends StatefulWidget { 5 | @override 6 | _DetailBottomBarWidgetState createState() => _DetailBottomBarWidgetState(); 7 | } 8 | 9 | class _DetailBottomBarWidgetState extends State { 10 | @override 11 | Widget build(BuildContext context) { 12 | ScreenAdapter.init(context); 13 | return Container( 14 | 15 | padding: EdgeInsets.fromLTRB(20, 0, 20, 0), 16 | decoration: BoxDecoration( 17 | color: Colors.white, 18 | boxShadow: [ 19 | BoxShadow( 20 | color: Color.fromRGBO(249, 249, 249, 1.0), 21 | offset: Offset(0, -5), //阴影xy轴偏移量 22 | blurRadius: 1.0, // 23 | ), 24 | ] 25 | ), 26 | height: ScreenAdapter.setHeight(120), 27 | child: _bottom(), 28 | 29 | ); 30 | } 31 | 32 | Widget _bottom(){ 33 | return Row( 34 | mainAxisAlignment: MainAxisAlignment.spaceBetween, 35 | children: [ 36 | _icon(Icons.message), 37 | _icon(Icons.favorite_border), 38 | _icon(Icons.star_border), 39 | _button() 40 | ], 41 | ); 42 | } 43 | Widget _button(){ 44 | 45 | return Container( 46 | alignment: Alignment.center, 47 | margin: EdgeInsets.fromLTRB(0, 10, 0, 10), 48 | padding: EdgeInsets.fromLTRB(25, 0, 25, 0), 49 | decoration: BoxDecoration( 50 | color: Colors.yellow, 51 | borderRadius: BorderRadius.circular(30) 52 | ), 53 | 54 | child: Text("文中提及",style: TextStyle(fontSize: 16,color: Colors.black,fontWeight: FontWeight.w600),), 55 | 56 | ); 57 | } 58 | 59 | Widget _icon(icon){ 60 | return Row( 61 | crossAxisAlignment: CrossAxisAlignment.start, 62 | children: [ 63 | Icon(icon), 64 | Text("14",style: TextStyle(fontWeight: FontWeight.w600),) 65 | ], 66 | ); 67 | } 68 | } 69 | -------------------------------------------------------------------------------- /flutter_mfw/lib/pages/detail/detail_carousel_widget.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/material.dart'; 2 | import 'package:flutter_mfw/model/travel_detail_model.dart'; 3 | import 'package:flutter_mfw/screen_adapter.dart'; 4 | class DetailCarouselWidget extends StatefulWidget { 5 | 6 | var medias = []; 7 | DetailCarouselWidget({Key key,this.medias}) : super(key:key); 8 | @override 9 | _DetailCarouselWidgetState createState() => _DetailCarouselWidgetState(); 10 | } 11 | 12 | class _DetailCarouselWidgetState extends State { 13 | 14 | var _index = 0; 15 | 16 | var _controller =PageController(initialPage: 1, viewportFraction: 1.0); 17 | 18 | 19 | 20 | @override 21 | void initState() { 22 | // TODO: implement initState 23 | super.initState(); 24 | } 25 | @override 26 | Widget build(BuildContext context) { 27 | 28 | ScreenAdapter.init(context); 29 | 30 | return Stack( 31 | children: [ 32 | _carousel(), 33 | Positioned( 34 | right: 15, 35 | bottom: 15, 36 | child: _control(), 37 | 38 | ) 39 | ], 40 | ); 41 | } 42 | 43 | Widget _control(){ 44 | return Container( 45 | padding: EdgeInsets.fromLTRB(5, 2, 5, 2), 46 | alignment: Alignment.center, 47 | decoration: BoxDecoration( 48 | color: Color.fromRGBO(0, 0, 0, 0.5), 49 | borderRadius: BorderRadius.circular(20) 50 | 51 | ), 52 | child: Text("${_index+1}" + "/" + "${widget.medias.length}",style:TextStyle(color: Colors.white,fontSize: 10),), 53 | ); 54 | } 55 | Widget _carousel(){ 56 | 57 | double image_width = widget.medias[_index].width.toDouble(); 58 | double image_height = widget.medias[_index].height.toDouble(); 59 | 60 | double rate = image_width / image_height; 61 | // MediaQuery.of(context).size.width 62 | double real_height = MediaQuery.of(context).size.height / rate; 63 | 64 | return Container( 65 | 66 | height:ScreenAdapter.setHeight(real_height), 67 | width:ScreenAdapter.getScreenWidth(), 68 | color: Colors.yellow, 69 | child: PageView( 70 | 71 | controller: _controller, 72 | onPageChanged: (index){ 73 | setState(() { 74 | _index = index; 75 | 76 | }); 77 | }, 78 | children: widget.medias.map((value){ 79 | return Image.network(value.bimg,fit: BoxFit.fill,); 80 | }).toList(), 81 | ), 82 | ); 83 | } 84 | 85 | } 86 | -------------------------------------------------------------------------------- /flutter_mfw/lib/pages/detail/detail_content_widget.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/material.dart'; 2 | 3 | class DetailContentWidget extends StatefulWidget { 4 | 5 | String content; 6 | 7 | DetailContentWidget({Key key,this.content}) : super(key : key); 8 | 9 | @override 10 | _DetailContentWidgetState createState() => _DetailContentWidgetState(); 11 | } 12 | 13 | class _DetailContentWidgetState extends State { 14 | 15 | var _maxLine = 12; 16 | 17 | @override 18 | Widget build(BuildContext context) { 19 | return GestureDetector( 20 | 21 | onTap: (){ 22 | setState(() { 23 | _maxLine = _maxLine == 12 ? 10000 : 12; 24 | }); 25 | }, 26 | child: Column( 27 | crossAxisAlignment: CrossAxisAlignment.start, 28 | children: [ 29 | _textContent(), 30 | Padding( 31 | padding: EdgeInsets.only(left: 15,top: 0,right: 15,bottom: 0), 32 | child: Text("${_maxLine == 12 ? "点击查看全部>>" : ""}",style: TextStyle(color: Color.fromRGBO(86, 164, 251, 1.0)),), 33 | ) 34 | ], 35 | ) 36 | ); 37 | } 38 | 39 | Widget _textContent(){ 40 | 41 | return Padding( 42 | padding: EdgeInsets.only(left: 15,top: 0,right: 15,bottom: 10), 43 | child: Text("${widget.content}", 44 | maxLines: _maxLine, 45 | style: TextStyle(fontSize: 18,wordSpacing: 8,color: Colors.black)) 46 | ); 47 | } 48 | } 49 | -------------------------------------------------------------------------------- /flutter_mfw/lib/pages/detail/detail_recommend_title_widget.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/material.dart'; 2 | import 'package:flutter_mfw/screen_adapter.dart'; 3 | class DetailRecommendTitleWidget extends StatefulWidget { 4 | @override 5 | _DetailRecommendTitleWidgetState createState() => _DetailRecommendTitleWidgetState(); 6 | } 7 | 8 | class _DetailRecommendTitleWidgetState extends State { 9 | @override 10 | Widget build(BuildContext context) { 11 | ScreenAdapter.init(context); 12 | 13 | return Container( 14 | color: Colors.white, 15 | child: Column( 16 | children: [ 17 | Container( 18 | margin: EdgeInsets.only(top: 15), 19 | color: Color.fromRGBO(246, 246, 249, 1.0), 20 | height: ScreenAdapter.setHeight(10), 21 | ), 22 | Padding( 23 | padding: EdgeInsets.only(top: 10,bottom: 10), 24 | child: Text("相关推荐",style: TextStyle(color: Colors.black,fontSize: 16,fontWeight: FontWeight.w600)) 25 | 26 | ), 27 | Divider( 28 | height: 1, 29 | color: Color.fromRGBO(227, 238, 221, 1.0), 30 | ) 31 | 32 | ], 33 | ), 34 | ); 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /flutter_mfw/lib/pages/detail/detail_remind_widget.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/material.dart'; 2 | import 'package:flutter_mfw/screen_adapter.dart'; 3 | import 'package:flutter_mfw/model/travel_detail_model.dart'; 4 | 5 | class DetailRemmindWidget extends StatefulWidget { 6 | var favouriteList = List(); 7 | 8 | 9 | var replyNumber = 0; 10 | 11 | DetailRemmindWidget({Key key, this.favouriteList,this.replyNumber}) : super(key: key); 12 | 13 | @override 14 | _DetailRemmindWidgetState createState() => _DetailRemmindWidgetState(); 15 | } 16 | 17 | class _DetailRemmindWidgetState extends State { 18 | @override 19 | Widget build(BuildContext context) { 20 | return Container( 21 | margin: EdgeInsets.fromLTRB(15, 10, 15, 0), 22 | child: Column( 23 | crossAxisAlignment: CrossAxisAlignment.start, 24 | children: [ 25 | Divider( 26 | height: 1, 27 | color: Color.fromRGBO(227, 238, 221, 1.0), 28 | ), 29 | Padding( 30 | padding: EdgeInsets.fromLTRB(0, 10, 0, 0), 31 | child: Text( 32 | "文中提及", 33 | style: TextStyle(fontWeight: FontWeight.w600, fontSize: 18), 34 | ), 35 | ), 36 | _remindItem(), 37 | _timeShoot(), 38 | _likeList(), 39 | Divider( 40 | height: 1, 41 | color: Color.fromRGBO(227, 238, 221, 1.0), 42 | ) 43 | 44 | ], 45 | ), 46 | ); 47 | } 48 | 49 | //文中提及 50 | Widget _remindItem() { 51 | return Container( 52 | margin: EdgeInsets.only(top: 10), 53 | decoration: BoxDecoration(color: Colors.white, boxShadow: [ 54 | BoxShadow( 55 | color: Color.fromRGBO(249, 249, 249, 1.0), 56 | offset: Offset(0, -5), //阴影xy轴偏移量 57 | blurRadius: 1.0, // 58 | ), 59 | BoxShadow( 60 | color: Color.fromRGBO(249, 249, 249, 1.0), 61 | offset: Offset(0, 5), //阴影xy轴偏移量 62 | blurRadius: 1.0, // 63 | ), 64 | BoxShadow( 65 | color: Color.fromRGBO(249, 249, 249, 1.0), 66 | offset: Offset(5, 0), //阴影xy轴偏移量 67 | blurRadius: 1.0, // 68 | ), 69 | BoxShadow( 70 | color: Color.fromRGBO(249, 249, 249, 1.0), 71 | offset: Offset(-5, 0), //阴影xy轴偏移量 72 | blurRadius: 1.0, // 73 | ) 74 | ]), 75 | padding: EdgeInsets.fromLTRB(10, 10, 10, 10), 76 | child: Row( 77 | children: [ 78 | Stack( 79 | children: [ 80 | ClipRRect( 81 | borderRadius: BorderRadius.circular(5), 82 | child: Image.network( 83 | "https://b1-q.mafengwo.net/s13/M00/82/06/wKgEaVx5P-yAdvuGAGAUjwqcy1g26.jpeg?imageMogr2/thumbnail/!400x400r/strip/gravity/Center/crop/!400x400/quality/90", 84 | width: ScreenAdapter.setWidth(136), 85 | height: ScreenAdapter.setHeight(136)), 86 | ), 87 | Container( 88 | padding: EdgeInsets.fromLTRB(5, 0, 5, 0), 89 | decoration: BoxDecoration( 90 | borderRadius: BorderRadius.only( 91 | topLeft: Radius.circular(5), 92 | bottomRight: Radius.circular(5)), 93 | color: Colors.green), 94 | child: Text( 95 | "景点", 96 | style: TextStyle(color: Colors.white, fontSize: 12), 97 | ), 98 | ) 99 | ], 100 | ), 101 | Padding( 102 | padding: EdgeInsets.only(left: 10), 103 | child: Column( 104 | crossAxisAlignment: CrossAxisAlignment.start, 105 | mainAxisAlignment: MainAxisAlignment.spaceBetween, 106 | children: [ 107 | Text( 108 | "红井路", 109 | style: TextStyle(fontSize: 17, fontWeight: FontWeight.w600), 110 | ), 111 | Text("205篇点评"), 112 | Padding( 113 | padding: EdgeInsets.only(top: 8), 114 | child: Text( 115 | "位于房山", 116 | style: TextStyle(color: Color.fromRGBO(152, 152, 152, 1.0)), 117 | ), 118 | ) 119 | ], 120 | ), 121 | ) 122 | ], 123 | ), 124 | ); 125 | } 126 | 127 | //拍摄时间 128 | Widget _timeShoot() { 129 | return Padding( 130 | padding: EdgeInsets.only(top: 20), 131 | child: Text( 132 | "拍摄于 2014-04-26", 133 | style: TextStyle(color: Color.fromRGBO(199, 201, 204, 1.0)), 134 | )); 135 | } 136 | 137 | //喜欢人数 138 | Widget _likeList() { 139 | var _favourite = widget.favouriteList.length > 6 140 | ? widget.favouriteList.sublist(0, 6) 141 | : widget.favouriteList; 142 | 143 | return Padding( 144 | padding: EdgeInsets.only(top: 20,bottom: 20), 145 | child: Row( 146 | mainAxisAlignment: MainAxisAlignment.spaceBetween, 147 | children: [ 148 | Row( 149 | children: _favourite.map((value){ 150 | 151 | return Padding( 152 | padding: EdgeInsets.only(right: 10), 153 | child: ClipOval( 154 | child: Image.network( 155 | value.logo, 156 | width: ScreenAdapter.setWidth(46), 157 | height: ScreenAdapter.setHeight(46), 158 | fit: BoxFit.cover, 159 | ), 160 | )); 161 | 162 | }).toList(), 163 | ), 164 | 165 | Row( 166 | children: [ 167 | Icon(Icons.favorite_border), 168 | Text("${widget.replyNumber}") 169 | ], 170 | ) 171 | ], 172 | 173 | ), 174 | ); 175 | } 176 | } 177 | -------------------------------------------------------------------------------- /flutter_mfw/lib/pages/detail/detail_title_widget.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/material.dart'; 2 | class DetailTitleWidget extends StatefulWidget { 3 | 4 | String poin; 5 | String mmd; 6 | String title; 7 | DetailTitleWidget({Key key,this.poin,this.mmd,this.title}): super(key:key); 8 | 9 | @override 10 | _DetailTitleWidgetState createState() => _DetailTitleWidgetState(); 11 | } 12 | 13 | class _DetailTitleWidgetState extends State { 14 | @override 15 | Widget build(BuildContext context) { 16 | 17 | if (widget.title.length == 0){ 18 | widget.title = ""; 19 | } 20 | 21 | return Column( 22 | children: [ 23 | Padding(padding: EdgeInsets.fromLTRB(15, 20, 15, 0), 24 | child: Text("${widget.title}",style: TextStyle(fontSize: 23,fontWeight: FontWeight.w600))), 25 | 26 | Padding(padding: EdgeInsets.only(left: 10,top: 15), 27 | child: Row( 28 | children: [ 29 | Container( 30 | padding: EdgeInsets.fromLTRB(10, 5, 10, 5), 31 | decoration: BoxDecoration( 32 | borderRadius: BorderRadius.circular(5), 33 | color: Color.fromRGBO(246, 246, 246, 1.0) 34 | ), 35 | child: Text("董里",style: TextStyle(color: Color.fromRGBO(86, 164, 251, 1.0)),), 36 | ), 37 | Container( 38 | margin: EdgeInsets.only(left: 20), 39 | decoration: BoxDecoration( 40 | borderRadius: BorderRadius.circular(5), 41 | color: Color.fromRGBO(246, 246, 246, 1.0) 42 | ), 43 | padding: EdgeInsets.fromLTRB(10, 5, 10, 5), 44 | child: Row( 45 | children: [ 46 | Icon(Icons.location_on,color: Color.fromRGBO(86, 164, 251, 1.0),size: 20,), 47 | Text("洛克岛浮潜",style: TextStyle(color: Color.fromRGBO(86, 164, 251, 1.0)),) 48 | ], 49 | ), 50 | ) 51 | 52 | ], 53 | ), 54 | ), 55 | 56 | Padding(padding: EdgeInsets.only(left: 10,right: 10,top: 10), 57 | child: Divider( 58 | color: Color.fromRGBO(236, 236, 236, 1.0), 59 | 60 | height: 2, 61 | )) 62 | 63 | ], 64 | ); 65 | } 66 | } 67 | -------------------------------------------------------------------------------- /flutter_mfw/lib/pages/detail/travel_detail_widget.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/material.dart'; 2 | 3 | import 'package:flutter_mfw/screen_adapter.dart'; 4 | import 'package:flutter_mfw/pages/detail/detail_appbar_widget.dart'; 5 | import 'package:flutter_mfw/pages/detail/detail_carousel_widget.dart'; 6 | import 'package:flutter_mfw/dao/travel_detail_dao.dart'; 7 | import 'package:flutter_mfw/model/travel_detail_model.dart'; 8 | import 'package:flutter_mfw/pages/detail/detail_title_widget.dart'; 9 | import 'package:flutter_mfw/pages/detail/detail_content_widget.dart'; 10 | import 'package:flutter_mfw/pages/detail/detail_remind_widget.dart'; 11 | import 'package:flutter_mfw/pages/detail/detail_reply_widget.dart'; 12 | import 'package:flutter_mfw/pages/detail/detail_recommend_title_widget.dart'; 13 | import 'package:flutter_mfw/pages/home/home_waterfall_page.dart'; 14 | 15 | import 'package:flutter_mfw/dao/home_dao.dart'; 16 | 17 | import 'package:flutter_mfw/model/waterfall_model.dart'; 18 | 19 | import 'package:flutter_mfw/pages/detail/detail_bottom_bar_widget.dart'; 20 | 21 | class TravelDetailWidget extends StatefulWidget { 22 | 23 | var animation = false; 24 | TravelDetailWidget({Key key,this.animation}) : super(key :key); 25 | 26 | @override 27 | _TravelDetailWidgetState createState() => _TravelDetailWidgetState(); 28 | } 29 | 30 | class _TravelDetailWidgetState extends State { 31 | 32 | 33 | 34 | TravelDetailModel _travelDetailModel; 35 | 36 | var _owner; 37 | var _medias = []; 38 | 39 | var _waterfallList = []; 40 | 41 | @override 42 | void initState() { 43 | // TODO: implement initState 44 | super.initState(); 45 | _getData(); 46 | _getWaterFallData(); 47 | } 48 | 49 | void _getData(){ 50 | TravelDetailDao.fetch().then((value){ 51 | _travelDetailModel = value; 52 | setState(() { 53 | _owner = _travelDetailModel.weng.owner; 54 | 55 | _medias = _travelDetailModel.weng.media; 56 | }); 57 | 58 | }); 59 | } 60 | 61 | void _getWaterFallData(){ 62 | WaterFallDao.fetch().then((result){ 63 | setState(() { 64 | 65 | _waterfallList = result.list; 66 | }); 67 | 68 | }); 69 | } 70 | @override 71 | Widget build(BuildContext context) { 72 | 73 | 74 | ScreenAdapter.init(context); 75 | return Scaffold( 76 | backgroundColor: Colors.white, 77 | appBar: AppBar( 78 | backgroundColor: Colors.white, 79 | title:DetailAppbarWidget( 80 | owner: _owner, 81 | ), 82 | elevation: 0, 83 | actions: [ 84 | Padding(padding: EdgeInsets.only(right: 10), 85 | child: Icon(Icons.more_horiz)) 86 | ], 87 | ), 88 | body:SafeArea( 89 | child: Stack( 90 | children: [ 91 | _travelDetailModel == null ? Center( 92 | child: Text("加载中"), 93 | ) : 94 | CustomScrollView( 95 | slivers: [ 96 | ///1、轮播图 waterfall 97 | SliverToBoxAdapter( 98 | child: Hero( 99 | tag: "waterfall", 100 | child: DetailCarouselWidget( 101 | medias: _medias, 102 | ), 103 | ), 104 | ), 105 | ///2、位置 坐标 106 | SliverToBoxAdapter( 107 | child: DetailTitleWidget( 108 | title: _travelDetailModel.weng.title_edit, 109 | ), 110 | ), 111 | ///3、 内容文字 112 | SliverToBoxAdapter( 113 | child: DetailContentWidget( 114 | content: _travelDetailModel.weng.content, 115 | ), 116 | ), 117 | ///4、文中提及 118 | SliverToBoxAdapter( 119 | child: DetailRemmindWidget( 120 | favouriteList: _travelDetailModel.weng.favUsers, 121 | replyNumber: _travelDetailModel.weng.num_reply, 122 | ), 123 | ), 124 | ///5、回复列表 125 | SliverToBoxAdapter( 126 | child: DetailReplyWidget( 127 | replies: _travelDetailModel.weng.replies, 128 | ), 129 | ), 130 | ///6、相关推荐标题 131 | SliverToBoxAdapter( 132 | child: DetailRecommendTitleWidget(), 133 | ), 134 | ///7. 瀑布流 135 | SliverToBoxAdapter( 136 | child: Padding( 137 | padding: EdgeInsets.only(bottom: 90), 138 | child: HomeWaterfallPage( 139 | id: 23, 140 | animation: true, 141 | ), 142 | ), 143 | ) 144 | 145 | ], 146 | ), 147 | Positioned( 148 | bottom: 0, 149 | left: 0, 150 | right: 0, 151 | child: DetailBottomBarWidget(), 152 | ) 153 | ], 154 | ) 155 | ) 156 | 157 | 158 | ); 159 | } 160 | 161 | 162 | 163 | 164 | } 165 | 166 | 167 | -------------------------------------------------------------------------------- /flutter_mfw/lib/pages/home/home_page.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/material.dart'; 2 | import 'package:flutter_mfw/model/tabar_model.dart'; 3 | import 'package:flutter_mfw/model/hote_model.dart'; 4 | import 'package:flutter_mfw/screen_adapter.dart'; 5 | 6 | import 'package:flutter_mfw/model/waterfall_model.dart'; 7 | import 'package:flutter_mfw/dao/home_dao.dart'; 8 | import 'package:flutter_mfw/pages/home/widget/home_navbar_widget.dart'; 9 | import 'package:flutter_mfw/pages/home/widget/home_top_nav.widget.dart'; 10 | import 'package:flutter_mfw/pages/home/widget/home_tabbar_widget.dart'; 11 | import 'package:flutter_mfw/pages/home/home_waterfall_page.dart'; 12 | 13 | 14 | 15 | class HomePage extends StatefulWidget { 16 | 17 | @override 18 | _HomePageState createState() => _HomePageState(); 19 | } 20 | 21 | class _HomePageState extends State with AutomaticKeepAliveClientMixin{ 22 | 23 | 24 | var _tabbarList = []; 25 | var _hoteList = []; 26 | 27 | 28 | var _pageController; 29 | 30 | var _currentId = "55"; 31 | 32 | @override 33 | // TODO: implement wantKeepAlive 34 | bool get wantKeepAlive => true; 35 | 36 | @override 37 | void initState() { 38 | // TODO: implement initState 39 | super.initState(); 40 | _pageController = PageController( 41 | initialPage:1, 42 | 43 | ); 44 | 45 | _getTabrData(); 46 | _getHoteData(); 47 | 48 | } 49 | 50 | void _animateToPage(index){ 51 | 52 | 53 | _pageController.jumpToPage(index); 54 | 55 | } 56 | 57 | 58 | 59 | //热门话题 60 | void _getHoteData(){ 61 | 62 | HoteListDao.fetch().then((result){ 63 | 64 | setState(() { 65 | _hoteList = result.list; 66 | 67 | }); 68 | 69 | }).catchError((error){ 70 | print(error); 71 | }); 72 | } 73 | 74 | //tabbar 数据 75 | void _getTabrData(){ 76 | TabbarListDao.fetch().then((result){ 77 | 78 | setState(() { 79 | _tabbarList = result.tabList; 80 | }); 81 | 82 | }).catchError((error){ 83 | print(error); 84 | }); 85 | } 86 | 87 | @override 88 | Widget build(BuildContext context) { 89 | return _pageNestedScrollViewWidget(); 90 | } 91 | 92 | 93 | 94 | Widget _pageNestedScrollViewWidget(){ 95 | 96 | if (_tabbarList.length == 0){ 97 | return Center( 98 | child: Text("加载中...") 99 | ); 100 | } 101 | 102 | 103 | return NestedScrollView( 104 | headerSliverBuilder: (context,inner){ 105 | return [ 106 | SliverPersistentHeader( 107 | pinned: true, 108 | delegate: StickyNavBarDelegate(child: HomeNavbarWidget()), 109 | ), 110 | 111 | SliverToBoxAdapter( 112 | child: HomeTopNavWidget(), 113 | ), 114 | 115 | 116 | SliverPersistentHeader( 117 | pinned: true, 118 | delegate: StickyTabbarDelegate( 119 | child: HomeTabbarWidget( 120 | 121 | onTap: (item){ 122 | 123 | var index = 0; 124 | for(var i in _tabbarList){ 125 | index ++; 126 | if(i.id == item.id){ 127 | _animateToPage(index); 128 | break; 129 | } 130 | } 131 | setState(() { 132 | _currentId = item.id; 133 | }); 134 | }, 135 | currentId: _currentId, 136 | tabbarList: _tabbarList 137 | ) 138 | ), 139 | ), 140 | 141 | 142 | ]; 143 | }, 144 | 145 | body: PageView( 146 | 147 | 148 | controller: _pageController, 149 | onPageChanged: (index){ 150 | setState(() { 151 | _currentId = _tabbarList[index].id; 152 | }); 153 | }, 154 | children: _tabbarList.map((item){ 155 | return HomeWaterfallPage(id: _currentId,hoteList: _hoteList,animation: false); 156 | 157 | }).toList() 158 | ), 159 | ); 160 | } 161 | } 162 | 163 | 164 | class StickyTabbarDelegate extends SliverPersistentHeaderDelegate { 165 | 166 | final HomeTabbarWidget child; 167 | 168 | 169 | StickyTabbarDelegate({@required this.child}); 170 | 171 | @override 172 | Widget build( 173 | BuildContext context, double shrinkOffset, bool overlapsContent) { 174 | ScreenAdapter.init(context); 175 | return this.child; 176 | } 177 | 178 | @override 179 | double get maxExtent => ScreenAdapter.setHeight(84); 180 | 181 | @override 182 | double get minExtent => ScreenAdapter.setHeight(84); 183 | 184 | @override 185 | bool shouldRebuild(SliverPersistentHeaderDelegate oldDelegate) { 186 | return true; 187 | } 188 | 189 | } 190 | 191 | class StickyNavBarDelegate extends SliverPersistentHeaderDelegate { 192 | final HomeNavbarWidget child; 193 | 194 | 195 | StickyNavBarDelegate({@required this.child}); 196 | 197 | @override 198 | Widget build( 199 | BuildContext context, double shrinkOffset, bool overlapsContent) { 200 | ScreenAdapter.init(context); 201 | return this.child; 202 | } 203 | 204 | @override 205 | double get maxExtent => ScreenAdapter.setHeight(96)+ScreenAdapter.getStatusBarHeight() ; 206 | 207 | @override 208 | double get minExtent => ScreenAdapter.setHeight(96)+ScreenAdapter.getStatusBarHeight(); 209 | 210 | @override 211 | bool shouldRebuild(SliverPersistentHeaderDelegate oldDelegate) { 212 | return true; 213 | } 214 | 215 | } 216 | -------------------------------------------------------------------------------- /flutter_mfw/lib/pages/home/home_waterfall_page.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/material.dart'; 2 | 3 | import 'package:flutter_mfw/dao/home_dao.dart'; 4 | import 'package:flutter_mfw/model/hote_model.dart'; 5 | import 'package:flutter_mfw/model/waterfall_model.dart'; 6 | import 'package:flutter_mfw/pages/home/waterfall_widget/water_fallItem_widget.dart'; 7 | import 'package:flutter_staggered_grid_view/flutter_staggered_grid_view.dart'; 8 | 9 | import 'package:flutter_mfw/pages/home/widget/home_hote_topic_widget.dart'; 10 | import 'package:flutter_mfw/screen_adapter.dart'; 11 | import 'package:flutter_mfw/pages/detail/travel_detail_widget.dart'; 12 | 13 | 14 | class HomeWaterfallPage extends StatefulWidget { 15 | 16 | var id; 17 | 18 | var hoteList = []; 19 | 20 | var animation = false; 21 | 22 | HomeWaterfallPage({Key key,this.id,this.hoteList,this.animation}) : super(key:key); 23 | 24 | @override 25 | _HomeWaterfallPageState createState() => _HomeWaterfallPageState(); 26 | } 27 | 28 | class _HomeWaterfallPageState extends State with AutomaticKeepAliveClientMixin{ 29 | 30 | @override 31 | // TODO: implement wantKeepAlive 32 | bool get wantKeepAlive => true; 33 | 34 | var _waterfallList = []; 35 | @override 36 | void initState() { 37 | // TODO: implement initState 38 | super.initState(); 39 | _getWaterFallData(); 40 | 41 | } 42 | 43 | //瀑布流数据 44 | void _getWaterFallData(){ 45 | WaterFallDao.fetch().then((result){ 46 | setState(() { 47 | 48 | _waterfallList = result.list; 49 | }); 50 | 51 | }); 52 | } 53 | @override 54 | Widget build(BuildContext context) { 55 | 56 | if(_waterfallList.length == 0){ 57 | return Center( 58 | child: Text("加载中..."), 59 | ); 60 | } 61 | 62 | 63 | ScreenAdapter.init(context); 64 | return Stack( 65 | children: [ 66 | StaggeredGridView.countBuilder( 67 | physics: ClampingScrollPhysics(), 68 | 69 | crossAxisCount: 4, 70 | shrinkWrap: true, 71 | primary:true, 72 | itemCount: _waterfallList.length, 73 | itemBuilder: (context,index) => _waterfallItem(index), 74 | staggeredTileBuilder:(index) => StaggeredTile.fit(2), 75 | ), 76 | widget.id == "55" ? HomeHoteTopicWidget(hoteList: widget.hoteList) : Text("") 77 | 78 | ], 79 | ); 80 | } 81 | 82 | Widget _waterfallItem(index){ 83 | 84 | 85 | return GestureDetector( 86 | onTap: (){ 87 | 88 | 89 | if(widget.animation == false){ 90 | Navigator.of(context).pushNamed("/travel_detail_widget"); 91 | return; 92 | } 93 | 94 | Navigator.of(context).push(MaterialPageRoute( 95 | 96 | builder: (BuildContext context){ 97 | 98 | return TravelDetailWidget(); 99 | } 100 | 101 | )); 102 | 103 | 104 | }, 105 | 106 | child: _heroAnimation(index) 107 | ); 108 | } 109 | 110 | Widget _heroAnimation(index){ 111 | 112 | 113 | if(widget.animation == false){ 114 | return WaterfallItemWidget( 115 | item: _waterfallList[index], 116 | ); 117 | } 118 | return Hero( 119 | tag: "waterfall", 120 | child: WaterfallItemWidget( 121 | item: _waterfallList[index], 122 | ), 123 | ); 124 | } 125 | 126 | 127 | } 128 | -------------------------------------------------------------------------------- /flutter_mfw/lib/pages/home/widget/home_adv_widget.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/material.dart'; 2 | class HomeAdvWidget extends StatefulWidget { 3 | @override 4 | _HomeAdvWidgetState createState() => _HomeAdvWidgetState(); 5 | } 6 | 7 | class _HomeAdvWidgetState extends State { 8 | @override 9 | Widget build(BuildContext context) { 10 | return Container( 11 | margin: EdgeInsets.only(top: 0), 12 | width: double.infinity, 13 | height: 200, 14 | color: Colors.red, 15 | 16 | ); 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /flutter_mfw/lib/pages/home/widget/home_hote_topic_widget.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/material.dart'; 2 | import 'package:flutter_mfw/model/hote_model.dart'; 3 | import 'package:flutter_mfw/screen_adapter.dart'; 4 | 5 | class HomeHoteTopicWidget extends StatefulWidget { 6 | var hoteList = []; 7 | 8 | HomeHoteTopicWidget({Key key,this.hoteList}) : super(key:key); 9 | @override 10 | _HomeHoteTopicWidgetState createState() => _HomeHoteTopicWidgetState(); 11 | } 12 | 13 | class _HomeHoteTopicWidgetState extends State { 14 | 15 | 16 | 17 | @override 18 | void initState() { 19 | // TODO: implement initState 20 | super.initState(); 21 | 22 | 23 | } 24 | 25 | @override 26 | Widget build(BuildContext context) { 27 | ScreenAdapter.init(context); 28 | return Container( 29 | 30 | width: double.infinity, 31 | color: Colors.white, 32 | height: ScreenAdapter.setHeight(148), 33 | child: _hoteItemsWidget(), 34 | ); 35 | } 36 | 37 | Widget _hoteItemsWidget(){ 38 | return ListView( 39 | 40 | padding: EdgeInsets.fromLTRB(10, 0, 0, 0), 41 | scrollDirection: Axis.horizontal, 42 | children:widget.hoteList.map((item){ 43 | 44 | return item.title == "热门玩法" ? _hoteWidget(item) : _itemWidget(item); 45 | }).toList(), 46 | ); 47 | } 48 | 49 | Widget _positionWidget(){ 50 | 51 | return Positioned( 52 | left: 12, 53 | right: 12, 54 | bottom: 2, 55 | height: 10, 56 | child: Container( 57 | 58 | decoration: BoxDecoration( 59 | color: Color.fromRGBO(233, 235, 236, 1.0), 60 | borderRadius: BorderRadius.circular(10) 61 | ), 62 | 63 | ), 64 | ); 65 | } 66 | ///热门玩法 67 | Widget _hoteWidget(HoteItemModel itemModel){ 68 | return Stack( 69 | children: [ 70 | _positionWidget(), 71 | 72 | Container( 73 | margin: EdgeInsets.fromLTRB(10, 0, 10, 5), 74 | 75 | width: ScreenAdapter.setWidth(134), 76 | 77 | decoration: BoxDecoration( 78 | color: Colors.red, 79 | borderRadius: BorderRadius.circular(4), 80 | 81 | ), 82 | child: Column( 83 | mainAxisAlignment: MainAxisAlignment.center, 84 | children: [ 85 | Text("${itemModel.title}",style: TextStyle(color:Colors.white,fontSize: 12,fontWeight: FontWeight.w600)), 86 | Container( 87 | margin: EdgeInsets.only(top: 5), 88 | decoration: BoxDecoration( 89 | color: Colors.white, 90 | borderRadius: BorderRadius.circular(20) 91 | ), 92 | width: ScreenAdapter.setWidth(40), 93 | height: ScreenAdapter.setHeight(40), 94 | child: Icon(Icons.keyboard_arrow_right,color: Colors.red,size: 20), 95 | ) 96 | ], 97 | ), 98 | ) 99 | ], 100 | ); 101 | } 102 | 103 | Widget _itemWidget(HoteItemModel itemModel){ 104 | return Stack( 105 | children: [ 106 | _positionWidget(), 107 | Container( 108 | margin: EdgeInsets.fromLTRB(0, 0, 10, 5), 109 | decoration: BoxDecoration( 110 | image:DecorationImage( 111 | image: NetworkImage("${itemModel.image}") 112 | ), 113 | 114 | ), 115 | width: ScreenAdapter.setWidth(190), 116 | child: Stack( 117 | children: [ 118 | Container( 119 | 120 | decoration: BoxDecoration( 121 | color: Color.fromRGBO(0, 0, 0, 0.5), 122 | borderRadius: BorderRadius.circular(4), 123 | ), 124 | ), 125 | Positioned( 126 | top: 5, 127 | left: 10, 128 | right: 10, 129 | child: Text("${itemModel.title}",style: TextStyle(color: Colors.white,fontWeight: FontWeight.w600),maxLines: 2), 130 | ), 131 | Positioned( 132 | bottom: 5, 133 | left: 5, 134 | right: 5, 135 | child: Text("${itemModel.subTitle}",maxLines: 1,overflow: TextOverflow.ellipsis, style: TextStyle(fontSize: 10,color: Color.fromRGBO(255, 255, 255, 0.7))), 136 | ) 137 | ], 138 | ), 139 | ) 140 | ], 141 | ); 142 | } 143 | } 144 | -------------------------------------------------------------------------------- /flutter_mfw/lib/pages/home/widget/home_navbar_widget.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/material.dart'; 2 | import 'package:flutter_mfw/screen_adapter.dart'; 3 | 4 | class HomeNavbarWidget extends StatefulWidget { 5 | @override 6 | _HomeNavbarWidgetState createState() => _HomeNavbarWidgetState(); 7 | } 8 | 9 | class _HomeNavbarWidgetState extends State { 10 | @override 11 | Widget build(BuildContext context) { 12 | ScreenAdapter.init(context); 13 | return Column( 14 | children: [ 15 | Container( 16 | height: ScreenAdapter.getStatusBarHeight(), 17 | color: Colors.white, 18 | ), 19 | Container( 20 | 21 | color: Colors.white, 22 | width: double.infinity, 23 | height: ScreenAdapter.setHeight(96), 24 | child: Row( 25 | mainAxisAlignment: MainAxisAlignment.end, 26 | children: [ 27 | _searchWidget(), 28 | _messageWidget() 29 | ], 30 | ), 31 | ) 32 | ], 33 | ); 34 | } 35 | 36 | Widget _searchWidget(){ 37 | return Expanded( 38 | flex: 1, 39 | child: Container( 40 | 41 | height: ScreenAdapter.setHeight(78), 42 | margin: EdgeInsets.fromLTRB(13, 0, 0, 0), 43 | decoration: BoxDecoration( 44 | borderRadius: BorderRadius.circular(30), 45 | color: Color.fromRGBO(246, 246, 249, 1) 46 | ), 47 | child: TextField( 48 | 49 | decoration: InputDecoration( 50 | icon: Padding( 51 | padding: EdgeInsets.fromLTRB(10, 0, 0, 0), 52 | child: Icon(Icons.search,color: Colors.grey,), 53 | ), 54 | contentPadding: EdgeInsets.fromLTRB(0, 20, 0, 0), 55 | hintText: "西安", 56 | hintStyle: TextStyle( 57 | fontSize: 14 58 | ), 59 | border: OutlineInputBorder( 60 | borderSide: BorderSide.none 61 | ) 62 | ), 63 | 64 | ), 65 | 66 | ), 67 | ); 68 | } 69 | 70 | Widget _messageWidget(){ 71 | 72 | return Padding( 73 | padding: EdgeInsets.fromLTRB(13, 0, 13, 0), 74 | child: Image.asset("assets/images/icon_message.png",width:20,height: 20) 75 | ); 76 | } 77 | } 78 | -------------------------------------------------------------------------------- /flutter_mfw/lib/pages/home/widget/home_tabbar_widget.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/material.dart'; 2 | import 'package:flutter_mfw/screen_adapter.dart'; 3 | import 'package:flutter_mfw/model/tabar_model.dart'; 4 | 5 | typedef ValueChanged = void Function(T value); 6 | 7 | class HomeTabbarWidget extends StatefulWidget { 8 | 9 | var tabbarList = []; 10 | var currentId; 11 | final ValueChanged onTap; 12 | 13 | HomeTabbarWidget({Key key,this.tabbarList,this.currentId,this.onTap}) : super(key:key); 14 | 15 | @override 16 | _HomeTabbarWidgetState createState() => _HomeTabbarWidgetState(); 17 | } 18 | 19 | class _HomeTabbarWidgetState extends State { 20 | 21 | 22 | 23 | @override 24 | Widget build(BuildContext context) { 25 | ScreenAdapter.init(context); 26 | return Container( 27 | width: double.infinity, 28 | color: Colors.white, 29 | 30 | height: ScreenAdapter.setHeight(90), 31 | child: Row( 32 | mainAxisAlignment: MainAxisAlignment.end, 33 | children: [ 34 | _itemScrollWidget(), 35 | _downWidget() 36 | ], 37 | ), 38 | ); 39 | } 40 | 41 | Widget _itemScrollWidget(){ 42 | 43 | return Expanded( 44 | child: ListView( 45 | scrollDirection: Axis.horizontal, 46 | 47 | children: widget.tabbarList.map((item){ 48 | 49 | return InkWell( 50 | onTap: (){ 51 | setState(() { 52 | widget.currentId = item.id; 53 | }); 54 | widget.onTap(item); 55 | }, 56 | child: _itemWidet(item.name,item.id), 57 | ); 58 | 59 | }).toList() 60 | ), 61 | ); 62 | } 63 | 64 | Widget _itemWidet(String title,String id){ 65 | var selected = id == widget.currentId; 66 | 67 | return Padding( 68 | padding: EdgeInsets.fromLTRB(20, 0, 0, 0), 69 | child:Center( 70 | 71 | child: Text("${title}", 72 | style: TextStyle( 73 | color: selected ? Colors.black : Color.fromRGBO(116, 116, 116, 1.0), 74 | fontSize: selected ? 18 : 14, 75 | fontWeight: selected ? FontWeight.w500 : FontWeight.w600 76 | ) 77 | ), 78 | ) 79 | ); 80 | } 81 | 82 | Widget _downWidget(){ 83 | return Stack( 84 | children: [ 85 | Container( 86 | height: double.infinity, 87 | width: ScreenAdapter.setWidth(84), 88 | decoration: BoxDecoration( 89 | color: Colors.white, 90 | 91 | ), 92 | child: Icon(Icons.keyboard_arrow_down,color: Color.fromRGBO(26, 30, 35, 1.0)), 93 | 94 | ), 95 | Positioned( 96 | left: 2, 97 | top: 10, 98 | bottom: 10, 99 | width: 2, 100 | child: Container( 101 | color: Color.fromRGBO(248, 249, 249, 0.7) 102 | ), 103 | ) 104 | ], 105 | ); 106 | } 107 | } 108 | -------------------------------------------------------------------------------- /flutter_mfw/lib/pages/home/widget/home_top_nav.widget.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/material.dart'; 2 | import 'package:flutter_mfw/screen_adapter.dart'; 3 | 4 | import 'package:flutter_mfw/dao/home_dao.dart'; 5 | import 'package:flutter_mfw/model/home_main_icon_model.dart'; 6 | class HomeTopNavWidget extends StatefulWidget { 7 | @override 8 | _HomeTopNavWidgetState createState() => _HomeTopNavWidgetState(); 9 | } 10 | 11 | class _HomeTopNavWidgetState extends State { 12 | 13 | 14 | var _list = []; 15 | 16 | 17 | @override 18 | void initState() { 19 | // TODO: implement initState 20 | super.initState(); 21 | _getData(); 22 | } 23 | _getData(){ 24 | MainIconDao.fetch().then((result){ 25 | setState(() { 26 | _list = result.data.mainIcons.listWithColor; 27 | }); 28 | 29 | }).catchError((error){ 30 | 31 | }); 32 | } 33 | 34 | @override 35 | Widget build(BuildContext context) { 36 | ScreenAdapter.init(context); 37 | return Stack( 38 | children: [ 39 | Container( 40 | 41 | height: ScreenAdapter.setHeight(280), 42 | width: double.infinity, 43 | child: Padding( 44 | padding: EdgeInsets.fromLTRB(10, 30, 10, 0), 45 | child: _navRowWidget(), 46 | ), 47 | decoration: BoxDecoration( 48 | color: Colors.white, 49 | borderRadius: BorderRadius.only(topLeft:Radius.circular(10),topRight: Radius.circular(10)) 50 | 51 | ), 52 | ), 53 | Positioned( 54 | bottom: 0, 55 | left: 0, 56 | right: 0, 57 | height: 1, 58 | child: Container( 59 | color: Color.fromRGBO(245, 247, 248, 1), 60 | ), 61 | ) 62 | ], 63 | ); 64 | } 65 | 66 | Widget _navRowWidget(){ 67 | return Row( 68 | mainAxisAlignment: MainAxisAlignment.spaceBetween, 69 | 70 | children: _list.map((item){ 71 | 72 | return _navItemWidget(item.icon,item.title); 73 | }).toList() 74 | ); 75 | } 76 | 77 | Widget _navItemWidget(String image,String title){ 78 | return Column( 79 | children: [ 80 | Image.network(image,width: ScreenAdapter.setWidth(100),height: ScreenAdapter.setHeight(100)), 81 | Padding( 82 | padding: EdgeInsets.fromLTRB(0, 15, 0, 0), 83 | child: Text( 84 | "${title}", 85 | style: TextStyle(fontSize: 13,color: Color.fromRGBO(120, 120, 120, 1.0))), 86 | ) 87 | ], 88 | ); 89 | } 90 | } 91 | -------------------------------------------------------------------------------- /flutter_mfw/lib/pages/location/page/location_recommend_page.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/material.dart'; 2 | import 'package:flutter_mfw/model/location_tababr_model.dart'; 3 | import 'package:flutter_mfw/model/waterfall_model.dart'; 4 | import 'package:flutter_mfw/dao/home_dao.dart'; 5 | import 'package:flutter_staggered_grid_view/flutter_staggered_grid_view.dart'; 6 | import 'package:flutter_mfw/screen_adapter.dart'; 7 | import 'package:flutter_mfw/pages/home/waterfall_widget/water_fallItem_widget.dart'; 8 | import 'package:flutter_mfw/pages/location/widget/location_synthesize_widget.dart'; 9 | class LocationRecommendPage extends StatefulWidget { 10 | 11 | bool isShowSynthesize; 12 | 13 | var wanfaList = []; 14 | 15 | LocationRecommendPage({Key key,this.isShowSynthesize,this.wanfaList}) : super(key:key); 16 | 17 | @override 18 | _LocationRecommendPageState createState() => _LocationRecommendPageState(); 19 | } 20 | 21 | class _LocationRecommendPageState extends State with AutomaticKeepAliveClientMixin{ 22 | 23 | @override 24 | // TODO: implement wantKeepAlive 25 | bool get wantKeepAlive => true; 26 | @override 27 | void initState() { 28 | // TODO: implement initState 29 | super.initState(); 30 | _getWaterFallData(); 31 | } 32 | var _waterfallList = []; 33 | //瀑布流数据 34 | void _getWaterFallData(){ 35 | WaterFallDao.fetch().then((result){ 36 | setState(() { 37 | 38 | _waterfallList = result.list; 39 | }); 40 | 41 | }); 42 | } 43 | 44 | @override 45 | Widget build(BuildContext context) { 46 | ScreenAdapter.init(context); 47 | return CustomScrollView( 48 | physics: ClampingScrollPhysics(), 49 | slivers: [ 50 | SliverToBoxAdapter( 51 | child: widget.isShowSynthesize == true ? LocationSynthesizeWidget( 52 | wanfaList: widget.wanfaList, 53 | ) : Text(""), 54 | ), 55 | SliverToBoxAdapter( 56 | child:StaggeredGridView.countBuilder( 57 | padding: EdgeInsets.only(top: 1), 58 | physics: ClampingScrollPhysics(), 59 | crossAxisCount: 4, 60 | shrinkWrap: true, 61 | primary:true, 62 | itemCount: _waterfallList.length, 63 | itemBuilder: (context,index) => WaterfallItemWidget(item: _waterfallList[index]), 64 | staggeredTileBuilder:(index) => StaggeredTile.fit(2), 65 | ), 66 | ) 67 | ], 68 | ); 69 | 70 | 71 | } 72 | } 73 | -------------------------------------------------------------------------------- /flutter_mfw/lib/pages/location/widget/location_adv_widget.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/material.dart'; 2 | 3 | import 'package:flutter_mfw/screen_adapter.dart'; 4 | class LocationAdvWidget extends StatefulWidget { 5 | 6 | var advImageUrl; 7 | 8 | LocationAdvWidget({Key key,this.advImageUrl}) : super(key:key); 9 | 10 | 11 | @override 12 | _LocationAdvWidgetState createState() => _LocationAdvWidgetState(); 13 | } 14 | 15 | class _LocationAdvWidgetState extends State { 16 | @override 17 | Widget build(BuildContext context) { 18 | ScreenAdapter.init(context); 19 | if(widget.advImageUrl == null){ 20 | return Text(""); 21 | } 22 | return Container( 23 | width: double.infinity, 24 | height: ScreenAdapter.setHeight(220), 25 | decoration: BoxDecoration( 26 | color: Colors.white, 27 | boxShadow: [ 28 | BoxShadow( 29 | color:Color.fromRGBO(249, 249, 249, 1.0), 30 | offset: Offset(0, -3), //阴影xy轴偏移量 31 | blurRadius: 1.0, //阴影模糊程度 32 | 33 | ) 34 | ] 35 | ), 36 | child: Stack( 37 | children: [ 38 | Padding( 39 | padding: EdgeInsets.fromLTRB(15, 10, 15, 10), 40 | child: ClipRRect( 41 | borderRadius:BorderRadius.circular(6.0), 42 | child:Image.network("${widget.advImageUrl}") , 43 | ), 44 | ), 45 | Positioned( 46 | bottom: 0, 47 | left: 0, 48 | right: 0, 49 | child: Container( 50 | color: Color.fromRGBO(233, 233, 233, 1.0), 51 | height: 0.5, 52 | width: double.infinity, 53 | )) 54 | ], 55 | ), 56 | 57 | ); 58 | } 59 | } 60 | -------------------------------------------------------------------------------- /flutter_mfw/lib/pages/location/widget/location_navbar_widget.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/material.dart'; 2 | import 'package:flutter_mfw/screen_adapter.dart'; 3 | class LocationNavbarWidget extends StatefulWidget { 4 | var opacity; 5 | 6 | LocationNavbarWidget({Key key,this.opacity}) : super(key:key); 7 | 8 | @override 9 | _LocationNavbarWidgetState createState() => _LocationNavbarWidgetState(); 10 | } 11 | 12 | class _LocationNavbarWidgetState extends State { 13 | @override 14 | Widget build(BuildContext context) { 15 | ScreenAdapter.init(context); 16 | 17 | return Container( 18 | color: Color.fromRGBO(255, 255, 255, widget.opacity), 19 | padding: EdgeInsets.only(top: ScreenAdapter.getStatusBarHeight(),left: 10,bottom: 10), 20 | child: _navbarWidget() 21 | ); 22 | } 23 | 24 | 25 | Widget _navbarWidget(){ 26 | return Row( 27 | children: [ 28 | _locationWidget(), 29 | Expanded( 30 | flex: 1, 31 | child: _searchWidget(), 32 | ) 33 | 34 | ], 35 | ); 36 | } 37 | 38 | Widget _searchWidget(){ 39 | return Container( 40 | height: ScreenAdapter.setHeight(92), 41 | margin: EdgeInsets.fromLTRB(10, 0, 10, 0), 42 | 43 | decoration: BoxDecoration( 44 | color: widget.opacity >= 0.5 ? Color.fromRGBO(246, 247, 249, 1.0) : Colors.white, 45 | borderRadius: BorderRadius.circular(20) 46 | ), 47 | 48 | ); 49 | } 50 | 51 | //显示地理位置 52 | Widget _locationWidget(){ 53 | return Row( 54 | children: [ 55 | Text("北京",style: TextStyle(fontSize: 20,fontWeight: FontWeight.w700,color:widget.opacity >= 0.5 ? Colors.black : Colors.white)), 56 | Container( 57 | margin: EdgeInsets.only(left: 5), 58 | width: ScreenAdapter.setWidth(30), 59 | height: ScreenAdapter.setHeight(30), 60 | decoration: BoxDecoration( 61 | borderRadius: BorderRadius.circular(ScreenAdapter.setWidth(15)), 62 | color: Colors.white 63 | ), 64 | child: Center( 65 | child: Icon(Icons.keyboard_arrow_down,color:Colors.blue,size: ScreenAdapter.setWidth(30)), 66 | ), 67 | ) 68 | ], 69 | ); 70 | } 71 | 72 | 73 | } 74 | 75 | -------------------------------------------------------------------------------- /flutter_mfw/lib/pages/location/widget/location_sticky_category_widget.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/material.dart'; 2 | import 'package:flutter_mfw/screen_adapter.dart'; 3 | import 'package:flutter_mfw/model/location_tababr_model.dart'; 4 | typedef ValueChanged = void Function(T value); 5 | 6 | class LocationStickyCategoryWidget extends StatefulWidget { 7 | 8 | var selectIndex = 0; 9 | final ValueChanged onTap; 10 | var tabbarTagList = []; 11 | 12 | LocationStickyCategoryWidget({Key key,this.selectIndex,this.tabbarTagList,this.onTap}) : super(key:key); 13 | 14 | 15 | @override 16 | _LocationStickyCategoryWidgetState createState() => _LocationStickyCategoryWidgetState(); 17 | } 18 | 19 | class _LocationStickyCategoryWidgetState extends State { 20 | 21 | var _selectedIndex = 0; 22 | 23 | @override 24 | Widget build(BuildContext context) { 25 | ScreenAdapter.init(context); 26 | 27 | return _scrollCategory(); 28 | } 29 | 30 | Widget _scrollCategory(){ 31 | var index= 0; 32 | 33 | return Container( 34 | margin: EdgeInsets.only(top: 0,bottom: 0), 35 | 36 | height: ScreenAdapter.setHeight(86), 37 | color: Color.fromRGBO(250, 250, 250, 1.0), 38 | 39 | child: ListView( 40 | 41 | padding: EdgeInsets.fromLTRB(15, 0, 0, 10), 42 | scrollDirection:Axis.horizontal, 43 | children: widget.tabbarTagList.map((item){ 44 | var itemWidget = _scrollItemCategroy(index,item.tagName); 45 | index ++; 46 | return itemWidget; 47 | }).toList() 48 | ), 49 | ); 50 | } 51 | 52 | Widget _scrollItemCategroy(index ,title){ 53 | return GestureDetector( 54 | onTap: (){ 55 | setState(() { 56 | _selectedIndex = index; 57 | widget.onTap(index); 58 | }); 59 | }, 60 | child: Container( 61 | margin: EdgeInsets.only(right: 10), 62 | padding: EdgeInsets.fromLTRB(10, 5, 10, 5), 63 | child: Text("${title}",style: TextStyle(fontWeight: index == _selectedIndex ? FontWeight.w700 : FontWeight.w400),), 64 | decoration: BoxDecoration( 65 | borderRadius: BorderRadius.circular(5), 66 | border: Border.all(color: index == _selectedIndex ? Colors.white : Color.fromRGBO(237, 237, 237, 1.0),width: 0.5), 67 | color: index == _selectedIndex ? Color.fromRGBO(253, 213, 63, 1.0) :Colors.white 68 | ), 69 | 70 | ), 71 | ); 72 | } 73 | } 74 | -------------------------------------------------------------------------------- /flutter_mfw/lib/pages/location/widget/location_stycky_widget.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/material.dart'; 2 | import 'package:flutter_mfw/screen_adapter.dart'; 3 | 4 | typedef ValueChanged = void Function(T value); 5 | 6 | class LocationStyckyWidget extends StatefulWidget { 7 | 8 | final ValueChanged onTap; 9 | var selectedIndex; 10 | 11 | LocationStyckyWidget({Key key,this.onTap,this.selectedIndex}) : super(key:key); 12 | 13 | 14 | @override 15 | _LocationStyckyWidgetState createState() => _LocationStyckyWidgetState(); 16 | } 17 | 18 | class _LocationStyckyWidgetState extends State { 19 | 20 | 21 | @override 22 | Widget build(BuildContext context) { 23 | ScreenAdapter.init(context); 24 | 25 | return Container( 26 | width: double.infinity, 27 | height: ScreenAdapter.setHeight(110), 28 | color: Color.fromRGBO(250, 250, 250, 1.0), 29 | child: Row( 30 | mainAxisAlignment: MainAxisAlignment.spaceAround, 31 | children: [ 32 | _item("推荐",0), 33 | _item("预定",1) 34 | ], 35 | ), 36 | ); 37 | 38 | } 39 | 40 | Widget _item(title,index){ 41 | 42 | return InkWell( 43 | onTap: (){ 44 | widget.onTap(index); 45 | 46 | setState(() { 47 | widget.selectedIndex = index; 48 | }); 49 | }, 50 | child: Text( 51 | "${title}", 52 | style: TextStyle( 53 | color: Colors.black, 54 | fontWeight: widget.selectedIndex == index ? FontWeight.w700 : FontWeight.w400, 55 | fontSize: widget.selectedIndex == index ? 25 : 16 56 | ) 57 | ), 58 | ); 59 | } 60 | } 61 | -------------------------------------------------------------------------------- /flutter_mfw/lib/pages/location/widget/location_synthesize_widget.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/material.dart'; 2 | import 'package:flutter_mfw/screen_adapter.dart'; 3 | import 'package:flutter_mfw/model/location_tababr_model.dart'; 4 | class LocationSynthesizeWidget extends StatefulWidget { 5 | 6 | var wanfaList = []; 7 | 8 | LocationSynthesizeWidget({Key key,this.wanfaList}) : super(key:key); 9 | 10 | @override 11 | _LocationSynthesizeWidgetState createState() => _LocationSynthesizeWidgetState(); 12 | } 13 | 14 | class _LocationSynthesizeWidgetState extends State { 15 | @override 16 | Widget build(BuildContext context) { 17 | ScreenAdapter.init(context); 18 | return Container( 19 | height: ScreenAdapter.setHeight(310), 20 | width: double.infinity, 21 | 22 | 23 | child: ListView( 24 | shrinkWrap:true, 25 | physics:ScrollPhysics(parent: const BouncingScrollPhysics()), 26 | scrollDirection: Axis.horizontal, 27 | padding: EdgeInsets.only(left: 10,bottom: 15,top: 0), 28 | children: widget.wanfaList.map((item){ 29 | return _scrollViewItem(item.thumbList[0],item.thumbList[1],item.thumbList[2],item.title,item.subtitle); 30 | }).toList() 31 | ), 32 | ); 33 | } 34 | Widget _scrollViewItem(leftImageUrl,rightTopImageUrl,rightBottomUrl,title,subTitle){ 35 | return Container( 36 | 37 | 38 | decoration: BoxDecoration( 39 | color: Colors.white, 40 | borderRadius: BorderRadius.circular(5), 41 | boxShadow: [ 42 | BoxShadow( 43 | color:Color.fromRGBO(224, 224, 224, 1.0), 44 | offset: Offset(2, 4), //阴影xy轴偏移量 45 | blurRadius: 2.0, //阴影模糊程度 46 | 47 | ) 48 | ], 49 | ), 50 | margin: EdgeInsets.only(right: 10), 51 | width: ScreenAdapter.setWidth(342), 52 | 53 | child: Column( 54 | crossAxisAlignment: CrossAxisAlignment.start, 55 | children: [ 56 | _imageItem(leftImageUrl,rightTopImageUrl,rightBottomUrl), 57 | _titleItem(title), 58 | _subTitleItem(subTitle) 59 | 60 | ], 61 | ), 62 | ); 63 | } 64 | Widget _titleItem(title){ 65 | return Row( 66 | children: [ 67 | Padding( 68 | padding: EdgeInsets.only(left: 10,right: 5,top: 5), 69 | child: Image.asset( 70 | "assets/images/topic.png", 71 | width: ScreenAdapter.setWidth(30), 72 | height: ScreenAdapter.setHeight(30) 73 | ), 74 | ), 75 | Expanded( 76 | child: Padding( 77 | padding: EdgeInsets.only(top: 5,right: 5), 78 | child: Text("${title}",style: 79 | TextStyle( 80 | fontSize: 15, 81 | fontWeight: FontWeight.w500 82 | ), 83 | maxLines: 1, 84 | 85 | overflow: TextOverflow.ellipsis), 86 | ), 87 | ) 88 | 89 | 90 | ], 91 | ); 92 | } 93 | Widget _subTitleItem(subTitle){ 94 | return Padding( 95 | padding: EdgeInsets.only(left: 12,top: 5,right: 5), 96 | child: Text("${subTitle}",style: TextStyle(fontSize: 10,color: Color.fromRGBO(130, 130, 130, 1.0))), 97 | ); 98 | } 99 | 100 | Widget _imageItem(leftImageUrl,rightTopImageUrl,rightBottomUrl){ 101 | return Container( 102 | 103 | 104 | height: ScreenAdapter.setHeight(160), 105 | decoration: BoxDecoration( 106 | color: Colors.white, 107 | borderRadius:BorderRadius.circular(5) 108 | ), 109 | child: Stack( 110 | children: [ 111 | 112 | Positioned( 113 | top: 0, 114 | left: 0, 115 | bottom: 0, 116 | width: ScreenAdapter.setWidth(235), 117 | child: ClipRRect( 118 | borderRadius: BorderRadius.only(topLeft: Radius.circular(5)), 119 | child: Image.network("${leftImageUrl}", 120 | 121 | height: ScreenAdapter.setHeight(160), 122 | fit:BoxFit.cover 123 | ), 124 | ) 125 | 126 | ), 127 | Positioned( 128 | right: 0, 129 | top: 0, 130 | width: ScreenAdapter.setWidth(105), 131 | height: ScreenAdapter.setHeight(79), 132 | child: ClipRRect( 133 | borderRadius: BorderRadius.only(topRight: Radius.circular(5)), 134 | child: Image.network("${rightTopImageUrl}", 135 | 136 | height: ScreenAdapter.setHeight(160), 137 | fit:BoxFit.cover 138 | ), 139 | ), 140 | ), 141 | Positioned( 142 | right: 0, 143 | bottom: 0, 144 | width: ScreenAdapter.setWidth(105), 145 | height: ScreenAdapter.setHeight(79), 146 | child: Image.network("${rightBottomUrl}", 147 | 148 | height: ScreenAdapter.setHeight(160), 149 | fit:BoxFit.cover 150 | ) 151 | ) 152 | ], 153 | ), 154 | ); 155 | } 156 | 157 | } 158 | -------------------------------------------------------------------------------- /flutter_mfw/lib/pages/location/widget/location_what_grid_widget.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/material.dart'; 2 | import 'package:flutter_mfw/screen_adapter.dart'; 3 | import 'package:flutter_mfw/model/location_model.dart'; 4 | class LocationWhatGridWidget extends StatefulWidget { 5 | 6 | var listWhatModel = []; 7 | 8 | LocationWhatGridWidget({Key key,this.listWhatModel}) : super(key:key); 9 | 10 | @override 11 | _LocationWhatGridWidgetState createState() => _LocationWhatGridWidgetState(); 12 | } 13 | 14 | class _LocationWhatGridWidgetState extends State { 15 | @override 16 | Widget build(BuildContext context) { 17 | ScreenAdapter.init(context); 18 | 19 | var firstList = []; 20 | var seconeList = []; 21 | var index = 0; 22 | for(var item in widget.listWhatModel){ 23 | if(index <= 2){ 24 | firstList.add(item); 25 | }else{ 26 | seconeList.add(item); 27 | } 28 | 29 | index++; 30 | } 31 | return Column( 32 | mainAxisAlignment: MainAxisAlignment.start, 33 | children: [ 34 | Padding( 35 | padding: EdgeInsets.only(left: 15,right: 0), 36 | child: Row( 37 | children: firstList.map((item){ 38 | return _gridItem(context,item.thumbnail,item.title,item.subtitle); 39 | }).toList() 40 | ), 41 | ), 42 | Padding( 43 | padding: EdgeInsets.only(left: 15,right: 0), 44 | child: Row( 45 | children: seconeList.map((item){ 46 | return _gridItem(context,item.thumbnail,item.title,item.subtitle); 47 | }).toList() 48 | ), 49 | ) 50 | 51 | ], 52 | ); 53 | } 54 | 55 | Widget _gridItem(context,thumbnail,title,subTitle){ 56 | return Container( 57 | 58 | width: (MediaQuery.of(context).size.width-(15*2+20))/3.0, 59 | margin: EdgeInsets.only(right: 10), 60 | child: Column( 61 | crossAxisAlignment: CrossAxisAlignment.start, 62 | children: [ 63 | 64 | ClipRRect( 65 | borderRadius:BorderRadius.circular(5), 66 | child: Image.network("${thumbnail}", 67 | width:double.infinity, 68 | height: ScreenAdapter.setHeight(174), 69 | fit:BoxFit.cover, 70 | 71 | ) 72 | ), 73 | Padding( 74 | padding: EdgeInsets.only(top: 5), 75 | child: Text("${title}",style: TextStyle(fontWeight: FontWeight.w600)), 76 | ), 77 | Padding( 78 | padding: EdgeInsets.only(bottom: 10), 79 | child: Text("${subTitle}",style: TextStyle(color: Color.fromRGBO(147, 147, 147, 1.0),fontSize: 12)), 80 | ) 81 | ], 82 | ), 83 | ); 84 | } 85 | 86 | 87 | 88 | } 89 | -------------------------------------------------------------------------------- /flutter_mfw/lib/pages/location/widget/location_what_widget.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/material.dart'; 2 | import 'package:flutter_mfw/screen_adapter.dart'; 3 | import 'package:flutter_mfw/model/location_model.dart'; 4 | import 'package:flutter_mfw/pages/location/widget/location_what_grid_widget.dart'; 5 | class LocationWhatWidget extends StatefulWidget { 6 | 7 | DataNavModel cityGuideModel; 8 | 9 | 10 | LocationWhatWidget({Key key,this.cityGuideModel}) : super(key:key); 11 | 12 | 13 | @override 14 | _LocationWhatWidgetState createState() => _LocationWhatWidgetState(); 15 | } 16 | 17 | class _LocationWhatWidgetState extends State { 18 | 19 | var _selectIndex = 0; 20 | 21 | @override 22 | Widget build(BuildContext context) { 23 | if(widget.cityGuideModel?.tagList == null || widget.cityGuideModel?.tabList == null){ 24 | return Text(""); 25 | } 26 | ScreenAdapter.init(context); 27 | return Column( 28 | children: [ 29 | _whatNav(), 30 | _scrollCategory(), 31 | LocationWhatGridWidget( 32 | listWhatModel: widget.cityGuideModel.tagList[_selectIndex].listWhatModel, 33 | ), 34 | _bottomSwitch() 35 | ], 36 | ); 37 | } 38 | //上方导航 39 | Widget _whatNav(){ 40 | return Container( 41 | margin: EdgeInsets.only(left: 15,right: 15), 42 | 43 | decoration: BoxDecoration( 44 | border: Border( 45 | top: BorderSide(color: Color.fromRGBO(237, 237, 237, 1.0),width: 1), 46 | bottom: BorderSide(color: Color.fromRGBO(237, 237, 237, 1.0),width: 1) 47 | ) 48 | ), 49 | child: Row( 50 | children: widget.cityGuideModel.tabList.map((item){ 51 | 52 | return _wahtItemNav(item.name); 53 | 54 | }).toList() 55 | ), 56 | ); 57 | } 58 | 59 | Widget _wahtItemNav(title){ 60 | 61 | return Padding( 62 | padding: EdgeInsets.fromLTRB(0, 10, 20, 10), 63 | child: Text("${title}"), 64 | ); 65 | } 66 | Widget _scrollCategory(){ 67 | var index= 0; 68 | return Container( 69 | margin: EdgeInsets.only(top: 10,bottom: 10), 70 | height: ScreenAdapter.setHeight(66), 71 | child: ListView( 72 | 73 | padding: EdgeInsets.fromLTRB(15, 0, 0, 0), 74 | scrollDirection:Axis.horizontal, 75 | children: widget.cityGuideModel.tagList.map((item){ 76 | var itemWidget = _scrollItemCategroy(index,item.title); 77 | index ++; 78 | return itemWidget; 79 | }).toList() 80 | ), 81 | ); 82 | } 83 | 84 | Widget _scrollItemCategroy(index ,title){ 85 | return GestureDetector( 86 | onTap: (){ 87 | setState(() { 88 | _selectIndex = index; 89 | }); 90 | }, 91 | child: Container( 92 | margin: EdgeInsets.only(right: 10), 93 | padding: EdgeInsets.fromLTRB(10, 5, 10, 5), 94 | child: Text("${title}",style: TextStyle(fontWeight: index == _selectIndex ? FontWeight.w700 : FontWeight.w400),), 95 | decoration: BoxDecoration( 96 | borderRadius: BorderRadius.circular(5), 97 | border: Border.all(color: index == _selectIndex ? Colors.white : Color.fromRGBO(237, 237, 237, 1.0),width: 0.5), 98 | color: index == _selectIndex ? Color.fromRGBO(253, 213, 63, 1.0) :Colors.white 99 | ), 100 | 101 | ), 102 | ); 103 | } 104 | 105 | Widget _bottomSwitch(){ 106 | return Container( 107 | alignment: Alignment.center, 108 | margin: EdgeInsets.only(left: 15,right: 15), 109 | height: ScreenAdapter.setHeight(100), 110 | decoration: BoxDecoration( 111 | border: Border( 112 | bottom: BorderSide(color: Color.fromRGBO(237, 237, 237, 1.0),width: 1) 113 | ) 114 | ), 115 | child: Text("查看更多",style: TextStyle(color: Color.fromRGBO(81, 153, 251, 1.0))), 116 | ); 117 | } 118 | } 119 | -------------------------------------------------------------------------------- /flutter_mfw/lib/pages/my/my_page.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/material.dart'; 2 | import 'package:flutter_mfw/screen_adapter.dart'; 3 | import 'package:flutter_mfw/pages/my/widget/my_navbar_widget.dart'; 4 | import 'package:flutter_mfw/pages/my/widget/my_logout_widget.dart'; 5 | 6 | import 'package:flutter_mfw/pages/my/widget/my_get_honey_widget.dart'; 7 | import 'package:flutter_mfw/pages/my/widget/my_travel_widget.dart'; 8 | import 'package:flutter_mfw/pages/my/widget/my_service_card_widget.dart'; 9 | class MyPage extends StatefulWidget { 10 | @override 11 | _MyPageState createState() => _MyPageState(); 12 | } 13 | 14 | class _MyPageState extends State with AutomaticKeepAliveClientMixin { 15 | @override 16 | // TODO: implement wantKeepAlive 17 | bool get wantKeepAlive => true; 18 | @override 19 | Widget build(BuildContext context) { 20 | ScreenAdapter.init(context); 21 | return Scaffold( 22 | backgroundColor: Color.fromRGBO(242, 242, 242, 1.0), 23 | 24 | body: Stack( 25 | children: [ 26 | 27 | Padding( 28 | padding: EdgeInsets.only(top:ScreenAdapter.setHeight(88)), 29 | child: ListView( 30 | 31 | children: [ 32 | MyLogoutWidget(), 33 | MyGetHoneyWidget(), 34 | MyTravelWidget(), 35 | MyServiceCardWidget() 36 | ], 37 | ), 38 | ), 39 | Positioned( 40 | top: 0, 41 | left: 0, 42 | right: 0, 43 | child: MyNavbarWidget() 44 | ), 45 | ], 46 | ) 47 | ); 48 | } 49 | 50 | 51 | } 52 | -------------------------------------------------------------------------------- /flutter_mfw/lib/pages/my/widget/my_get_honey_widget.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/material.dart'; 2 | 3 | import 'package:flutter_mfw/screen_adapter.dart'; 4 | class MyGetHoneyWidget extends StatefulWidget { 5 | @override 6 | _MyGetHoneyWidgetState createState() => _MyGetHoneyWidgetState(); 7 | } 8 | 9 | class _MyGetHoneyWidgetState extends State { 10 | @override 11 | Widget build(BuildContext context) { 12 | ScreenAdapter.init(context); 13 | return Container( 14 | 15 | height: ScreenAdapter.setHeight(150), 16 | margin: EdgeInsets.fromLTRB(20, 0, 20, 0), 17 | decoration: BoxDecoration( 18 | image: DecorationImage(image:NetworkImage("https://n2-q.mafengwo.net/s14/M00/BF/00/wKgE2l0Hb2KAKFYXAACjGheCxCU116.png") ) 19 | ), 20 | ); 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /flutter_mfw/lib/pages/my/widget/my_items_widget.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/cupertino.dart'; 2 | import 'package:flutter/material.dart'; 3 | import 'package:flutter_mfw/screen_adapter.dart'; 4 | class MyItemsWidget extends StatefulWidget { 5 | @override 6 | _MyItemsWidgetState createState() => _MyItemsWidgetState(); 7 | } 8 | 9 | class _MyItemsWidgetState extends State { 10 | @override 11 | Widget build(BuildContext context) { 12 | ScreenAdapter.init(context); 13 | return Container( 14 | 15 | height: ScreenAdapter.setHeight(160), 16 | margin: EdgeInsets.fromLTRB(20, 0, 20, 0), 17 | decoration: BoxDecoration( 18 | color: Colors.white, 19 | borderRadius: BorderRadius.circular(5) 20 | ), 21 | child: Container( 22 | margin: EdgeInsets.only(top: 12), 23 | child: Row( 24 | mainAxisAlignment: MainAxisAlignment.spaceEvenly, 25 | 26 | children: [ 27 | _itemWidget("我的收藏","https://n4-q.mafengwo.net/s12/M00/31/C8/wKgED1uXhA-AbQyvAAAiBit6y74637.png"), 28 | Padding( 29 | padding: EdgeInsets.fromLTRB(35, 0, 35, 0), 30 | child: _itemWidget("我的订单","https://p4-q.mafengwo.net/s12/M00/E6/E1/wKgED1uXUoaAV7-tAAAdXfKX00o716.png"), 31 | ), 32 | _itemWidget("我的历史","https://b4-q.mafengwo.net/s12/M00/E7/CD/wKgED1uXUz-AAjHIAAAocBa4sgs237.png"), 33 | ], 34 | ), 35 | ) 36 | ); 37 | } 38 | 39 | Widget _itemWidget(title,imagePath){ 40 | return Column( 41 | children: [ 42 | Image.network(imagePath,width: 30,height: 30), 43 | Padding( 44 | padding: EdgeInsets.only(top: 5), 45 | child: Text("${title}"), 46 | ) 47 | ], 48 | ); 49 | } 50 | } 51 | -------------------------------------------------------------------------------- /flutter_mfw/lib/pages/my/widget/my_logout_widget.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/material.dart'; 2 | import 'package:flutter_mfw/screen_adapter.dart'; 3 | import 'package:flutter_mfw/pages/my/widget/my_items_widget.dart'; 4 | class MyLogoutWidget extends StatefulWidget { 5 | @override 6 | _MyLogoutWidgetState createState() => _MyLogoutWidgetState(); 7 | } 8 | 9 | class _MyLogoutWidgetState extends State { 10 | @override 11 | Widget build(BuildContext context) { 12 | ScreenAdapter.init(context); 13 | // MyItemsWidget(), 14 | return Container( 15 | height: ScreenAdapter.setHeight(530), 16 | child: Stack( 17 | children: [ 18 | _unLog(), 19 | Positioned( 20 | bottom: 10, 21 | left: 0, 22 | right: 0, 23 | child: MyItemsWidget() 24 | ) 25 | ], 26 | ), 27 | ); 28 | } 29 | 30 | Widget _unLog(){ 31 | return Container( 32 | child: Container( 33 | alignment: Alignment.topLeft, 34 | width: double.infinity, 35 | padding: EdgeInsets.fromLTRB(20, 10, 0, 0), 36 | height: ScreenAdapter.setHeight(400), 37 | color: Color.fromRGBO(254, 217, 49, 1.0), 38 | child: Column( 39 | crossAxisAlignment: CrossAxisAlignment.start, 40 | children: [ 41 | Text("Hi~欢迎来到马蜂窝",style: TextStyle(fontSize: 23,fontWeight: FontWeight.w700)), 42 | Padding( 43 | padding: EdgeInsets.fromLTRB(0, 5, 0, 30), 44 | child: Text("愿每一个旅行愿望得以达成"), 45 | ), 46 | Container( 47 | alignment: Alignment.center, 48 | width: ScreenAdapter.setWidth(260), 49 | height: ScreenAdapter.setWidth(90), 50 | decoration: BoxDecoration( 51 | borderRadius: BorderRadius.circular(30), 52 | color: Color.fromRGBO(36, 38, 41, 1.0) 53 | 54 | ), 55 | child: Text( 56 | "登录/注册", 57 | style: TextStyle(color: Color.fromRGBO(248, 215, 62, 1.0),fontSize: 16,fontWeight: FontWeight.w500)), 58 | ) 59 | ], 60 | ), 61 | ), 62 | ); 63 | } 64 | } 65 | -------------------------------------------------------------------------------- /flutter_mfw/lib/pages/my/widget/my_navbar_widget.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/material.dart'; 2 | import 'package:flutter_mfw/screen_adapter.dart'; 3 | class MyNavbarWidget extends StatefulWidget { 4 | @override 5 | _MyNavbarWidgetState createState() => _MyNavbarWidgetState(); 6 | } 7 | 8 | class _MyNavbarWidgetState extends State { 9 | @override 10 | Widget build(BuildContext context) { 11 | ScreenAdapter.init(context); 12 | return Container( 13 | 14 | padding: EdgeInsets.only(bottom: 10), 15 | width: double.infinity, 16 | height: ScreenAdapter.getStatusBarHeight()+ScreenAdapter.setHeight(88), 17 | color: Color.fromRGBO(254, 217, 49, 1.0), 18 | child: Stack( 19 | children: [ 20 | 21 | Positioned( 22 | bottom: 5, 23 | left: 20, 24 | child: _leadingsWidget(), 25 | ), 26 | Positioned( 27 | right: 20, 28 | bottom: 5, 29 | child: Image.asset("assets/images/icon_message.png",width:20,height: 20), 30 | ) 31 | 32 | ], 33 | ), 34 | ); 35 | } 36 | Widget _leadingsWidget(){ 37 | 38 | return Row( 39 | children: [ 40 | Padding( 41 | padding: EdgeInsets.fromLTRB(0, 0, 15, 0), 42 | child: Image.asset("assets/images/setting.png"), 43 | ), 44 | Image.asset("assets/images/saoma.png") 45 | ], 46 | ); 47 | } 48 | 49 | } 50 | -------------------------------------------------------------------------------- /flutter_mfw/lib/pages/my/widget/my_service_card_widget.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/material.dart'; 2 | import 'package:flutter_mfw/screen_adapter.dart'; 3 | 4 | import 'package:flutter_mfw/dao/my_dao.dart'; 5 | 6 | import 'package:flutter_mfw/model/my_channel_model.dart'; 7 | class MyServiceCardWidget extends StatefulWidget { 8 | @override 9 | _MyServiceCardWidgetState createState() => _MyServiceCardWidgetState(); 10 | } 11 | 12 | class _MyServiceCardWidgetState extends State { 13 | 14 | var _list = []; 15 | @override 16 | void initState() { 17 | // TODO: implement initState 18 | super.initState(); 19 | _getListData(); 20 | } 21 | 22 | void _getListData(){ 23 | 24 | MyChannelDao.fetch().then((result){ 25 | setState(() { 26 | _list = result.data.normalChannels; 27 | }); 28 | 29 | }).catchError((error){ 30 | print(error); 31 | }); 32 | } 33 | 34 | 35 | @override 36 | Widget build(BuildContext context) { 37 | ScreenAdapter.init(context); 38 | if(_list.length == 0){ 39 | return Center( 40 | child: Text("正在加载"), 41 | ); 42 | } 43 | return Container( 44 | height: ScreenAdapter.setHeight(650), 45 | margin: EdgeInsets.fromLTRB(20, 10, 20, 10), 46 | decoration: BoxDecoration( 47 | color: Colors.white, 48 | ), 49 | child: Column( 50 | crossAxisAlignment: CrossAxisAlignment.start, 51 | children: [ 52 | Padding( 53 | padding: EdgeInsets.only(top: 10,left: 10,bottom: 20), 54 | child: Text("更多服务",style: TextStyle(fontWeight: FontWeight.w600,fontSize: 16)), 55 | ), 56 | 57 | Container( 58 | 59 | 60 | height: ScreenAdapter.setHeight(520), 61 | 62 | child: _gridService() 63 | ) 64 | ], 65 | ), 66 | ); 67 | } 68 | 69 | Widget _gridService(){ 70 | 71 | return GridView.count( 72 | crossAxisCount: 4, 73 | physics: NeverScrollableScrollPhysics(), 74 | children: _list.map((item){ 75 | 76 | return _itemService(item); 77 | }).toList() 78 | ); 79 | } 80 | 81 | Widget _itemService(MyChannelModelDataNormalChannel item){ 82 | return Column( 83 | children: [ 84 | Image.network("${item.icon}", 85 | width: ScreenAdapter.setWidth(64), 86 | height: ScreenAdapter.setHeight(64), 87 | ), 88 | Text("${item.title}") 89 | ], 90 | ); 91 | } 92 | } 93 | -------------------------------------------------------------------------------- /flutter_mfw/lib/pages/my/widget/my_travel_widget.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter_mfw/pages/my/widget/my_travel_widget.dart'; 2 | import 'package:flutter/material.dart'; 3 | import 'package:flutter_mfw/screen_adapter.dart'; 4 | class MyTravelWidget extends StatefulWidget { 5 | @override 6 | _MyTravelWidgetState createState() => _MyTravelWidgetState(); 7 | } 8 | 9 | class _MyTravelWidgetState extends State { 10 | 11 | @override 12 | Widget build(BuildContext context) { 13 | ScreenAdapter.init(context); 14 | return Container( 15 | 16 | decoration: BoxDecoration( 17 | color: Colors.white, 18 | borderRadius: BorderRadius.circular(5) 19 | ), 20 | height: ScreenAdapter.setHeight(300), 21 | width: double.infinity, 22 | margin: EdgeInsets.fromLTRB(20, 10, 20, 0), 23 | child: Stack( 24 | children: [ 25 | Padding(padding: EdgeInsets.only(top: 20),child: Center( 26 | heightFactor: 2.0, 27 | child: Column( 28 | mainAxisAlignment: MainAxisAlignment.center, 29 | 30 | children: [ 31 | Container( 32 | alignment: Alignment.center, 33 | width: ScreenAdapter.setWidth(410), 34 | height: ScreenAdapter.setHeight(118), 35 | child:Row( 36 | mainAxisAlignment: MainAxisAlignment.center, 37 | children: [ 38 | Image.asset("assets/images/qianbi.png",width: ScreenAdapter.setWidth(40),height: ScreenAdapter.setHeight(40)), 39 | Text("上传照片",style: TextStyle(fontWeight: FontWeight.w700),), 40 | ], 41 | ), 42 | decoration: BoxDecoration( 43 | borderRadius: BorderRadius.circular(30), 44 | color: Color.fromRGBO(254, 234, 128, 1.0) 45 | ), 46 | ), 47 | Padding(padding: EdgeInsets.only(top: 10), 48 | child: Text("如何使用照片记录旅行?",style: TextStyle(fontSize: 12,color: Color.fromRGBO(0, 137, 251, 1.0)),)) 49 | ], 50 | ), 51 | ) ), 52 | Positioned( 53 | left: 10, 54 | top: 10, 55 | child: Text("我的旅行",style: TextStyle(fontWeight: FontWeight.w600,fontSize: 16)) 56 | ), 57 | 58 | ], 59 | ), 60 | ); 61 | } 62 | } 63 | -------------------------------------------------------------------------------- /flutter_mfw/lib/pages/travel/travel_page.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/material.dart'; 2 | import 'package:flutter_mfw/pages/travel/widget/travel_banner_widget.dart'; 3 | import 'package:flutter_mfw/pages/travel/widget/travel_grid_widget.dart'; 4 | import 'package:flutter_mfw/pages/travel/widget/travel_recommend_widget.dart'; 5 | import 'package:flutter_mfw/pages/travel/widget/travel_everyday_widget.dart'; 6 | import 'package:flutter_mfw/pages/travel/widget/travel_navsearch_widget.dart'; 7 | 8 | 9 | import 'package:flutter_mfw/pages/travel/widget/travel_waterfall_widget.dart'; 10 | import 'package:flutter_mfw/pages/travel/widget/travel_tab_control_widget.dart'; 11 | import 'package:flutter_mfw/model/travel_list_model.dart'; 12 | import 'package:flutter_mfw/dao/travel_dao.dart'; 13 | import 'package:flutter_mfw/pages/travel/widget/travel_destination_widget.dart'; 14 | import 'package:flutter_mfw/model/travel_header_model.dart'; 15 | import 'package:flutter_mfw/pages/travel/widget/travel_calendar_widget.dart'; 16 | 17 | import 'package:flutter_mfw/screen_adapter.dart'; 18 | class TravelPage extends StatefulWidget { 19 | @override 20 | _TravelPageState createState() => _TravelPageState(); 21 | } 22 | 23 | class _TravelPageState extends State with AutomaticKeepAliveClientMixin{ 24 | 25 | 26 | //轮播图信息 27 | BannerData _bannerData; 28 | 29 | //轮播图下面的卡片信息 30 | DynamicData _dynamicData; 31 | //渠道 32 | ChannelData _channelData; 33 | 34 | //旅行日历 35 | ColumnData _columnData; 36 | 37 | HotData _hotSaleData; 38 | 39 | 40 | StyleData _styleData; 41 | 42 | FeedData _feedData; 43 | 44 | String _tableId; 45 | 46 | var _scrollOffy = 0.0; 47 | 48 | var _scrollViewController = ScrollController(); 49 | 50 | @override 51 | // TODO: implement wantKeepAlive 52 | bool get wantKeepAlive => true; 53 | 54 | @override 55 | void initState() { 56 | // TODO: implement initState 57 | super.initState(); 58 | _scrollViewController.addListener((){ 59 | var offy = _scrollViewController.position.pixels; 60 | 61 | setState(() { 62 | _scrollOffy = offy; 63 | }); 64 | 65 | }); 66 | 67 | _getData(); 68 | _getRecommendData(); 69 | } 70 | 71 | void _getRecommendData(){ 72 | TravelListDao.fetch().then((result){ 73 | setState(() { 74 | 75 | for(var item in result.data.dataList){ 76 | if(item.style == "recommend_mdd"){ 77 | _styleData = item.styleData; 78 | } 79 | if(item.style == "feed_tab"){ 80 | _feedData = item.feedData; 81 | } 82 | } 83 | 84 | }); 85 | 86 | }).catchError((error){ 87 | print(error); 88 | }); 89 | } 90 | void _getData(){ 91 | 92 | TravelHeaderDao.fetch().then((response){ 93 | setState(() { 94 | 95 | for(var item in response.data.bannerList){ 96 | if(item.style == "banner"){ 97 | _bannerData = item.bannerData; 98 | 99 | } 100 | if(item.style == "dynamic_activity"){ 101 | _dynamicData = item.dynamicData; 102 | } 103 | if(item.style == "channel"){ 104 | _channelData = item.channelData; 105 | } 106 | if(item.style == "hot_sale"){ 107 | _hotSaleData = item.hotData; 108 | } 109 | if(item.style == "column_section"){ 110 | _columnData = item.columnData; 111 | } 112 | } 113 | }); 114 | 115 | } 116 | ).catchError((error){ 117 | 118 | print(error); 119 | }); 120 | 121 | } 122 | 123 | @override 124 | Widget build(BuildContext context) { 125 | ScreenAdapter.init(context); 126 | return Stack( 127 | children: [ 128 | 129 | _tabbarController(), 130 | TravelNavsearchWidget( 131 | scrollOffy: _scrollOffy, 132 | ), 133 | 134 | ], 135 | ); 136 | } 137 | 138 | Widget _tabbarController(){ 139 | if(_feedData == null){ 140 | return Center( 141 | child: Text("加载中..."), 142 | ); 143 | } 144 | return NestedScrollView( 145 | controller: _scrollViewController, 146 | headerSliverBuilder: (BuildContext context, bool innerBoxIsScrolled) { 147 | 148 | return [ 149 | SliverToBoxAdapter( 150 | child: TravelBannerWidget( 151 | bannerData: _bannerData, 152 | ), 153 | ), 154 | SliverToBoxAdapter( 155 | child: TravelGridWidget( 156 | channelData: _channelData, 157 | ), 158 | ), 159 | SliverToBoxAdapter( 160 | child: TravelRecommendWidget(), 161 | ), 162 | SliverToBoxAdapter( 163 | child: TravelEverydayWidget( 164 | hotdata: _hotSaleData, 165 | ), 166 | ), 167 | SliverToBoxAdapter( 168 | child: TravelDestinationWidget( 169 | styleData: _styleData, 170 | ), 171 | 172 | ), 173 | SliverToBoxAdapter( 174 | child: _travelTabbarControl(Color.fromRGBO(246, 246, 246, 1.0)) 175 | ), 176 | 177 | ]; 178 | }, 179 | body: PageView( 180 | children: _feedData.tabList.map((item){ 181 | 182 | return TravelWaterfallWidget( 183 | tableId: _tableId, 184 | ); 185 | }).toList() 186 | ) 187 | ); 188 | 189 | } 190 | 191 | 192 | Widget _travelTabbarControl(color){ 193 | return TravelTabControlWidget( 194 | 195 | feedData: _feedData, 196 | backGroundColor: color, 197 | onTap: (index){ 198 | setState(() { 199 | _tableId = _feedData.tabList[index].tId; 200 | }); 201 | }, 202 | ); 203 | } 204 | } 205 | -------------------------------------------------------------------------------- /flutter_mfw/lib/pages/travel/widget/travel_banner_widget.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/material.dart'; 2 | import 'package:flutter_mfw/screen_adapter.dart'; 3 | 4 | import 'package:flutter_mfw/model/travel_header_model.dart'; 5 | import 'package:flutter_swiper/flutter_swiper.dart'; 6 | 7 | class TravelBannerWidget extends StatefulWidget { 8 | 9 | BannerData bannerData; 10 | DynamicData dynamicData; 11 | 12 | TravelBannerWidget({Key key,this.bannerData,this.dynamicData}) : super(key:key); 13 | 14 | @override 15 | _TravelBannerWidgetState createState() => _TravelBannerWidgetState(); 16 | } 17 | 18 | class _TravelBannerWidgetState extends State { 19 | @override 20 | Widget build(BuildContext context) { 21 | if(widget.bannerData == null){ 22 | return Text(""); 23 | } 24 | 25 | ScreenAdapter.init(context); 26 | 27 | return Container( 28 | width: double.infinity, 29 | color:Color.fromRGBO(240, 240, 240, 1.0), 30 | height: ScreenAdapter.setHeight(468), 31 | child: _bannerSwiper() 32 | ); 33 | } 34 | 35 | Widget _bannerSwiper() { 36 | 37 | return Swiper( 38 | itemBuilder: (BuildContext context,int index){ 39 | return Image.network("${widget.bannerData.imageList[index].src}",fit: BoxFit.fill,); 40 | }, 41 | autoplay:true, 42 | 43 | itemCount: widget.bannerData.imageList.length, 44 | pagination: new SwiperPagination(), 45 | control: new SwiperControl(size: 0), 46 | ); 47 | } 48 | 49 | 50 | 51 | 52 | 53 | 54 | Widget _carContainer(){ 55 | return Container( 56 | width: double.infinity, 57 | height: ScreenAdapter.setHeight(288), 58 | padding: EdgeInsets.fromLTRB(10, 10, 5, 0), 59 | decoration: BoxDecoration( 60 | color: Color.fromRGBO(240, 240, 240, 1.0), 61 | borderRadius: BorderRadius.only(topLeft: Radius.circular(10),topRight: Radius.circular(10)) 62 | ), 63 | child: _carRow(), 64 | ); 65 | } 66 | 67 | 68 | Widget _carRow(){ 69 | return Row( 70 | children: widget.dynamicData.dynamicList.first.singleList.map((item){ 71 | 72 | return _carItem(item.singleData.imgUrl); 73 | 74 | }).toList() 75 | ); 76 | } 77 | 78 | Widget _carItem(imageURL){ 79 | return Expanded( 80 | flex: 1, 81 | child: Container( 82 | 83 | decoration: BoxDecoration( 84 | image: DecorationImage( 85 | 86 | image: NetworkImage("${imageURL}") 87 | ), 88 | borderRadius: BorderRadius.circular(5) 89 | ), 90 | margin: EdgeInsets.only(right: 5), 91 | height: ScreenAdapter.setHeight(268), 92 | 93 | 94 | ) 95 | 96 | ); 97 | } 98 | 99 | 100 | 101 | Widget _bannerImage(imageURL){ 102 | 103 | return Image.network("${imageURL}", 104 | 105 | fit: BoxFit.fitWidth, 106 | ); 107 | } 108 | } 109 | -------------------------------------------------------------------------------- /flutter_mfw/lib/pages/travel/widget/travel_destination_widget.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/material.dart'; 2 | import 'package:flutter_mfw/screen_adapter.dart'; 3 | 4 | import 'package:flutter_mfw/model/travel_list_model.dart'; 5 | 6 | class TravelDestinationWidget extends StatefulWidget { 7 | 8 | StyleData styleData; 9 | 10 | TravelDestinationWidget({Key key,this.styleData}) : super(key:key); 11 | 12 | 13 | @override 14 | _TravelDestinationWidgetState createState() => _TravelDestinationWidgetState(); 15 | } 16 | 17 | class _TravelDestinationWidgetState extends State { 18 | 19 | 20 | 21 | @override 22 | Widget build(BuildContext context) { 23 | if(widget.styleData == null){ 24 | return Text(""); 25 | } 26 | var _topThreeList = widget.styleData.mddList.sublist(0,3); 27 | var _gridList = widget.styleData.mddList.sublist(3,widget.styleData.mddList.length); 28 | 29 | ScreenAdapter.init(context); 30 | return Container( 31 | margin: EdgeInsets.fromLTRB(10, 10, 10, 10), 32 | decoration: BoxDecoration( 33 | color: Colors.white, 34 | borderRadius: BorderRadius.circular(5) 35 | ), 36 | child: Column( 37 | crossAxisAlignment: CrossAxisAlignment.start, 38 | children: [ 39 | _title(), 40 | _travelCarList(_topThreeList), 41 | _travelGridList(_gridList) 42 | ], 43 | ), 44 | ); 45 | } 46 | Widget _travelGridList(List list){ 47 | 48 | return Container( 49 | 50 | // margin: EdgeInsets.only(top: 5,bottom: 10), 51 | height: ScreenAdapter.setHeight(250), 52 | child: GridView.builder( 53 | padding: EdgeInsets.fromLTRB(0, 0, 0, 0), 54 | physics: NeverScrollableScrollPhysics(), 55 | gridDelegate: SliverGridDelegateWithFixedCrossAxisCount( 56 | crossAxisCount: 3, 57 | crossAxisSpacing: 0, 58 | mainAxisSpacing: 0, 59 | childAspectRatio: 1.8 60 | 61 | ), itemBuilder: (BuildContext context,int index){ 62 | var item = list[index]; 63 | 64 | return _travelGridItem(item.title,item.subTitle); 65 | }, 66 | itemCount: list.length 67 | ), 68 | ); 69 | } 70 | 71 | Widget _travelGridItem(title,subTitle){ 72 | 73 | return Column( 74 | mainAxisAlignment: MainAxisAlignment.start, 75 | children: [ 76 | Padding( 77 | padding: EdgeInsets.fromLTRB(5, 5, 5, 5), 78 | child: Text("${title}",style: TextStyle(color: Colors.black,fontWeight: FontWeight.w600)), 79 | ), 80 | Container( 81 | padding: EdgeInsets.only(left: 5,right: 5), 82 | decoration: BoxDecoration( 83 | color: Color.fromRGBO(245, 247, 249, 1.0), 84 | borderRadius: BorderRadius.circular(8) 85 | ), 86 | child: Text("${subTitle}",style: TextStyle(color: Color.fromRGBO(112, 115, 117, 1.0),fontSize: 12)), 87 | ) 88 | ], 89 | ); 90 | } 91 | 92 | 93 | Widget _travelCarList(List list){ 94 | 95 | return Padding( 96 | padding: EdgeInsets.only(left: 10), 97 | child: Row( 98 | children: list.map((item){ 99 | 100 | return _travelCarItem(item.title,item.subTitle,item.imgUrl); 101 | 102 | }).toList() 103 | ), 104 | ); 105 | } 106 | Widget _travelCarItem(title,subTitle,imageUrl){ 107 | return Expanded( 108 | flex: 1, 109 | child: Container( 110 | 111 | alignment: Alignment.center, 112 | padding: EdgeInsets.only(top: 60), 113 | margin: EdgeInsets.only(right: 10,bottom: 0), 114 | decoration: BoxDecoration( 115 | 116 | image: DecorationImage(image: NetworkImage("${imageUrl}")), 117 | borderRadius: BorderRadius.circular(8) 118 | ), 119 | child: Column( 120 | children: [ 121 | Padding( 122 | padding: EdgeInsets.only(bottom: 10), 123 | child: Text("${title}",style: TextStyle(color: Colors.white,fontWeight: FontWeight.w700,fontSize: 18)), 124 | 125 | ), 126 | Padding( 127 | padding: EdgeInsets.only(bottom: 10), 128 | child: Text("${subTitle}",style: TextStyle(color: Colors.white),maxLines: 1,), 129 | ) 130 | ], 131 | ) 132 | 133 | ), 134 | ); 135 | } 136 | 137 | Widget _title(){ 138 | return Padding(padding: EdgeInsets.only(left: 10,top: 10), 139 | child: Text("推荐目的地",style: TextStyle(fontWeight: FontWeight.w600,fontSize: 18)), 140 | ); 141 | } 142 | } 143 | -------------------------------------------------------------------------------- /flutter_mfw/lib/pages/travel/widget/travel_grid_widget.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/material.dart'; 2 | import 'package:flutter_mfw/screen_adapter.dart'; 3 | import 'package:flutter_mfw/model/travel_header_model.dart'; 4 | class TravelGridWidget extends StatefulWidget { 5 | 6 | var channelData = ChannelData(); 7 | TravelGridWidget({Key key,this.channelData}) : super(key:key); 8 | 9 | @override 10 | _TravelGridWidgetState createState() => _TravelGridWidgetState(); 11 | } 12 | 13 | class _TravelGridWidgetState extends State { 14 | @override 15 | Widget build(BuildContext context) { 16 | ScreenAdapter.init(context); 17 | if(widget.channelData == null){ 18 | return Text(""); 19 | } 20 | 21 | return Container( 22 | width: double.infinity, 23 | 24 | color: Color.fromRGBO(240, 240, 240, 1.0), 25 | child: Container( 26 | margin: EdgeInsets.fromLTRB(10, 15, 10, 10), 27 | 28 | decoration: BoxDecoration( 29 | color: Colors.white, 30 | borderRadius: BorderRadius.circular(5) 31 | ), 32 | 33 | child:Column( 34 | mainAxisAlignment: MainAxisAlignment.center, 35 | children: [ 36 | _topCategory(), 37 | _centerCategory(), 38 | _bottomCategory() 39 | ], 40 | ) 41 | 42 | ), 43 | 44 | ); 45 | } 46 | 47 | Widget _topCategory(){ 48 | var topList = widget.channelData.channels.sublist(0,5); 49 | return Container( 50 | color: Color.fromRGBO(240, 240, 240, 1.0), 51 | padding: EdgeInsets.only(bottom: 15), 52 | child: Row( 53 | mainAxisAlignment: MainAxisAlignment.spaceBetween, 54 | children: topList.map((item){ 55 | return Column( 56 | children: [ 57 | Image.network( 58 | item.icon, 59 | width: ScreenAdapter.setWidth(90), 60 | height: ScreenAdapter.setHeight(90) 61 | ), 62 | Text( 63 | item.title, 64 | style: TextStyle( 65 | fontSize: 12, 66 | color: Color.fromRGBO(70, 70, 70, 1.0) 67 | ), 68 | ) 69 | ], 70 | ); 71 | }).toList() 72 | ), 73 | ); 74 | } 75 | 76 | Widget _centerCategory(){ 77 | 78 | // var itemWidth = (ScreenAdapter.getScreenWidth()/2.0-ScreenAdapter.setWidth(20))/5.0; 79 | // 80 | // 81 | var channeList = widget.channelData.channels.sublist(5); 82 | // 83 | // var colum = (channeList.length % 5).ceil(); 84 | 85 | var containHeight = 470.0; 86 | 87 | return Container( 88 | 89 | decoration: BoxDecoration( 90 | borderRadius: BorderRadius.circular(10) 91 | ), 92 | 93 | height: ScreenAdapter.setHeight(containHeight), 94 | child: GridView.builder( 95 | padding: EdgeInsets.fromLTRB(0, 0, 0, 0), 96 | physics: NeverScrollableScrollPhysics(), 97 | gridDelegate: SliverGridDelegateWithFixedCrossAxisCount( 98 | crossAxisCount: 5, 99 | crossAxisSpacing: 0, 100 | mainAxisSpacing: 0, 101 | childAspectRatio: 1.0 102 | 103 | ), itemBuilder: (BuildContext context,int index){ 104 | 105 | Channels channels = channeList[index]; 106 | 107 | return _gridCarItem(channels); 108 | }, 109 | itemCount: channeList.length 110 | ), 111 | ); 112 | } 113 | 114 | Widget _bottomCategory(){ 115 | 116 | 117 | var _index = 0; 118 | return Row( 119 | children: widget.channelData.columns.map((item){ 120 | 121 | var widget = _bottomCategoryItem(item.imageUrl,_index); 122 | _index ++; 123 | return widget; 124 | }).toList(), 125 | ); 126 | } 127 | 128 | Widget _bottomCategoryItem(imageURL,index){ 129 | return Expanded( 130 | flex: 1, 131 | child: Stack( 132 | children: [ 133 | Positioned( 134 | top: 0, 135 | left: 0, 136 | right: 0, 137 | height: 1, 138 | child: Container( 139 | height: 1, 140 | color:Color.fromRGBO(240, 240, 240, 1.0), 141 | ), 142 | ), 143 | Positioned( 144 | right: 0, 145 | top: 0, 146 | width: 1, 147 | bottom: 0, 148 | child: Container( 149 | height: 1, 150 | color:index==2 ? Colors.white : Color.fromRGBO(240, 240, 240, 1.0), 151 | ), 152 | ), 153 | Container( 154 | margin: EdgeInsets.only(top: 1,right: 1), 155 | alignment: Alignment.center, 156 | height: ScreenAdapter.setHeight(70), 157 | 158 | decoration: BoxDecoration( 159 | borderRadius: BorderRadius.only(bottomLeft: Radius.circular(index==0 ? 5 :0),bottomRight: Radius.circular(index==2 ? 5 :0)), 160 | color: Colors.white, 161 | image: DecorationImage( 162 | image: NetworkImage("${imageURL}") 163 | ) 164 | ), 165 | ), 166 | ], 167 | ) 168 | ); 169 | } 170 | 171 | Widget _gridCarItem(Channels channel){ 172 | return Container( 173 | //padding: EdgeInsets.only(top: 5,bottom: 5), 174 | 175 | child: Column( 176 | mainAxisAlignment: MainAxisAlignment.center, 177 | children: [ 178 | Image.network("${channel.icon}", 179 | fit: BoxFit.cover, 180 | width: ScreenAdapter.setWidth(70), 181 | height: ScreenAdapter.setHeight(70) 182 | ), 183 | Text("${channel.title}", 184 | maxLines: 1, 185 | style: TextStyle( 186 | color: Color.fromRGBO(70, 70, 70, 1.0),fontSize: 11), 187 | 188 | ) 189 | ], 190 | ), 191 | ); 192 | } 193 | 194 | } 195 | -------------------------------------------------------------------------------- /flutter_mfw/lib/pages/travel/widget/travel_navsearch_widget.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/material.dart'; 2 | import 'package:flutter_mfw/screen_adapter.dart'; 3 | class TravelNavsearchWidget extends StatefulWidget { 4 | 5 | 6 | 7 | var scrollOffy; 8 | 9 | TravelNavsearchWidget({Key key,this.scrollOffy}) : super(key:key); 10 | 11 | 12 | @override 13 | _TravelNavsearchWidgetState createState() => _TravelNavsearchWidgetState(); 14 | } 15 | 16 | class _TravelNavsearchWidgetState extends State { 17 | @override 18 | Widget build(BuildContext context) { 19 | ScreenAdapter.init(context); 20 | 21 | var marginTop = widget.scrollOffy < 0 ? widget.scrollOffy*-1.0 : 0.0; 22 | var alpha = widget.scrollOffy <= 0 ? 0.0 : 1.0; 23 | 24 | return Container( 25 | margin: EdgeInsets.only(top: marginTop), 26 | color: Color.fromRGBO(255, 255, 255, alpha), 27 | width: double.infinity, 28 | height: MediaQuery.of(context).padding.top + ScreenAdapter.setHeight(88), 29 | child:Column( 30 | children: [ 31 | Container( 32 | height: MediaQuery.of(context).padding.top, 33 | ), 34 | Container( 35 | margin: EdgeInsets.only(left: 10,right: 10), 36 | height: ScreenAdapter.setHeight(88), 37 | child: _navBar(alpha), 38 | ) 39 | ], 40 | ), 41 | ); 42 | } 43 | 44 | 45 | Widget _navBar(alpha){ 46 | return Row( 47 | mainAxisAlignment: MainAxisAlignment.spaceBetween, 48 | children: [ 49 | Icon(Icons.access_time,color: alpha == 1.0 ? Colors.black : Colors.white,), 50 | Expanded( 51 | child: Container( 52 | alignment: Alignment.center, 53 | decoration: BoxDecoration( 54 | color: alpha == 1.0 ? Color.fromRGBO(245, 245, 245, 1.0) : Colors.white, 55 | borderRadius: BorderRadius.circular(20) 56 | ), 57 | margin: EdgeInsets.only(left: 10,right: 10), 58 | height: ScreenAdapter.setHeight(74), 59 | child: Row( 60 | mainAxisAlignment: MainAxisAlignment.center, 61 | children: [ 62 | Icon(Icons.search,color: Color.fromRGBO(139, 139, 139, 1.0)), 63 | Text("温泉",style: TextStyle(color: Color.fromRGBO(139, 139, 139, 1.0)),) 64 | ], 65 | ), 66 | ), 67 | ), 68 | Icon(Icons.more_horiz,color: alpha == 1.0 ? Colors.black : Colors.white) 69 | ], 70 | ); 71 | } 72 | } 73 | -------------------------------------------------------------------------------- /flutter_mfw/lib/pages/travel/widget/travel_tab_control_widget.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/material.dart'; 2 | import 'package:flutter_mfw/screen_adapter.dart'; 3 | 4 | import 'package:flutter_mfw/model/travel_list_model.dart'; 5 | 6 | typedef GestureTapCallback = void Function(int value); 7 | 8 | class TravelTabControlWidget extends StatefulWidget { 9 | 10 | FeedData feedData; 11 | Color backGroundColor; 12 | final GestureTapCallback onTap; 13 | 14 | TravelTabControlWidget({Key key,this.feedData,this.onTap,this.backGroundColor}) : super(key:key); 15 | 16 | @override 17 | _TravelTabControlWidgetState createState() => _TravelTabControlWidgetState(); 18 | } 19 | 20 | class _TravelTabControlWidgetState extends State { 21 | 22 | var _selectedIndex = 0; 23 | 24 | @override 25 | Widget build(BuildContext context) { 26 | if(widget.feedData == null){ 27 | return Text(""); 28 | } 29 | 30 | ScreenAdapter.init(context); 31 | 32 | var index = 0; 33 | return Container( 34 | width: double.infinity, 35 | height: ScreenAdapter.setHeight(80), 36 | color: widget.backGroundColor, 37 | padding: EdgeInsets.only(left: 20,top: 0, right: 20), 38 | child: Row( 39 | mainAxisAlignment: MainAxisAlignment.spaceBetween, 40 | children: widget.feedData.tabList.map((item){ 41 | var widget = _item(item.name,index); 42 | index ++; 43 | return widget; 44 | }).toList() 45 | ), 46 | ); 47 | } 48 | 49 | Widget _item(title,index){ 50 | 51 | return GestureDetector( 52 | onTap: (){ 53 | widget.onTap(index); 54 | setState(() { 55 | _selectedIndex = index; 56 | }); 57 | }, 58 | child: Text("${title}",style: TextStyle(fontWeight: _selectedIndex == index ? FontWeight.w600 : FontWeight.w400,fontSize: _selectedIndex == index ? 18 : 14),), 59 | 60 | ); 61 | } 62 | } 63 | -------------------------------------------------------------------------------- /flutter_mfw/lib/pages/travel/widget/travel_waterfall_widget.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/material.dart'; 2 | import 'package:flutter_staggered_grid_view/flutter_staggered_grid_view.dart'; 3 | import 'package:flutter_mfw/dao/travel_dao.dart'; 4 | import 'package:flutter_mfw/model/travel_list_model.dart'; 5 | class TravelWaterfallWidget extends StatefulWidget { 6 | 7 | var tableId; 8 | 9 | 10 | TravelWaterfallWidget({Key key,this.tableId}) : super(key:key); 11 | 12 | 13 | @override 14 | _TravelWaterfallWidgetState createState() => _TravelWaterfallWidgetState(); 15 | } 16 | 17 | class _TravelWaterfallWidgetState extends State with AutomaticKeepAliveClientMixin { 18 | 19 | 20 | var _list = []; 21 | 22 | @override 23 | // TODO: implement wantKeepAlive 24 | bool get wantKeepAlive => true; 25 | @override 26 | void initState() { 27 | // TODO: implement initState 28 | super.initState(); 29 | 30 | getData(widget.tableId); 31 | 32 | } 33 | void getData(tableId){ 34 | TravelListDao.fetch().then((value){ 35 | 36 | setState(() { 37 | for(var item in value.data.dataList){ 38 | 39 | if(item.style == "simple_product"){ 40 | _list.add(item); 41 | } 42 | 43 | }}); 44 | 45 | }); 46 | } 47 | @override 48 | Widget build(BuildContext context) { 49 | 50 | 51 | 52 | return StaggeredGridView.countBuilder( 53 | padding: EdgeInsets.only(top: 10,bottom: 20), 54 | physics: ClampingScrollPhysics(), 55 | crossAxisCount: 4, 56 | shrinkWrap: true, 57 | primary: true, 58 | itemCount: _list.length, 59 | itemBuilder: (context, index) => _productWaterfallItem(_list[index].productData), 60 | 61 | staggeredTileBuilder: (index) => StaggeredTile.fit(2), 62 | ); 63 | } 64 | 65 | Widget _articleWaterfallItem(imageURL){ 66 | 67 | return Card( 68 | clipBehavior: Clip.antiAlias, 69 | child: Column( 70 | children: [ 71 | Image.network( 72 | "${imageURL}" 73 | ), 74 | Container( 75 | margin: EdgeInsets.fromLTRB(10, 10, 10, 10), 76 | color: Colors.white, 77 | //child: _articleContainer(""), 78 | ) 79 | ], 80 | ), 81 | ); 82 | } 83 | 84 | Widget _articleContainer( ProductData productData){ 85 | 86 | return Column( 87 | crossAxisAlignment: CrossAxisAlignment.start, 88 | children: [ 89 | _themeTitle("_themeTitle"), 90 | _title("_title") 91 | ], 92 | ); 93 | 94 | } 95 | 96 | Widget _productWaterfallItem(ProductData productData) { 97 | return Card( 98 | clipBehavior: Clip.antiAlias, 99 | child: Column( 100 | crossAxisAlignment: CrossAxisAlignment.start, 101 | children: [ 102 | Image.network( 103 | "${productData.imgUrl}" 104 | ), 105 | _themeTitle(productData.theme), 106 | _title(productData.title), 107 | _bottomPrice(productData.price,productData.priceSuffix,productData.soldPrefix,productData.salesNum) 108 | ], 109 | ), 110 | ); 111 | } 112 | 113 | Widget _bottomPrice(price,priceSuffix,soldPrefix,salesNum){ 114 | return Padding( 115 | padding: EdgeInsets.only(left: 5,right: 5,top: 10,bottom: 10), 116 | child: Row( 117 | mainAxisAlignment: MainAxisAlignment.spaceBetween, 118 | children: [ 119 | RichText( 120 | text: TextSpan( 121 | children: [ 122 | TextSpan( 123 | text: "¥", 124 | style: TextStyle( 125 | color: Color.fromRGBO(252, 85, 74, 1.0), 126 | fontSize: 10, 127 | fontWeight: FontWeight.w600 128 | ) 129 | ), 130 | TextSpan( 131 | text: "${price}", 132 | style: TextStyle( 133 | color: Color.fromRGBO(252, 85, 74, 1.0), 134 | fontWeight: FontWeight.w700, 135 | fontSize: 15 136 | ) 137 | ), 138 | TextSpan( 139 | text: "${priceSuffix}", 140 | style: TextStyle( 141 | color: Color.fromRGBO(160, 160, 160, 1.0), 142 | fontSize: 12, 143 | 144 | ) 145 | ) 146 | ] 147 | ), 148 | ), 149 | Text("${soldPrefix}${salesNum}",style: TextStyle(color: Color.fromRGBO(160, 160, 160, 1.0),fontSize: 13),) 150 | ], 151 | ), 152 | ); 153 | } 154 | Widget _title(title) { 155 | return Padding( 156 | padding: EdgeInsets.only(top: 10, left: 5), 157 | child: Text( 158 | "${title}", 159 | maxLines: 2, 160 | overflow: TextOverflow.ellipsis, 161 | style: TextStyle( 162 | color: Colors.black, 163 | fontWeight: FontWeight.w600, 164 | fontSize: 15, 165 | 166 | ), 167 | ), 168 | ); 169 | } 170 | 171 | Widget _themeTitle(theme) { 172 | return Padding( 173 | padding: EdgeInsets.only(top: 5, left: 5), 174 | child: Text("${theme}", 175 | style: TextStyle( 176 | color: Color.fromRGBO(195, 151, 97, 1.0), 177 | fontWeight: FontWeight.w600, 178 | fontSize: 12)), 179 | ); 180 | } 181 | } 182 | -------------------------------------------------------------------------------- /flutter_mfw/lib/routers/router.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/material.dart'; 2 | import 'package:flutter_mfw/tabbar/tabbar_page.dart'; 3 | import 'package:flutter_mfw/pages/detail/travel_detail_widget.dart'; 4 | final routers = { 5 | "/": (context) => TabbarPage(), 6 | "/travel_detail_widget":(context,{arguments}) => TravelDetailWidget() 7 | }; 8 | 9 | var onGenerateRoute = (RouteSettings settings) { 10 | 11 | final String name = settings.name; 12 | final Function pageContentBuilder = routers[name]; 13 | if (pageContentBuilder != null) { 14 | if (settings.arguments != null) { 15 | final Route route = MaterialPageRoute( 16 | builder: (context) => 17 | pageContentBuilder(context, arguments: settings.arguments)); 18 | return route; 19 | } else { 20 | final Route route = 21 | MaterialPageRoute(builder: (context) => pageContentBuilder(context)); 22 | return route; 23 | } 24 | } 25 | }; -------------------------------------------------------------------------------- /flutter_mfw/lib/screen_adapter.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/cupertino.dart'; 2 | import 'package:flutter_screenutil/flutter_screenutil.dart'; 3 | 4 | class ScreenAdapter{ 5 | static init(context){ 6 | var ratio = 2.0; 7 | 8 | var screen_width = MediaQuery.of(context).size.width; 9 | 10 | var screen_height = MediaQuery.of(context).size.height; 11 | 12 | 13 | ScreenUtil.instance = ScreenUtil(width: screen_width*ratio,height: screen_height*ratio,allowFontScaling: true)..init(context); 14 | 15 | 16 | //iphone5s 17 | // ScreenUtil.instance = ScreenUtil(width: 640,height: 1136)..init(context); 18 | 19 | //iphone6s 20 | //ScreenUtil.instance = ScreenUtil(width: 750,height: 1334)..init(context); 21 | 22 | //iphone7pluse 23 | 24 | // ScreenUtil.instance = ScreenUtil(width: 818,height: 1472,allowFontScaling: true)..init(context); 25 | 26 | //iphoneX 及以上设备 27 | // ScreenUtil.instance = ScreenUtil(width: 828,height: 1792,allowFontScaling: true)..init(context); 28 | 29 | 30 | 31 | } 32 | 33 | 34 | static getStatusBarHeight(){ 35 | return ScreenUtil.statusBarHeight; 36 | } 37 | 38 | static setHeight(double value){ 39 | return ScreenUtil.getInstance().setHeight(value); 40 | } 41 | 42 | static setWidth(double value){ 43 | return ScreenUtil.getInstance().setWidth(value); 44 | } 45 | 46 | static getScreenHeight(){ 47 | return ScreenUtil.screenHeight; 48 | } 49 | 50 | static getScreenWidth(){ 51 | return ScreenUtil.screenWidth; 52 | } 53 | } -------------------------------------------------------------------------------- /flutter_mfw/lib/tabbar/tabbar_page.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/material.dart'; 2 | 3 | import 'package:flutter_mfw/pages/home/home_page.dart'; 4 | import 'package:flutter_mfw/pages/location/location_page.dart'; 5 | import 'package:flutter_mfw/pages/travel/travel_page.dart'; 6 | import 'package:flutter_mfw/pages/my/my_page.dart'; 7 | 8 | import 'package:flutter_mfw/screen_adapter.dart'; 9 | 10 | class TabbarPage extends StatefulWidget { 11 | @override 12 | _TabbarPageState createState() => _TabbarPageState(); 13 | } 14 | 15 | class _TabbarPageState extends State { 16 | 17 | var _currentIndex = 0; 18 | 19 | var _pageController; 20 | 21 | 22 | var _tabNavList = [ 23 | { 24 | "title":"首页", 25 | "selectImage":"assets/images/tab_homepage_selected.png", 26 | "normalImage":"assets/images/tab_homepage_normal.png", 27 | }, 28 | { 29 | "title":"北京", 30 | "selectImage":"assets/images/tab_destination_selected.png", 31 | "normalImage":"assets/images/tab_destination_normal.png", 32 | }, 33 | { 34 | "title":"发布", 35 | "selectImage":"assets/images/tab_destination_selected.png", 36 | "normalImage":"assets/images/tab_destination_normal.png", 37 | }, 38 | 39 | { 40 | "title":"去旅行", 41 | "selectImage":"assets/images/tab_focused_mall.png", 42 | "normalImage":"assets/images/tab_default_mall.png", 43 | }, 44 | { 45 | "title":"我的", 46 | "selectImage":"assets/images/tab_mine_selected.png", 47 | "normalImage":"assets/images/tab_mine_normal.png", 48 | } 49 | ]; 50 | 51 | var _pages = [ 52 | HomePage(), 53 | LocationPage(), 54 | Text(""), 55 | TravelPage(), 56 | MyPage() 57 | ]; 58 | 59 | @override 60 | void initState() { 61 | // TODO: implement initState 62 | super.initState(); 63 | _pageController = PageController(initialPage: _currentIndex); 64 | } 65 | @override 66 | Widget build(BuildContext context) { 67 | ScreenAdapter.init(context); 68 | var _index = 0; 69 | return Scaffold( 70 | backgroundColor: Color.fromRGBO(246, 246, 246, 1.0), 71 | body: PageView( 72 | physics: NeverScrollableScrollPhysics(), 73 | controller: _pageController, 74 | children: _pages, 75 | onPageChanged: (index) { 76 | setState(() { 77 | _currentIndex = index; 78 | }); 79 | 80 | }, 81 | ), 82 | 83 | floatingActionButton: Container( 84 | margin: EdgeInsets.only(top: 8), 85 | width: ScreenAdapter.setWidth(110), 86 | height: ScreenAdapter.setHeight(110), 87 | padding: EdgeInsets.fromLTRB(5, 5, 5, 5), 88 | decoration: BoxDecoration( 89 | borderRadius: BorderRadius.circular(ScreenAdapter.setWidth(55)), 90 | color: Color.fromRGBO(246, 246, 246, 1.0) 91 | ), 92 | 93 | child: FloatingActionButton( 94 | 95 | elevation: 0, 96 | focusElevation: 0, 97 | 98 | onPressed: (){ 99 | print("发布视频"); 100 | }, 101 | child: Icon(Icons.add,size: 25,color: Colors.black,), 102 | backgroundColor: Color.fromRGBO(253, 219, 69, 1.0), 103 | ), 104 | 105 | ), 106 | floatingActionButtonLocation: FloatingActionButtonLocation.centerDocked, 107 | bottomNavigationBar: BottomNavigationBar( 108 | 109 | 110 | currentIndex: _currentIndex, 111 | onTap: (index) { 112 | if(index == 2){ 113 | print("发布视频"); 114 | }else{ 115 | setState(() { 116 | _currentIndex = index; 117 | _pageController.jumpToPage(index); 118 | }); 119 | } 120 | 121 | }, 122 | 123 | ///用于修复tabbar的item 过多出现的问题 124 | type: BottomNavigationBarType.fixed, 125 | selectedItemColor: Color.fromRGBO(70, 70, 70, 1.0), 126 | items:_tabNavList.map((item){ 127 | var bavItem = BottomNavigationBarItem( 128 | icon: _barItemIcon(_index, item["selectImage"],item["normalImage"]), 129 | title: Text(item["title"]) 130 | ); 131 | 132 | _index ++; 133 | return bavItem; 134 | }).toList() 135 | ), 136 | 137 | ); 138 | } 139 | 140 | 141 | Widget _barItemIcon(index,selectedImage,normalImage){ 142 | 143 | return Image.asset("${index == _currentIndex ? selectedImage : normalImage}", 144 | width:ScreenAdapter.setWidth(50), 145 | height: ScreenAdapter.setHeight(50), 146 | ); 147 | } 148 | 149 | } 150 | -------------------------------------------------------------------------------- /flutter_mfw/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_mfw/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 | -------------------------------------------------------------------------------- /img/01.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/coder-dongjiayi/fluter_mfw/87a25f1335b4137f9c5ee780853d38053a4456eb/img/01.jpg -------------------------------------------------------------------------------- /img/02.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/coder-dongjiayi/fluter_mfw/87a25f1335b4137f9c5ee780853d38053a4456eb/img/02.jpg -------------------------------------------------------------------------------- /img/03.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/coder-dongjiayi/fluter_mfw/87a25f1335b4137f9c5ee780853d38053a4456eb/img/03.jpg --------------------------------------------------------------------------------