目录

  • 项目功能
  • 实现步骤
    • 创建安卓应用
    • 将图片素材放入drawable和mipmap
    • 创建按钮背景图片选择器
    • 在项目清单文件里授权访问外置存储卡,设置应用程序图标
    • 创建anim包里面创建animator.xml
    • 主布局资源文件activity_main.xml
    • 布局文件activity_splash_screen_activity.xml
    • 字符串资源文件strings.xml
    • 创建音乐名列表项模板music_name_list_item.xml
    • 创建ui子包,将MainActivity拖进ui子包
    • 创建entity子包,在里面创建音乐实体类 - Music
    • 创建app子包,在里面创建音乐播放器应用程序类 - MusicPlayerApplication
    • 给音乐播放器应用程序类注册
    • 创建adapter子包,在里面创建音乐适配器 - MusicAdapter
    • 在app子包常见应用程序常量接口 - AppConstants
    • 创建service子包,在里面创建音乐播放服务类 - MusicPlayService
    • 主界面类 - MainActivity
    • 在ui子包里创建SplashScreenActivity(启动画面)
    • 运行效果

项目功能

  • 在基于存储卡音乐播放器V0.5基础上,作如下修改:
    1、添加启动画面(SplashScreenActivity)
    2、添加音乐播放幕式功能:顺序播放、随机播放、单曲循环播放
    3、将进度条(ProgressBar)改为拖拽条(SeekBar),用户通过拖拽可自行设置音乐播放进度值

实现步骤

创建安卓应用

将图片素材放入drawable和mipmap

创建按钮背景图片选择器

在项目清单文件里授权访问外置存储卡,设置应用程序图标

创建anim包里面创建animator.xml

<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android"><alphaandroid:duration="3000"android:fromAlpha="0.0"android:toAlpha="1.0" /><rotateandroid:duration="3000"android:fromDegrees="0"android:pivotX="50%"android:pivotY="50%"android:repeatCount="1"android:repeatMode="reverse"android:toDegrees="+360" />
</set>

主布局资源文件activity_main.xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"xmlns:tools="http://schemas.android.com/tools"android:layout_width="match_parent"android:layout_height="match_parent"android:background="@drawable/background"android:orientation="vertical"android:padding="20dp"tools:context=".ui.MainActivity"><LinearLayoutandroid:layout_width="match_parent"android:layout_height="wrap_content"android:orientation="horizontal"><ProgressBarandroid:id="@+id/pbScanMusic"android:layout_width="100dp"android:layout_height="100dp"android:visibility="gone" /><TextViewandroid:id="@+id/tvScanMusic"android:layout_width="wrap_content"android:layout_height="wrap_content"android:text="@string/scan_music"android:textColor="#0000ff"android:textSize="25sp"android:visibility="gone" /></LinearLayout><LinearLayoutandroid:layout_width="match_parent"android:layout_height="50dp"android:background="@drawable/custom_border"android:gravity="center"android:orientation="horizontal"android:padding="5dp"><TextViewandroid:id="@+id/tv_play_mode"android:layout_width="wrap_content"android:layout_height="wrap_content"android:text="@string/play_mode"android:textSize="13sp" /><RadioGroupandroid:id="@+id/rg_play_mode"android:layout_width="wrap_content"android:layout_height="wrap_content"android:orientation="horizontal"><RadioButtonandroid:id="@+id/rb_order"android:layout_width="wrap_content"android:layout_height="wrap_content"android:checked="true"android:text="@string/order"android:textSize="13sp" /><RadioButtonandroid:id="@+id/rb_random"android:layout_width="wrap_content"android:layout_height="wrap_content"android:text="@string/random"android:textSize="13sp" /><RadioButtonandroid:id="@+id/rb_loop"android:layout_width="wrap_content"android:layout_height="wrap_content"android:text="@string/loop"android:textSize="13sp" /></RadioGroup></LinearLayout><ListViewandroid:id="@+id/lvMusicName"android:layout_width="match_parent"android:layout_height="0dp"android:layout_marginBottom="16dp"android:layout_weight="8" /><TextViewandroid:id="@+id/tvMusicName"android:layout_width="wrap_content"android:layout_height="wrap_content"android:layout_weight="0.5"android:textColor="#0000ff"android:textSize="20sp" /><LinearLayoutandroid:layout_width="match_parent"android:layout_height="wrap_content"android:layout_marginTop="10dp"android:layout_marginBottom="10dp"android:layout_weight="0.5"android:gravity="center"android:orientation="horizontal"><TextViewandroid:id="@+id/tvCurrentPosition"android:layout_width="0dp"android:layout_height="wrap_content"android:layout_weight="1"android:textColor="#ff0000" /><SeekBarandroid:id="@+id/sb_music_progress"android:layout_width="0dp"android:layout_height="wrap_content"android:layout_weight="6" /><TextViewandroid:id="@+id/tvDuration"android:layout_width="0dp"android:layout_height="wrap_content"android:layout_weight="1"android:textColor="#ff00ff" /></LinearLayout><LinearLayoutandroid:layout_width="match_parent"android:layout_height="wrap_content"android:layout_weight="0.5"android:gravity="center"android:orientation="horizontal"><Buttonandroid:id="@+id/btnPrevious"android:layout_width="60dp"android:layout_height="50dp"android:background="@drawable/previous_button_selector"android:onClick="doPrevious" /><Buttonandroid:id="@+id/btnPlayOrPause"android:layout_width="60dp"android:layout_height="50dp"android:background="@drawable/play_button_selector"android:onClick="doPlayOrPause" /><Buttonandroid:id="@+id/btnNext"android:layout_width="60dp"android:layout_height="50dp"android:background="@drawable/next_button_selector"android:onClick="doNext" /></LinearLayout>
</LinearLayout>

布局文件activity_splash_screen_activity.xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"android:id="@+id/root_layout"android:layout_width="match_parent"android:layout_height="match_parent"android:background="@drawable/background"android:gravity="center"android:orientation="vertical"><ImageViewandroid:id="@+id/iv_music_icon"android:layout_width="wrap_content"android:layout_height="wrap_content"android:layout_marginTop="20dp"android:src="@drawable/music" /><TextViewandroid:id="@+id/tv_title"android:layout_width="wrap_content"android:layout_height="wrap_content"android:layout_marginTop="30dp"android:text="@string/title"android:textColor="#0000ff"android:textSize="25sp" /><TextViewandroid:id="@+id/tv_version"android:layout_width="wrap_content"android:layout_height="wrap_content"android:layout_marginTop="20dp"android:text="@string/version"android:textColor="#ff0000"android:textSize="20sp" /><TextViewandroid:id="@+id/tv_author"android:layout_width="wrap_content"android:layout_height="wrap_content"android:layout_marginTop="20dp"android:text="@string/author"android:textColor="#000000"android:textSize="20sp" />
</LinearLayout>

字符串资源文件strings.xml

创建音乐名列表项模板music_name_list_item.xml

创建ui子包,将MainActivity拖进ui子包

创建entity子包,在里面创建音乐实体类 - Music

创建app子包,在里面创建音乐播放器应用程序类 - MusicPlayerApplication

package com.zjs.sdcard_music_player_v06.app;import android.app.Application;
import android.os.Environment;import com.zjs.sdcard_music_player_v06.entity.Music;import java.io.File;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.List;public class MusicPlayerApplication extends Application {private SimpleDateFormat sdf; // 简单日期格式private int currentMusicIndex;//当前音乐索引private int currentPosition;//当前播放位置private int playMode;//播放模式private int progressChangedByUser;//用户修改的播放进度@Overridepublic void onCreate() {super.onCreate();// 实例化简单日期格式sdf = new SimpleDateFormat("mm:ss");}public int getCurrentMusicIndex() {return currentMusicIndex;}public void setCurrentMusicIndex(int currentMusicIndex) {this.currentMusicIndex = currentMusicIndex;}public int getCurrentPosition() {return currentPosition;}public void setCurrentPosition(int currentPosition) {this.currentPosition = currentPosition;}public int getPlayMode() {return playMode;}public void setPlayMode(int playMode) {this.playMode = playMode;}public int getProgressChangedByUser() {return progressChangedByUser;}public void setProgressChangedByUser(int progressChangedByUser) {this.progressChangedByUser = progressChangedByUser;}/*** 获取格式化时间** @param time 单位是毫秒* @return mm:ss格式的时间*/public String getFormatTime(int time) {return sdf.format(time);}/*** 生成指定目录下某种类型的文件列表** @param dir* @param suffix* @param typeFileList*/public void makeTypeFileList(File dir, String suffix, List<String> typeFileList) {// 获取指定目录下的File数组(File既可以指向目录,也可以指向文件)File[] files = dir.listFiles();// 遍历File数组for (File file : files) {// 判断file是否是文件if (file.isFile()) { // file是文件// 按照后缀来过滤文件if (file.getName().endsWith(suffix)) {// 将满足条件的文件添加到文件列表typeFileList.add(file.getAbsolutePath());}} else { // file是目录// 目录非空,递归调用if (file.list() != null) {makeTypeFileList(file, suffix, typeFileList);}}}}/*** 获取音乐列表** @return 音乐列表*/public List<Music> getMusicList() {// 声明音乐列表List<Music> musicList = null;// 获取外置存储卡根目录File sdRootDir = Environment.getExternalStorageDirectory();// 创建后缀字符串String suffix = ".mp3";// 创建音乐文件列表List<String> musicFileList = new ArrayList<>();// 调用方法,生成指定目录下某种类型文件列表makeTypeFileList(sdRootDir, suffix, musicFileList);// 判断音乐文件列表里是否有元素if (musicFileList.size() > 0) {// 实例化音乐列表musicList = new ArrayList<>();// 遍历音乐文件列表for (String musicFile : musicFileList) {// 创建音乐实体Music music = new Music();// 设置实体属性music.setMusicName(musicFile);// 将音乐实体添加到音乐列表musicList.add(music);}}// 返回音乐列表return musicList;}
}

给音乐播放器应用程序类注册

创建adapter子包,在里面创建音乐适配器 - MusicAdapter

package com.zjs.sdcard_music_player_v06.adapter;import android.content.Context;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.BaseAdapter;
import android.widget.TextView;import com.zjs.sdcard_music_player_v06.R;import java.util.List;public class MusicAdapter extends BaseAdapter {private Context context; // 上下文private List<com.zjs.sdcard_music_player_v06.entity.Music> musicList; // 音乐列表/*** 构造方法** @param context* @param musicList*/public MusicAdapter(Context context, List<com.zjs.sdcard_music_player_v06.entity.Music> musicList) {this.context = context;this.musicList = musicList;}@Overridepublic int getCount() {return musicList.size();}@Overridepublic Object getItem(int position) {return musicList.get(position);}@Overridepublic long getItemId(int position) {return position;}@Overridepublic View getView(int position, View convertView, ViewGroup parent) {// 声明视图容器ViewHolder holder = null;// 判断转换视图是否为空if (convertView == null) {// 将列表项模板映射成转换视图convertView = LayoutInflater.from(context).inflate(R.layout.music_name_list_item, null);// 创建视图容器对象holder = new ViewHolder();// 实例化转换视图里的控件holder.tvMusicName = convertView.findViewById(R.id.tvMusicName);// 将视图容器附加到转换视图convertView.setTag(holder);} else {// 从转换视图里取出视图容器holder = (ViewHolder) convertView.getTag();}// 获取列表项要显示的数据com.zjs.sdcard_music_player_v06.entity.Music music = musicList.get(position);// 设置列表项控件的属性(去掉路径和扩展名)holder.tvMusicName.setText(music.getMusicName().substring(music.getMusicName().lastIndexOf("/") + 1, music.getMusicName().lastIndexOf(".")));// 返回转换视图return convertView;}/*** 视图容器*/private static class ViewHolder {TextView tvMusicName;}
}

在app子包常见应用程序常量接口 - AppConstants

package com.zjs.sdcard_music_player_v06.app;public interface AppConstants {String TAG = "net.hw.sdcard_musicplayer_v06"; // 应用程序标记String INTENT_ACTION_PREVIOUS = TAG + ".intent.action.PREVIOUS"; // 广播频道常量:播放上一首String INTENT_ACTION_PLAY = TAG + ".intent.action.PLAY"; // 广播频道常量:播放String INTENT_ACTION_PLAY_OR_PAUSE = TAG + ".intent.action.PLAY_OR_PAUSE"; // 广播频道常量:播放或暂停String INTENT_ACTION_NEXT = TAG + ".intent.action.NEXT"; // 广播频道常量:播放下一首String INTENT_ACTION_UPDATE_PROGRESS = TAG + ".intent.action.UPDATE_PROGRESS"; // 广播频道常量:更新播放进度String INTENT_ACTION_USER_CHANGE_PROGRESS = TAG + ".intent.action.USER_CHANGE_PROGRESS";//广播频道常量:用户改变播放进度String CONTROL_ICON = "control_icon"; // 控制图标名称常量String DURATION = "duration"; // 播放时长名称常量String CURRENT_POSITION = "current_position"; // 当前播放位置名称常量int PLAY_MODE_ORDER = 0;//播放模式:顺序播放int PLAY_MODE_RANDOM = 1;//播放模式:随机播放int PLAY_MODE_LOOP = 2;//播放模式:单曲循环
}

创建service子包,在里面创建音乐播放服务类 - MusicPlayService

主界面类 - MainActivity

package com.zjs.sdcard_music_player_v06.ui;import android.Manifest;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.content.pm.PackageManager;
import android.os.AsyncTask;
import android.os.Bundle;
import android.view.View;
import android.widget.AdapterView;
import android.widget.Button;
import android.widget.ListView;
import android.widget.ProgressBar;
import android.widget.RadioGroup;
import android.widget.SeekBar;
import android.widget.TextView;
import android.widget.Toast;import androidx.appcompat.app.AppCompatActivity;
import androidx.core.app.ActivityCompat;import com.zjs.sdcard_music_player_v06.R;
import com.zjs.sdcard_music_player_v06.adapter.MusicAdapter;
import com.zjs.sdcard_music_player_v06.app.AppConstants;
import com.zjs.sdcard_music_player_v06.app.MusicPlayerApplication;
import com.zjs.sdcard_music_player_v06.service.MusicPlayService;import java.util.List;public class MainActivity extends AppCompatActivity implements AppConstants {private String musicName; // 音乐文件名private TextView tvMusicName; // 音乐名标签private Button btnPlayOrPause; // 播放|暂停按钮private MusicReceiver receiver;//音乐广播接收器private TextView tvCurrentPosition; // 显示当前播放位置的标签private TextView tvDuration; // 显示音乐播放时长的标签private SeekBar sbMusicProgress;//音乐播放拖拽条private ListView lvMusicName; // 音乐名列表控件private List<com.zjs.sdcard_music_player_v06.entity.Music> musicList; // 音乐列表(数据源)private MusicAdapter adapter; // 音乐适配器private MusicPlayerApplication app; // 音乐播放器应用程序对象private ProgressBar pbScanMusic; // 扫描存储卡音乐进度条private TextView tvScanMusic; // 扫描存储卡音乐标签(提示用户耐心等待)private RadioGroup rgPlayMode;//播放模式单选按钮组@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);// 利用布局资源文件设置用户界面setContentView(R.layout.activity_main);// 通过资源标识符获取控件实例lvMusicName = findViewById(R.id.lvMusicName);tvMusicName = findViewById(R.id.tvMusicName);btnPlayOrPause = findViewById(R.id.btnPlayOrPause);tvCurrentPosition = findViewById(R.id.tvCurrentPosition);tvDuration = findViewById(R.id.tvDuration);pbScanMusic = findViewById(R.id.pbScanMusic);tvScanMusic = findViewById(R.id.tvScanMusic);sbMusicProgress = findViewById(R.id.sb_music_progress);rgPlayMode = findViewById(R.id.rg_play_mode);// 获取音乐播放器应用程序对象app = (MusicPlayerApplication) getApplication();// 定义存储读写权限数组String[] PERMISSIONS_STORAGE = {Manifest.permission.READ_EXTERNAL_STORAGE,Manifest.permission.WRITE_EXTERNAL_STORAGE};// 检查是否有读权限final int permission = ActivityCompat.checkSelfPermission(this, PERMISSIONS_STORAGE[0]);// 如果没有授权,那么就请求读权限if (permission != PackageManager.PERMISSION_GRANTED) {ActivityCompat.requestPermissions(this, PERMISSIONS_STORAGE, 0);return;}//执行填充音乐列表的异步任务new FillMusicListTask().execute();// 给音乐列表控件注册监听器lvMusicName.setOnItemClickListener(new AdapterView.OnItemClickListener() {@Overridepublic void onItemClick(AdapterView<?> adapterView, View view, int position, long id) {// 获取音乐索引app.setCurrentMusicIndex(position);// 当前播放位置归零app.setCurrentPosition(0);// 获取音乐名musicName = app.getMusicList().get(position).getMusicName();// 设置音乐名标签内容,去掉路径和扩展名,添加序号tvMusicName.setText("No." + (app.getCurrentMusicIndex() + 1) + "" + musicName.substring(musicName.lastIndexOf("/") + 1, musicName.lastIndexOf(".")));//创建意图Intent intent = new Intent();//设置广播频道:播放intent.setAction(INTENT_ACTION_PLAY);//按意图发送广播sendBroadcast(intent);}});// 给播放模式单选按钮组注册监听器rgPlayMode.setOnCheckedChangeListener(new RadioGroup.OnCheckedChangeListener() {@Overridepublic void onCheckedChanged(RadioGroup radioGroup, int checkedId) {// 判断用户选择何种播放模式switch (checkedId) {// 顺序播放模式case R.id.rb_order:app.setPlayMode(PLAY_MODE_ORDER);break;// 随机播放模式case R.id.rb_random:app.setPlayMode(PLAY_MODE_RANDOM);break;// 单曲循环模式case R.id.rb_loop:app.setPlayMode(PLAY_MODE_LOOP);break;}}});// 给音乐播放拖拽条注册监听器sbMusicProgress.setOnSeekBarChangeListener(new SeekBar.OnSeekBarChangeListener() {@Overridepublic void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) {// 判断进度是否为用户修改if (fromUser) {// 设置用户修改的播放进度app.setProgressChangedByUser(progress);// 创建意图Intent intent = new Intent();// 设置广播频道:用户修改播放进度intent.setAction(INTENT_ACTION_USER_CHANGE_PROGRESS);// 按意图发送广播sendBroadcast(intent);}}@Overridepublic void onStartTrackingTouch(SeekBar seekBar) {}@Overridepublic void onStopTrackingTouch(SeekBar seekBar) {}});//创建音乐广播接收器receiver = new MusicReceiver();//创建意图过滤器IntentFilter filter = new IntentFilter();//通过意图过滤器添加广播频道filter.addAction(INTENT_ACTION_UPDATE_PROGRESS);//注册音乐广播接收器registerReceiver(receiver,filter);}/*** 填充音乐列表异步任务类*/private class FillMusicListTask extends AsyncTask<Void, Integer, Void> {/*** 耗时工作执行前*/@Overrideprotected void onPreExecute() {super.onPreExecute();// 显示扫描音乐进度条pbScanMusic.setVisibility(View.VISIBLE);// 显示扫描音乐标签tvScanMusic.setVisibility(View.VISIBLE);}@Overrideprotected Void doInBackground(Void... voids) {// 获取音乐列表musicList = app.getMusicList();// 故意耗时,要不然扫描太快结束for (long i = 0; i < 2000000000; i++) {}return null;}/*** 耗时工作执行后** @param aVoid*/@Overrideprotected void onPostExecute(Void aVoid) {super.onPostExecute(aVoid);// 隐藏扫描音乐进度条pbScanMusic.setVisibility(View.GONE);// 隐藏扫描音乐标签tvScanMusic.setVisibility(View.GONE);// 判断音乐列表是否有元素if (musicList.size() > 0) {// 创建音乐适配器adapter = new MusicAdapter(MainActivity.this, musicList);// 给音乐列表控件设置适配器lvMusicName.setAdapter(adapter);// 获取当前要播放的音乐名(默认是音乐播放列表的第一首)musicName = musicList.get(0).getMusicName();// 设置音乐名标签内容,去掉路径和扩展名,添加序号tvMusicName.setText("No." + (app.getCurrentMusicIndex() +1)+""+musicName.substring(musicName.lastIndexOf("/")+1,musicName.lastIndexOf(".")));//创建意图,用于启动音乐服务Intent intent = new Intent(MainActivity.this, MusicPlayService.class);//按意图启动服务startService(intent);} else {// 提示用户没有音乐文件Toast.makeText(MainActivity.this, "外置存储卡上没有音乐文件!", Toast.LENGTH_SHORT);}}}/*** 音乐广播接收器*/private class MusicReceiver extends BroadcastReceiver {@Overridepublic void onReceive(Context context, Intent intent){//获取广播频道String action = intent.getAction();//判断广播频道是否为空if (action != null){//根据不同广播频道执行不同操作if(INTENT_ACTION_UPDATE_PROGRESS.equals(action)){//获取播放时长int duration = intent.getIntExtra(DURATION,0);//获取播放控制图标int controLIcon = intent.getIntExtra(CONTROL_ICON,R.drawable.play_button_selector);//计算进度值int progress = app.getCurrentPosition() * 100 / duration;//获取音乐名musicName = app.getMusicList().get(app.getCurrentMusicIndex()).getMusicName();//设置正在播放的文件名(去掉扩展名)tvMusicName.setText("No." + (app.getCurrentMusicIndex() +1)+""+musicName.substring(musicName.lastIndexOf("/")+1,musicName.lastIndexOf(".")));//设置播放进度值标签tvCurrentPosition.setText(app.getFormatTime(app.getCurrentPosition()));//设置播放时长标签tvDuration.setText(app.getFormatTime(duration));// 设置播放拖拽条的进度值sbMusicProgress.setProgress(progress);//设置【播放|暂停】按钮显示的图标btnPlayOrPause.setBackgroundResource(controLIcon);}}}}/*** 上一首按钮单击事件处理方法** @param view*/public void doPrevious(View view)  {//创建意图Intent intent = new Intent();//设置广播频道intent.setAction(INTENT_ACTION_PREVIOUS);//按意图发送广播sendBroadcast(intent);}/*** 下一首按钮单击事件处理方法** @param view*/public void doNext(View view)  {//创建意图Intent intent = new Intent();//设置广播频道intent.setAction(INTENT_ACTION_NEXT);//按意图发送广播sendBroadcast(intent);}/*** 播放|暂停按钮单击事件处理方法** @param view*/public void doPlayOrPause(View view)  {//创建意图Intent intent = new Intent();//设置广播频道intent.setAction(INTENT_ACTION_PLAY_OR_PAUSE);//按意图发送广播sendBroadcast(intent);}/*** 销毁回调方法*/@Overrideprotected void onDestroy() {super.onDestroy();//停止音乐播放服务stopService(new Intent(MainActivity.this, MusicPlayService.class));//注销广播接收器if(receiver != null){unregisterReceiver(receiver);}}}

在ui子包里创建SplashScreenActivity(启动画面)

package com.zjs.sdcard_music_player_v06.ui;import android.content.Intent;
import android.os.Bundle;
import android.view.animation.Animation;
import android.view.animation.AnimationUtils;
import android.widget.ImageView;import androidx.appcompat.app.AppCompatActivity;import com.zjs.sdcard_music_player_v06.R;public class SplashScreenActivity extends AppCompatActivity {private Animation animation;//动画对象private ImageView ivMusicIcon;//音乐图标图像控件@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);// 利用布局资源文件设置用户界面setContentView(R.layout.activity_splash_screen_activity);// 通过资源标识获得控件实例ivMusicIcon = findViewById(R.id.iv_music_icon);// 加载动画资源文件,创建动画对象animation = AnimationUtils.loadAnimation(this, R.anim.animator);// 让音乐图标图像控件启动动画ivMusicIcon.startAnimation(animation);// 给动画对象设置监听器animation.setAnimationListener(new Animation.AnimationListener() {@Overridepublic void onAnimationStart(Animation animation) {}@Overridepublic void onAnimationEnd(Animation animation) {// 启动主界面startActivity(new Intent(SplashScreenActivity.this, MainActivity.class));// 关闭启动界面finish();}@Overridepublic void onAnimationRepeat(Animation animation) {}});}}

运行效果



Android实训日志:基于外部存储的音乐播放器V06相关推荐

  1. Android实训日志:基于外部存储的音乐播放器V04

    文章目录 项目功能 实现步骤 创建安卓应用 将图片素材放入drawable 按钮背景图片选择器 在项目清单文件里设置安卓应用的图标和授权访问外置存储卡 主布局资源文件activity_main.xml ...

  2. Android 实训日志:基于外部存储的音乐播放器V03

    文章目录 项目功能 实现步骤 创建安卓应用 将图片素材放入drawable 按钮背景图片选择器 在项目清单文件里设置安卓应用的图标和授权访问外置存储卡 主布局资源文件activity_main.xml ...

  3. Android实训日志:基于外部存储的音乐播放器V05

    目录 项目功能 实现步骤 创建安卓应用 将图片素材放入drawable 按钮图片选择器 编写主布局文件 编写字符串文件 创建音乐列表项模板music_name_list_item.xml 创建ui子包 ...

  4. Android实训日志:基于外部存储卡的音乐播放器V02

    目录 功能要求 实现步骤 创建安卓应用 将图片素材放入drawable 播放按钮图片选择器 编写主布局文件 创建ui目录,将主界面类放入 创建util目录,创建CommonUtils工具类 编写Com ...

  5. 【网络收录】基于51单片机开发音乐播放器

    [网络收录]基于51单片机开发音乐播放器 本文作者:天析 作者邮箱:2200475850@qq.com 发布时间: Thu, 22 May 2014 18:14:00 +0800 特别声明:本资料来源 ...

  6. (附源码)springboot+基于微信小程序音乐播放器的设计与实现 毕业设计271156

    Springboot音乐播放小程序的设计与实现 摘 要 本文设计了一种基于微信小程序的音乐播放器,系统为人们提供了方便快捷.即用即搜的音乐搜索播放服务,包括音乐资讯.音乐库推荐.交流论坛.注册登录.最 ...

  7. springboot+基于微信小程序音乐播放器的设计与实现 毕业设计-附源码271156

    Springboot音乐播放小程序的设计与实现 摘 要 本文设计了一种基于微信小程序的音乐播放器,系统为人们提供了方便快捷.即用即搜的音乐搜索播放服务,包括音乐资讯.音乐库推荐.交流论坛.注册登录.最 ...

  8. html实现音乐界面设计,基于HTML5技术的音乐播放器的设计与实现.doc

    基于HTML5技术的音乐播放器的设计与实现 基于HTML5技术的音乐播放器的设计与实现 常志强 刘正余 杨劲楠 皖西学院电子与信息工程学院 X 关注成功! 加关注后您将方便地在 我的关注中得到本文献的 ...

  9. web html5音乐播放器设计与实现,基于HTML5技术的音乐播放器的设计与实现

    Vol.33No.11Nov.2017 赤峰学院学报(自然科学版) Journal of Chifeng University (Natural Science Edition )第33卷第11期(下 ...

最新文章

  1. 浪潮集团执行总裁王柏华:这次人工智能产业发展大潮“是真的”
  2. 一个网站让你系统的入门脑机接口和神经科学
  3. 谷歌研发能处理多域多任务的机器学习模型——MultiModel
  4. 反应能力测试题_微笑抑郁的表现症状有哪些?你是否正在受微笑抑郁困扰?(内附测试题)...
  5. Python帮你识破双11的套路
  6. MFC改变对话框背景图片实例
  7. FPGA专有名词的积累
  8. java设计模式之状态模式_Java中的状态设计模式
  9. css 实现16:9比例自适应手机尺寸,可设置任意比例
  10. 【Nginx那些事】Nginx 配置文件说明
  11. 通过路由远程计算机重启,路由器怎么重启?这几种方法教你重启怎么弄!
  12. 华为机试HJ88:扑克牌大小
  13. 使用kubeadm安装k8s集群故障处理三则
  14. [HDOJ]1001. Sum Problem
  15. Windows7 简体中文旗舰版下载 (MSDN官方发布正式版原版镜像)
  16. vue项目中我的收货地址功能做法(添加地址、编辑地址、删除地址、默认地址、省市区三级联动)
  17. python扫雷游戏代码_基于Python实现的扫雷游戏实例代码
  18. php中fastcgi和php-fpm是什么
  19. buuctf misc 小易的U盘
  20. http请求digest auth认证

热门文章

  1. SQL Server 批量插入数据的两种方法(转)
  2. xx is not in the sudoers file 问题解决
  3. 腾讯云linux服务器怎么使用图形化界面_自己搭建一个自动签到和远程下载的服务器...
  4. 【控制】《复杂运动体系统的分布式协同控制与优化》-方浩老师-第4章-一类欧拉-拉格朗日系统全局稳定的输出反馈协调控制
  5. 1.4 满足和优化指标-深度学习第三课《结构化机器学习项目》-Stanford吴恩达教授
  6. C语言之详解#ifdef等宏
  7. DIY烤肉加热台,了解一下?
  8. C++类与const关键字
  9. 传统IDC转型有了新思路 Zstack除了混合云还有托管云
  10. Windows Server2012 搭建域错误“本地Administraor账户不需要密码”