实现功能:
1:启动动画(运行程序出现一个2秒钟的视频),2秒钟后进入下一界面!
2:登录注册(账号和密码采用了MD5Utile加密),输入正确的账号和密码进入主界面(没有账号和密码可以进行注册),另外也可以勾选复选框记住密码,这样再次运行程序时就不需要再次输入或者注册帐号密码了(需要注意是由于密码采用MD5加密,所以密码栏里的密码会出现一大串黑点的掩饰字符)
3:轮播图,使用viewpager结合适配器做到了图片无线循环自动滚动(也可以自动鼠标左右滚动),可以实现轮播图的ontouch的点击功能,另外轮播图的每张照片下面配有对应的字符也会随着照片动态滚动变化,另外照片下方也会有数量(同轮播的照片数量)的圆点,显示哪张照片时,其位置对应的圆点就会变成显示红色!
4:音乐播放,歌曲使用listview排列,实现了音乐的暂停,播放,继续和上下歌曲的切换,另外再歌曲播放的页面也设计了唱盘(可以360°圆弧转动),也引入了seekbar进度条(会动态跟随音乐的进度而同步变化,也可以手动拖动进度条改变音乐进度)!
5:搜索实现,使用了Android原生的searchview,对listview列表的音乐进行一个简单的搜索展示!
6:视频专栏,刚才介绍的时音乐的fragment导栏,这个时视频fragment栏目,使用videoview简单对视频进行播放,该部分没有太对代码的亮点!
7:我的fragment,实现了对个人信息的设置,以及APP反馈(就是调用了Intent_Dial组件)来调用系统的电话程序,以及APP评分(就是可以对app进行打分(1-5分)),还有一些其他琐碎的东西!
8:程序的组件UI布局非常美观,尽可能做到外在与内在的统一,拿去做课程设计是非常不错的!
有需要Android设计代做的也可以私聊我!
接下来贴关键的部分代码:
启动动画:
package com.ypc.xiaoxiongmusic;
import androidx.appcompat.app.AppCompatActivity;
import android.content.Intent;
import android.net.Uri;
import android.os.Bundle;
import android.os.Handler;
import android.widget.VideoView;
public class MainActivity extends AppCompatActivity {
private final long SPLASH_LENGTH = 3000;
Handler handler = new Handler();
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
//时间控制处理
handler.postDelayed(new Runnable() { //使用handler的postDelayed实现延时跳转
public void run() {
Intent intent = new Intent(MainActivity.this, LoginActivity.class);
startActivity(intent);
finish();
}
}, SPLASH_LENGTH);//3秒后跳转至应用主界面MainActivity
}
}
登录实现:
package com.ypc.xiaoxiongmusic;
import android.content.DialogInterface;
import android.content.Intent;
import android.content.SharedPreferences;
import android.os.Bundle;
import android.preference.PreferenceManager;
import android.text.TextUtils;
import android.view.View.OnClickListener;
import android.view.View;
import android.widget.Button;
import android.widget.CheckBox;
import android.widget.EditText;
import android.widget.ProgressBar;
import android.widget.TextView;
import android.widget.Toast;
import androidx.appcompat.app.AlertDialog;
import androidx.appcompat.app.AppCompatActivity;
public class LoginActivity extends AppCompatActivity implements View.OnClickListener {
private EditText etAccount;
private EditText etPassword;
private Button btnLogin;
private TextView tvRegister;
private CheckBox rememberPass;
// 读取数据和存储数据的对象
private SharedPreferences pref;
private SharedPreferences.Editor editor;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_login);
initView();
}
private void initView() {
etAccount = findViewById(R.id.et_account);
etPassword = findViewById(R.id.et_password);
btnLogin = findViewById(R.id.btn_login);
tvRegister = findViewById(R.id.tv_register);
rememberPass = findViewById(R.id.rememberPass);
btnLogin.setOnClickListener(this);
tvRegister.setOnClickListener(this);
pref = getSharedPreferences("data", MODE_PRIVATE);
boolean isRemember = pref.getBoolean("remember", false);
// 如果记住密码
if (isRemember) {
String account = pref.getString("account", "");
String password = pref.getString("password", "");
// 将账号和密码设置到文本框中
etAccount.setText(account);
etPassword.setText(password);
rememberPass.setChecked(true);
}
}
@Override
public void onClick(View view) {
switch (view.getId()) {
case R.id.btn_login:
// 文本框中的内容
String acc = etAccount.getText().toString().trim();
String pass = etPassword.getText().toString().trim();
// 键值对存储的数据
String account = pref.getString("account", "");
String password = pref.getString("password", "");
// 逻辑判断
if (TextUtils.isEmpty(acc) || TextUtils.isEmpty(pass)) {
Toast.makeText(LoginActivity.this, "账号和密码不能为空", Toast.LENGTH_SHORT).show();
} else if (acc.equals(account) && (MD5Utils.md5(pass).equals(password) || pass.equals(password))){
editor = pref.edit(); // 获取editor实例
if (rememberPass.isChecked()) {
editor.putBoolean("remember", true);
} else {
editor.putBoolean("remember", false);
}
editor.apply();
Toast.makeText(LoginActivity.this, "欢迎登录", Toast.LENGTH_SHORT).show();
Intent intent = new Intent(LoginActivity.this, MainInterfaceActivity.class);
startActivity(intent);
finish();
} else {
Toast.makeText(LoginActivity.this, "账号或密码不正确", Toast.LENGTH_SHORT).show();
}
break;
case R.id.tv_register:
// 跳转到注册活动
Intent intent = new Intent(LoginActivity.this, RegisterActivity.class);
startActivityForResult(intent, 1);
break;
default:
break;
}
}
// 得到注册活动返回的数据
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
switch (requestCode) {
case 1:
if (resultCode == RESULT_OK) {
String acc = data.getStringExtra("acc");
String pass = data.getStringExtra("pass");
// 将账号和密码设置到文本框中
etAccount.setText(acc);
etPassword.setText(pass);
}
break;
default:
break;
}
}
}
注册实现:
package com.ypc.xiaoxiongmusic;
import androidx.appcompat.app.AppCompatActivity;
import android.content.Intent;
import android.content.SharedPreferences;
import android.os.Bundle;
import android.text.TextUtils;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import android.widget.TextView;
import android.widget.Toast;
public class RegisterActivity extends AppCompatActivity implements View.OnClickListener {
private EditText etAccount, etPassword, etConfirm;
private Button btnRegister;
private TextView tvReturn, tvMember;
private SharedPreferences pref;
private SharedPreferences.Editor editor;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_register);
initView();
}
private void initView() {
etAccount = findViewById(R.id.et_account);
etPassword = findViewById(R.id.et_password);
etConfirm = findViewById(R.id.et_confirm);
btnRegister = findViewById(R.id.btn_register);
tvReturn = findViewById(R.id.tv_return);
tvMember = findViewById(R.id.tv_member);
btnRegister.setOnClickListener(this);
tvReturn.setOnClickListener(this);
tvMember.setOnClickListener(this);
pref = getSharedPreferences("data", MODE_PRIVATE);
}
@Override
public void onClick(View view) {
switch (view.getId()) {
case R.id.btn_register:
String account = etAccount.getText().toString().trim();
String password = etPassword.getText().toString().trim();
String confirm = etConfirm.getText().toString().trim();
if (TextUtils.isEmpty(account) || TextUtils.isEmpty(password) || TextUtils.isEmpty(confirm)) {
Toast.makeText(RegisterActivity.this, "账号或密码不能为空", Toast.LENGTH_SHORT).show();
} else if (!password.equals(confirm)) {
Toast.makeText(RegisterActivity.this, "两次输入的密码不一致", Toast.LENGTH_SHORT).show();
} else if (account.length() < 6 || password.length() < 6) {
Toast.makeText(RegisterActivity.this, "账号或密码长度不能小于6", Toast.LENGTH_SHORT).show();
} else {
String mps = MD5Utils.md5(password);
editor = pref.edit();
editor.putString("account", account);
editor.putString("password", mps);
editor.apply();
// 向上一个活动返回数据,参数1处理结果,参数2意图
Intent intent = new Intent();
intent.putExtra("acc", account);
intent.putExtra("pass", password);
setResult(RESULT_OK, intent);
finish();
}
break;
case R.id.tv_return:
finish();
break;
case R.id.tv_member:
Toast.makeText(this, "您已经加入会员", Toast.LENGTH_SHORT).show();
break;
default:
break;
}
}
}
MD5加密:
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
public class MD5Utils {
// md5 加密算法
public static String md5(String text) {
MessageDigest messageDigest;
try {
messageDigest = MessageDigest.getInstance("md5");
// 文本转为字节数组
byte[] result = messageDigest.digest(text.getBytes());
// 创建StringBuilder对象,建议StringBuffer,安全性高
// StringBuilder sb = new StringBuilder();
StringBuffer sb = new StringBuffer();
// for 循环数组byte[] result;
for (byte b : result){
// 0xff为16进制,进行位与运算
int number = b & 0xff;
// number值 转换 字符串 Integer.toHexString( );
String hex = Integer.toHexString(number);
if (hex.length() == 1){
sb.append("0" + hex);
}else {
sb.append(hex);
}
}
return sb.toString();
} catch (NoSuchAlgorithmException e) {
// 打印工作栈的使用痕迹
e.printStackTrace();
// return空字符串
return "";
}
}
}
轮播图与音乐展示:
package com.ypc.xiaoxiongmusic;
import android.annotation.SuppressLint;
import android.content.Intent;
import android.media.Image;
import android.net.Uri;
import android.os.Bundle;
import android.os.Handler;
import android.text.TextUtils;
import android.view.LayoutInflater;
import android.view.Menu;
import android.view.MotionEvent;
import android.view.View;
import android.view.ViewGroup;
import android.widget.AdapterView;
import android.widget.BaseAdapter;
import android.widget.ImageView;
import android.widget.ListView;
import android.widget.SearchView;
import android.widget.TextView;
import android.app.Fragment;
import androidx.viewpager.widget.PagerAdapter;
import androidx.viewpager.widget.ViewPager;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;
import static android.view.View.VISIBLE;
@SuppressLint("ValidFragment")
public class musicFragment extends Fragment {
ListView lv;
private ViewPager mViewPaper;
private List<ImageView> images;
private List<View> dots;
private int currentItem;
//记录上一次点的位置
private int oldPosition = 0;
//存放图片的id
private int selectedPosition=0;
private ImageView bf;
private int[] imageIds = new int[]{
R.drawable.lv1,
R.drawable.lv2,
R.drawable.lv3,
R.drawable.lv4,
R.drawable.lv1
};
//存放图片的标题
private String[] titles = new String[]{
"once more thing",
"forgive never",
"always once a day",
"see you again",
"just be you"
};
private TextView title;
private ViewPagerAdapter adapter;
private ScheduledExecutorService scheduledExecutorService;
private static List<Integer> sPics=new ArrayList<>();
private View view;
public static String[] name={"从前说","追光者","爱长久","原谅我","明天会更好","浮萍","兔失志","潮湿的心","长相依","中华民谣","拜年"};
public static int[] icons={R.drawable.musicx,R.drawable.musicx,R.drawable.musicx,R.drawable.musicx,R.drawable.musicx,
R.drawable.musicx,R.drawable.musicx,R.drawable.musicx,R.drawable.musicx,R.drawable.musicx,
R.drawable.musicx};
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState){
View view = inflater.inflate(R.layout.fragment_music, container, false);
//lv.setAdapter(new ArrayAdapter<String>(getActivity(), android.R.layout.simple_list_item_1, name));
lv=view.findViewById(R.id.lv);
lv.setTextFilterEnabled(true);
mViewPaper = view. findViewById(R.id.vp);
images = new ArrayList<ImageView>();
for(int i = 0; i < imageIds.length; i++){
ImageView imageView = new ImageView(getActivity());
imageView.setBackgroundResource(imageIds[i]);
images.add(imageView);
}
dots = new ArrayList<View>();
dots.add(view.findViewById(R.id.dot_0));
dots.add(view.findViewById(R.id.dot_1));
dots.add(view.findViewById(R.id.dot_2));
dots.add(view.findViewById(R.id.dot_3));
dots.add(view.findViewById(R.id.dot_4));
title = (TextView) view.findViewById(R.id.title);
title.setText(titles[0]);
adapter = new ViewPagerAdapter();
mViewPaper.setAdapter(adapter);
//论插图的ontauch点击方法
mViewPaper.setOnTouchListener(new View.OnTouchListener() {
int flage = 0 ;
public boolean onTouch(View v, MotionEvent event) {
switch (event.getAction()){
case MotionEvent.ACTION_DOWN:
flage = 0 ;
break ;
case MotionEvent.ACTION_MOVE:
flage = 1 ;
break ;
case MotionEvent.ACTION_UP :
if (flage == 0) {
int item = mViewPaper.getCurrentItem();
if (item == 0) {
Intent intent = new Intent();
intent.setAction("android.intent.action.VIEW");
Uri content_url = Uri.parse("https://v.kuaishou.com/BPhDVP");//此处填链接
intent.setData(content_url);
startActivity(intent);
} else if (item == 1) {
Intent intent = new Intent();
intent.setAction("android.intent.action.VIEW");
Uri content_url = Uri.parse("https://v.kuaishou.com/BPhDVP");//此处填链接
intent.setData(content_url);
startActivity(intent);
} else if (item == 2) {
Intent intent = new Intent();
intent.setAction("android.intent.action.VIEW");
Uri content_url = Uri.parse("https://v.kuaishou.com/CelGqE");//此处填链接
intent.setData(content_url);
startActivity(intent);
}else if (item == 3) {
Intent intent = new Intent();
intent.setAction("android.intent.action.VIEW");
Uri content_url = Uri.parse("https://v.kuaishou.com/BPhDVP");//此处填链接
intent.setData(content_url);
startActivity(intent);
} else if (item == 4) {
Intent intent = new Intent();
intent.setAction("android.intent.action.VIEW");
Uri content_url = Uri.parse("https://v.kuaishou.com/CelGqE");//此处填链接
intent.setData(content_url);
startActivity(intent);
}
}
break ;
}
return false;
}
});
mViewPaper.setOnPageChangeListener(new ViewPager.OnPageChangeListener() {
@Override
public void onPageSelected(int position) {
title.setText(titles[position]);
dots.get(position).setBackgroundResource(R.drawable.red);
//Toast.makeText(getActivity(),"hurhurhghrui",Toast.LENGTH_SHORT).show();
dots.get(oldPosition).setBackgroundResource(R.drawable.pure);
oldPosition = position;
currentItem = position;
}
@Override
public void onPageScrolled(int arg0, float arg1, int arg2) {
}
@Override
public void onPageScrollStateChanged(int arg0) {
}
});
//ListView listView=view.findViewById(R.id.lv);
MyBaseAdapter adapter=new MyBaseAdapter();
lv.setAdapter(adapter);
lv.setOnItemClickListener(new AdapterView.OnItemClickListener() {
@Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
Intent intent=new Intent(getActivity(),Music_Activity.class);//创建Intent对象,启动check
//将数据存入Intent对象
intent.putExtra("name",name[position]);
intent.putExtra("position",String.valueOf(position));
startActivity(intent);
lv.setSelector(R.drawable.bf1);
}
});
return view;
}
private class ViewPagerAdapter extends PagerAdapter {
@Override
public int getCount() {
return images.size();
}
@Override
public boolean isViewFromObject(View arg0, Object arg1) {
return arg0 == arg1;
}
@Override
public void destroyItem(ViewGroup view, int position, Object object) {
// TODO Auto-generated method stub
view.removeView(images.get(position));
}
@Override
public Object instantiateItem(ViewGroup view, int position) {
// TODO Auto-generated method stub
view.addView(images.get(position));
return images.get(position);
}
}
/* @Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.main, menu);
return true;
}*/
/**
* 利用线程池定时执行动画轮播
*/
@Override
public void onStart() {
// TODO Auto-generated method stub
super.onStart();
scheduledExecutorService = Executors.newSingleThreadScheduledExecutor();
scheduledExecutorService.scheduleWithFixedDelay(
new ViewPageTask(),
2,
2,
TimeUnit.SECONDS);
}
/**
* 图片轮播任务
* @author liuyazhuang
*
*/
private class ViewPageTask implements Runnable{
@Override
public void run() {
currentItem = (currentItem + 1) % imageIds.length;
mHandler.sendEmptyMessage(0);
}
}
/**
* 接收子线程传递过来的数据
*/
private Handler mHandler = new Handler(){
public void handleMessage(android.os.Message msg) {
mViewPaper.setCurrentItem(currentItem);
};
};
@Override
public void onStop() {
// TODO Auto-generated method stub
super.onStop();
if(scheduledExecutorService != null){
scheduledExecutorService.shutdown();
scheduledExecutorService = null;
}
}
class MyBaseAdapter extends BaseAdapter{
@Override
public int getCount(){return name.length;}
@Override
public Object getItem(int i){return name[i];}
@Override
public long getItemId(int i){return i;}
@Override
public View getView(int i ,View convertView, ViewGroup parent) {
View view=View.inflate(musicFragment.this.getActivity(),R.layout.item_layout,null);
TextView tv_name=view.findViewById(R.id.item_name);
ImageView iv=view.findViewById(R.id.iv);
tv_name.setText(name[i]);
iv.setImageResource(icons[i]);
return view;
}
}
}
音乐功能以及唱盘和进度条实现:
package com.ypc.xiaoxiongmusic;
import android.animation.ObjectAnimator;
import android.app.Activity;
import android.content.ComponentName;
import android.content.Intent;
import android.content.ServiceConnection;
import android.os.Build;
import android.os.Bundle;
import android.os.Handler;
import android.os.IBinder;
import android.os.Message;
import android.view.View;
import android.view.animation.LinearInterpolator;
import android.widget.Button;
import android.widget.ImageView;
import android.widget.SeekBar;
import android.widget.TextView;
import androidx.annotation.RequiresApi;
import static java.lang.Integer.parseInt;
public class Music_Activity extends Activity implements View.OnClickListener{
private static SeekBar sb;
private static TextView tv_progress,tv_total;
private ObjectAnimator animator;
private MusicService .MusicControl musicControl;
private ImageView bt_1;
private ImageView iv_music;
private TextView tv_name;
private int change;
String name;
Intent intent1,intent2;
MyServiceConn conn;//
private boolean isUnbind =false;//记录服务是否被解绑
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_music);
intent1=getIntent();
init();
View v=findViewById(R.id.bg_1);
// v.getBackground().setAlpha(180);
tv_name=findViewById(R.id.song_name);
iv_music=findViewById(R.id.iv_music);
bt_1=findViewById(R.id.bt_1);
bt_1.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
finish();
}
});
}
private void init(){
tv_progress=(TextView)findViewById(R.id.tv_progress);
tv_total=(TextView)findViewById(R.id.tv_total);
sb=(SeekBar)findViewById(R.id.sb);
TextView tv_name=(TextView)findViewById(R.id.song_name);
ImageView iv_music=(ImageView)findViewById(R.id.iv_music);
findViewById(R.id.btn_play).setOnClickListener(this);
findViewById(R.id.btn_pause).setOnClickListener(this);
findViewById(R.id.btn_continue_play).setOnClickListener(this);
findViewById(R.id.btn_next).setOnClickListener(this);
findViewById(R.id.btn_jixu).setOnClickListener(this);
name=intent1.getStringExtra("name");
tv_name.setText(name);
intent2=new Intent(this,MusicService.class);//创建意图对象
conn=new MyServiceConn();//创建服务连接对象
bindService(intent2,conn,BIND_AUTO_CREATE);//绑定服务
//为滑动条添加事件监听
sb.setOnSeekBarChangeListener(new SeekBar.OnSeekBarChangeListener() {
@RequiresApi(api = Build.VERSION_CODES.KITKAT)
@Override
public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) {
//进度条改变时,会调用此方法
if (progress==seekBar.getMax()){//当滑动条到末端时,结束动画
animator.pause();//停止播放动画
}
}
@Override
public void onStartTrackingTouch(SeekBar seekBar) {//滑动条开始滑动时调用
}
@Override
public void onStopTrackingTouch(SeekBar seekBar) {//滑动条停止滑动时调用
//根据拖动的进度改变音乐播放进度
int progress=seekBar.getProgress();//获取seekBar的进度
musicControl.seekTo(progress);//改变播放进度
}
});
animator= ObjectAnimator.ofFloat(iv_music,"rotation",0f,360.0f);
animator.setDuration(15000);//动画旋转一周的时间为10秒
animator.setInterpolator(new LinearInterpolator());//匀速
animator.setRepeatCount(-1);//-1表示设置动画无限循环
}
public static Handler handler=new Handler(){//创建消息处理器对象
//在主线程中处理从子线程发送过来的消息
@Override
public void handleMessage(Message msg){
Bundle bundle=msg.getData();//获取从子线程发送过来的音乐播放进度
int duration=bundle.getInt("duration");
int currentPosition=bundle.getInt("currentPosition");
sb.setMax(duration);
sb.setProgress(currentPosition);
//歌曲总时长
int minute=duration/1000/60;
int second=duration/1000%60;
String strMinute=null;
String strSecond=null;
if(minute<10){//如果歌曲的时间中的分钟小于10
strMinute="0"+minute;//在分钟的前面加一个0
}else{
strMinute=minute+"";
}
if (second<10){//如果歌曲中的秒钟小于10
strSecond="0"+second;//在秒钟前面加一个0
}else{
strSecond=second+"";
}
tv_total.setText(strMinute+":"+strSecond);
//歌曲当前播放时长
minute=currentPosition/1000/60;
second=currentPosition/1000%60;
if(minute<10){//如果歌曲的时间中的分钟小于10
strMinute="0"+minute;//在分钟的前面加一个0
}else{
strMinute=minute+" ";
}
if (second<10){//如果歌曲中的秒钟小于10
strSecond="0"+second;//在秒钟前面加一个0
}else{
strSecond=second+" ";
}
tv_progress.setText(strMinute+":"+strSecond);
}
};
class MyServiceConn implements ServiceConnection {//创建一个自定义类用于实现连接服务
@Override
public void onServiceConnected(ComponentName name, IBinder service){
musicControl=(MusicService.MusicControl) service;
}
@Override
public void onServiceDisconnected(ComponentName name){
}
}
private void unbind(boolean isUnbind){
if(!isUnbind){//判断服务是否被解绑
musicControl.pausePlay();//暂停播放音乐
unbindService(conn);//解绑服务
}
}
@RequiresApi(api = Build.VERSION_CODES.KITKAT)//如果注释掉,则需要手动在grideMouble里面把api从15调到更高如19
@Override
public void onClick(View v) {
String position=intent1.getStringExtra("position");
int i=parseInt(position);
switch (v.getId()){
case R.id.btn_play://播放按钮点击事件
musicControl.play(i);
animator.start();
break;
case R.id.btn_pause://暂停按钮点击事件
musicControl.pausePlay();
animator.pause();
break;
case R.id.btn_jixu://继续按钮点击事件
musicControl.continuePlay();
animator.resume();
break;
case R.id.btn_continue_play://上一首
if(( i +change)<1) {
change=name.length()-1-i;
musicControl.play(i+change);
animator.start();
tv_name.setText(name);
}
else {
change-=1;
iv_music.setImageResource(musicFragment.icons[i+change]);
tv_name.setText(musicFragment.name[i+change]);
musicControl.play(i-change);
animator.start();
break;
}
case R.id.btn_next://下一首按钮点击事件
if((i+change)==name.length()-1) {//这里Name.length-1表示的最后一首歌的下标,即歌曲总数-1
change=-i;
musicControl.play(i+change);
iv_music.setImageResource(musicFragment.icons[i+change]);
// name_song.setText(name);
animator.start();
tv_name.setText((String)musicFragment.name[i+change]);
}
else {
change++;
iv_music.setImageResource(musicFragment.icons[i+change]);
tv_name.setText(musicFragment.name[i+change]);
musicControl.play(i+change);
animator.start();
break;
}
}
}
@Override
protected void onDestroy(){
super.onDestroy();
unbind(isUnbind);//解绑服务
}
}
部分运行截图:
启动动画:
登录注册:
主界面(轮播图和音乐列表)
音乐播放界面:
个人界面
APP反馈:
APP评分:
个人信息展示:
退出程序提示: