胖葵音乐(Android项目实战 云音乐app)

胖葵音乐(Android 云音乐app)

运行效果

登录注册:

在这里插入图片描述

打开专辑,播放音乐,暂停播放,切换音乐

在这里插入图片描述

通知栏,通知栏进入app

在这里插入图片描述

修改密码

在这里插入图片描述

退出登录

在这里插入图片描述

开发工具

Android Studio 4.1.0

AndroidUtilCode主工具类模块:utilcode

glideTranformtions框架:CircleImageView

Realm数据库

项目整体框架说明

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-XCzEduMY-1606146468648)(C:\Users\15631\AppData\Roaming\Typora\typora-user-images\image-20201123111309490.png)]

各个文件说明

这里简要概括,具体在代码里有注释说明
在这里插入图片描述
assets
1、资源文件

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-WdLNxcWm-1606146157597)(C:\Users\15631\AppData\Roaming\Typora\typora-user-images\image-20201123112138362.png)]

activity

1、专辑列表

2、基础通用部分,可供其他activity继承,避免重复啰嗦

3、修改密码界面

4、登录界面

5、主界面

6、个人中心页面

7、音乐播放页面

8、注册界面

9、欢迎界面

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-3zOBkGf8-1606146157598)(C:\Users\15631\AppData\Roaming\Typora\typora-user-images\image-20201123112148838.png)]

adapter

1、音乐专辑适配器

2、音乐列表适配器

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-KfH0irZ4-1606146157599)(C:\Users\15631\AppData\Roaming\Typora\typora-user-images\image-20201123112156549.png)]

constants

1、SharedPreferences常量

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-KEelM5vE-1606146157600)(C:\Users\15631\AppData\Roaming\Typora\typora-user-images\image-20201123112204094.png)]

helps

1、音乐播放器相关方法

2、Realm数据库相关方法

3、用户相关方法

在这里插入图片描述

migration

1、数据迁移

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-08KIixn8-1606146157601)(C:\Users\15631\AppData\Roaming\Typora\typora-user-images\image-20201123112211687.png)]

models

1、专辑模型

2、音乐模型

3、音乐资源模型

4、用户模型

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-6OJMgl4V-1606146157603)(C:\Users\15631\AppData\Roaming\Typora\typora-user-images\image-20201123112234463.png)]

services

1、音乐服务

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-MiTpYX89-1606146157603)(C:\Users\15631\AppData\Roaming\Typora\typora-user-images\image-20201123112243658.png)]

utils

1、资源数据读取

2、SharedPreference用户标记

3、用户功能

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-pGuyXgRa-1606146157604)(C:\Users\15631\AppData\Roaming\Typora\typora-user-images\image-20201123112250691.png)]

views

1、专辑间距离

2、输入框基本形式

3、音乐播放视图(含光盘、指针动画)

4、设置图片宽高相等

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-5G4Pz1v9-1606146157606)(C:\Users\15631\AppData\Roaming\Typora\typora-user-images\image-20201123112313653.png)]

myapplication

1、完成一些依赖工具的初始化

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-UHZ9slLI-1606146157607)(C:\Users\15631\AppData\Roaming\Typora\typora-user-images\image-20201123112406483.png)]

anim

1、2、3、4、页面切换动画

5、光盘旋转动画

6、7、光盘指针动画

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-j9FJbFde-1606146157607)(C:\Users\15631\AppData\Roaming\Typora\typora-user-images\image-20201123112416275.png)]

drawable

1、2、3、按钮点击高亮显示

4、5、8、文本点击高亮显示

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-jLHpeDUI-1606146157608)(C:\Users\15631\AppData\Roaming\Typora\typora-user-images\image-20201123112427351.png)]

layout

1、专辑列表

2、修改密码

3、登录

4、主页面

5、个人中心

6、音乐播放页基础布局

7、注册

8、欢迎

9、输入框

10、专辑基础布局

11、音乐基础布局

12、顶部导航栏

13、音乐播放页面动画布局

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-L51F5p0a-1606146157609)(C:\Users\15631\AppData\Roaming\Typora\typora-user-images\image-20201123112436407.png)]

values

1、输入框样式

3、尺寸

4、常数

一些总结

下面总结一些项目中用到的比较重要的点,其他的请大家结合代码注释看吧。

AndroidUtilCode工具类

我们这里调用方法来判断手机号是否有效,使用如下:

if(!RegexUtils.isMobileExact(phone)){
    Toast.makeText(context, "手机号无效", Toast.LENGTH_SHORT).show();

}

任务和返回栈(Task栈)

任务是指在执行特定作业时与用户交互的一系列 Activity。 这些 Activity 按照各自的打开顺序排列在堆栈(即返回栈)中。一般情况下我们可以认为一个应用就是一个任务,并且这个应用启动的所有Activity会按照打开的顺序放入堆栈中即是这个任务对应的返回栈。

默认情况下,一个应用对应一个任务对应一个返回栈。如果应用之前没有被启动过,点击主屏幕应用启动器中的图标的时候会生成一个全新的任务,并且该应用的“主”Activity 将作为任务返回栈中的根 Activity 打开,之后依次打开的Activity会按照打开的顺序压入返回栈中。当按”BACK”键返回时,这些压入返回栈中的Activity会按照“后进先出”的原则依次出栈,恢复回退栈中前一个 Activity 的执行。

由此可知,当我们要实现退出登录的功能时,如果只是单纯的跳转到登录界面,那么当用户点返回键时,就会再回到个人中心页面。显然这是不合逻辑的,我们需要用户退出登陆后回到登录页面,并且点返回键会直接退出app。这就需要用到intent标志符。

Intent.FLAG_ACTIVITY_CLEAR_TASK 清除当前TASK栈中的Activity

Intent.FLAG_ACTIVITY_NEW_TASK 新建一个TASK栈

这样处理之后,栈中就只剩下我们新打开的登录页面一个Activity,这时候再按返回键就会直接退出app了。

实现如下:

Intent intent = new Intent(context, LoginActivity.class);
//添加 intent标识符,清理 task栈,并且新生成一个 task栈
intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TASK | Intent.FLAG_ACTIVITY_NEW_TASK);
context.startActivity(intent);

recyclerview及其分割线

https://blog.csdn.net/lmj623565791/article/details/45059587

LayoutInflater

在实际开发中LayoutInflater这个类还是非常有用的,它的作用类似于findViewById()。不同点是LayoutInflater是用来找res/layout/下的xml布局文件,并且实例化;而findViewById()是找xml布局文件下的具体widget控件(如Button、TextView等)。

具体作用:

1、对于一个没有被载入或者想要动态载入的界面,都需要使用LayoutInflater.inflate()来载入;

2、对于一个已经载入的界面,就可以使用Activiyt.findViewById()方法来获得其中的界面元素。

LayoutInflater 是一个抽象类,在文档中如下声明:

public abstract class LayoutInflater extends Object

获得 LayoutInflater 实例的三种方式

  1. LayoutInflater inflater = getLayoutInflater();//调用Activity的getLayoutInflater()

  2. LayoutInflater inflater = LayoutInflater.from(context);

  3. LayoutInflater inflater = (LayoutInflater)context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);

更多内容请看:https://www.cnblogs.com/top5/archive/2012/05/04/2482328.html

onMeasure

View在屏幕上显示出来要先经过measure(计算)和layout(布局)

当控件的父元素正要放置该控件时调用.父元素会问子控件一个问题,“你想要用多大地方啊?”,然后传入两个参数——widthMeasureSpec和heightMeasureSpec.
这两个参数指明控件可获得的空间以及关于这个空间描述的元数据.
更好的方法是你传递View的高度和宽度到setMeasuredDimension方法里,这样可以直接告诉父控件,需要多大地方放置子控件.

更多内容请看:http://blog.sina.com.cn/s/blog_61fbf8d10100zzoy.html

glideTranformtions框架

加载网络图片,用法如下:
  /**
    * 加载网络图片
    * 基本形式 先with(),再load(),最后into()
    */
    mImage = (ImageView)findViewById(R.id.image);
    Glide.with(this)
        .load("https://s0.52poke.wiki/wiki/thumb/4/4f/120Staryu.png/300px-120Staryu.png")
        .into(mImage);
CircleImageView

圆角 ImageView,用于显示光盘圆图

更多内容请看:https://www.cnblogs.com/WUXIAOCHANG/p/10667210.html

interpolator

Interpolator负责控制动画变化的速率,使得基本的动画效果能够以匀速、加速、减速、抛物线速率等各种速率变化。
动画是开发者给定开始和结束的“关键帧”,其变化的“中间帧”是有系统计算决定然后播放出来。因此,动画的每一帧都将在开始和结束之间的特定时间显示。此时动画时间被转换为时间索引,则动画时间轴上的每个点都可以转换成0.0到1.0之间的一个浮点数。然后再将该值用于计算该对象的属性变换。在变换的情况下,y轴上,0.0对应于起始位置,1.0对应于结束位置,0.5对应于起始和结束之间的中间,对于一些插值器其值还可以是0~1之外的数值。

MediaPlayer

Android的MediaPlayer包含了Audio和Video的播放功能,在Android的界面上,Music和Video两个应用程序都是调用MediaPlaer来实现的。

更多内容请看:https://www.cnblogs.com/senior-engineer/p/7867626.html

Realm数据库

Realm数据库是一个非常轻量级的数据库,相比于sqlite,它的存储速度更快。

Realm数据库通过将Java对象直接保存到磁盘作为对象,而不是首先将它们映射到其他数据类型(如SQLite)来工作。在Realm数据库的中心,这个叫Realm的东西,这相当于一个传统的数据库。Realm可以将不同类型的对象映射到磁盘上的一个文件。另一种查看方式是,Realm是不需要从Java对象到磁盘上持久版本的单独映射的数据库。

它是一种像你所看到的是什么保存的工作流程 - 如果对象是Realm管理对象,则用户界面中对象的更改将自动保存到数据库。Realm管理的对象与SQLite表相当。要使Java对象成为Realm管理,该类必须扩展RealmObject或实现RealmModel接口。

更多内容请看:https://blog.csdn.net/jxq1994/article/details/75670295

MD5加密

在网络中传输明文是一件非常危险的事情,所以通常将密码加密后传至服务器,由服务器保存密文在登录判定时只需比较密文是否相同即可。

MD5加密是一种常用的加密算法,全称为“Message-Digest Algorithm 5”,即消息摘要算法,由MD2、MD3、MD4演变过来的,是一种单向加密算法,是一种不可逆的加密方式。

MD5优点:

  • 压缩性:任意长度的数据,算出的MD5值长度都是固定的。
  • 容易计算:从原数据计算出MD5值很容易。
  • 抗修改性:对原数据进行任何改动,所得到的MD5值都有很大区别。
  • 强抗碰撞:已知原数据和其MD5值,想找到一个相同MD5值得数据是非常困难的。

我们引入Realm数据库,进行MD5加密实现如下:

RealmHelp realmHelp = new RealmHelp();
boolean result = realmHelp.validataUser(phone,EncryptUtils.encryptMD5ToString(password));

我们查看数据库内容,可以看到存储的加密密码如下:

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-po2Qre53-1606146157609)(C:\Users\15631\AppData\Roaming\Typora\typora-user-images\image-20201123210643776.png)]

SharedPreferences

SharedPreferences是Android平台上一个轻量级的存储类,用来保存应用的一些常用配置,比如Activity状态,Activity暂停时,将此activity的状态保存到SharedPereferences中;当Activity重载,系统回调方法onSaveInstanceState时,再从SharedPreferences中将值取出。
其中的原理是通过Android系统生成一个xml文件保到:/data/data/包名/shared_prefs目录下,类似键值对的方式来存储数据。
Sharedpreferences提供了常规的数据类型保存接口比如:int、long、boolean、String、Float、Set和Map这些数据类型。

我们的应用如下:

1、用户登录

(1)新账号第一次登录时,利用SharedPreferences保存登录用户的用户标记(在这里就是手机号)

​ (2)用全局单例类UserHelp保存登录用户信息

​ <1>用户登录之后

​ <2>用户打开应用程序,检测SharedPreferences中是否存在登录用户标记,如果存在则给UserHelp赋值,并进入主页,否则进入登录页面

2、用户退出登录

删除SharedPreferences保存的用户标记,退出到登录页面

实现如下:

//保存用户登录标记
boolean isSaved = SharedPreferencesUtils.saveUser(context,phone);
//删除SP保存的用户标记
boolean isRemove = SharedPreferencesUtils.removeUser(context);
数据库迁移(升级)

使用Realm时,设定好model类,直接使用Realm.getDefaultInstance()就可以直接创建跟model类相对应的表格。但有时候需要更新表格或添加或减少表格,就要更新model类了。但直接更新model类是不行的,会报错,要进行migrate迁移操作才能成功更新图表。

实现如下:

/*
* Realm数据库发生结构性变化(模型或模型中的字段发生了增删改)时
* 需要对数据库进行数据迁移(升级)
*/
private static RealmConfiguration getRealmConf(){
    return new RealmConfiguration.Builder()
            .schemaVersion(1)
            .migration(new Migration())
            .build();
}

更多内容请看:https://blog.csdn.net/amberoot/article/details/94615346

完整项目链接

github:https://github.com/guyuanjunxi/PKmusic

csdn:https://download.csdn.net/download/qq_41117896/13181691

评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值