实现功能:

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();@Overrideprotected 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;@Overrideprotected 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);}}@Overridepublic 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;}}// 得到注册活动返回的数据@Overrideprotected 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;@Overrideprotected 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);}@Overridepublic 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;//存放图片的idprivate 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};@Overridepublic 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() {@Overridepublic 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;}@Overridepublic void onPageScrolled(int arg0, float arg1, int arg2) {}@Overridepublic void onPageScrollStateChanged(int arg0) {}});//ListView listView=view.findViewById(R.id.lv);MyBaseAdapter adapter=new MyBaseAdapter();lv.setAdapter(adapter);lv.setOnItemClickListener(new AdapterView.OnItemClickListener() {@Overridepublic 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 {@Overridepublic int getCount() {return images.size();}@Overridepublic boolean isViewFromObject(View arg0, Object arg1) {return arg0 == arg1;}@Overridepublic void destroyItem(ViewGroup view, int position, Object object) {// TODO Auto-generated method stubview.removeView(images.get(position));}@Overridepublic Object instantiateItem(ViewGroup view, int position) {// TODO Auto-generated method stubview.addView(images.get(position));return images.get(position);}}/* @Overridepublic 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;}*//*** 利用线程池定时执行动画轮播*/@Overridepublic void onStart() {// TODO Auto-generated method stubsuper.onStart();scheduledExecutorService = Executors.newSingleThreadScheduledExecutor();scheduledExecutorService.scheduleWithFixedDelay(new ViewPageTask(),2,2,TimeUnit.SECONDS);}/*** 图片轮播任务* @author liuyazhuang**/private class ViewPageTask implements Runnable{@Overridepublic 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);};};@Overridepublic void onStop() {// TODO Auto-generated method stubsuper.onStop();if(scheduledExecutorService != null){scheduledExecutorService.shutdown();scheduledExecutorService = null;}}class MyBaseAdapter extends BaseAdapter{@Overridepublic int getCount(){return  name.length;}@Overridepublic Object getItem(int i){return name[i];}@Overridepublic long getItemId(int i){return i;}@Overridepublic 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;//记录服务是否被解绑@Overrideprotected 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() {@Overridepublic 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)@Overridepublic void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) {//进度条改变时,会调用此方法if (progress==seekBar.getMax()){//当滑动条到末端时,结束动画animator.pause();//停止播放动画}}@Overridepublic void onStartTrackingTouch(SeekBar seekBar) {//滑动条开始滑动时调用}@Overridepublic 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(){//创建消息处理器对象//在主线程中处理从子线程发送过来的消息@Overridepublic 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){//如果歌曲的时间中的分钟小于10strMinute="0"+minute;//在分钟的前面加一个0}else{strMinute=minute+"";}if (second<10){//如果歌曲中的秒钟小于10strSecond="0"+second;//在秒钟前面加一个0}else{strSecond=second+"";}tv_total.setText(strMinute+":"+strSecond);//歌曲当前播放时长minute=currentPosition/1000/60;second=currentPosition/1000%60;if(minute<10){//如果歌曲的时间中的分钟小于10strMinute="0"+minute;//在分钟的前面加一个0}else{strMinute=minute+" ";}if (second<10){//如果歌曲中的秒钟小于10strSecond="0"+second;//在秒钟前面加一个0}else{strSecond=second+" ";}tv_progress.setText(strMinute+":"+strSecond);}};class MyServiceConn implements ServiceConnection {//创建一个自定义类用于实现连接服务@Overridepublic void onServiceConnected(ComponentName name, IBinder service){musicControl=(MusicService.MusicControl) service;}@Overridepublic 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@Overridepublic 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表示的最后一首歌的下标,即歌曲总数-1change=-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;}}}@Overrideprotected void onDestroy(){super.onDestroy();unbind(isUnbind);//解绑服务}
}

部分运行截图:

启动动画:

登录注册:

主界面(轮播图和音乐列表)

音乐播放界面:

个人界面

APP反馈:

APP评分:

个人信息展示:

退出程序提示:

Android音乐播放器(高分课设)相关推荐

  1. Android音乐播放器开发(2)—登录

    1. 说明 本音乐播放器基于Android开发,原为我和另外两个小伙伴在上学期间一起做的一个小项目,近来有时间整理一下.之前我有文章已经介绍了播放界面的功能实现(Android音乐播放器开发),但介绍 ...

  2. Android音乐播放器开发(3)—注册

    1. 说明 本音乐播放器基于Android开发,原为我和另外两个小伙伴在上学期间一起做的一个小项目,近来有时间整理一下.之前我有文章已经介绍了播放界面的功能实现(Android音乐播放器开发),但介绍 ...

  3. Android音乐播放器开发(4)—修改密码

    1. 说明 本音乐播放器基于Android开发,原为我和另外两个小伙伴在上学期间一起做的一个小项目,近来有时间整理一下.之前我有文章已经介绍了播放界面的功能实现(Android音乐播放器开发),但介绍 ...

  4. Android音乐播放器开发(6)—ListView组件创建歌曲播放列表(内含原理分析)

    1. 说明 源码已同步到Gitee仓库,GitHub仓库,觉得还不错的话帮忙点个"star"吧,非常感谢. 以往的文章 服务端:Android音乐播放器开发–服务端 登录:Andr ...

  5. Android音乐播放器开发(5)—播放界面(播放、暂停、上一首、下一首,顺序播放、随机播放、拖拽进度条…)

    1. 说明 源码已同步到Gitee仓库,Github仓库,觉得还不错的话帮忙点个"star"吧,非常感谢. Android播放器专栏其它文章: 服务端:Android音乐播放器开发 ...

  6. 基于android音乐播放器的设计

    本科毕业论文(设计)诚信声明 本人郑重声明:所呈交的毕业论文(设计),题目<---基于android音乐播放器的设计----------->是本人在指导教师的指导下,进行研究工作所取得的成 ...

  7. 简单android音乐播放器课程设计,android音乐播放器课程设计报告.doc

    android音乐播放器课程设计报告 android音乐播放器课程设计报告 基于Android音乐播放器的设计与实现 滨江学院 <移动通信程序设计> 课程设计 题 目 院 系 专 业学生姓 ...

  8. android音乐播放器完整教程,android实现简单音乐播放器

    本文实例为大家分享了android音乐播放器的具体代码,供大家参考,具体内容如下 话不多说先上效果 前言 写这个音乐播放器实在是迫不得已.因为我们Andoird课程要求写一个音乐播放器.所以就有了此项 ...

  9. 自编Win8风格Android音乐播放器应用源码(单机版)

    用闲暇的两天时间,研究编写了一个类Win8风格的android音乐播放器,实现了大部分基本功能.下面看具体描述: 基本实现功能: 注意事项:Android系统版本须在2.2以上,保证手机安装有SD卡( ...

  10. Android音乐播放器的设计与实现

    课程设计报告 实习名称 课程设计2 设计题目 Android音乐播放器的设计与实现 目录 摘要11 1 引言22 2 可行性分析22 2.1 技术可行性22 2.2 经济可行性33 2.3 管理可行性 ...

最新文章

  1. Wireshark基本介绍和学习TCP三次握手
  2. 《python核心编程》读书笔记--第15章 正则表达式
  3. 使用轮转算法求时间片_彩票调度算法,让进程们拼手气? --当操作系统遇上随机算法...
  4. linux错误:E212 can‘t open file for writing
  5. python迭代器好处_关于Python中迭代器的作用
  6. 你碰到过的最难调试的 Bug 是什么样的?
  7. 开发自上而下的Web服务项目
  8. 李国庆三位姐姐加入战局 正面刚俞渝:如继续侮辱我们,也将抓破你的脸!
  9. JavaIO15FileReader和FileWriter源码分析及介绍使用
  10. GCN图卷积网络简单实现
  11. 分形理论中的分维解析
  12. android ip地址扫描仪,通过IP地址添加网络扫描仪(适用于CC2软件Mac OS)
  13. 输入输出隔离的半/全双工RS-485/RS-422接口隔离芯片电路
  14. 【学习随记】Gyro,Btn,filters_addClass
  15. intent-filter属性介绍
  16. Verilog中reg和wire的区别
  17. oracleTNS-12555: TNS:permission denied、TNS-12541: TNS:no listener、Instance orcl, status UNKNOWN
  18. 【Cesium】加载互联网地图服务——高德地图
  19. 经济学基础(本)【1】
  20. vscode下载和安装教程和配置中文插件(超详细)

热门文章

  1. javaweb基于JSP开发辛馨墙衣壁纸企业官网宣传网站系统+全套文档+PPT 毕业设计 课程设计 大作业源码
  2. VS2008下水晶报表之简单示例
  3. Go按多组id数组出现次数,由多到少排序并去重,输出权重id数组
  4. 组件化拆分(三)-Todos案例——单页面-详细代码
  5. 量子力学(4) 全同粒子
  6. ai人工智能_人工智能已经如何统治世界
  7. java计算机毕业设计基于安卓Android的社交app-社会交友app
  8. scala中 sorted,sortBy,sortWith语法使用
  9. 阿里云免费个人Docker镜像仓库搭建
  10. 高通QCM6125的LK部分(uefi/xbl)编译