近几年由于国内对音乐版权的重视,有些歌曲在某一个音乐app上完全搜不到,所以手机上往往要下载比如QQ音乐、网易云音乐、酷狗音乐、咪咕音乐等诸多个app,对于和我一样有手机内存洁癖的人来说,实属忍无可忍。索性了解到Flutter 使用Dart语言可以做到跨平台(IOS、Android、Window、Web等)的应用的高效实现,所以自己动手实现一个集各大音乐平台于一体的音乐播放器 --- 《FreeMusic》喜欢的小伙伴可以下载使用,附上下载地址:蓝奏云下载地址。如果你对Dart + Flutter 还不是很了解,可以自行百度学习一下。 好了废话不多说,开启我们的音乐播放器之旅。
思维导图
该图只是截止到目前,后续还会有一些功能加进去。
项目初始化
首先要搭建自己的flutter环境,这里不做教程。然后选择目录,运行flutter create 命令。
等待命令执行完毕后,会看到如下结果,代表项目已经创建成功。此时运行flutter run 命令,即可在模拟器或者你的手机上看到刚刚创建的应用程序。(本文是建立在flutter环境,Android或者ios 环境已经搭建完毕之后的,如果flutte命令出现一些问题,可以私信我,或者百度搜索)
项目创建好之后,我们用vscode打开,然后删除一些自动生产的代码,其中主要是main.dart,替换为如下代码
import 'package:flutter/material.dart';
void main() => runApp(FreeMusicApp());
class FreeMusicApp extends StatefulWidget {
@override
State<StatefulWidget> createState() {
return FreeMusicState();
}
}
class FreeMusicState extends State<FreeMusicApp> {
@override
Widget build(BuildContext context) {
return MaterialApp(
debugShowCheckedModeBanner: false,
title: 'FreeMusic',
home: Scaffold(
body: Container(
child: Text("Hello FreeMusic"),
),
),
);
}
}
test文件夹下的文件是测试用的,对我们没有用处,也可以删除。接下来在lib文件夹下创建以下文件夹。
在与lib同级的目录下创建images,用于存放app中用到的图片。
添加插件
flutter 项目的插件是在项目根目录下的 pubspec.yaml 文件中统一管理的。在pubspec.yaml文件中的 dependencies 节点插入该app需要的依赖。保存后flutter可以自动拉取依赖。
fluttertoast: ^2.1.1 #消息提示框
flutter_flux: ^4.1.3 #状态管理,数据流
sqflite: ^1.1.7+1 #android本地数据库
shared_preferences: ^0.5.6 #本地存储数据,持久化
sticky_headers: "^0.1.8" #粘性头部
flutter_spinkit: "^4.1.0" #一个loading插件
audioplayers: ^0.13.5 #播放音乐的
package_info: ^0.4.0+13 #获取app信息的
url_launcher: ^5.4.1 #打开url
webview_flutter: ^0.3.18+1 #支持显示web页面
crypto: ^2.0.6 #加密
encrypt: ^4.0.0 #解密
dio: ^3.0.3 #网络请求
path_provider: ^1.4.0 #访问本机文件
marquee: ^1.3.1 #轮播
permission_handler: ^4.0.0 #手动获取权限
flutter_audio_query: ^0.3.2 #本地多媒体文件
添加图片引用
flutter 项目的静态图片引用比较麻烦,需要先在pubspec.yaml文件中的 assets 节点中声明,然后才能在代码中通过Image.assets()的方式访问到,因此,我们需要把项目要用到的图片引用添加到pubspec.yaml文件中
assets:
- images/more.png
- images/mobile.jpg
- images/netease.png
- images/nvhai.png
- images/qq.png
- images/favorite.png
- images/shoucang.png
- images/zuijin.png
- images/yun.png
…… 下面的省略
创建工具类
这里的工具类共有两个,Constant.dart -- APP中常用的常量,比如背景色之类的; SQFLite.dart -- app 需要创建的数据库和数据表
import 'package:flutter/material.dart';
class Constant {
static Color themeColor = Color.fromRGBO(216, 30, 6, 0.8);
static Color wordColor = Color.fromRGBO(96,96,96, 1);
static Color toolBarColor = Color.fromRGBO(96,96,96, 0.5);
static Color backgroundColor = Color.fromRGBO(240, 240, 240, 1);
}
import 'package:sqflite/sqflite.dart';
import 'package:path/path.dart';
class SQFLiteUtil {
static SQFLiteUtil _instance;
static Database _db;
SQFLiteUtil._();
static Future<SQFLiteUtil> get instance async {
return await getInstance();
}
static Future<SQFLiteUtil> getInstance() async {
if (_instance == null) {
_instance = SQFLiteUtil._();
}
if (_db == null) {
await _instance._initDB();
}
return _instance;
}
Future _initDB() async {
String dataBasePath = await getDatabasesPath();
String path = join(dataBasePath, "freemusic.db");
_db = await openDatabase(path, version: 1, onCreate: _onCreate);
}
void _onCreate(Database db, int newVersion) async {
await db.transaction((txn) async {
await txn.execute('''
CREATE TABLE IF NOT EXISTS `gedan` (
id INTEGER PRIMARY KEY AUTOINCREMENT,
gd_name TEXT,
picture TEXT,
description TEXT,
created TEXT
);
''');
await txn.execute('''
CREATE TABLE IF NOT EXISTS `song` (
id INTEGER PRIMARY KEY AUTOINCREMENT,
hash TEXT,
songid INTEGER,
albummid TEXT,
playUrl TEXT,
img TEXT,
timeLength INTEGER,
singerName TEXT,
songName TEXT,
type TEXT,
platform TEXT
);
''');
await txn.execute('''
CREATE TABLE IF NOT EXISTS `gedan_song` (
id INTEGER PRIMARY KEY AUTOINCREMENT,
gd_id INTEGER,
song_hash TEXT
);
''');
});
}
Database open() {
return _db;
}
}
至此,FreeMusic的初始化工作已经完成,相关代码已上传到码云上。
gitee: https://gitee.com/JTaoLee/FreeMusic/tree/fm-dev-one
写在最后
本篇文章是这一系列的第一篇文章,笔者会持续更新,请大家多多关注,如果你有疑问可以留言或私信我。