├── .gitattributes
├── .gitignore
├── .metadata
├── README.md
├── android
├── app
│ ├── build.gradle
│ └── src
│ │ ├── debug
│ │ └── AndroidManifest.xml
│ │ ├── main
│ │ ├── AndroidManifest.xml
│ │ ├── java
│ │ │ └── com
│ │ │ │ └── nullno
│ │ │ │ └── flutter
│ │ │ │ └── flutter_vmusic
│ │ │ │ └── MainActivity.java
│ │ └── res
│ │ │ ├── drawable
│ │ │ ├── ic_launcher.png
│ │ │ ├── launch_background.xml
│ │ │ └── launch_image.jpg
│ │ │ ├── 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
│ │ │ ├── colors.xml
│ │ │ └── styles.xml
│ │ └── profile
│ │ └── AndroidManifest.xml
├── build.gradle
├── gradle.properties
├── gradle
│ └── wrapper
│ │ └── gradle-wrapper.properties
└── settings.gradle
├── assets
└── image
│ ├── disc-plus.png
│ ├── disc.png
│ ├── disc_back.png
│ ├── disc_light-plus.png
│ ├── disc_light.png
│ ├── needle-plus.png
│ ├── needle.png
│ └── play_btn_3x.png
├── com.nullno.flutter.flutter_dxmusic.apk
├── ios
├── Flutter
│ ├── AppFrameworkInfo.plist
│ ├── Debug.xcconfig
│ └── Release.xcconfig
├── Runner.xcodeproj
│ ├── project.pbxproj
│ ├── project.xcworkspace
│ │ └── contents.xcworkspacedata
│ └── xcshareddata
│ │ └── xcschemes
│ │ └── Runner.xcscheme
├── Runner.xcworkspace
│ └── contents.xcworkspacedata
└── Runner
│ ├── AppDelegate.h
│ ├── AppDelegate.m
│ ├── Assets.xcassets
│ ├── AppIcon.appiconset
│ │ ├── Contents.json
│ │ ├── Icon-App-1024x1024@1x.png
│ │ ├── Icon-App-20x20@1x.png
│ │ ├── Icon-App-20x20@2x.png
│ │ ├── Icon-App-20x20@3x.png
│ │ ├── Icon-App-29x29@1x.png
│ │ ├── Icon-App-29x29@2x.png
│ │ ├── Icon-App-29x29@3x.png
│ │ ├── Icon-App-40x40@1x.png
│ │ ├── Icon-App-40x40@2x.png
│ │ ├── Icon-App-40x40@3x.png
│ │ ├── Icon-App-60x60@2x.png
│ │ ├── Icon-App-60x60@3x.png
│ │ ├── Icon-App-76x76@1x.png
│ │ ├── Icon-App-76x76@2x.png
│ │ └── Icon-App-83.5x83.5@2x.png
│ └── LaunchImage.imageset
│ │ ├── Contents.json
│ │ ├── LaunchImage.png
│ │ ├── LaunchImage@2x.png
│ │ ├── LaunchImage@3x.png
│ │ └── README.md
│ ├── Base.lproj
│ ├── LaunchScreen.storyboard
│ └── Main.storyboard
│ ├── Info.plist
│ └── main.m
├── lib
├── components
│ ├── exitApp.dart
│ ├── find.dart
│ ├── my.dart
│ ├── playPanel.dart
│ └── video.dart
├── conf
│ ├── api.dart
│ ├── appsate.dart
│ ├── platform.dart
│ └── router.dart
├── main.dart
├── pages
│ ├── home_page.dart
│ ├── landing_page.dart
│ ├── player_page.dart
│ ├── search_page.dart
│ ├── song_menu_page.dart
│ ├── song_mlist_page.dart
│ ├── template_blank.dart
│ └── video_detail_page.dart
└── utils
│ ├── FixedSizeText.dart
│ ├── custom.dart
│ ├── store.dart
│ ├── tool.dart
│ └── video_player.dart
├── pubspec.lock
├── pubspec.yaml
└── test
└── widget_test.dart
/.gitattributes:
--------------------------------------------------------------------------------
1 | # Auto detect text files and perform LF normalization
2 | * text=auto
3 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | # Miscellaneous
2 | *.class
3 | *.log
4 | *.pyc
5 | *.swp
6 | *.apk
7 | .DS_Store
8 | .atom/
9 | .buildlog/
10 | .history
11 | .svn/
12 |
13 | # IntelliJ related
14 | *.iml
15 | *.ipr
16 | *.iws
17 | .idea/
18 |
19 | # The .vscode folder contains launch configuration and tasks you configure in
20 | # VS Code which you may wish to be included in version control, so this line
21 | # is commented out by default.
22 | #.vscode/
23 |
24 | # Flutter/Dart/Pub related
25 | **/doc/api/
26 | .dart_tool/
27 | .flutter-plugins
28 | .packages
29 | .pub-cache/
30 | .pub/
31 | /build/
32 |
33 | # Android related
34 | **/android/**/gradle-wrapper.jar
35 | **/android/.gradle
36 | **/android/captures/
37 | **/android/gradlew
38 | **/android/gradlew.bat
39 | **/android/local.properties
40 | **/android/**/GeneratedPluginRegistrant.java
41 |
42 | # iOS/XCode related
43 | **/ios/**/*.mode1v3
44 | **/ios/**/*.mode2v3
45 | **/ios/**/*.moved-aside
46 | **/ios/**/*.pbxuser
47 | **/ios/**/*.perspectivev3
48 | **/ios/**/*sync/
49 | **/ios/**/.sconsign.dblite
50 | **/ios/**/.tags*
51 | **/ios/**/.vagrant/
52 | **/ios/**/DerivedData/
53 | **/ios/**/Icon?
54 | **/ios/**/Pods/
55 | **/ios/**/.symlinks/
56 | **/ios/**/profile
57 | **/ios/**/xcuserdata
58 | **/ios/.generated/
59 | **/ios/Flutter/App.framework
60 | **/ios/Flutter/Flutter.framework
61 | **/ios/Flutter/Generated.xcconfig
62 | **/ios/Flutter/app.flx
63 | **/ios/Flutter/app.zip
64 | **/ios/Flutter/flutter_assets/
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 |
--------------------------------------------------------------------------------
/.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: 20e59316b8b8474554b38493b8ca888794b0234a
8 | channel: stable
9 |
10 | project_type: app
11 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # flutter-vmusic
2 |
3 | flutter 制造的一款音乐播放器;
4 |
5 |
6 | ### 数据来源
7 | https://binaryify.github.io/NeteaseCloudMusicApi/#/?id=neteasecloudmusicapi
8 |
9 | ### api接口
10 | https://musicapi.nullno.com/
11 |
12 | ### 界面
13 | 
14 | https://source.nullno.com/images/Screenshot_20191011-164737.jpg
15 |
16 | 
17 |
18 | ##功能
19 |
20 | 1、歌单热歌榜
21 |
22 | 2、视频播放
23 |
24 | 3、音乐播放
25 |
26 | 4、音乐下载(dev..)
27 |
28 | ##安卓下载地址
29 |
30 | https://nullno.github.io/flutter-vmusic/com.nullno.flutter.flutter_dxmusic.apk
31 |
32 |
--------------------------------------------------------------------------------
/android/app/build.gradle:
--------------------------------------------------------------------------------
1 | def localProperties = new Properties()
2 | def localPropertiesFile = rootProject.file('local.properties')
3 | if (localPropertiesFile.exists()) {
4 | localPropertiesFile.withReader('UTF-8') { reader ->
5 | localProperties.load(reader)
6 | }
7 | }
8 |
9 | def flutterRoot = localProperties.getProperty('flutter.sdk')
10 | if (flutterRoot == null) {
11 | throw new GradleException("Flutter SDK not found. Define location with flutter.sdk in the local.properties file.")
12 | }
13 |
14 | def flutterVersionCode = localProperties.getProperty('flutter.versionCode')
15 | if (flutterVersionCode == null) {
16 | flutterVersionCode = '1'
17 | }
18 |
19 | def flutterVersionName = localProperties.getProperty('flutter.versionName')
20 | if (flutterVersionName == null) {
21 | flutterVersionName = '1.0'
22 | }
23 |
24 | apply plugin: 'com.android.application'
25 | apply from: "$flutterRoot/packages/flutter_tools/gradle/flutter.gradle"
26 |
27 | android {
28 | compileSdkVersion 28
29 |
30 | lintOptions {
31 | disable 'InvalidPackage'
32 | }
33 |
34 | defaultConfig {
35 | // TODO: Specify your own unique Application ID (https://developer.android.com/studio/build/application-id.html).
36 | applicationId "com.nullno.flutter.flutter_vmusic"
37 | minSdkVersion 16
38 | targetSdkVersion 28
39 | versionCode flutterVersionCode.toInteger()
40 | versionName flutterVersionName
41 | testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
42 | }
43 |
44 | buildTypes {
45 | release {
46 | // TODO: Add your own signing config for the release build.
47 | // Signing with the debug keys for now, so `flutter run --release` works.
48 | signingConfig signingConfigs.debug
49 | }
50 | }
51 | }
52 |
53 | flutter {
54 | source '../..'
55 | }
56 |
57 | dependencies {
58 | testImplementation 'junit:junit:4.12'
59 | androidTestImplementation 'androidx.test:runner:1.1.1'
60 | androidTestImplementation 'androidx.test.espresso:espresso-core:3.1.1'
61 | }
62 |
--------------------------------------------------------------------------------
/android/app/src/debug/AndroidManifest.xml:
--------------------------------------------------------------------------------
1 |
3 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/android/app/src/main/AndroidManifest.xml:
--------------------------------------------------------------------------------
1 |
3 |
4 |
5 |
6 |
7 |
8 |
13 |
17 |
24 |
28 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
43 |
44 |
45 |
46 |
47 |
48 |
49 |
--------------------------------------------------------------------------------
/android/app/src/main/java/com/nullno/flutter/flutter_vmusic/MainActivity.java:
--------------------------------------------------------------------------------
1 | package com.nullno.flutter.flutter_vmusic;
2 |
3 | import android.os.Bundle;
4 | import io.flutter.app.FlutterActivity;
5 | import io.flutter.plugins.GeneratedPluginRegistrant;
6 |
7 | public class MainActivity extends FlutterActivity {
8 | @Override
9 | protected void onCreate(Bundle savedInstanceState) {
10 |
11 | super.onCreate(savedInstanceState);
12 |
13 |
14 | GeneratedPluginRegistrant.registerWith(this);
15 | }
16 | }
--------------------------------------------------------------------------------
/android/app/src/main/res/drawable/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nullno/flutter-vmusic/c67eb26cb4e321cab3e3907d5a455a4ece493683/android/app/src/main/res/drawable/ic_launcher.png
--------------------------------------------------------------------------------
/android/app/src/main/res/drawable/launch_background.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 | -
7 |
10 |
11 |
12 |
--------------------------------------------------------------------------------
/android/app/src/main/res/drawable/launch_image.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nullno/flutter-vmusic/c67eb26cb4e321cab3e3907d5a455a4ece493683/android/app/src/main/res/drawable/launch_image.jpg
--------------------------------------------------------------------------------
/android/app/src/main/res/mipmap-hdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nullno/flutter-vmusic/c67eb26cb4e321cab3e3907d5a455a4ece493683/android/app/src/main/res/mipmap-hdpi/ic_launcher.png
--------------------------------------------------------------------------------
/android/app/src/main/res/mipmap-mdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nullno/flutter-vmusic/c67eb26cb4e321cab3e3907d5a455a4ece493683/android/app/src/main/res/mipmap-mdpi/ic_launcher.png
--------------------------------------------------------------------------------
/android/app/src/main/res/mipmap-xhdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nullno/flutter-vmusic/c67eb26cb4e321cab3e3907d5a455a4ece493683/android/app/src/main/res/mipmap-xhdpi/ic_launcher.png
--------------------------------------------------------------------------------
/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nullno/flutter-vmusic/c67eb26cb4e321cab3e3907d5a455a4ece493683/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png
--------------------------------------------------------------------------------
/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nullno/flutter-vmusic/c67eb26cb4e321cab3e3907d5a455a4ece493683/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png
--------------------------------------------------------------------------------
/android/app/src/main/res/values/colors.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | #EDE7DF
4 | #00000000
5 |
--------------------------------------------------------------------------------
/android/app/src/main/res/values/styles.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
13 |
14 |
--------------------------------------------------------------------------------
/android/app/src/profile/AndroidManifest.xml:
--------------------------------------------------------------------------------
1 |
3 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/android/build.gradle:
--------------------------------------------------------------------------------
1 | buildscript {
2 | repositories {
3 | google()
4 | jcenter()
5 | }
6 |
7 | dependencies {
8 | classpath 'com.android.tools.build:gradle:3.2.1'
9 | }
10 | }
11 |
12 | allprojects {
13 | repositories {
14 | google()
15 | jcenter()
16 | }
17 | }
18 |
19 | rootProject.buildDir = '../build'
20 | subprojects {
21 | project.buildDir = "${rootProject.buildDir}/${project.name}"
22 | }
23 | subprojects {
24 | project.evaluationDependsOn(':app')
25 | }
26 |
27 | task clean(type: Delete) {
28 | delete rootProject.buildDir
29 | }
30 |
--------------------------------------------------------------------------------
/android/gradle.properties:
--------------------------------------------------------------------------------
1 | org.gradle.jvmargs=-Xmx1536M
2 |
--------------------------------------------------------------------------------
/android/gradle/wrapper/gradle-wrapper.properties:
--------------------------------------------------------------------------------
1 | #Fri Jun 23 08:50:38 CEST 2017
2 | distributionBase=GRADLE_USER_HOME
3 | distributionPath=wrapper/dists
4 | zipStoreBase=GRADLE_USER_HOME
5 | zipStorePath=wrapper/dists
6 | distributionUrl=https\://services.gradle.org/distributions/gradle-4.10.2-all.zip
7 |
--------------------------------------------------------------------------------
/android/settings.gradle:
--------------------------------------------------------------------------------
1 | include ':app'
2 |
3 | def flutterProjectRoot = rootProject.projectDir.parentFile.toPath()
4 |
5 | def plugins = new Properties()
6 | def pluginsFile = new File(flutterProjectRoot.toFile(), '.flutter-plugins')
7 | if (pluginsFile.exists()) {
8 | pluginsFile.withReader('UTF-8') { reader -> plugins.load(reader) }
9 | }
10 |
11 | plugins.each { name, path ->
12 | def pluginDirectory = flutterProjectRoot.resolve(path).resolve('android').toFile()
13 | include ":$name"
14 | project(":$name").projectDir = pluginDirectory
15 | }
16 |
--------------------------------------------------------------------------------
/assets/image/disc-plus.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nullno/flutter-vmusic/c67eb26cb4e321cab3e3907d5a455a4ece493683/assets/image/disc-plus.png
--------------------------------------------------------------------------------
/assets/image/disc.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nullno/flutter-vmusic/c67eb26cb4e321cab3e3907d5a455a4ece493683/assets/image/disc.png
--------------------------------------------------------------------------------
/assets/image/disc_back.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nullno/flutter-vmusic/c67eb26cb4e321cab3e3907d5a455a4ece493683/assets/image/disc_back.png
--------------------------------------------------------------------------------
/assets/image/disc_light-plus.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nullno/flutter-vmusic/c67eb26cb4e321cab3e3907d5a455a4ece493683/assets/image/disc_light-plus.png
--------------------------------------------------------------------------------
/assets/image/disc_light.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nullno/flutter-vmusic/c67eb26cb4e321cab3e3907d5a455a4ece493683/assets/image/disc_light.png
--------------------------------------------------------------------------------
/assets/image/needle-plus.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nullno/flutter-vmusic/c67eb26cb4e321cab3e3907d5a455a4ece493683/assets/image/needle-plus.png
--------------------------------------------------------------------------------
/assets/image/needle.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nullno/flutter-vmusic/c67eb26cb4e321cab3e3907d5a455a4ece493683/assets/image/needle.png
--------------------------------------------------------------------------------
/assets/image/play_btn_3x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nullno/flutter-vmusic/c67eb26cb4e321cab3e3907d5a455a4ece493683/assets/image/play_btn_3x.png
--------------------------------------------------------------------------------
/com.nullno.flutter.flutter_dxmusic.apk:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nullno/flutter-vmusic/c67eb26cb4e321cab3e3907d5a455a4ece493683/com.nullno.flutter.flutter_dxmusic.apk
--------------------------------------------------------------------------------
/ios/Flutter/AppFrameworkInfo.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | CFBundleDevelopmentRegion
6 | $(DEVELOPMENT_LANGUAGE)
7 | CFBundleExecutable
8 | App
9 | CFBundleIdentifier
10 | io.flutter.flutter.app
11 | CFBundleInfoDictionaryVersion
12 | 6.0
13 | CFBundleName
14 | App
15 | CFBundlePackageType
16 | FMWK
17 | CFBundleShortVersionString
18 | 1.0
19 | CFBundleSignature
20 | ????
21 | CFBundleVersion
22 | 1.0
23 | MinimumOSVersion
24 | 8.0
25 |
26 |
27 |
--------------------------------------------------------------------------------
/ios/Flutter/Debug.xcconfig:
--------------------------------------------------------------------------------
1 | #include "Generated.xcconfig"
2 |
--------------------------------------------------------------------------------
/ios/Flutter/Release.xcconfig:
--------------------------------------------------------------------------------
1 | #include "Generated.xcconfig"
2 |
--------------------------------------------------------------------------------
/ios/Runner.xcodeproj/project.xcworkspace/contents.xcworkspacedata:
--------------------------------------------------------------------------------
1 |
2 |
4 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/ios/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme:
--------------------------------------------------------------------------------
1 |
2 |
5 |
8 |
9 |
15 |
21 |
22 |
23 |
24 |
25 |
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 |
--------------------------------------------------------------------------------
/ios/Runner.xcworkspace/contents.xcworkspacedata:
--------------------------------------------------------------------------------
1 |
2 |
4 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/ios/Runner/AppDelegate.h:
--------------------------------------------------------------------------------
1 | #import
2 | #import
3 |
4 | @interface AppDelegate : FlutterAppDelegate
5 |
6 | @end
7 |
--------------------------------------------------------------------------------
/ios/Runner/AppDelegate.m:
--------------------------------------------------------------------------------
1 | #include "AppDelegate.h"
2 | #include "GeneratedPluginRegistrant.h"
3 |
4 | @implementation AppDelegate
5 |
6 | - (BOOL)application:(UIApplication *)application
7 | didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
8 | [GeneratedPluginRegistrant registerWithRegistry:self];
9 | // Override point for customization after application launch.
10 | return [super application:application didFinishLaunchingWithOptions:launchOptions];
11 | }
12 |
13 | @end
14 |
--------------------------------------------------------------------------------
/ios/Runner/Assets.xcassets/AppIcon.appiconset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "size" : "20x20",
5 | "idiom" : "iphone",
6 | "filename" : "Icon-App-20x20@2x.png",
7 | "scale" : "2x"
8 | },
9 | {
10 | "size" : "20x20",
11 | "idiom" : "iphone",
12 | "filename" : "Icon-App-20x20@3x.png",
13 | "scale" : "3x"
14 | },
15 | {
16 | "size" : "29x29",
17 | "idiom" : "iphone",
18 | "filename" : "Icon-App-29x29@1x.png",
19 | "scale" : "1x"
20 | },
21 | {
22 | "size" : "29x29",
23 | "idiom" : "iphone",
24 | "filename" : "Icon-App-29x29@2x.png",
25 | "scale" : "2x"
26 | },
27 | {
28 | "size" : "29x29",
29 | "idiom" : "iphone",
30 | "filename" : "Icon-App-29x29@3x.png",
31 | "scale" : "3x"
32 | },
33 | {
34 | "size" : "40x40",
35 | "idiom" : "iphone",
36 | "filename" : "Icon-App-40x40@2x.png",
37 | "scale" : "2x"
38 | },
39 | {
40 | "size" : "40x40",
41 | "idiom" : "iphone",
42 | "filename" : "Icon-App-40x40@3x.png",
43 | "scale" : "3x"
44 | },
45 | {
46 | "size" : "60x60",
47 | "idiom" : "iphone",
48 | "filename" : "Icon-App-60x60@2x.png",
49 | "scale" : "2x"
50 | },
51 | {
52 | "size" : "60x60",
53 | "idiom" : "iphone",
54 | "filename" : "Icon-App-60x60@3x.png",
55 | "scale" : "3x"
56 | },
57 | {
58 | "size" : "20x20",
59 | "idiom" : "ipad",
60 | "filename" : "Icon-App-20x20@1x.png",
61 | "scale" : "1x"
62 | },
63 | {
64 | "size" : "20x20",
65 | "idiom" : "ipad",
66 | "filename" : "Icon-App-20x20@2x.png",
67 | "scale" : "2x"
68 | },
69 | {
70 | "size" : "29x29",
71 | "idiom" : "ipad",
72 | "filename" : "Icon-App-29x29@1x.png",
73 | "scale" : "1x"
74 | },
75 | {
76 | "size" : "29x29",
77 | "idiom" : "ipad",
78 | "filename" : "Icon-App-29x29@2x.png",
79 | "scale" : "2x"
80 | },
81 | {
82 | "size" : "40x40",
83 | "idiom" : "ipad",
84 | "filename" : "Icon-App-40x40@1x.png",
85 | "scale" : "1x"
86 | },
87 | {
88 | "size" : "40x40",
89 | "idiom" : "ipad",
90 | "filename" : "Icon-App-40x40@2x.png",
91 | "scale" : "2x"
92 | },
93 | {
94 | "size" : "76x76",
95 | "idiom" : "ipad",
96 | "filename" : "Icon-App-76x76@1x.png",
97 | "scale" : "1x"
98 | },
99 | {
100 | "size" : "76x76",
101 | "idiom" : "ipad",
102 | "filename" : "Icon-App-76x76@2x.png",
103 | "scale" : "2x"
104 | },
105 | {
106 | "size" : "83.5x83.5",
107 | "idiom" : "ipad",
108 | "filename" : "Icon-App-83.5x83.5@2x.png",
109 | "scale" : "2x"
110 | },
111 | {
112 | "size" : "1024x1024",
113 | "idiom" : "ios-marketing",
114 | "filename" : "Icon-App-1024x1024@1x.png",
115 | "scale" : "1x"
116 | }
117 | ],
118 | "info" : {
119 | "version" : 1,
120 | "author" : "xcode"
121 | }
122 | }
123 |
--------------------------------------------------------------------------------
/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-1024x1024@1x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nullno/flutter-vmusic/c67eb26cb4e321cab3e3907d5a455a4ece493683/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-1024x1024@1x.png
--------------------------------------------------------------------------------
/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@1x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nullno/flutter-vmusic/c67eb26cb4e321cab3e3907d5a455a4ece493683/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@1x.png
--------------------------------------------------------------------------------
/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nullno/flutter-vmusic/c67eb26cb4e321cab3e3907d5a455a4ece493683/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@2x.png
--------------------------------------------------------------------------------
/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@3x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nullno/flutter-vmusic/c67eb26cb4e321cab3e3907d5a455a4ece493683/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@3x.png
--------------------------------------------------------------------------------
/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@1x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nullno/flutter-vmusic/c67eb26cb4e321cab3e3907d5a455a4ece493683/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@1x.png
--------------------------------------------------------------------------------
/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nullno/flutter-vmusic/c67eb26cb4e321cab3e3907d5a455a4ece493683/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@2x.png
--------------------------------------------------------------------------------
/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@3x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nullno/flutter-vmusic/c67eb26cb4e321cab3e3907d5a455a4ece493683/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@3x.png
--------------------------------------------------------------------------------
/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@1x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nullno/flutter-vmusic/c67eb26cb4e321cab3e3907d5a455a4ece493683/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@1x.png
--------------------------------------------------------------------------------
/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nullno/flutter-vmusic/c67eb26cb4e321cab3e3907d5a455a4ece493683/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@2x.png
--------------------------------------------------------------------------------
/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@3x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nullno/flutter-vmusic/c67eb26cb4e321cab3e3907d5a455a4ece493683/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@3x.png
--------------------------------------------------------------------------------
/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nullno/flutter-vmusic/c67eb26cb4e321cab3e3907d5a455a4ece493683/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@2x.png
--------------------------------------------------------------------------------
/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@3x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nullno/flutter-vmusic/c67eb26cb4e321cab3e3907d5a455a4ece493683/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@3x.png
--------------------------------------------------------------------------------
/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@1x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nullno/flutter-vmusic/c67eb26cb4e321cab3e3907d5a455a4ece493683/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@1x.png
--------------------------------------------------------------------------------
/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nullno/flutter-vmusic/c67eb26cb4e321cab3e3907d5a455a4ece493683/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@2x.png
--------------------------------------------------------------------------------
/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-83.5x83.5@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nullno/flutter-vmusic/c67eb26cb4e321cab3e3907d5a455a4ece493683/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-83.5x83.5@2x.png
--------------------------------------------------------------------------------
/ios/Runner/Assets.xcassets/LaunchImage.imageset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "idiom" : "universal",
5 | "filename" : "LaunchImage.png",
6 | "scale" : "1x"
7 | },
8 | {
9 | "idiom" : "universal",
10 | "filename" : "LaunchImage@2x.png",
11 | "scale" : "2x"
12 | },
13 | {
14 | "idiom" : "universal",
15 | "filename" : "LaunchImage@3x.png",
16 | "scale" : "3x"
17 | }
18 | ],
19 | "info" : {
20 | "version" : 1,
21 | "author" : "xcode"
22 | }
23 | }
24 |
--------------------------------------------------------------------------------
/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nullno/flutter-vmusic/c67eb26cb4e321cab3e3907d5a455a4ece493683/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage.png
--------------------------------------------------------------------------------
/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nullno/flutter-vmusic/c67eb26cb4e321cab3e3907d5a455a4ece493683/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@2x.png
--------------------------------------------------------------------------------
/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@3x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nullno/flutter-vmusic/c67eb26cb4e321cab3e3907d5a455a4ece493683/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@3x.png
--------------------------------------------------------------------------------
/ios/Runner/Assets.xcassets/LaunchImage.imageset/README.md:
--------------------------------------------------------------------------------
1 | # Launch Screen Assets
2 |
3 | You can customize the launch screen with your own desired assets by replacing the image files in this directory.
4 |
5 | You can also do it by opening your Flutter project's Xcode project with `open ios/Runner.xcworkspace`, selecting `Runner/Assets.xcassets` in the Project Navigator and dropping in the desired images.
--------------------------------------------------------------------------------
/ios/Runner/Base.lproj/LaunchScreen.storyboard:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
--------------------------------------------------------------------------------
/ios/Runner/Base.lproj/Main.storyboard:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
--------------------------------------------------------------------------------
/ios/Runner/Info.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | CFBundleDevelopmentRegion
6 | $(DEVELOPMENT_LANGUAGE)
7 | CFBundleExecutable
8 | $(EXECUTABLE_NAME)
9 | CFBundleIdentifier
10 | $(PRODUCT_BUNDLE_IDENTIFIER)
11 | CFBundleInfoDictionaryVersion
12 | 6.0
13 | CFBundleName
14 | flutter_vmusic
15 | CFBundlePackageType
16 | APPL
17 | CFBundleShortVersionString
18 | $(FLUTTER_BUILD_NAME)
19 | CFBundleSignature
20 | ????
21 | CFBundleVersion
22 | $(FLUTTER_BUILD_NUMBER)
23 | LSRequiresIPhoneOS
24 |
25 | UILaunchStoryboardName
26 | LaunchScreen
27 | UIMainStoryboardFile
28 | Main
29 | UISupportedInterfaceOrientations
30 |
31 | UIInterfaceOrientationPortrait
32 | UIInterfaceOrientationLandscapeLeft
33 | UIInterfaceOrientationLandscapeRight
34 |
35 | UISupportedInterfaceOrientations~ipad
36 |
37 | UIInterfaceOrientationPortrait
38 | UIInterfaceOrientationPortraitUpsideDown
39 | UIInterfaceOrientationLandscapeLeft
40 | UIInterfaceOrientationLandscapeRight
41 |
42 | UIViewControllerBasedStatusBarAppearance
43 |
44 |
45 |
46 |
--------------------------------------------------------------------------------
/ios/Runner/main.m:
--------------------------------------------------------------------------------
1 | #import
2 | #import
3 | #import "AppDelegate.h"
4 |
5 | int main(int argc, char* argv[]) {
6 | @autoreleasepool {
7 | return UIApplicationMain(argc, argv, nil, NSStringFromClass([AppDelegate class]));
8 | }
9 | }
10 |
--------------------------------------------------------------------------------
/lib/components/exitApp.dart:
--------------------------------------------------------------------------------
1 | /*
2 | 退出应用确认框
3 | */
4 | import 'package:flutter/material.dart';
5 | import 'package:flutter/cupertino.dart';
6 |
7 | Future exitApp(context) {
8 | return showDialog(
9 | context: context,
10 | barrierDismissible: true, // user must tap button!
11 | builder: (BuildContext context){
12 | return CupertinoAlertDialog(
13 | title: Text('是否退出应用?'),
14 | actions:[
15 | CupertinoDialogAction(
16 | child: Text('取消'),
17 | onPressed: () => Navigator.pop(context, false),
18 | ),
19 | CupertinoDialogAction(
20 | child: Text('退出'),
21 | onPressed: () => Navigator.pop(context, true),
22 | ),
23 | ],
24 | );
25 | },
26 | );
27 | }
28 |
29 |
--------------------------------------------------------------------------------
/lib/components/find.dart:
--------------------------------------------------------------------------------
1 | /*
2 | 推荐模块
3 | */
4 | import 'package:flutter/material.dart';
5 | import 'package:flutter_vmusic/conf/router.dart';
6 |
7 | import 'package:cached_network_image/cached_network_image.dart';
8 | import 'dart:async';
9 |
10 | //import 'package:flutter/painting.dart';
11 | import 'package:flutter_vmusic/conf/api.dart';
12 | import 'package:flutter_vmusic/utils/tool.dart';
13 | import 'package:flutter_vmusic/utils/FixedSizeText.dart';
14 |
15 | import 'package:loading/loading.dart';
16 | import 'package:loading/indicator/line_scale_indicator.dart';
17 |
18 |
19 |
20 | class Find extends StatefulWidget{
21 |
22 | @override
23 |
24 | State createState() => new _Find();
25 |
26 | }
27 |
28 | class _Find extends State with SingleTickerProviderStateMixin{
29 |
30 |
31 |
32 |
33 | // banner数据
34 | List adList = [];
35 | // 热歌榜数据
36 | List songRanks = [];
37 | //歌单
38 | List songLists = [];
39 | //加载状态
40 | int loadState = 0; //0加载中 1加载成功 2加载失败
41 |
42 | TabController AdController;//tab控制器
43 | int _AdcurrentIndex = 0; //选中下标
44 |
45 | //下拉刷新
46 | final GlobalKey _refreshIndicatorKey = new GlobalKey();
47 |
48 | @override
49 | void initState(){
50 | super.initState();
51 | _flashData();
52 | }
53 | //广告图初始化controller并添加监听
54 | void _adController(){
55 | AdController = TabController(initialIndex:0,length:adList.length, vsync: this);
56 | AdController.addListener((){
57 | if (AdController.index.toDouble() == AdController.animation.value) {
58 | //赋值 并更新数据
59 | if(mounted) {
60 | this.setState(() {
61 | _AdcurrentIndex = AdController.index;
62 | });
63 | }
64 | }
65 | });
66 | }
67 |
68 | // 刷新获取数据
69 | Future _flashData(){
70 | final Completer completer = new Completer();
71 |
72 | getData((status){
73 | if(mounted) {
74 | setState(() {
75 | loadState = status;
76 | completer.complete(null);
77 | if (adList.length > 0) {
78 | _adController();
79 | }
80 | });
81 | }
82 | });
83 |
84 | /* // 启动一下 [Timer] 在3秒后,在list里面添加一条数据,关完成这个刷新
85 | new Timer(Duration(seconds: 2), () {
86 | // 添加数据,更新界面
87 | // 完成刷新
88 | completer.complete(null);
89 | });
90 | */
91 |
92 | return completer.future;
93 | }
94 | //获取数据
95 | void getData(complete) async{
96 | var status = 0;
97 |
98 | await homeGet((res){
99 | status = 1;
100 | adList = res[0]['banners'];
101 | songLists= res[1]['result'];
102 | },(err){
103 | status = 2;
104 | print(err);
105 | });
106 | complete(status);
107 | }
108 |
109 |
110 | @override
111 | Widget build(BuildContext context) {
112 |
113 | Widget _loader(BuildContext context, String url) {
114 | return new Center(
115 | widthFactor:12.0,
116 | child: CircularProgressIndicator(
117 | backgroundColor:Colors.white,
118 | ),
119 | );
120 | }
121 |
122 | Widget _error(BuildContext context, String url, Object error) {
123 | // print(error);
124 | return new Center(
125 | child: Icon(Icons.error,color: Colors.white),
126 | );
127 | }
128 |
129 | Widget _loaderImgBlank(BuildContext context, String url) {
130 | return new Center(
131 | widthFactor:12.0,
132 | child:Icon(Icons.image,size:158,color: Colors.grey,)
133 | );
134 | }
135 |
136 | //广告图
137 | Widget slideBanner = adList.length>0?TabBarView(
138 | controller: AdController,
139 | children: adList.map((item){
140 | return Container(
141 | margin:EdgeInsets.fromLTRB(15.0, 0, 15.0, 0),
142 | child: ClipRRect(
143 | borderRadius: BorderRadius.circular(5),
144 | child:Container(
145 | color:Colors.white30,
146 | child: new CachedNetworkImage(
147 | placeholder: _loader,
148 | errorWidget: _error,
149 | imageUrl: item['imageUrl'],//item['imageUrl'],
150 | fit: BoxFit.cover,
151 | )
152 | ),
153 | )
154 | );
155 | }).toList()
156 | ):Container();
157 |
158 | //热歌榜
159 | Widget songRank = Column(
160 | crossAxisAlignment: CrossAxisAlignment.stretch,
161 | children: [
162 | FixedSizeText('热歌榜',textAlign:TextAlign.left,style:TextStyle(fontSize:16.0, fontWeight:FontWeight.bold)),
163 | GridView.count(
164 | primary: false,
165 | padding: EdgeInsets.fromLTRB(0.0,10.0,0.0,0.0),
166 | crossAxisSpacing: 10,
167 | mainAxisSpacing: 10,
168 | childAspectRatio: 1,
169 | crossAxisCount: 6,
170 | shrinkWrap: true,
171 | children: [
172 | Column(
173 | children: [
174 | ClipRRect(
175 | borderRadius: BorderRadius.circular(50),
176 | child: Stack(
177 | children: [
178 | InkWell(
179 | onTap: (){
180 | Router.fadeNavigator(context,"/songmenulist",{'id':4395559,'from':'/find'},(res){});
181 | },
182 | child: new CachedNetworkImage(
183 | imageUrl:'https://p1.music.126.net/N2whh2Prf0l8QHmCpShrcQ==/19140298416347251.jpg',//item['playlist']['coverImgUrl'],
184 | fit: BoxFit.cover,
185 | ),
186 | )
187 | /* Positioned(
188 | left:20.0,
189 | bottom:3.0,
190 | child:Row(
191 | children: [
192 | Icon(Icons.play_arrow,color:Colors.white,size:10.0,),
193 | FixedSizeText(tranNumber(item['playlist']['playCount']),style:TextStyle(color:Colors.white,fontSize:10.0))
194 | ],
195 | ),
196 | )*/
197 | ],
198 | )
199 | ),
200 | /* FixedSizeText(item['playlist']['name'],
201 | maxLines:1,
202 | overflow: TextOverflow.ellipsis,
203 | style:TextStyle(fontSize:13.0,height:1.5))*/
204 | ],
205 | ),
206 | Column(
207 | children: [
208 | ClipRRect(
209 | borderRadius: BorderRadius.circular(50),
210 | child: Stack(
211 | children: [
212 | InkWell(
213 | onTap: (){
214 | Router.fadeNavigator(context,"/songmenulist",{'id':2617766278,'from':'/find'},(res){});
215 | },
216 | child: new CachedNetworkImage(
217 | imageUrl:'https://p1.music.126.net/XbjRDARP1xv5a-40ZDOy6A==/109951163785427934.jpg',//item['playlist']['coverImgUrl'],
218 | fit: BoxFit.cover,
219 | ),
220 | )
221 | ],
222 | )
223 | ),
224 | ],
225 | ),
226 | Column(
227 | children: [
228 | ClipRRect(
229 | borderRadius: BorderRadius.circular(50),
230 | child: Stack(
231 | children: [
232 | InkWell(
233 | onTap: (){
234 | Router.fadeNavigator(context,"/songmenulist",{'id':3779629,'from':'/find'},(res){});
235 | },
236 | child: new CachedNetworkImage(
237 | imageUrl:'http://p1.music.126.net/N2HO5xfYEqyQ8q6oxCw8IQ==/18713687906568048.jpg',//item['playlist']['coverImgUrl'],
238 | fit: BoxFit.cover,
239 | ),
240 | )
241 | ],
242 | )
243 | ),
244 | ],
245 | ),
246 | Column(
247 | children: [
248 | ClipRRect(
249 | borderRadius: BorderRadius.circular(50),
250 | child: Stack(
251 | children: [
252 | InkWell(
253 | onTap: (){
254 | Router.fadeNavigator(context,"/songmenulist",{'id':3778678,'from':'/find'},(res){});
255 | },
256 | child: new CachedNetworkImage(
257 | imageUrl:'http://p2.music.126.net/GhhuF6Ep5Tq9IEvLsyCN7w==/18708190348409091.jpg',//item['playlist']['coverImgUrl'],
258 | fit: BoxFit.cover,
259 | ),
260 | )
261 | ],
262 | )
263 | ),
264 | ],
265 | ),
266 | Column(
267 | children: [
268 | ClipRRect(
269 | borderRadius: BorderRadius.circular(50),
270 | child: Stack(
271 | children: [
272 | InkWell(
273 | onTap: (){
274 | Router.fadeNavigator(context,"/songmenulist",{'id':2884035,'from':'/find'},(res){});
275 | },
276 | child: new CachedNetworkImage(
277 | imageUrl:'http://p2.music.126.net/sBzD11nforcuh1jdLSgX7g==/18740076185638788.jpg',//item['playlist']['coverImgUrl'],
278 | fit: BoxFit.cover,
279 | ),
280 | )
281 | ],
282 | )
283 | ),
284 | ],
285 | ),
286 | Column(
287 | children: [
288 | ClipRRect(
289 | borderRadius: BorderRadius.circular(50),
290 | child: Stack(
291 | children: [
292 | InkWell(
293 | onTap: (){
294 | Router.fadeNavigator(context,"/songmenulist",{'id':2250011882,'from':'/find'},(res){});
295 | },
296 | child: new CachedNetworkImage(
297 | imageUrl:'http://p1.music.126.net/oUxnXXvM33OUHxxukYnUjQ==/109951164174523461.jpg',//item['playlist']['coverImgUrl'],
298 | fit: BoxFit.cover,
299 | ),
300 | )
301 | ],
302 | )
303 | ),
304 | ],
305 | ),
306 | ],
307 |
308 |
309 | ),
310 |
311 | ],
312 | );
313 |
314 | //歌单
315 | Widget songList = Column(
316 | crossAxisAlignment: CrossAxisAlignment.stretch,
317 | children: [
318 | Row(
319 | mainAxisAlignment:MainAxisAlignment.spaceBetween,
320 | children: [
321 | FixedSizeText('推荐歌单',textAlign:TextAlign.left,style:TextStyle(fontSize:16.0, fontWeight:FontWeight.bold)),
322 | ClipRRect(
323 | borderRadius: BorderRadius.circular(10),
324 | child: Material(
325 | color:Colors.white,
326 | child: InkWell(
327 | onTap: (){
328 | Router.fadeNavigator(context,"/songmenu",{'from':'/find'},(res){});
329 | },
330 | highlightColor:Colors.grey,
331 |
332 | child:Icon(Icons.more_horiz),
333 | ),
334 | )
335 | ),
336 |
337 | ],
338 | ),
339 |
340 | GridView.count(
341 | primary: false,
342 | padding: EdgeInsets.fromLTRB(0.0,10.0,0.0,0.0),
343 | crossAxisSpacing: 10,
344 | mainAxisSpacing: 10,
345 | childAspectRatio: 0.75,
346 | crossAxisCount: 2,
347 | shrinkWrap: true,
348 | children: songLists.map((item){
349 | return Column(
350 | crossAxisAlignment: CrossAxisAlignment.start,
351 | children: [
352 | InkWell(
353 | onTap: (){
354 | Router.fadeNavigator(context,"/songmenulist",{'id':item['id'],'from':'/find'},(res){});
355 | },
356 | child:ClipRRect(
357 | borderRadius: BorderRadius.circular(5),
358 | child: Stack(
359 | children: [
360 | new CachedNetworkImage(
361 | placeholder: _loaderImgBlank,
362 | errorWidget: _error,
363 | imageUrl:item['picUrl'],//item['picUrl'],
364 | fit: BoxFit.cover,
365 | ),
366 | Positioned(
367 | top:3.0,
368 | right:3.0,
369 | child:Row(
370 | children: [
371 | Icon(Icons.play_circle_outline,color:Colors.white,size:15.0,),
372 | FixedSizeText(tranNumber(item['playCount']),style:TextStyle(color:Colors.white,fontSize:14.0))
373 | ],
374 | ),
375 | )
376 | ],
377 | )
378 | ) ,
379 | ),
380 |
381 | Container(
382 | padding:EdgeInsets.fromLTRB(0.0, 3.0, 0.0, 0.0),
383 | child:FixedSizeText(item['name'],
384 | maxLines:2,
385 | overflow: TextOverflow.ellipsis,
386 | style:TextStyle(fontSize:13.0,height:1.2)),
387 | )
388 |
389 | ],
390 | );
391 | }).toList()
392 | ),
393 |
394 | ],
395 | );
396 |
397 | return Material(
398 | // 255, 240,62,57
399 | child:loadState!=1?Center(child:loadState==0?Loading(indicator: LineScaleIndicator(), size: 50.0):Icon(Icons.cloud_off,size:40.0,)):RefreshIndicator(
400 | key: _refreshIndicatorKey,
401 | onRefresh: _flashData, // onRefresh 参数是一个 Future 的回调
402 | child: ListView(
403 | primary: true,
404 | physics: BouncingScrollPhysics(),
405 | padding:const EdgeInsets.fromLTRB(0.0,0.0,0.0,60.0),
406 | children: [
407 | Container(
408 | height: 150.0,
409 | margin: EdgeInsets.fromLTRB(0.0, 0.0, 0, 0.0),
410 | padding:EdgeInsets.fromLTRB(0, 8.0, 0.0, 8.0),
411 | color: Colors.white,
412 | child: slideBanner,
413 | ),
414 | Container(
415 | color:Colors.white,
416 | margin:EdgeInsets.fromLTRB(0.0, 10.0, 0.0, 0.0),
417 | padding:EdgeInsets.fromLTRB(15.0, 8.0, 15.0, 8.0),
418 | child: songRank,
419 | ),
420 | Container(
421 | color:Colors.white,
422 | margin:EdgeInsets.fromLTRB(0.0, 10.0, 0.0, 0.0),
423 | padding:EdgeInsets.fromLTRB(15.0, 8.0, 15.0, 8.0),
424 | child: songList,
425 | ),
426 | FixedSizeText('~我也是有底线的呦~',textAlign:TextAlign.center,style:TextStyle(height:2.0,fontSize:12.0),)
427 |
428 |
429 | ],
430 | ),
431 | )
432 |
433 |
434 | );
435 |
436 | }
437 |
438 | @override
439 | void dispose() {
440 |
441 | AdController.dispose();
442 | super.dispose();
443 | }
444 |
445 | }
--------------------------------------------------------------------------------
/lib/components/my.dart:
--------------------------------------------------------------------------------
1 | /*
2 | 我的模块
3 | */
4 | import 'package:flutter/material.dart';
5 |
6 | class MyCenter extends StatefulWidget{
7 |
8 | @override
9 |
10 | State createState() => new _MyCenter();
11 |
12 | }
13 |
14 | class _MyCenter extends State{
15 |
16 | @override
17 | Widget build(BuildContext context) {
18 | // TODO: implement build
19 | return Text('我的模块');
20 | }
21 | }
--------------------------------------------------------------------------------
/lib/components/playPanel.dart:
--------------------------------------------------------------------------------
1 | /*
2 | 播放面板
3 | */
4 | import 'dart:async';
5 | import 'package:flutter/material.dart';
6 | import 'package:audioplayers/audioplayers.dart';
7 | import 'package:flutter_vmusic/utils/FixedSizeText.dart';
8 |
9 | import 'package:flutter_vmusic/conf/appsate.dart';
10 | import 'package:cached_network_image/cached_network_image.dart';
11 |
12 | import 'package:flutter_vmusic/conf/router.dart';
13 | import 'package:flutter_vmusic/conf/platform.dart';
14 |
15 | class PlayPanel extends StatefulWidget{
16 | final Map params;
17 | PlayPanel({
18 | Key key,
19 | this.params,
20 | }) : super(key: key);
21 | @override
22 | _PlayPanel createState() => _PlayPanel();
23 | }
24 |
25 | class _PlayPanel extends State{
26 |
27 | AudioPlayer audioPlayer = AppState.player['audioPlayer'] ;
28 |
29 | void initState() {
30 | super.initState();
31 |
32 | }
33 |
34 | //播放歌曲
35 | void playSong(url) async{
36 | print(url);
37 | int result = await audioPlayer.play(url.replaceAll('http:', 'https:'));
38 | if(result==1) {
39 | setState(() {
40 | AppState.player['playStatus']=true;
41 |
42 | });
43 | }
44 | }
45 | //暂停播放
46 | void pauseSong() async{
47 | int result = await audioPlayer.pause();
48 | if(result==1) {
49 | setState(() {
50 | AppState.player['playStatus']=false;
51 | });
52 | }
53 | }
54 |
55 | @override
56 | Widget build(BuildContext context) {
57 | return RawMaterialButton(
58 | onPressed: (){
59 | Router.fadeNavigator(context,"/playerpage",{'id':AppState.player['id'],'from':'/panel'},(res){
60 | SYS.systemUI(Colors.transparent,Colors.black,Brightness.dark);
61 | });
62 | },
63 | splashColor:Color(0xff898B8B),
64 | child:Container(
65 | width: double.infinity,
66 | height: 50.0,
67 | padding:EdgeInsets.all(5.0),
68 | decoration: BoxDecoration(color:Color.fromRGBO(255, 255, 255, 0.95)),
69 | child: new Row(
70 | mainAxisAlignment: MainAxisAlignment.spaceAround,
71 | crossAxisAlignment:CrossAxisAlignment.center,
72 | children: [
73 | Padding(
74 | padding:EdgeInsets.fromLTRB(4.0,0,5.0,0),
75 | child:ClipRRect(
76 | borderRadius: BorderRadius.circular(50),
77 | child:Container(
78 | height:40.0,
79 | width:40.0,
80 | color:Colors.grey,
81 | child: new CachedNetworkImage(
82 | imageUrl:AppState.player['face'],//item['picUrl'],
83 | ),
84 | )
85 | ) ,),
86 |
87 | Expanded(
88 | child: Column(
89 | crossAxisAlignment: CrossAxisAlignment.start,
90 | mainAxisAlignment: MainAxisAlignment.center,
91 | children: [
92 | FixedSizeText(AppState.player['name'], overflow: TextOverflow.ellipsis,style:TextStyle(fontSize:13.0),),
93 | FixedSizeText(AppState.player['singer'],style:TextStyle(color:Colors.black45,fontSize:11.0)),
94 | ],
95 | )
96 | ),
97 | IconButton(
98 | padding:EdgeInsets.all(0.0),
99 | splashColor:Color(0xff898B8B),
100 | onPressed: (){
101 | if(!AppState.player['playStatus']){
102 | playSong(AppState.player['url']);
103 | }else{
104 | pauseSong();
105 | }
106 |
107 | },
108 | icon: Icon( AppState.player['playStatus']==false?Icons.play_circle_outline:Icons.pause_circle_outline,color: Colors.black,size:40.0)
109 | ),
110 | IconButton(
111 | padding:EdgeInsets.all(0.0),
112 | splashColor:Color(0xff898B8B),
113 | onPressed: (){
114 |
115 | },
116 | icon: Icon(Icons.playlist_play,color: Colors.black,size:40.0),
117 | )
118 |
119 | ],
120 | ),
121 | ),
122 |
123 | );
124 | }
125 | }
--------------------------------------------------------------------------------
/lib/components/video.dart:
--------------------------------------------------------------------------------
1 | /*
2 | 视频模块
3 | */
4 | import 'package:flutter/material.dart';
5 | import 'package:cached_network_image/cached_network_image.dart';
6 |
7 | import 'package:flutter_vmusic/utils/tool.dart';
8 | import 'package:flutter_vmusic/utils/video_player.dart';
9 | import 'package:flutter_vmusic/utils/FixedSizeText.dart';
10 |
11 | import 'package:loading/loading.dart';
12 | import 'package:loading/indicator/line_scale_pulse_out_indicator.dart';
13 |
14 | import 'dart:async';
15 | import 'package:flutter_vmusic/conf/api.dart';
16 |
17 | import 'package:flutter_vmusic/conf/router.dart';
18 | import 'package:flutter_vmusic/conf/platform.dart';
19 |
20 | class VideoList extends StatefulWidget{
21 |
22 | @override
23 |
24 | State createState() => new _VideoList();
25 |
26 | }
27 |
28 | class _VideoList extends State{
29 |
30 |
31 | // 推荐MV数据
32 | List topList = [];
33 | // 全部MV数据
34 | List allList = [];
35 | //加载状态
36 | int loadState = 0; //0加载中 1加载成功 2加载失败
37 | //下拉刷新
38 | final GlobalKey _refreshIndicatorKey = new GlobalKey();
39 |
40 | Map loadMore={
41 | "Text":"----",
42 | "Page":0,
43 | "hasMore":true,
44 | "isScrollBottom":false,
45 | };
46 |
47 | //初始化滚动监听器,加载更多使用
48 | ScrollController _scrollController = new ScrollController();
49 |
50 | @override
51 | void initState(){
52 | super.initState();
53 | if(mounted) {
54 | addloadMore();
55 | // 数据刷新
56 | _flashData();
57 | }
58 | }
59 |
60 | // 全部mv监听加载更多
61 | addloadMore(){
62 | _scrollController.addListener(() {
63 | var maxScroll = _scrollController.position.maxScrollExtent.toStringAsFixed(0);
64 | var pixel = _scrollController.position.pixels.toStringAsFixed(0);
65 |
66 | if (maxScroll == pixel && loadMore["hasMore"]&&!loadMore["isScrollBottom"]) {
67 |
68 | setState(() {
69 | loadMore["Text"] = "正在加载中...";
70 | loadMore["isScrollBottom"]=true;
71 | getAllMV({"area":'全部',"offset":loadMore['Page']*10},(res){
72 | loadMore['hasMore']=res['hasMore'];
73 | loadMore['Page']=loadMore['Page']+1;
74 | loadMore["isScrollBottom"]=false;
75 | res['data'].forEach((aitem)=>{
76 | aitem['vurl']=null,
77 | allList.add(aitem)
78 | });
79 | },(err){
80 | print(err);
81 | });
82 | });
83 |
84 | } else if(!loadMore['hasMore']) {
85 | setState(() {
86 | loadMore["isScrollBottom"]=true;
87 | loadMore["Text"] = "~我也是有底线的呦~";
88 | });
89 | }
90 | });
91 | }
92 |
93 | // 下拉刷新数据
94 | Future _flashData() async{
95 | final Completer completer = new Completer();
96 | getData((status){
97 | setState(() {
98 | loadState=status;
99 | completer.complete(null);
100 | });
101 |
102 | });
103 |
104 |
105 | return completer.future;
106 | }
107 | //获取数据
108 | void getData(complete) async{
109 | var status = 0;
110 |
111 | //获取推荐
112 | await getPersonalizedMV((res){
113 | status = 1;
114 | topList=res['result'];
115 | },(err){
116 | status = 2;
117 | print(err);
118 | });
119 |
120 | // 获取全部
121 | await getAllMV({"area":'全部',"offset":0},(res){
122 | status = 1;
123 | loadMore['hasMore']=res['hasMore'];
124 | loadMore['Page']=1;
125 | loadMore["isScrollBottom"]=false;
126 | allList.clear();
127 | res['data'].forEach((aitem)=>{
128 | aitem['vurl']=null,
129 | allList.add(aitem)
130 |
131 | });
132 | },(err){
133 | status = 2;
134 | print(err);
135 | });
136 |
137 | complete(status);
138 | }
139 |
140 | //获取播放链接
141 | void midPlayer(mid){
142 | var result = allList.singleWhere((aitem)=>(aitem['id']==mid),orElse: ()=>(0));
143 |
144 | setState(() {
145 | result['vurl']=1;
146 | });
147 | getMVDetail(mid,(res){
148 | if(res['code']==200){
149 | setState(() {
150 | allList.forEach((aitem)=>{
151 | aitem['vurl']=null
152 | });
153 | result['vurl']= videoUrl(res['data']['brs']);
154 |
155 | });
156 | }
157 |
158 | },(err)=>{});
159 |
160 | }
161 |
162 |
163 | @override
164 | Widget build(BuildContext context) {
165 |
166 | Widget _error(BuildContext context, String url, Object error) {
167 | // print(error);
168 | return new Center(
169 | child: Icon(Icons.error,color: Colors.white),
170 | );
171 | }
172 |
173 | Widget _loaderImg(BuildContext context, String url) {
174 | return new Center(
175 | child:Icon(Icons.image,size:88.0,color:Colors.grey,),
176 | );
177 | }
178 |
179 | //推荐
180 | Widget topMV = Column(
181 | crossAxisAlignment: CrossAxisAlignment.stretch,
182 | children: [
183 | FixedSizeText('精选MV',textAlign:TextAlign.left,style:TextStyle(fontSize:16.0, fontWeight:FontWeight.bold)),
184 | GridView.count(
185 | primary: false,
186 | padding: EdgeInsets.fromLTRB(0.0,10.0,0.0,0.0),
187 | crossAxisSpacing: 10,
188 | mainAxisSpacing: 10,
189 | childAspectRatio: 1.25,
190 | crossAxisCount: 2,
191 | shrinkWrap: true,
192 | children: topList.map((item){
193 | return InkWell(
194 | onTap:()=>{
195 | Router.fadeNavigator(context,"/videopage",{'vid':item['id'],'type':0, 'from':'/video'},(res){
196 | SYS.systemUI(Colors.transparent,Colors.black,Brightness.dark);
197 | })
198 | },
199 | child: Column(
200 | crossAxisAlignment: CrossAxisAlignment.start,
201 | children: [
202 | ClipRRect(
203 | borderRadius: BorderRadius.circular(5),
204 | child: Stack(
205 | children: [
206 | new CachedNetworkImage(
207 | placeholder: _loaderImg,
208 | errorWidget: _error,
209 | imageUrl:item['picUrl'],//item['playlist']['coverImgUrl'],
210 | fit: BoxFit.cover,
211 | ),
212 | Positioned(
213 | right:3.0,
214 | top:3.0,
215 | child:Row(
216 | children: [
217 | Icon(Icons.play_arrow,color:Colors.white,size:10.0,),
218 | FixedSizeText(tranNumber(item['playCount']),style:TextStyle(color:Colors.white,fontSize:10.0))
219 | ],
220 | ),
221 | )
222 | ],
223 | )
224 | ),
225 | Container(
226 | padding:EdgeInsets.fromLTRB(0.0, 3.0, 0.0, 0.0),
227 | child: FixedSizeText(item['name'],
228 | maxLines:1,
229 | overflow: TextOverflow.ellipsis,
230 | style:TextStyle(fontSize:13.0)),
231 | ),
232 |
233 | FixedSizeText(item['artistName'],
234 | maxLines:1,
235 | overflow: TextOverflow.ellipsis,
236 | style:TextStyle(fontSize:11.0,color:Colors.grey))
237 | ],
238 | )
239 | );
240 |
241 | }).toList()
242 | ),
243 |
244 | ],
245 | );
246 |
247 | //视频片段
248 | Widget mvList(List mvdata){
249 |
250 | return ListView.builder(
251 | itemCount: mvdata.length,
252 | shrinkWrap: true,
253 | primary:false,
254 | padding:EdgeInsets.all(0.0),
255 | itemBuilder: (context, i) => Container(
256 | color:Colors.white,
257 | width:double.infinity,
258 | padding:EdgeInsets.fromLTRB(15.0, 8.0, 15.0, 8.0),
259 | margin:EdgeInsets.fromLTRB(0.0, 0.0, 0.0, 10.0),
260 | child: Column(
261 | crossAxisAlignment: CrossAxisAlignment.start,
262 | children: [
263 | ClipRRect(
264 | borderRadius: BorderRadius.circular(5),
265 | child: new Stack(
266 | alignment:Alignment.center,
267 | children: [
268 | Container(
269 | width:double.infinity,
270 | color:Colors.black,
271 | height:185.0,
272 | child:mvdata[i]['vurl']==null||mvdata[i]['vurl']==1?new CachedNetworkImage(
273 | imageUrl:mvdata[i]['cover']!=null?mvdata[i]['cover']:"http://p1.music.126.net/l6zOREIvWGNk3L67EkffRw==/1401877337913197.jpg",//item['picUrl'],
274 | fit: BoxFit.cover,
275 | ):SimpleViewPlayer(mvdata[i]['vurl'], isFullScreen: false),
276 | ),
277 | mvdata[i]['vurl']==null||mvdata[i]['vurl']==1?Positioned(
278 | bottom:3.0,
279 | left:3.0,
280 | child:Row(
281 | children: [
282 | Icon(Icons.play_arrow,color:Colors.white,size:13.0,),
283 | FixedSizeText(tranNumber(mvdata[i]['playCount']),style:TextStyle(color:Colors.white,fontSize:12.0))
284 | ],
285 | ),
286 | ):Container(),
287 | mvdata[i]['vurl']==null||mvdata[i]['vurl']==1?Positioned(
288 | bottom:3.0,
289 | right:3.0,
290 | child:Row(
291 | children: [
292 | Icon(Icons.graphic_eq,color:Colors.white,size:13.0,),
293 | FixedSizeText(formatDuration(mvdata[i]['duration']),style:TextStyle(color:Colors.white,fontSize:12.0))
294 | ],
295 | ),
296 | ):Container(),
297 | mvdata[i]['vurl']==1?CircularProgressIndicator(backgroundColor:Colors.redAccent):mvdata[i]['vurl']==null?Positioned(
298 | child:InkWell(
299 | onTap:(){
300 | midPlayer(mvdata[i]['id']);
301 | },
302 | child:Icon(Icons.play_arrow,color:Colors.white70,size:45.0,),
303 | ),
304 | ):Container()
305 | ],
306 | )
307 | ),
308 | Material(
309 | color:Colors.white,
310 | child:InkWell(
311 | highlightColor:Colors.transparent,
312 | onTap:(){
313 | setState(() {
314 | mvdata[i]['vurl']=null;
315 | });
316 | Router.fadeNavigator(context,"/videopage",{'vid':mvdata[i]['id'],'type':0, 'from':'/video'},(res){
317 | SYS.systemUI(Colors.transparent,Colors.black,Brightness.dark);
318 | });
319 | },
320 | child:Padding(
321 | padding:EdgeInsets.only(top:10.0,bottom:10.0),
322 | child: Row(
323 | crossAxisAlignment: CrossAxisAlignment.center,
324 | mainAxisAlignment:MainAxisAlignment.spaceBetween,
325 | children: [
326 | Expanded(
327 | flex:7,
328 | child:Container(
329 | margin:EdgeInsets.fromLTRB(0.0,5.0,0.0,5.0),
330 | width:Adapt.screenW(),
331 | child:FixedSizeText(mvdata[i]['name']+'---'+mvdata[i]['artistName'],
332 | maxLines:2,
333 | overflow: TextOverflow.ellipsis,
334 | style:TextStyle(fontSize:14.0,height:1.2))),
335 | ),
336 | Icon(Icons.send,color:Colors.grey,size:15.0,)
337 | ],
338 | ),
339 | ),
340 |
341 | )
342 | )
343 |
344 | ],
345 | ),
346 | )
347 | );
348 |
349 | }
350 |
351 | //全部
352 | Widget allMV = Column(
353 | crossAxisAlignment: CrossAxisAlignment.stretch,
354 | children: [
355 | Container(
356 | color:Colors.white,
357 | padding:EdgeInsets.fromLTRB(15.0, 10.0, 15.0, 2.0),
358 | child: Row(
359 | mainAxisAlignment:MainAxisAlignment.spaceBetween,
360 | children: [
361 | FixedSizeText('全部',textAlign:TextAlign.left,style:TextStyle(fontSize:16.0, fontWeight:FontWeight.bold)),
362 |
363 | ],
364 | ),
365 | ),
366 | mvList(allList)
367 |
368 | ],
369 | );
370 |
371 | return Material(
372 |
373 | child:loadState!=1?Center(child:loadState==0?Loading(indicator: LineScalePulseOutIndicator(), size: 50.0):Icon(Icons.cloud_off,size:40.0,)):RefreshIndicator(
374 | key: _refreshIndicatorKey,
375 | onRefresh: _flashData, // onRefresh 参数是一个 Future 的回调
376 | child: ListView(
377 | controller: _scrollController,
378 | // primary: true,
379 | physics: const BouncingScrollPhysics(),
380 | padding:const EdgeInsets.fromLTRB(0.0,0.0,0.0,60.0),
381 | children: [
382 | Container(
383 | color:Colors.white,
384 | // margin:EdgeInsets.fromLTRB(0.0, 10.0, 0.0, 0.0),
385 | padding:EdgeInsets.fromLTRB(15.0, 8.0, 15.0, 8.0),
386 | child: topMV,
387 | ),
388 | Container(
389 | margin:EdgeInsets.fromLTRB(0.0, 10.0, 0.0, 0.0),
390 | padding:EdgeInsets.fromLTRB(0.0, 8.0, 0.0, 8.0),
391 | child: allMV,
392 | ),
393 | Visibility(
394 | child: Row(
395 | mainAxisAlignment: MainAxisAlignment.center,
396 | children: [
397 | loadMore["hasMore"]?Container(
398 | width:15.0,
399 | height:15.0,
400 | margin:EdgeInsets.all(5.0),
401 | child:Loading(indicator: LineScalePulseOutIndicator(), size: 100.0),
402 | ):Container(),
403 | FixedSizeText(loadMore["Text"],textAlign:TextAlign.center,style:TextStyle(height:1,fontSize:12.0))
404 | ],
405 | ),
406 | visible: loadMore["isScrollBottom"],
407 | )
408 | ],
409 | ),
410 | )
411 |
412 |
413 | );
414 | }
415 |
416 | @override
417 | void dispose() {
418 | _scrollController.dispose();
419 | super.dispose();
420 | }
421 | }
--------------------------------------------------------------------------------
/lib/conf/api.dart:
--------------------------------------------------------------------------------
1 | /*数据接口*/
2 | import 'package:dio/dio.dart';
3 | import 'dart:convert';
4 | import 'dart:async';
5 |
6 |
7 |
8 | // Set default configs
9 | // or new Dio with a BaseOptions instance.
10 | BaseOptions options = new BaseOptions(
11 | baseUrl: "https://musicapi.nullno.com",
12 | connectTimeout: 5000,
13 | receiveTimeout: 3000,
14 | );
15 |
16 | Dio dio = new Dio(options); // with default Options
17 |
18 |
19 |
20 |
21 | //搜索
22 | void search(parameters,resolve,[reject]) async {
23 | try {
24 | Response response = await dio.get("/search",queryParameters:{"keywords":parameters['keywords'],"limit": 20,"offset":parameters['offset'],"type":parameters["type"]});
25 | resolve(jsonDecode(response.toString()));
26 | } catch (e) {
27 | reject(e);
28 | }
29 | }
30 | //搜索建议
31 | void searchSuggest(parameters,resolve,[reject]) async {
32 | try {
33 | Response response = await dio.get("/search/suggest",queryParameters:{"keywords":parameters['keywords'],"type":"mobile"});
34 | resolve(jsonDecode(response.toString()));
35 | } catch (e) {
36 | reject(e);
37 | }
38 | }
39 |
40 | //热搜榜
41 | void searchHot(resolve,[reject]) async {
42 | try {
43 | Response response = await dio.get("/search/hot/detail",);
44 | resolve(jsonDecode(response.toString()));
45 | } catch (e) {
46 | reject(e);
47 | }
48 | }
49 |
50 |
51 | //歌曲排行榜
52 | void getRank(resolve,[reject]) async {
53 | try {
54 | List response = await Future.wait([
55 | dio.get("/playlist/detail",queryParameters:{"id":"4395559"}),
56 | dio.get("/playlist/detail",queryParameters:{"id":"2617766278"}),
57 | dio.get("/playlist/detail",queryParameters:{"id":"3779629"}),
58 | dio.get("/playlist/detail",queryParameters:{"id":"3778678"}),
59 | // dio.get("/playlist/detail",queryParameters:{"id":"1978921795"}),
60 | // dio.get("/playlist/detail",queryParameters:{"id":"19723756"}),
61 | dio.get("/playlist/detail",queryParameters:{"id":"2884035"}),
62 | dio.get("/playlist/detail",queryParameters:{"id":"2250011882"})
63 | ]);
64 | resolve(jsonDecode(response.toString()));
65 | } catch (e) {
66 | reject(e);
67 | }
68 | }
69 |
70 |
71 | //banner
72 | void getBanner(resolve,reject) async {
73 | try {
74 | Response response = await dio.get("/banner",queryParameters:{"types": "1",});
75 | resolve(jsonDecode(response.toString()));
76 | } catch (e) {
77 | reject(e);
78 | }
79 | }
80 |
81 | //获取推荐歌单
82 | void getPersonalizedSongList(resolve,[reject]) async {
83 | try {
84 | Response response = await dio.get("/personalized",queryParameters:{"limit": 20});
85 | resolve(jsonDecode(response.toString()));
86 | } catch (e) {
87 | reject(e);
88 | }
89 | }
90 | void homeGet(resolve,[reject]) async{
91 | try{
92 | List response = await Future.wait([
93 | dio.get("/banner",queryParameters:{"types": "1",}),
94 | dio.get("/personalized",queryParameters:{"limit": 20})
95 | ]);
96 | resolve(jsonDecode(response.toString()));
97 | }catch(e){
98 |
99 | }
100 |
101 | }
102 |
103 |
104 | //精品歌单(歌单广场)
105 | void getHighqualitySongList(parameters,resolve,[reject]) async {
106 | try {
107 | Response response = await dio.get("/top/playlist/highquality",queryParameters:{"limit": 8,"before":parameters['before'],"cat":parameters["cat"]});
108 | resolve(jsonDecode(response.toString()));
109 | } catch (e) {
110 | reject(e);
111 | }
112 | }
113 |
114 | //获取歌单详情
115 | void getSongMenuDetail(parameters,resolve,[reject]) async {
116 | try {
117 | Response response = await dio.get("/playlist/detail",queryParameters:{"id":parameters["id"]});
118 | resolve(jsonDecode(response.toString()));
119 | } catch (e) {
120 | reject(e);
121 | }
122 | }
123 |
124 | //获取推荐mv
125 | void getPersonalizedMV(resolve,[reject]) async {
126 | try {
127 | Response response = await dio.get("/personalized/mv");
128 | resolve(jsonDecode(response.toString()));
129 | } catch (e) {
130 | reject(e);
131 | }
132 | }
133 | //获取全部mv
134 | void getAllMV(parameters,resolve,[reject]) async {
135 | try {
136 | Response response = await dio.get("/mv/all",queryParameters:{"area":parameters['area'],"limit": 8,"offset":parameters['offset']});
137 | resolve(jsonDecode(response.toString()));
138 | } catch (e) {
139 | reject(e);
140 | }
141 | }
142 |
143 |
144 | //获取mv视频播放数据
145 | void getMVDetail(mvId,resolve,[reject]) async {
146 | try {
147 | Response response = await dio.get("/mv/detail",queryParameters:{"mvid":mvId});
148 | resolve(jsonDecode(response.toString()));
149 | } catch (e) {
150 | reject(e);
151 | }
152 | }
153 |
154 | //获取视频详情
155 | void getVideoDetail(vid,resolve,[reject]) async {
156 | try {
157 | Response response = await dio.get("/video/detail",queryParameters:{"id":vid});
158 | resolve(jsonDecode(response.toString()));
159 | } catch (e) {
160 | reject(e);
161 | }
162 | }
163 |
164 | //获取视频播放数据
165 |
166 | void getVideoUrl(vid,resolve,[reject]) async {
167 | try {
168 | Response response = await dio.get("/video/url",queryParameters:{"id":vid});
169 | resolve(jsonDecode(response.toString()));
170 | } catch (e) {
171 | reject(e);
172 | }
173 | }
174 |
175 | //获取mv评论
176 | void getMvComment(vid,resolve,[reject]) async {
177 |
178 | try {
179 | Response response = await dio.get("/comment/mv",queryParameters:{"id":vid});
180 | resolve(jsonDecode(response.toString()));
181 | } catch (e) {
182 | reject(e);
183 | }
184 | }
185 |
186 | //获取视频评论
187 | void getVideoComment(parameters,resolve,[reject]) async {
188 |
189 | try {
190 | var path = parameters['type']==0?"/comment/mv":"/comment/video";
191 | Response response = await dio.get(path,queryParameters:{"id":parameters['vid'],"limit":20,"offset":parameters['offset'],"before":parameters['before']});
192 | resolve(jsonDecode(response.toString()));
193 | } catch (e) {
194 | reject(e);
195 | }
196 | }
197 |
198 | //获取歌曲详情
199 | void getSongDetail(ids,resolve,[reject]) async {
200 | try {
201 | Response response = await dio.get("/song/detail",queryParameters:{"ids":ids});
202 | resolve(jsonDecode(response.toString()));
203 | } catch (e) {
204 | reject(e);
205 | }
206 | }
207 |
208 | //获取歌曲播放链接
209 | void getSongUrl(id,resolve,[reject]) async {
210 | try {
211 | Response response = await dio.get("/song/url",queryParameters:{"id":id});
212 | resolve(jsonDecode(response.toString()));
213 | } catch (e) {
214 | reject(e);
215 | }
216 | }
--------------------------------------------------------------------------------
/lib/conf/appsate.dart:
--------------------------------------------------------------------------------
1 |
2 | import 'package:audioplayers/audioplayers.dart';
3 | /// 应用程序状态
4 |
5 | class AppState{
6 |
7 | //音乐控制
8 | static Map player ={
9 | "id":0,
10 | "url":'未知',
11 | "face":'https://p1.music.126.net/N2whh2Prf0l8QHmCpShrcQ==/19140298416347251.jpg',
12 | "name":'未知',
13 | "singer":'未知',
14 | "duration":null,
15 | "position":null,
16 | "loop":true,
17 | "playStatus":false,
18 | "audioPlayer":new AudioPlayer(),
19 | "play":(url,[callback]) async{
20 | int result = await AppState.player['audioPlayer'].play(url.replaceAll('http:', 'https:'));
21 | if(result==1) {
22 | if(callback)callback();
23 | }
24 | },
25 | "pause":([callback]) async{
26 | int result = await AppState.player['audioPlayer'].pause();
27 | if(result==1) {
28 | if(callback)callback();
29 | }
30 | }
31 | };
32 |
33 |
34 | }
35 |
36 |
37 |
--------------------------------------------------------------------------------
/lib/conf/platform.dart:
--------------------------------------------------------------------------------
1 | /*
2 | 系统平台设置
3 | */
4 | import 'package:flutter/services.dart';
5 | import 'dart:io';
6 |
7 | class SYS {
8 | static systemUI(statusBarColor,navColor,brightcolor){
9 | if (Platform.isAndroid) {
10 | // 以下两行 设置android状态栏为透明的沉浸。写在组件渲染之后,是为了在渲染后进行set赋值,覆盖状态栏,写在渲染之前MaterialApp组件会覆盖掉这个值。
11 | SystemChrome.setEnabledSystemUIOverlays([SystemUiOverlay.top,SystemUiOverlay.bottom]);
12 | SystemUiOverlayStyle systemUiOverlayStyle = SystemUiOverlayStyle(statusBarColor:statusBarColor,
13 | systemNavigationBarIconBrightness: Brightness.dark,
14 | systemNavigationBarColor:statusBarColor,
15 | statusBarIconBrightness:brightcolor,
16 | // statusBarBrightness:brightcolor,
17 | );
18 | SystemChrome.setSystemUIOverlayStyle(systemUiOverlayStyle);
19 | }
20 | }
21 | static hideBar(){
22 | SystemChrome.setEnabledSystemUIOverlays([]);
23 | }
24 | static hideTopBar(){
25 | SystemChrome.setEnabledSystemUIOverlays([SystemUiOverlay.bottom]);
26 | }
27 | static showBar(){
28 | SystemChrome.setEnabledSystemUIOverlays([SystemUiOverlay.top, SystemUiOverlay.bottom]);
29 | }
30 |
31 |
32 | }
33 |
--------------------------------------------------------------------------------
/lib/conf/router.dart:
--------------------------------------------------------------------------------
1 | /*
2 | 路由信息配置
3 | */
4 | import 'package:flutter/material.dart';
5 | import 'package:flutter_vmusic/utils/custom.dart';
6 |
7 | import 'package:flutter_vmusic/pages/landing_page.dart';
8 | import 'package:flutter_vmusic/pages/home_page.dart';
9 |
10 | import 'package:flutter_vmusic/pages/song_menu_page.dart';
11 | import 'package:flutter_vmusic/pages/song_mlist_page.dart';
12 | import 'package:flutter_vmusic/pages/search_page.dart';
13 | import 'package:flutter_vmusic/pages/video_detail_page.dart';
14 | import 'package:flutter_vmusic/pages/player_page.dart';
15 |
16 |
17 | class Router{
18 | //初始化路由
19 | static String initialRoute ='/launch';
20 | //命名路由(静态路由)
21 | static Map routes={
22 | '/launch':(BuildContext context) => LandingPage(),
23 | '/home':(BuildContext context) => HomePage(),
24 | };
25 | //自定义路由跳转
26 |
27 | static fadeNavigator(BuildContext context,String routeName,Map params,pop){
28 | Widget pageWidget;
29 | switch(routeName){
30 | case'/launch':
31 | pageWidget=LandingPage();
32 | break;
33 | case'/home':
34 | pageWidget=HomePage(params:params);
35 | break;
36 | case'/songmenu':
37 | pageWidget=SongMenu(params:params);
38 | break;
39 | case'/songmenulist':
40 | pageWidget=SongMenuList(params:params);
41 | break;
42 | case'/searchpage':
43 | pageWidget=SearchPage(params:params);
44 | break;
45 | case'/videopage':
46 | pageWidget=VideoPage(params:params);
47 | break;
48 | case'/playerpage':
49 | pageWidget=PlayerPage(params:params);
50 |
51 |
52 | }
53 | if(pageWidget!=null){
54 | if(params['from']=='/launch'){
55 | Navigator.pushAndRemoveUntil(context, FadeRoute(page: pageWidget),(route) => route == null).then((Object result) {
56 | pop(result);
57 | });
58 | }else{
59 | Navigator.push(context, MaterialPageRoute(builder: (context) {
60 | return pageWidget;
61 | })).then((Object result) {
62 | pop(result);
63 | });
64 | }
65 | }else{
66 | Navigator.of(context).pushNamed(routeName).then((Object result) {
67 | pop(result);
68 | });
69 | }
70 |
71 | // Navigator.push(context, EnterExitRoute(exitPage: LandingPage(), enterPage: HomePage()));
72 | }
73 |
74 | static goHome(BuildContext context,Map params,pop){
75 |
76 | Navigator.pushAndRemoveUntil(context, EnterExitRoute(exitPage:LandingPage(),enterPage:HomePage(params:params)),(route) => route == null).then((Object result) {
77 | pop(result);
78 | });
79 |
80 | }
81 |
82 |
83 | }
84 |
85 |
86 |
--------------------------------------------------------------------------------
/lib/main.dart:
--------------------------------------------------------------------------------
1 | import 'package:flutter/material.dart';
2 | import 'package:flutter_vmusic/conf/router.dart';
3 | import 'package:flutter_vmusic/pages/landing_page.dart';
4 |
5 |
6 |
7 | void main(){
8 | runApp(MyApp());
9 | }
10 |
11 |
12 | class MyApp extends StatelessWidget {
13 |
14 | @override
15 | Widget build(BuildContext context) {
16 | return MaterialApp(
17 | debugShowCheckedModeBanner: false,
18 | title:'vmusic',
19 | theme: new ThemeData(
20 | primaryColor: Colors.white,
21 | accentColor: Colors.black45,
22 | accentColorBrightness: Brightness.light,
23 | ),
24 | home: LandingPage(),
25 | color:Colors.white,
26 | routes: Router.routes,
27 | initialRoute: Router.initialRoute,
28 | );
29 | }
30 | }
--------------------------------------------------------------------------------
/lib/pages/home_page.dart:
--------------------------------------------------------------------------------
1 | import 'package:flutter/material.dart';
2 | //import 'dart:ui';
3 | import 'package:flutter_vmusic/components/playPanel.dart';
4 | import 'package:flutter_vmusic/components/exitApp.dart';
5 | //三大模块
6 | import 'package:flutter_vmusic/components/find.dart';
7 | //import 'package:flutter_vmusic/components/my.dart';
8 | import 'package:flutter_vmusic/components/video.dart';
9 |
10 | import 'package:flutter_vmusic/conf/platform.dart';
11 | import 'package:flutter_vmusic/conf/router.dart';
12 |
13 |
14 | class HomePage extends StatefulWidget{
15 | final Map params;
16 | HomePage({
17 | Key key,
18 | this.params,
19 | }) : super(key: key);
20 | @override
21 | _HomePage createState() => _HomePage();
22 | }
23 |
24 | class _HomePage extends State with SingleTickerProviderStateMixin{
25 |
26 | //主页退出app确认
27 | Future _onWillPop()=>exitApp(context);
28 | //自定义打开Drawer
29 | final GlobalKey _scaffoldKey = GlobalKey();
30 | //滑动切配置(自定义TabBar和TabBarView联动)
31 | TabController controller;//tab控制器
32 | int _currentIndex = 0; //选中下标
33 |
34 |
35 |
36 | List