作为android初学者,最近把疯狂android讲义和疯狂Java讲义看了一遍,看到书中介绍的知识点非常多,很难全部记住,为了更好的掌握基础知识点,我将开发一个网络音乐播放器-EasyMusic来巩固下,也当作是练练手。感兴趣的朋友可以看看,有设计不足的地方也欢迎指出。
开发之前首先介绍下该音乐播放器将要开发的功能(需求):
1.本地音乐的加载和播放;
2.网络音乐的搜索,试听和下载;
3.音乐的断点下载;
4.点击播放图标加载专辑图片,点击歌词加载歌词并滚动显示(支持滑动歌词改变音乐播放进度);
5.支持基于popupWindow的弹出式菜单;
6.支持后台任务栏显示和控制。
该篇主要是贴上一些关键类的代码以及音乐播放器的展示效果图:
首先看下效果图:
1>收藏音乐:
2>取消收藏:
然后主要代码如下:
1.MainActivity.java
package com.sprd.easymusic;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Locale;
import java.util.Map;
import com.sprd.easymusic.fragment.DownloadFragment;
import com.sprd.easymusic.fragment.MusicListFragment;
import com.sprd.easymusic.fragment.NetFragment;
import com.sprd.easymusic.fragment.StoredSongFragment;
import com.sprd.easymusic.mysql.MyDBHelper;
import com.sprd.easymusic.service.PlayMusicService;
import android.app.Activity;
import android.app.Service;
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.content.ServiceConnection;
import android.database.Cursor;
import android.os.Bundle;
import android.os.IBinder;
import android.provider.MediaStore;
import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentActivity;
import android.support.v4.app.FragmentManager;
import android.support.v4.app.FragmentPagerAdapter;
import android.support.v4.view.ViewPager;
import android.support.v4.view.ViewPager.OnPageChangeListener;
import android.util.DisplayMetrics;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.view.ViewGroup;
import android.widget.AdapterView;
import android.widget.AdapterView.OnItemClickListener;
import android.widget.BaseAdapter;
import android.widget.ListView;
import android.widget.SimpleAdapter;
import android.widget.TextView;
import android.widget.Toast;
public class MainActivity extends FragmentActivity implements
MusicListFragment.CallBack, StoredSongFragment.CallBack,
View.OnClickListener {
private String TAG = "MainActivity";
private final int FRAGMENT_COUNT = 4;
// dbMusic保存媒体库中的所有音乐
private ViewPager mViewPager;
private SectionsPagerAdapter mSectionsPagerAdapter;
private List<Map<String, Object>> allMusic = new ArrayList<>();
private List<Map<String, Object>> storedMusic = new ArrayList<>();
private Context mContext;
private TextView fragmentTitle1, fragmentTitle2, fragmentTitle3,
fragmentTitle4, titleBottomLine;
private int screenWidth, bottomLineWidth;
private PlayMusicService playService;
private MyDBHelper myHelper;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mContext = this;
myHelper = new MyDBHelper(mContext, "easyMusic.db3", null, 1);
getAllMusicFromDb();
getStoredMusic(storedMusic, myHelper);
getBottomLineWidth();
mSectionsPagerAdapter = new SectionsPagerAdapter(
getSupportFragmentManager());
mViewPager = (ViewPager) findViewById(R.id.pager);
mViewPager.setAdapter(mSectionsPagerAdapter);
fragmentTitle1 = (TextView) findViewById(R.id.fragment1);
fragmentTitle1.setOnClickListener(this);
fragmentTitle2 = (TextView) findViewById(R.id.fragment2);
fragmentTitle2.setOnClickListener(this);
fragmentTitle3 = (TextView) findViewById(R.id.fragment3);
fragmentTitle3.setOnClickListener(this);
fragmentTitle4 = (TextView) findViewById(R.id.fragment4);
fragmentTitle4.setOnClickListener(this);
titleBottomLine = (TextView) findViewById(R.id.fragmentTitle);
bindToService();
mViewPager.setOnPageChangeListener(new OnPageChangeListener() {
public void onPageSelected(int position) {
}
public void onPageScrolled(int item, float percent, int offset) {
titleBottomLine.setX(item * bottomLineWidth + offset
/ FRAGMENT_COUNT);
}
public void onPageScrollStateChanged(int position) {
}
});
}
private void getBottomLineWidth() {
DisplayMetrics dm = new DisplayMetrics();
this.getWindowManager().getDefaultDisplay().getMetrics(dm);
screenWidth = dm.widthPixels;
bottomLineWidth = screenWidth / FRAGMENT_COUNT;
}
// 绑定服务时的ServiceConnection参数
private ServiceConnection conn = new ServiceConnection() {
// 绑定成功后该方法回调,并获得服务端IBinder的引用
public void onServiceConnected(ComponentName name, IBinder service) {
// 通过获得的IBinder获取PlayMusicService的引用
playService = ((PlayMusicService.MusicBinder) service).getService();
Toast.makeText(mContext, "onServiceConnected", Toast.LENGTH_LONG)
.show();
}
@Override
public void onServiceDisconnected(ComponentName name) {
Log.d(TAG, "onServiceDisconnected");
}
};
// 绑定服务PlayMusicService
private void bindToService() {
bindService(new Intent(mContext,
com.sprd.easymusic.service.PlayMusicService.class), conn,
Service.BIND_AUTO_CREATE);
}
// 通过获得的PlayMusicService引用调用播放音乐的方法,方法传进去的参数为音乐url
protected void playMusic(String url) {
if (playService != null) {
playService.play(url);
}
}
// 从媒体库中查询音乐
private void getAllMusicFromDb() {
if (allMusic.size() > 0)
allMusic.clear();
Cursor musicCursor1 = this
.getContentResolver()
.query(MediaStore.Audio.Media.EXTERNAL_CONTENT_URI, null, null,
null, MediaStore.Audio.Media.DEFAULT_SORT_ORDER);
// 从外部存储获取
getMusic(musicCursor1);
Cursor musicCursor2 = this
.getContentResolver()
.query(MediaStore.Audio.Media.INTERNAL_CONTENT_URI, null, null,
null, MediaStore.Audio.Media.DEFAULT_SORT_ORDER);
// 从内部存储获取
getMusic(musicCursor2);
}
// 检查当前歌曲是否在收藏列表中,在收藏列表返回true,否则返回false
protected boolean checkIfStored(String url) {
for (Map<String, Object> map : storedMusic) {
if (url.equals((String) map.get("url"))) {
return true;
}
}
return false;
}
// 获取到的音乐以Map的形式存储在dbMusic中
private void getMusic(Cursor musicCursor) {
while (musicCursor.moveToNext()) {
Map<String, Object> item = new HashMap<String, Object>();
long id = musicCursor.getLong(musicCursor
.getColumnIndex(MediaStore.Audio.Media._ID));
String title = musicCursor.getString(musicCursor
.getColumnIndex(MediaStore.Audio.Media.TITLE));
String artist = musicCursor.getString(musicCursor
.getColumnIndex(MediaStore.Audio.Media.ARTIST));
if (artist != null && artist.equals("<unknown>")) {
continue;
}
long duration = musicCursor.getLong(musicCursor
.getColumnIndex(MediaStore.Audio.Media.DURATION));
long size = musicCursor.getLong(musicCursor
.getColumnIndex(MediaStore.Audio.Media.SIZE));
String url = musicCursor.getString(musicCursor
.getColumnIndex(MediaStore.Audio.Media.DATA));
int isMusic = musicCursor.getInt(musicCursor
.getColumnIndex(MediaStore.Audio.Media.IS_MUSIC));
if (isMusic != 0) {
item.put("id", id);
item.put("title", title);
item.put("artist", artist);
item.put("duration", formatDuration(duration));
item.put("size", size);
item.put("url", url);
Log.d("MainActivity", "MusicTitle = " + title);
Log.d("MainActivity", "MusicArtist = " + artist);
Log.d("MainActivity", "MusicUrl = " + url);
allMusic.add(item);
}
}
}
// 将音乐时长转换为00:00格式
public static String formatDuration(long dur) {
long totalSecond = dur / 1000;
String minute = totalSecond / 60 + "";
if (minute.length() < 2)
minute = "0" + minute;
String second = totalSecond % 60 + "";
if (second.length() < 2)
second = "0" + second;
return minute + ":" + second;
}
// 从数据库中查询已收藏音乐
private void getStoredMusic(List<Map<String, Object>> storedMusic,
MyDBHelper myHelper) {
if (storedMusic.size() > 0)
storedMusic.clear();
Cursor cursor = myHelper.getReadableDatabase().rawQuery(
"select * from stored_music", null);
while (cursor.moveToNext()) {
Map<String, Object> item = new HashMap<>();
item.put("title", cursor.getString(1));
item.put("artist", cursor.getString(2));
item.put("duration", cursor.getString(3));
item.put("url", cursor.getString(4));
storedMusic.add(item);
}
}
public class SectionsPagerAdapter extends FragmentPagerAdapter {
public SectionsPagerAdapter(FragmentManager fm) {
super(fm);
}
@Override
public Fragment getItem(int position) {
Fragment fragment = null;
switch (position) {
case 0:
fragment = new MusicListFragment();
break;
case 1:
fragment = new StoredSongFragment();
break;
case 2:
fragment = new NetFragment();
break;
case 3:
fragment = new DownloadFragment();
break;
}
return fragment;
}
@Override
public int getCount() {
return FRAGMENT_COUNT;
}
@Override
public CharSequence getPageTitle(int position) {
Locale l = Locale.getDefault();
switch (position) {
case 0:
return getString(R.string.title_section1).toUpperCase(l);
case 1:
return getString(R.string.title_section2).toUpperCase(l);
case 2:
return getString(R.string.title_section3).toUpperCase(l);
case 3:
return getString(R.string.title_section4).toUpperCase(l);
}
return null;
}
}
@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 boolean onOptionsItemSelected(MenuItem item) {
// Handle action bar item clicks here. The action bar will
// automatically handle clicks on the Home/Up button, so long
// as you specify a parent activity in AndroidManifest.xml.
int id = item.getItemId();
if (id == R.id.action_settings) {
return true;
}
return super.onOptionsItemSelected(item);
}
@Override
public void onItemSelected(String url) {
playMusic(url);
}
@Override
public List<Map<String, Object>> getAllMusic() {
return allMusic;
}
@Override
public List<Map<String, Object>> getStoredMusic() {
return storedMusic;
}
@Override
public void onClick(View v) {
if (v == fragmentTitle1) {
mViewPager.setCurrentItem(0);
} else if (v == fragmentTitle2) {
mViewPager.setCurrentItem(1);
} else if (v == fragmentTitle3) {
mViewPager.setCurrentItem(2);
} else if (v == fragmentTitle4) {
mViewPager.setCurrentItem(3);
}
}
}
MainActivity主要负责管理整个音乐播放器应用,像数据库查询,服务启动等都是该类负责。其布局为:
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/LinearLayout1"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
tools:context="com.sprd.easymusic.MainActivity" >
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="center"
android:background="#18f" >
<TextView
android:id="@+id/fragment1"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:gravity="center"
android:text="@string/title_section1"/>
<TextView
android:id="@+id/fragment2"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:gravity="center"
android:text="@string/title_section2"/>
<TextView
android:id="@+id/fragment3"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:gravity="center"
android:text="@string/title_section3"/>
<TextView
android:id="@+id/fragment4"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:gravity="center"
android:text="@string/title_section4"/>
</LinearLayout>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="3dp"
android:gravity="center" >
<!-- 该textview作为红线移动到当前fragment下 -->
<TextView
android:id="@+id/fragmentTitle"
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_weight="1"
android:background="#f00" />
<TextView
android:id="@+id/textView6"
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_weight="3" />
</LinearLayout>
<android.support.v4.view.ViewPager
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/pager"
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="20"
android:alpha="0.8"
android:background="#afeeee"
tools:context=".MainActivity" >
</android.support.v4.view.ViewPager>
</LinearLayout>
2.MusicListFragment.java
package com.sprd.easymusic.fragment;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import com.sprd.easymusic.R;
import com.sprd.easymusic.mysql.MyDBHelper;
import com.sprd.easymusic.myview.RefreshableListView;
import android.app.Activity;
import android.content.Context;
import android.content.Intent;
import android.database.Cursor;
import android.support.v4.app.Fragment;
import android.os.AsyncTask;
import android.os.Bundle;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.ViewGroup;
import android.widget.AdapterView.OnItemClickListener;
import android.widget.AdapterView;
import android.widget.BaseAdapter;
import android.widget.ImageView;
import android.widget.ListView;
import android.widget.TextView;
import android.widget.Toast;
public class MusicListFragment extends Fragment {
private final String TAG = "MusicListFragment";
private final String ACTION_REFRESH = "action.refreshmusicList";
private List<Map<String, Object>> dbMusic = new ArrayList<>();
private List<Map<String, Object>> storedMusic = new ArrayList<>();
private ListView musicListView;
private LayoutInflater inflater;
private CallBack mCallBack;
private Context mContext;
private MyDBHelper myHelper;
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
Log.d(TAG, "onCreate");
mContext = this.getActivity();
myHelper = new MyDBHelper(mContext, "easyMusic.db3", null, 1);
inflater = LayoutInflater.from(mContext);
dbMusic = mCallBack.getAllMusic();
storedMusic = mCallBack.getStoredMusic();
}
// NetFragment向外界展示的内容,返回值为view
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.musiclist, container, false);
musicListView = (ListView) view.findViewById(R.id.musicList);
musicListView.setAdapter(musicListAdapter);
musicListView.setOnItemClickListener(new OnItemClickListener() {
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
mCallBack.onItemSelected((String) dbMusic.get(position).get("url"));
TextView title = (TextView) view.findViewWithTag("title");
Toast.makeText(mContext,"title = " + title.getText().toString(),Toast.LENGTH_SHORT).show();
}
});
return view;
}
// 音乐列表适配器
private BaseAdapter musicListAdapter = new BaseAdapter() {
@Override
public int getCount() {
return dbMusic.size();
}
@Override
public Object getItem(int position) {
return null;
}
@Override
public long getItemId(int position) {
return position;
}
@Override
public View getView(final int position, View convertView, ViewGroup parent) {
View view = convertView;
Map<String, Object> item = dbMusic.get(position);
if (convertView == null) {
view = inflater.inflate(R.layout.musiclist_item, null);
}
final ImageView storeMusic = (ImageView) view.findViewById(R.id.love);
if (checkIfStored((String) item.get("url"))) {
storeMusic.setImageResource(android.R.drawable.btn_star_big_on);
} else {
storeMusic.setImageResource(android.R.drawable.btn_star_big_off);
}
storeMusic.setOnClickListener(new OnClickListener() {
public void onClick(View v) {
new MyAsyncTask(storeMusic, dbMusic.get(position)).execute();
}
});
TextView musicTitle = (TextView) view.findViewById(R.id.musicTitle);
musicTitle.setTag("title");
TextView musicArtist = (TextView) view.findViewById(R.id.musicArtist);
musicTitle.setText((String) item.get("title"));
musicArtist.setText((String) item.get("artist"));
return view;
}
};
// 检查当前歌曲是否在收藏列表中,在收藏列表返回true,否则返回false
protected boolean checkIfStored(String url) {
for (Map<String, Object> map : storedMusic) {
if (url.equals((String) map.get("url"))) {
return true;
}
}
return false;
}
// 执行收藏或者取消收藏动作后刷新刷收藏音乐列表
private void refreshStoredMusic(Map<String, Object> musicInfo) {
int i = 0;
for (; i < storedMusic.size(); i++) {
Map<String, Object> map = storedMusic.get(i);
String url = (String) map.get("url");
if (url.equals((String) musicInfo.get("url"))) {
Log.d(TAG, "remove index =" + i);
storedMusic.remove(i);
//musicListAdapter.notifyDataSetChanged();
mContext.sendBroadcast(new Intent(ACTION_REFRESH));
return;
}
}
storedMusic.add(musicInfo);
//发送广播通知StoredSongFargment更新列表
mContext.sendBroadcast(new Intent(ACTION_REFRESH));
// 刷新收藏列表有两种方法:1:重新查询一次数据库-调用getStoredMusic(),这种效率比较低;2:用上面的方法,直接从storedMusic中删除或添加
// 这里用第一种方法
// getStoredMusic();
// 通知适配器数据发生改变的方法来刷新列表,最好别用musicListView.setAdapter(adapter)这种方法,该方法会导致焦点重新回到首行
//musicListAdapter.notifyDataSetChanged();
}
public void onAttach(Activity activity) {
super.onAttach(activity);
mCallBack = (CallBack) activity;
}
public void onDestroy() {
super.onDestroy();
}
public interface CallBack {
public void onItemSelected(String url);
public List<Map<String, Object>> getAllMusic();
public List<Map<String, Object>> getStoredMusic();
}
// 执行收藏音乐/取消收藏的异步任务
private class MyAsyncTask extends AsyncTask<String, Void, Void> {
private ImageView starView;
private Map<String, Object> musicInfo;
// 标记收藏,true表示收藏音乐成功,false表示取消收藏音乐
private boolean storeSuccess;
public MyAsyncTask(ImageView starView, Map<String, Object> musicInfo) {
this.starView = starView;
this.musicInfo = musicInfo;
}
protected void onPreExecute() {
super.onPreExecute();
}
protected void onProgressUpdate(Void... values) {
super.onProgressUpdate(values);
}
protected Void doInBackground(String... params) {
Log.d(TAG, "doInBackground");
Cursor cursor = myHelper.getReadableDatabase().rawQuery(
"select * from stored_music", null);
while (cursor.moveToNext()) {
String title = cursor.getString(1);
String artist = cursor.getString(2);
Log.d(TAG, "title = " + title + " artist = " + artist);
Log.d(TAG,
"musicInfo.title = " + (String) musicInfo.get("title")
+ " musicInfo.artist = "
+ (String) musicInfo.get("artist"));
if (cursor.getString(4).equals((String) musicInfo.get("url"))) {
// 已经收藏的音乐取消收藏并移出收藏音乐表格-stored_music
myHelper.getReadableDatabase()
.execSQL(
"delete from stored_Music where title like ? and artist like ?",
new String[] { title, artist });
storeSuccess = false;
return null;
}
}
// 未收藏的音乐加入到收藏中
myHelper.getReadableDatabase().execSQL(
"insert into stored_music values(null, ?, ?, ?, ?)",
new Object[] { musicInfo.get("title"),
musicInfo.get("artist"), musicInfo.get("duration"),
musicInfo.get("url") });
storeSuccess = true;
return null;
}
protected void onPostExecute(Void result) {
super.onPostExecute(result);
if (storeSuccess) {
starView.setImageResource(android.R.drawable.btn_star_big_on);
refreshStoredMusic(musicInfo);
Toast.makeText(mContext, "收藏成功", 100).show();
} else {
starView.setImageResource(android.R.drawable.btn_star_big_off);
refreshStoredMusic(musicInfo);
Toast.makeText(mContext, "取消收藏", 100).show();
}
}
}
}
MusicListFragment主要显示本地音乐,并提供音乐的收藏和取消收藏操作(异步任务来完成该操作)。其布局文件为:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical" >
<ListView
android:id="@+id/musicList"
android:layout_width="match_parent"
android:layout_height="wrap_content" >
</ListView>
</LinearLayout>
ListView的每个item布局为:
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/RelativeLayout1"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:gravity="center_vertical"
android:orientation="horizontal"
android:padding="5dp" >
<ImageView
android:id="@+id/musicTag"
android:layout_width="50dp"
android:layout_height="40dp"
android:layout_alignParentLeft="true"
android:layout_alignParentTop="true"
android:layout_centerVertical="true"
android:src="@drawable/music" />
<TextView
android:id="@+id/musicTitle"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentTop="true"
android:layout_toRightOf="@id/musicTag"
android:singleLine="true"
android:ellipsize="marquee"
android:marqueeRepeatLimit="marquee_forever"/>
<TextView
android:id="@+id/musicArtist"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_below="@+id/musicTitle"
android:layout_toRightOf="@id/musicTag"
android:text="TextView" />
<ImageView
android:id="@+id/love"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignBaseline="@+id/musicTag"
android:layout_alignParentRight="true"
android:src="@android:drawable/btn_star_big_off"/>
</RelativeLayout>
3.StoredSongFragment.java
package com.sprd.easymusic.fragment;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import com.sprd.easymusic.R;
import com.sprd.easymusic.myview.RefreshableListView;
import android.app.Activity;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.support.v4.app.Fragment;
import android.os.Bundle;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.AdapterView;
import android.widget.BaseAdapter;
import android.widget.ListView;
import android.widget.TextView;
import android.widget.Toast;
import android.widget.AdapterView.OnItemClickListener;
public class StoredSongFragment extends Fragment {
private final String TAG = "StoredSongFragment";
private final String ACTION_REFRESH = "action.refreshmusicList";
private List<Map<String, Object>> storedMusic = new ArrayList<>();
private ListView storedMusicList;
private CallBack mCallBack;
private LayoutInflater inflater;
private Context mContext;
public void onAttach(Activity activity) {
super.onAttach(activity);
mCallBack = (CallBack) activity;
}
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
mContext = this.getActivity();
inflater = LayoutInflater.from(mContext);
storedMusic = mCallBack.getStoredMusic();
IntentFilter filter = new IntentFilter();
filter.addAction(ACTION_REFRESH);
mContext.registerReceiver(refreshMusicReceiver, filter);
Log.d(TAG, "onCreate");
}
// StoredSongFragment向外界展示的内容,返回值为view
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View view = inflater
.inflate(R.layout.storedmusiclist, container, false);
storedMusicList = (ListView) view.findViewById(R.id.storedmusicList);
storedMusicList.setAdapter(musicListAdapter);
storedMusicList.setOnItemClickListener(new OnItemClickListener() {
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
mCallBack.onItemSelected((String) storedMusic.get(position).get("url"));
TextView title = (TextView) view.findViewWithTag("title");
Toast.makeText(mContext, "title = " + title.getText().toString(),Toast.LENGTH_SHORT).show();
}
});
return view;
}
// 音乐列表适配器
private BaseAdapter musicListAdapter = new BaseAdapter() {
public int getCount() {
return storedMusic.size();
}
public Object getItem(int position) {
return null;
}
public long getItemId(int position) {
return position;
}
public View getView(final int position, View convertView, ViewGroup parent) {
View view = convertView;
Map<String, Object> item = storedMusic.get(position);
if (convertView == null) {
view = inflater.inflate(R.layout.storedmusiclist_item, null);
}
TextView musicTitle = (TextView) view.findViewById(R.id.musicTitle);
musicTitle.setTag("title");
TextView musicArtist = (TextView) view.findViewById(R.id.musicArtist);
musicTitle.setText((String) item.get("title"));
musicArtist.setText((String) item.get("artist"));
return view;
}
};
public void onDestroy() {
if (refreshMusicReceiver != null) mContext.unregisterReceiver(refreshMusicReceiver);
super.onDestroy();
}
public interface CallBack {
public void onItemSelected(String url);
public List<Map<String, Object>> getStoredMusic();
}
//接收来自MusicListFragment的收藏或取消收藏音乐的广播,并更新收藏列表
private BroadcastReceiver refreshMusicReceiver = new BroadcastReceiver() {
public void onReceive(Context context, Intent intent) {
if (intent.getAction().equals(ACTION_REFRESH)) {
musicListAdapter.notifyDataSetChanged();
Toast.makeText(mContext, "刷新收藏列表成功!", 100).show();
}
}
};
}
StoredSongFragment主要显示收藏的音乐,也提供播放监听,其布局与MusicListragment几乎一样(区别在listview的item是否有收藏图标),因此就不提供了,参考MusicListragment的布局即可。
音乐播放器已完成,下载地址:
Android音乐播放器