功能簡介
- 讀取模擬器中音樂檔案;
- 串列展示,獲取歌曲詳細資訊:歌名、歌手名、專輯名、專輯封面、播放時間等;
- 基本功能:上下切歌,播放暫停、進度條顯示與點擊跳轉,
- 成品效果圖:

Mediaplayer基本狀態
Mediaplayer播放器主要涉及以下狀態,通過呼叫圖中函式進行狀態跳轉,
- Idle //mPlayer剛被創建或者重置之后還未被初始化時的狀態;
- Initialized //setDataSource()加載資源后進入初始化狀態;
- Preparing和Prepared //Preparing是準備中狀態, Prepared是就緒狀態,可進行播放屬性的設定,
- Started和Paused //播放和暫停狀態,呼叫start()和pause()進行跳轉
- Stop //停止狀態,當在某個時刻呼叫了stop()之后,就需要再次呼叫prepare()使mPlayer轉到就緒狀態,
- PlaybackCompleted //播放完畢狀態,如果設定了回圈播放模式,當播放完畢的時候,mPlayer會重新進入到Started狀態
- End //End是結束狀態,當呼叫release()時,會釋放播放引擎中與mPlayer相關的資源,這時就無法再轉換到其他狀態了,
- Error //當mPlayer出現一些錯誤(例如,格式錯誤),就會呼叫OnErrorListener.OnError()方法進入到Error狀態,

專案難點詳解
添加資源檔案
- 工程專案添加
專案res資源檔案夾 -> 新建raw資源檔案夾 -> 添加資源

- 模擬器添加音樂
1.打開模擬器存盤目錄,運行模擬器 -> View -> Tools Windows -> Device File Explorer;
2.存盤音樂至sdcard/Music/ 或storage/emulated/0/Music/;
3.右鍵點擊Upload,選擇音樂資源加載,

權限
- 靜態權限
讀權限&寫權限,直接宣告使用
[AndroidManifest.xml]
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/>
- 動態權限
因為涉及SD卡讀取,需要使用動態權限,Android6.0后權限分為靜態權限與動態權限,需要分開定義,如果讀取工程專案中指定資源資源檔案,使用靜態權限即可,
[MainActivity.java] 中宣告使用,分為權限獲取函式及其回呼函式
//動態權限申請函式
if (ContextCompat.checkSelfPermission( MainActivity.this,
Manifest.permission.WRITE_APN_SETTINGS ) != PackageManager.PERMISSION_GRANTED) //判斷是否已經授權
{
//申請權限 三個引數:1.Activity實體;2.String陣列,存放權限;3.唯一請求碼
ActivityCompat.requestPermissions( MainActivity.this, new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE,
Manifest.permission.READ_EXTERNAL_STORAGE}, 1 );
}else{
//填寫功能函式
loadLocalMusicData(); //權限請求失敗,則加載本地資料源,請求成功則呼叫回呼函式中的加載,不管成功與否都會呼叫
}
//動態權限獲取函式的回呼函式
@Override
public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
super.onRequestPermissionsResult( requestCode, permissions, grantResults );
switch (requestCode) {
case 1:
if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
//填寫功能函式
loadLocalMusicData(); //申請權限成功,掃描模擬器存盤,加載資源
} else {
finish();
Toast.makeText( this, "denied!", Toast.LENGTH_SHORT ).show();
}
}
}
媒體庫資源更新
在模擬器中添加資源,并通過動態權限進行讀取的程序中,Android系統并不會時時全域掃描資源,通常開關機模擬器時才掃描,所以需要進行媒體庫的主動掃描資源,
private void loadLocalMusicData() {
/* 更新媒體庫mp3檔案*/
String file_path = "storage/emulated/0/Music";
MediaScannerConnection.scanFile( this,
new String[]{file_path.toString()},
// null,
new String[]{"mp3"}, //指定掃描mp3檔案,縮短時間
new MediaScannerConnection.OnScanCompletedListener() {
@Override
public void onScanCompleted(String path, Uri uri) {
Log.i( "ExternalStorage", "Scanned" + path + ":" );
Log.i( "ExternalStorage", "->" + uri);
}
} );
讀取Android多媒體資源檔案
這里使用MediaStore庫,其是android系統提供的一個多媒體資料庫,專門用于存放多媒體資訊的,通過ContentResolver即可對資料庫進行操作,
- MediaStore.Files: 共享的檔案,包括多媒體和非多媒體資訊
- MediaStore.Audio: 存放音頻資訊
- MediaStore.Image: 存放圖片資訊
- MediaStore.Vedio: 存放視頻資訊
模塊化讀取資源資訊,如mp3檔案中的歌曲名、歌手名、專輯名、時長、存放路徑等資訊,
- MediaStore.Audio.Media.TITLE //歌曲標題
- MediaStore.Audio.Media.ARTIST //歌手名
- MediaStore.Audio.Media.ALBUM //專輯名
- MediaStore.Audio.Media.DATA //路徑
- MediaStore.Audio.Media.DURATION //視頻時長
- MediaStore.Audio.Media.ALBUM_ID //相冊名
[MainActivity.java]
/* 加載本地存盤當中的音樂mp3檔案到集合當中*/
// 1.獲取ContentResolver物件
ContentResolver resolver = getContentResolver();
// 2.獲取本地音樂存盤的Uri地址
Uri uri = MediaStore.Audio.Media.EXTERNAL_CONTENT_URI;
// 3 開始查詢地址 查詢介面
Cursor cursor = resolver.query(uri, null, null, null, null);
// 4.遍歷Cursor
int id = 0;
while (cursor.moveToNext()) {
String song = cursor.getString(cursor.getColumnIndex(MediaStore.Audio.Media.TITLE)); //歌曲標題
String singer = cursor.getString(cursor.getColumnIndex(MediaStore.Audio.Media.ARTIST)); //歌手名
String album = cursor.getString(cursor.getColumnIndex(MediaStore.Audio.Media.ALBUM)); //專輯名
id++;
String sid = String.valueOf(id); //序列號
String path = cursor.getString(cursor.getColumnIndex(MediaStore.Audio.Media.DATA)); //路徑
long duration = cursor.getLong(cursor.getColumnIndex(MediaStore.Audio.Media.DURATION)); //視頻時長
SimpleDateFormat sdf = new SimpleDateFormat("mm:ss");
String time = sdf.format(new Date(duration));
// 獲取專輯圖片主要是通過album_id進行查詢
String album_id = cursor.getString(cursor.getColumnIndex(MediaStore.Audio.Media.ALBUM_ID));//相冊名
String albumArt = getAlbumArt(album_id);
// 將一行當中的資料封裝到物件當中
LocalMusicBean bean = new LocalMusicBean(sid, song, singer, album, time, path, albumArt); //每一首歌的資訊封裝
mDatas.add(bean);
}
// 資料源變化,提示配接器更新
adapter.notifyDataSetChanged();
獲取歌曲封面
//獲取歌曲的封面
private void loadCover(String path){
MediaMetadataRetriever mediaMetadataRetriever = new MediaMetadataRetriever();
mediaMetadataRetriever.setDataSource( path );
byte[] cover = mediaMetadataRetriever.getEmbeddedPicture();
Bitmap bitmap = BitmapFactory.decodeByteArray( cover, 0, cover.length );
albumIv.setImageBitmap( bitmap );
}
獲取歌曲的時間以及進度條跳轉
- 兩個TextView:tv_star, tv_end分別時時顯示當前時間,時間總長;
- 一個SeekBar實作進度動態顯示與跳轉;
- 延時50ms更新時間進度條;
- SeekBar回呼函式,點擊時、移動時、確定時,
private void SeekBarSet(){
/*新增seekbar進度條*/
int duration = mediaPlayer.getDuration(); //獲取視頻總時間
seekBar.setMax( duration ); //將音樂總時間設定為Seekbar的最大值
Timer timer = new Timer( );
timer.schedule( new TimerTask() {
@Override
public void run() {
// if (!currentPausePositionInSong){
seekBar.setProgress( mediaPlayer.getCurrentPosition() );
// }
}
},0,50);
seekBar.setOnSeekBarChangeListener( new SeekBar.OnSeekBarChangeListener() {
@Override
public void onProgressChanged(SeekBar seekBar, int i, boolean b) {
int time_end = mediaPlayer.getDuration() / 1000 ; //獲取視頻時長
tv_end.setText(calaculateTime( time_end ));
int time_now = mediaPlayer.getCurrentPosition() / 1000;
tv_star.setText(calaculateTime( time_now ) );
}
@Override
public void onStartTrackingTouch(SeekBar seekBar) {
}
@Override
public void onStopTrackingTouch(SeekBar seekBar) {
mediaPlayer.seekTo( seekBar.getProgress() );
// tv_star.setText(formattime( mediaPlayer.getCurrentPosition() ));
}
} );
}
專案部分代碼
使用控制元件串列
| 控制元件型別 | 功能 | 詳細控制元件 |
|---|---|---|
| ImageView | 圖形按鍵 | 上一首、下一首、播放、暫停 |
| TextView | 文本欄 | 歌曲名、歌手名、專輯名、單前播放時間、總時長 |
| RecyclerView | 滑動串列 | 加載各歌曲資訊的串列 |
| LocalMusicAdapter | 橫條資訊展示欄 | 加載每一首歌曲資訊的基本資訊 |
| SeekBar | 進度條 | 顯示當前歌曲進度資訊 |
基本控制元件為以上所述,前端代碼就不貼了
專案詳細代碼
[MainActivity.java] 主類,包含各控制元件定義與各監聽器定義及功能
package com.example.musicplayer_2;
import androidx.annotation.NonNull;
import androidx.appcompat.app.AppCompatActivity;
import androidx.core.app.ActivityCompat;
import androidx.core.content.ContextCompat;
import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.recyclerview.widget.RecyclerView;
import android.Manifest;
import android.content.ContentResolver;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.database.Cursor;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.media.MediaMetadataRetriever;
import android.media.MediaPlayer;
import android.media.MediaScannerConnection;
import android.net.Uri;
import android.os.Build;
import android.os.Bundle;
import android.os.Environment;
import android.provider.MediaStore;
import android.util.Log;
import android.view.View;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.SeekBar;
import android.widget.TextView;
import android.widget.Toast;
import java.io.File;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Timer;
import java.util.TimerTask;
public class MainActivity extends AppCompatActivity implements View.OnClickListener {
private MediaPlayer mediaPlayer;
private ImageView nextIv,playIv,lastIv,albumIv; //影像控制元件:
private TextView singerTv,songTv; //文本資訊:歌手名、歌名
private RecyclerView musicRv; //類似ListView 可橫向滾動
private SeekBar seekBar;
private TextView tv_star, tv_end;
private List<LocalMusicBean> mDatas; //資料源 自定義類陣列 存放各歌曲資訊
private LocalMusicAdapter adapter; //歌曲橫條資訊控制元件設定
private int currnetPlayPosition = -1; //記錄當前正在播放的音樂的位置
private int currentPausePositionInSong = 0; //記錄暫停音樂時進度條的位置
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate( savedInstanceState );
setContentView( R.layout.activity_main );
initView(); //控制元件定義與系結 減少代碼量
mediaPlayer = new MediaPlayer();
mDatas = new ArrayList<>(); //任意型別陣列
//創建配接器物件
adapter = new LocalMusicAdapter(this, mDatas); //傳參context,mDatas
musicRv.setAdapter(adapter);
//設定布局管理器
LinearLayoutManager layoutManager = new LinearLayoutManager(this, LinearLayoutManager.VERTICAL, false);
musicRv.setLayoutManager(layoutManager);
//動態權限申請
if (ContextCompat.checkSelfPermission( MainActivity.this,
Manifest.permission.WRITE_APN_SETTINGS ) != PackageManager.PERMISSION_GRANTED) //判斷是否已經授權
{
//申請權限 三個引數:1.Activity實體;2.String陣列,存放權限;3.唯一請求碼
ActivityCompat.requestPermissions( MainActivity.this, new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE,
Manifest.permission.READ_EXTERNAL_STORAGE}, 1 );
}else{
loadLocalMusicData(); //權限請求失敗,則加載本地資料源,請求成功則呼叫回呼函式中的加載,不管成功與否都會呼叫
}
// loadLocalMusicData(); //加載本地資料源
setEventListener(); //設定每一項的點擊事件
}
//動態權限獲取函式的回呼函式
@Override
public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
super.onRequestPermissionsResult( requestCode, permissions, grantResults );
switch (requestCode) {
case 1:
if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
loadLocalMusicData(); //申請權限成功,掃描模擬器存盤,加載資源
} else {
finish();
Toast.makeText( this, "denied!", Toast.LENGTH_SHORT ).show();
}
}
}
private void loadLocalMusicData() {
/* 更新媒體庫mp3檔案*/
String file_path = "storage/emulated/0/Music";
MediaScannerConnection.scanFile( this,
new String[]{file_path.toString()},
// null,
new String[]{"mp3"},
new MediaScannerConnection.OnScanCompletedListener() {
@Override
public void onScanCompleted(String path, Uri uri) {
Log.i( "ExternalStorage", "Scanned" + path + ":" );
Log.i( "ExternalStorage", "->" + uri);
}
} );
/* 加載本地存盤當中的音樂mp3檔案到集合當中*/
// 1.獲取ContentResolver物件
ContentResolver resolver = getContentResolver();
// 2.獲取本地音樂存盤的Uri地址
Uri uri = MediaStore.Audio.Media.EXTERNAL_CONTENT_URI;
// 3 開始查詢地址 查詢介面
Cursor cursor = resolver.query(uri, null, null, null, null);
// 4.遍歷Cursor
int id = 0;
while (cursor.moveToNext()) {
String song = cursor.getString(cursor.getColumnIndex(MediaStore.Audio.Media.TITLE)); //歌曲標題
String singer = cursor.getString(cursor.getColumnIndex(MediaStore.Audio.Media.ARTIST)); //歌手名
String album = cursor.getString(cursor.getColumnIndex(MediaStore.Audio.Media.ALBUM)); //專輯名
id++;
String sid = String.valueOf(id); //序列號
String path = cursor.getString(cursor.getColumnIndex(MediaStore.Audio.Media.DATA)); //路徑
long duration = cursor.getLong(cursor.getColumnIndex(MediaStore.Audio.Media.DURATION)); //視頻時長
SimpleDateFormat sdf = new SimpleDateFormat("mm:ss");
String time = sdf.format(new Date(duration));
// 獲取專輯圖片主要是通過album_id進行查詢
String album_id = cursor.getString(cursor.getColumnIndex(MediaStore.Audio.Media.ALBUM_ID));//相冊名
String albumArt = getAlbumArt(album_id);
// 將一行當中的資料封裝到物件當中
LocalMusicBean bean = new LocalMusicBean(sid, song, singer, album, time, path, albumArt); //每一首歌的資訊封裝
mDatas.add(bean);
}
// 資料源變化,提示配接器更新
adapter.notifyDataSetChanged();
}
private void initView() {
/* 初始化控制元件的函式*/
nextIv = findViewById(R.id.local_music_bottom_iv_next);
playIv = findViewById(R.id.local_music_bottom_iv_play);
lastIv = findViewById(R.id.local_music_bottom_iv_last);
albumIv = findViewById(R.id.local_music_bottom_iv_icon);
singerTv = findViewById(R.id.local_music_bottom_tv_singer);
songTv = findViewById(R.id.local_music_bottom_tv_song);
musicRv = findViewById(R.id.local_music_rv);
nextIv.setOnClickListener(this);
lastIv.setOnClickListener(this);
playIv.setOnClickListener(this);
seekBar = findViewById( R.id.local_music_bottom_tv_time ); //進度條定義
tv_star = findViewById( R.id.local_music_bottom_tv_time_star );
tv_end = findViewById( R.id.local_music_bottom_tv_time_end );
}
private void setEventListener() {
/* 設定每一項的點擊事件*/
adapter.setOnItemClickListener(new LocalMusicAdapter.OnItemClickListener() {
@Override
public void OnItemClick(View view, int position) {
currnetPlayPosition = position;
LocalMusicBean musicBean = mDatas.get(position);
playMusicInMusicBean(musicBean);
}
});
}
public void playMusicInMusicBean(LocalMusicBean musicBean) { //傳入一首歌 資訊
/*根據傳入物件播放音樂*/
//設定底部顯示的歌手名稱和歌曲名
singerTv.setText(musicBean.getSinger()); //獲取當前資訊并設定
songTv.setText(musicBean.getSong());
stopMusic();
// 重置多媒體播放器
mediaPlayer.reset();
// 設定新的播放路徑
try {
mediaPlayer.setDataSource(musicBean.getPath());
String albumArt = musicBean.getAlbumArt();
Log.i("lsh123", "playMusicInMusicBean: albumpath=="+albumArt);
Bitmap bm = BitmapFactory.decodeFile(albumArt);
Log.i("lsh123", "playMusicInMusicBean: bm=="+bm);
albumIv.setImageBitmap(bm);
playMusic();
SeekBarSet(); //設定進度條及其時間顯示
loadCover(musicBean.getPath());
} catch (Exception e) {
e.printStackTrace();
}
}
private void SeekBarSet(){
/*新增seekbar進度條*/
int duration = mediaPlayer.getDuration(); //獲取視頻總時間
seekBar.setMax( duration ); //將音樂總時間設定為Seekbar的最大值
Timer timer = new Timer( );
timer.schedule( new TimerTask() {
@Override
public void run() {
// if (!currentPausePositionInSong){
seekBar.setProgress( mediaPlayer.getCurrentPosition() );
// }
}
},0,50);
seekBar.setOnSeekBarChangeListener( new SeekBar.OnSeekBarChangeListener() {
@Override
public void onProgressChanged(SeekBar seekBar, int i, boolean b) {
int time_end = mediaPlayer.getDuration() / 1000 ; //獲取視頻時長
tv_end.setText(calaculateTime( time_end ));
int time_now = mediaPlayer.getCurrentPosition() / 1000;
tv_star.setText(calaculateTime( time_now ) );
}
@Override
public void onStartTrackingTouch(SeekBar seekBar) {
}
@Override
public void onStopTrackingTouch(SeekBar seekBar) {
mediaPlayer.seekTo( seekBar.getProgress() );
// tv_star.setText(formattime( mediaPlayer.getCurrentPosition() ));
}
} );
}
/*
* 點擊播放按鈕播放音樂,或者暫停從新播放
* 播放音樂有兩種情況:
* 1.從暫停到播放
* 2.從停止到播放
* */
private void playMusic() {
/* 播放音樂的函式*/
if (mediaPlayer!=null&&!mediaPlayer.isPlaying()) {
if (currentPausePositionInSong == 0) { //如果已經停止播放
try {
mediaPlayer.prepare(); //重新準備播放
mediaPlayer.start();
} catch (Exception e) {
e.printStackTrace();
}
}else{
// 從暫停到播放
mediaPlayer.seekTo(currentPausePositionInSong);
mediaPlayer.start();
}
// playIv.setImageResource(R.mipmap.icon_pause);
}
}
private void pauseMusic() {
/* 暫停音樂的函式*/
if (mediaPlayer!=null&&mediaPlayer.isPlaying()) {
currentPausePositionInSong = mediaPlayer.getCurrentPosition(); //獲取進度條
mediaPlayer.pause();
playIv.setImageResource(R.mipmap.icon_play);
}
}
private void stopMusic() {
/* 停止音樂的函式*/
if (mediaPlayer!=null) {
currentPausePositionInSong = 0;
mediaPlayer.pause(); //播放器暫停
mediaPlayer.seekTo(0); //調至0
mediaPlayer.stop(); //停止
playIv.setImageResource(R.mipmap.icon_play); //顯示圖示
}
}
@Override
protected void onDestroy() {
super.onDestroy();
stopMusic();
}
/*進度條時間換算與格式轉變*/
//時間格式換算1
public String formattime(long time){
String min= (time/(1000*60))+"";
String second= (time%(1000*60)/1000)+"";
if(min.length()<2){
min = 0 + min;
}
if(second.length()<2){
second = 0 + second;
}
return min +":"+ second;
}
//時間格式換算2
public String calaculateTime(int time){
int minute, second;
if(time > 60){
minute = time / 60; //分鐘取整
second = time % 60; //秒鐘取余
//分鐘再0~9
if(minute >= 0 && minute < 10){ //0x:0x
//判斷秒
if(second >= 0 && second < 10){
return "0"+minute+":"+"0"+second;
}else {
return "0"+minute+":"+second;
}
}else {
//分鐘大于10再判斷秒
if(second >= 0 && second < 10){
return minute+":"+"0"+second;
}else {
return minute+":"+second;
}
}
}else if(time < 60){
second = time;
if(second >= 0 && second < 10){
return "00:"+"0"+second;
}else {
return "00:"+ second;
}
}
return null;
}
private String getAlbumArt(String album_id) {
String mUriAlbums = "content://media/external/audio/albums";
String[] projection = new String[]{"album_art"};
Cursor cur = this.getContentResolver().query(
Uri.parse(mUriAlbums + "/" + album_id),
projection, null, null, null);
String album_art = null;
if (cur.getCount() > 0 && cur.getColumnCount() > 0) {
cur.moveToNext();
album_art = cur.getString(0);
}
cur.close();
cur = null;
return album_art;
}
private void loadCover(String path){
MediaMetadataRetriever mediaMetadataRetriever = new MediaMetadataRetriever();
mediaMetadataRetriever.setDataSource( path );
byte[] cover = mediaMetadataRetriever.getEmbeddedPicture();
Bitmap bitmap = BitmapFactory.decodeByteArray( cover, 0, cover.length );
albumIv.setImageBitmap( bitmap );
}
@Override
public void onClick(View v) {
switch (v.getId()) {
case R.id.local_music_bottom_iv_last: //上一首
if (currnetPlayPosition ==0) {
Toast.makeText(this,"已經是第一首了,沒有上一曲!",Toast.LENGTH_SHORT).show();
return;
}
currnetPlayPosition = currnetPlayPosition-1; //序號索引-1
LocalMusicBean lastBean = mDatas.get(currnetPlayPosition); //從陣列中獲取上一首資訊
playMusicInMusicBean(lastBean);
break;
case R.id.local_music_bottom_iv_next: //下一首
if (currnetPlayPosition ==mDatas.size()-1) {
Toast.makeText(this,"已經是最后一首了,沒有下一曲!",Toast.LENGTH_SHORT).show();
return;
}
currnetPlayPosition = currnetPlayPosition+1;
LocalMusicBean nextBean = mDatas.get(currnetPlayPosition);
playMusicInMusicBean(nextBean);
break;
case R.id.local_music_bottom_iv_play:
if (currnetPlayPosition == -1) {
// 并沒有選中要播放的音樂
Toast.makeText(this,"請選擇想要播放的音樂",Toast.LENGTH_SHORT).show();
return;
}
if (mediaPlayer.isPlaying()) {
// 此時處于播放狀態,需要暫停音樂
pauseMusic();
}else {
// 此時沒有播放音樂,點擊開始播放音樂
playMusic();
}
break;
}
}
}
[LocalMusicBean.java] 歌曲資訊封裝類,包含歌曲各資訊
package com.example.musicplayer_2;
/**
* author : harrison
* e-mail : harrison.zfx@gmail.com
* data : zfx上午10:29
* version: 1.0
*/
public class LocalMusicBean {
private String id; //歌曲id
private String song; //歌曲名稱
private String singer; //歌手名稱
private String album; //專輯名稱
private String duration; //歌曲時長
private String path; //歌曲路徑
private String albumArt; //專輯地址
public LocalMusicBean() {
}
public LocalMusicBean(String id, String song, String singer, String album, String duration, String path, String albumArt) {
this.id = id;
this.song = song;
this.singer = singer;
this.album = album;
this.duration = duration;
this.path = path;
this.albumArt = albumArt;
}
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
public String getSong() {
return song;
}
public void setSong(String song) {
this.song = song;
}
public String getSinger() {
return singer;
}
public void setSinger(String singer) {
this.singer = singer;
}
public String getAlbum() {
return album;
}
public void setAlbum(String album) {
this.album = album;
}
public String getDuration() {
return duration;
}
public void setDuration(String duration) {
this.duration = duration;
}
public String getPath() {
return path;
}
public void setPath(String path) {
this.path = path;
}
public String getAlbumArt() {
return albumArt;
}
public void setAlbumArt(String albumArt) {
this.albumArt = albumArt;
}
}
[LocalMusicAdapter.java] 歌曲橫向展示類
package com.example.musicplayer_2;
import android.content.Context;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.AdapterView;
import android.widget.TextView;
import androidx.annotation.NonNull;
import androidx.recyclerview.widget.RecyclerView;
import java.util.List;
/**
* author : harrison
* e-mail : harrison.zfx@gmail.com
* data : zfx上午10:49
* version: 1.0
*/
public class LocalMusicAdapter extends RecyclerView.Adapter<LocalMusicAdapter.LocalMusicViewHolder>{
private Context context;
private List<LocalMusicBean>mDatas;
private OnItemClickListener onItemClickListener;
public void setOnItemClickListener(OnItemClickListener onItemClickListener) { //監聽器引數傳入
this.onItemClickListener = onItemClickListener;
}
public interface OnItemClickListener{
public void OnItemClick(View view,int position);
}
public LocalMusicAdapter(Context context, List<LocalMusicBean> mDatas) { //建構式傳入引數 context背景關系,資料集
this.context = context;
this.mDatas = mDatas;
}
@NonNull
@Override
public LocalMusicViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
View view = LayoutInflater.from(context).inflate(R.layout.item_local_music,parent,false);
LocalMusicViewHolder holder = new LocalMusicViewHolder(view);
return holder;
}
@Override
public void onBindViewHolder(@NonNull LocalMusicViewHolder holder, final int position) {
LocalMusicBean musicBean = mDatas.get(position);
holder.idTv.setText(musicBean.getId());
holder.songTv.setText(musicBean.getSong());
holder.singerTv.setText(musicBean.getSinger());
holder.albumTv.setText(musicBean.getAlbum());
holder.timeTv.setText(musicBean.getDuration());
holder.itemView.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
onItemClickListener.OnItemClick(v,position);
}
});
}
@Override
public int getItemCount() {
return mDatas.size();
}
class LocalMusicViewHolder extends RecyclerView.ViewHolder{
TextView idTv,songTv,singerTv,albumTv,timeTv;
public LocalMusicViewHolder(View itemView) {
super(itemView);
idTv = itemView.findViewById(R.id.item_local_music_num); //序號
songTv = itemView.findViewById(R.id.item_local_music_song); //歌名
singerTv = itemView.findViewById(R.id.item_local_music_singer); //歌手名
albumTv = itemView.findViewById(R.id.item_local_music_album); //專輯名
timeTv = itemView.findViewById(R.id.item_local_music_durtion); //時間
}
}
}
前端頁面代碼較長就不貼了,上表中已列清基本控制元件使用,
掙點積分,后續會上傳GitHub,完整工程地址:https://download.csdn.net/download/Harrison509/12894922
轉載請註明出處,本文鏈接:https://www.uj5u.com/qianduan/138983.html
標籤:其他
