音乐播放器项目

歌曲列表界面布局mian_activity:

<RelativeLayout 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"
    tools:context="com.yx.player.MainActivity" >

    <TextView
        android:id="@+id/tv_bar_title"
        android:layout_width="match_parent"
        android:layout_height="50dp"
        android:background="#16d9d8"
        android:textColor="#fff"
        android:textSize="18sp"
        android:gravity="center"
        android:text="歌曲列表" />

    <RadioGroup
        android:id="@+id/radioGroup"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_below="@+id/tv_bar_title"
        android:layout_marginTop="10dp"
        android:orientation="horizontal" >

        <RadioButton
            android:id="@+id/radioNew"
            android:layout_width="0dp"
            android:layout_height="wrap_content"
            android:layout_weight="1"
            android:checked="true"
            android:button="@null"
            android:gravity="center"
            android:textColor="@drawable/selector_bar"
            android:text="新歌榜" />

        <RadioButton
            android:id="@+id/radioHot"
            android:layout_width="0dp"
            android:layout_height="wrap_content"
            android:layout_weight="1"
            android:button="@null"
            android:gravity="center"
            android:textColor="@drawable/selector_bar"
            android:text="热歌榜" />
    </RadioGroup>
    
    <android.support.v4.view.ViewPager
        android:id="@+id/viewPager"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:layout_below="@+id/radioGroup" />
        
</RelativeLayout>
新建drawable文件夹,定义选择器selector_bar:

<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android" >
    <item android:state_checked="true" android:color="@color/tab_checked"></item>
    <item android:state_checked="false" android:color="@color/tab_unchecked"></item>
</selector>
创建fragment_music_list用于填充viewPager:

<RelativeLayout 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"
    tools:context=".MainActivity" >

    <ListView
        android:id="@+id/listView"
        android:layout_width="match_parent"
        android:layout_height="match_parent">
    </ListView>

</RelativeLayout>
NewMusicListFragment类承载新歌列表:

package com.yx.player.fragment;

import com.yx.player3.R;

import android.os.Bundle;
import android.support.v4.app.Fragment;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;

public class NewMusicListFragment extends Fragment {
	@Override
	public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
		View view = inflater.inflate(R.layout.fragment_music_list, null);
		
		
		return view;
	}
}


HotMusicListFragment类承载热歌列表:

package com.yx.player.fragment;



import com.yx.player3.R;
import android.os.Bundle;
import android.support.v4.app.Fragment;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;

public class HotMusicListFragment extends Fragment {
	@Override
	public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
		View view = inflater.inflate(R.layout.fragment_music_list, null);
		
		
		return view;
	}
}


MainActivity主类实现viewPager和radioButton的连动:

package com.yx.player.activity;

import java.util.ArrayList;
import java.util.List;

import com.yx.player.fragment.HotMusicListFragment;
import com.yx.player.fragment.NewMusicListFragment;
import com.yx.player3.R;

import android.os.Bundle;
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.PagerAdapter;
import android.support.v4.view.ViewPager;
import android.support.v4.view.ViewPager.OnPageChangeListener;
import android.widget.RadioButton;
import android.widget.RadioGroup;

public class MainActivity extends FragmentActivity {

	private ViewPager viewPager;
	private RadioGroup radioGroup;
	private RadioButton rbNew;
	private RadioButton rbHot;
	private List<Fragment> fragments;

	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.activity_main);
		//初始化控件
		setView();

		//初始化viewpager的适配器
		setPagerAdapter();

		//监听
		setListeners();
	}

	private void setListeners() {
        //viewPager控制radioGroup
        viewPager.setOnPageChangeListener(new OnPageChangeListener() {
            @Override
            public void onPageSelected(int position) {
                switch (position) {
                    case 0:
                        //选择了第一页
                        rbNew.setChecked(true);
                        break;
                    case 1:
                        //选择了第二页
                        rbHot.setChecked(true);
                        break;
                }
            }

            @Override
            public void onPageScrolled(int arg0, float arg1, int arg2) {
            }

            @Override
            public void onPageScrollStateChanged(int arg0) {
            }
        });
        
        //radioGroup控制viewpager
        radioGroup.setOnCheckedChangeListener(new OnCheckedChangeListener() {
            
            @Override
            public void onCheckedChanged(RadioGroup group, int checkedId) {
                switch (checkedId) {
                    case R.id.radioNew:
                        //选中了新歌列表
                        viewPager.setCurrentItem(0);
                        break;
                    case R.id.radioHot:
                        //选中了热歌列表
                        viewPager.setCurrentItem(1);
                        break;
                }
            }
        });
    }

	/**
	 * 初始化viewpager的适配器
	 */
	private void setPagerAdapter() {
		//准备两个Fragment作为数据源
		fragments = new ArrayList<Fragment>();
		fragments.add(new NewMusicListFragment());
		fragments.add(new HotMusicListFragment());
		PagerAdapter pagerAdapter = new MainPagerAdapter(getSupportFragmentManager());
		viewPager.setAdapter(pagerAdapter);
	}

	/**
	 * 初始化控件
	 */
	private void setView() {
		viewPager = (ViewPager) findViewById(R.id.viewPager);
		radioGroup = (RadioGroup) findViewById(R.id.radioGroup);
		rbNew = (RadioButton) findViewById(R.id.radioNew);
		rbHot = (RadioButton) findViewById(R.id.radioHot);
	}

	/**
	 * 声明ViewPager的适配器
	 * @author YX
	 */
	class MainPagerAdapter extends FragmentPagerAdapter {

		public MainPagerAdapter(FragmentManager fm) {
			super(fm);
		}

		@Override
		public Fragment getItem(int position) {
			return fragments.get(position);
		}

		@Override
		public int getCount() {
			return fragments.size();
		}
	}

}

下面开始实现加载网络上的在线音乐到本地,在这里用的是百度音乐提供的音乐库。百度提供的音乐接口文档如下:

1.	1)搜索建议  
2.	http://tingapi.ting.baidu.com/v1/restserver/ting?from=qianqian&version=2.1.0&method=baidu.ting.search.catalogSug&format=json&query=%E5%B0%8F%E8%8B%B9%E6%9E%9C  
3.	搜索建议:只有歌名  
4.	http://tingapi.ting.baidu.com/v1/restserver/ting?method=baidu.ting.search.suggestion&query=%E5%B0%8F%E8%8B%B9%E6%9E%9C&format=json&from=ios&version=2.1.1  
5.	2)搜索结果  
6.	http://tingapi.ting.baidu.com/v1/restserver/ting?from=qianqian&version=2.1.0&method=baidu.ting.search.common&format=json&query=%E5%B0%8F%E8%8B%B9%E6%9E%9C&page_no=1&page_size=30  
7.	3)  
8.	 http://tingapi.ting.baidu.com/v1/restserver/ting?from=qianqian&version=2.1.0&method=baidu.ting.artist.getList&format=json&order=1&offset=0&limit=5  
9.	 4)新歌榜  
10.	 http://tingapi.ting.baidu.com/v1/restserver/ting?from=qianqian&version=2.1.0&method=baidu.ting.billboard.billList&format=json&type=1&offset=0&size=50  
11.	 5)热歌榜  
12.	http://tingapi.ting.baidu.com/v1/restserver/ting?from=qianqian&version=2.1.0&method=baidu.ting.billboard.billList&format=json&type=2&offset=0&size=50  注意这个和上边的区别,type=1  
13.	 6)Billboard  
14.	 http://tingapi.ting.baidu.com/v1/restserver/ting?from=qianqian&version=2.1.0&method=baidu.ting.billboard.billList&format=json&type=8&offset=0&size=507)Hito中文榜  
15.	7)Hito中文榜  
16.	http://tingapi.ting.baidu.com/v1/restserver/ting?from=qianqian&version=2.1.0&method=baidu.ting.billboard.billList&format=json&type=18&offset=0&size=50  
17.	8)KTV热歌榜  
18.	http://tingapi.ting.baidu.com/v1/restserver/ting?from=qianqian&version=2.1.0&method=baidu.ting.billboard.billList&format=json&type=6&offset=0&size=50  
19.	9)电台列表  
20.	 http://tingapi.ting.baidu.com/v1/restserver/ting?from=qianqian&version=2.1.0&method=baidu.ting.radio.getCategoryList&format=json  
21.	 10)获取某个电台下的歌曲列表  
22.	 http://tingapi.ting.baidu.com/v1/restserver/ting?from=qianqian&version=2.1.0&method=baidu.ting.radio.getChannelSong&format=json&pn=0&rn=10&channelname=public_tuijian_ktv  
23.	 11)获取songid的歌曲信息  
24.	  http://tingapi.ting.baidu.com/v1/restserver/ting?from=qianqian&version=2.1.0&method=baidu.ting.song.getInfos&format=json&songid=8059247&ts=1408284347323&e=JoN56kTXnnbEpd9MVczkYJCSx%2FE1mkLx%2BPMIkTcOEu4%3D&nw=2&ucf=1&res=1   
25.	  12)获取登陆用户的喜爱歌曲列表,其中bduss参数用来标示唯一的用户  
26.	  http://tingapi.ting.baidu.com/v1/restserver/ting?from=qianqian&version=2.1.0&method=baidu.ting.favorite.getFavoriteSong&format=json&pn=0&rn=50&bduss=UlXZ1dWbm9icDBrMm13aFcwZ282ejlTM1dyS1NEd2JPWXpQcDgyT0w0Vn5SUmhVQVFBQUFBJCQAAAAAAAAAAAEAAAB0L~cOeHl3MDQzNzM1AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAH-48FN~uPBTd  
27.	  13)歌手列表  
28.	  http://tingapi.ting.baidu.com/v1/restserver/ting?from=qianqian&version=2.1.0&method=baidu.ting.artist.get72HotArtist&format=json&order=1&offset=0&limit=50  
29.	  14)歌手简介,tinguid为歌手id  
30.	  http://tingapi.ting.baidu.com/v1/restserver/ting?from=qianqian&version=2.1.0&method=baidu.ting.artist.getinfo&format=json&tinguid=7994  
31.	  15)歌手歌曲列表,tinguid为歌手id  
32.	  http://tingapi.ting.baidu.com/v1/restserver/ting?from=qianqian&version=2.1.0&method=baidu.ting.artist.getSongList&format=json&order=2&tinguid=7994&offset=0&limits=50  
33.	16)新碟上架  
34.	http://tingapi.ting.baidu.com/v1/restserver/ting?from=qianqian&version=2.1.0&method=baidu.ting.plaza.getRecommendAlbum&format=json&offset=0&limit=50  
35.	17)专辑信息  
36.	http://tingapi.ting.baidu.com/v1/restserver/ting?from=qianqian&version=2.1.0&method=baidu.ting.album.getAlbumInfo&format=json&album_id=122314357  
37.	18)新歌速递  
38.	http://tingapi.ting.baidu.com/v1/restserver/ting?from=qianqian&version=2.1.0&method=baidu.ting.plaza.getNewSongs&format=json&limit=50
定义用于描述音乐信息的实体类Music:

package com.yx.player.entity;

/**
 * 音乐实体类,用于描述一首音乐 
 * @author YX
 */
public class Music {
	private String artist_id;
	private String language;
	private String pic_big;
	private String pic_small;
	private String lrclink;
	private String hot;
	private String all_artist_id;
	private String style;
	private String song_id;
	private String title;
	private String ting_uid;
	private String author;
	private String album_id;
	private String album_title;
	private String artist_name;
	
	
	public Music() {
		super();
	}
	
	public Music(String artist_id, String language, String pic_big, String pic_small, String lrclink, String hot,
			String all_artist_id, String style, String song_id, String title, String ting_uid, String author,
			String album_id, String album_title, String artist_name) {
		super();
		this.artist_id = artist_id;
		this.language = language;
		this.pic_big = pic_big;
		this.pic_small = pic_small;
		this.lrclink = lrclink;
		this.hot = hot;
		this.all_artist_id = all_artist_id;
		this.style = style;
		this.song_id = song_id;
		this.title = title;
		this.ting_uid = ting_uid;
		this.author = author;
		this.album_id = album_id;
		this.album_title = album_title;
		this.artist_name = artist_name;
	}

	public String getArtist_id() {
		return artist_id;
	}
	public void setArtist_id(String artist_id) {
		this.artist_id = artist_id;
	}
	public String getLanguage() {
		return language;
	}
	public void setLanguage(String language) {
		this.language = language;
	}
	public String getPic_big() {
		return pic_big;
	}
	public void setPic_big(String pic_big) {
		this.pic_big = pic_big;
	}
	public String getPic_small() {
		return pic_small;
	}
	public void setPic_small(String pic_small) {
		this.pic_small = pic_small;
	}
	public String getLrclink() {
		return lrclink;
	}
	public void setLrclink(String lrclink) {
		this.lrclink = lrclink;
	}
	public String getHot() {
		return hot;
	}
	public void setHot(String hot) {
		this.hot = hot;
	}
	public String getAll_artist_id() {
		return all_artist_id;
	}
	public void setAll_artist_id(String all_artist_id) {
		this.all_artist_id = all_artist_id;
	}
	public String getStyle() {
		return style;
	}
	public void setStyle(String style) {
		this.style = style;
	}
	public String getSong_id() {
		return song_id;
	}
	public void setSong_id(String song_id) {
		this.song_id = song_id;
	}
	public String getTitle() {
		return title;
	}
	public void setTitle(String title) {
		this.title = title;
	}
	public String getTing_uid() {
		return ting_uid;
	}
	public void setTing_uid(String ting_uid) {
		this.ting_uid = ting_uid;
	}
	public String getAuthor() {
		return author;
	}
	public void setAuthor(String author) {
		this.author = author;
	}
	public String getAlbum_id() {
		return album_id;
	}
	public void setAlbum_id(String album_id) {
		this.album_id = album_id;
	}
	public String getAlbum_title() {
		return album_title;
	}
	public void setAlbum_title(String album_title) {
		this.album_title = album_title;
	}
	public String getArtist_name() {
		return artist_name;
	}
	public void setArtist_name(String artist_name) {
		this.artist_name = artist_name;
	}

	@Override
	public String toString() {
		return "Music:" + this.title;
	}
}

发送get请求的工具类HttpUtils的封装:

package com.yx.player.util;

import java.io.InputStream;
import java.net.URL;
import java.net.HttpURLConnection;

/**
 * 发送Http请求的工具类
 * @author YX
 *
 */
public class HttpUtils {
	/**
	 * 发送get请求,返回接收到的响应输入流
	 * @param path 请求资源路径
	 * @throws Exception 
	 */
	public static InputStream getInputStream(String path) throws Exception {
		URL url = new URL(path);
		HttpURLConnection connection = (HttpURLConnection) url.openConnection();
		connection.setRequestMethod("GET");
		InputStream is = connection.getInputStream(); 
		return is;
	}
	
}

URL工厂类,UrlFactory:

package com.yx.player.util;

/**
 * URL工厂,用于生成URL字符串
 * @author YX
 *
 */
public class UrlFactory {
	/**
	 * 获取新音乐榜url地址
	 * 
	 */
	public static String getNewMusicListUrl(int offset, int size) {
		String url = "http://tingapi.ting.baidu.com/v1/restserver/ting?from=qianqian&version=2.1.0&method=baidu.ting.billboard.billList&format=xml&type=1&offset="+offset+"&size="+size;
		return url;
	}
}
xml解析工具类XmlParser:

package com.yx.player.util;

import java.io.InputStream;
import java.util.ArrayList;
import java.util.List;
import org.xmlpull.v1.XmlPullParser;
import com.yx.player.entity.Music;
import android.util.Xml;

/**
 * xml解析器
 * @author YX
 *
 */
public class XmlParser {
	/**
	 * 解析音乐列表数据
	 * @throws Exception 
	 */
	public static List<Music> parseMusicList(InputStream is) throws Exception {
		//1. XmlPullParser
		XmlPullParser parser = Xml.newPullParser(); 
		//2. parser.setInput()
		parser.setInput(is, "utf-8");
		//3. eventType
		int eventType = parser.getEventType();
		//4. while(){}
		List<Music> musics = new ArrayList<Music>();
		Music music = null;
		
		while(eventType != XmlPullParser.END_DOCUMENT) {
			switch(eventType) {
			case XmlPullParser.START_TAG://开始标签
				String tag = parser.getName();
				//开始一首新歌
				if(tag.equals("song")) {
					music = new Music();
					musics.add(music);
				} else if(tag.equals("artist_id")) {
					music.setArtist_id(parser.nextText());
				} else if (tag.equals("language")) {
					music.setLanguage(parser.nextText());
				} else if (tag.equals("pic_big")) {
					music.setPic_big(parser.nextText());
				} else if (tag.equals("pic_small")) {
					music.setPic_small(parser.nextText());
				} else if (tag.equals("lrclink")) {
					music.setLrclink(parser.nextText());
				} else if (tag.equals("hot")) {
					music.setHot(parser.nextText());
				} else if (tag.equals("all_artist_id")) {
					music.setAll_artist_id(parser.nextText());
				} else if (tag.equals("style")) {
					music.setStyle(parser.nextText());
				} else if (tag.equals("song_id")) {
					music.setSong_id(parser.nextText());
				} else if (tag.equals("title")) {
					music.setTitle(parser.nextText());
				} else if (tag.equals("ting_uid")) {
					music.setTing_uid(parser.nextText());
				} else if (tag.equals("author")) {
					music.setAuthor(parser.nextText());
				} else if (tag.equals("album_id")) {
					music.setAlbum_id(parser.nextText());
				} else if (tag.equals("album_title")) {
					music.setAlbum_title(parser.nextText());
				} else if (tag.equals("artist_name")) {
					music.setArtist_name(parser.nextText());
				}
				break;
			}
			//向后驱动事件
			eventType = parser.next();
		}
		
		return musics;
	}
}
音乐业务类MusicModel:

package com.yx.player.model;

import java.io.InputStream;
import java.util.List;

import com.yx.player.entity.Music;
import com.yx.player.util.HttpUtils;
import com.yx.player.util.UrlFactory;
import com.yx.player.util.XmlParser;

import android.os.AsyncTask;
import android.util.Log;

/**
 * 音乐相关的业务类
 * @author YX
 *
 */
public class MusicModel {
	/**
	 * 添加新歌榜列表,需要发送http请求
	 * 必须在工作线程中发送请求
	 * @param offset 音乐的起始位置
	 * @param 向后查询的条目数
	 */
	public void loadNewMusicList(final int offset, final int size) {
		AsyncTask<String, String, List<Music>> task = new AsyncTask<String, String, List<Music>>() {

			@Override
			protected List<Music> doInBackground(String... params) {
				try {
					//发送http请求
					String url = UrlFactory.getNewMusicListUrl(offset, size);
					InputStream is = HttpUtils.getInputStream(url);
					//解析is中的xml文档,获取List<Music>
					List<Music> musics = XmlParser.parseMusicList(is);
					return musics;
				} catch (Exception e) {
					e.printStackTrace();
				}
				return null;
			}
			@Override
			protected void onPostExecute(List<Music> result) {
				Log.i("info", "音乐列表:" + result.toString());
				super.onPostExecute(result);
			}
		};
		task.execute();
	}
}
修改NewMusicListFragment类,加载新歌榜:

package com.yx.player.fragment;

import com.yx.player.model.MusicModel;
import com.yx.player3.R;

import android.os.Bundle;
import android.support.v4.app.Fragment;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ListView;

public class NewMusicListFragment extends Fragment {
	
	private ListView listView;
	private MusicModel model;
	
	@Override
	public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
		View view = inflater.inflate(R.layout.fragment_music_list, null);
		
		//初始化控件
		setView(view);
		
		//调用业务层的方法,加载新歌榜列表
		model = new MusicModel();
		model.loadNewMusicList(0, 100);
		
		return view;
	}

	private void setView(View view) {
		listView = (ListView) view.findViewById(R.id.listView);
	}
}

歌曲显示列表item布局:

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent" >

    <ImageView
        android:id="@+id/ivAlbum"
        android:layout_width="50dp"
        android:layout_height="50dp"
        android:layout_marginRight="10dp"
        android:src="@drawable/ic_launcher" />
    
    <TextView 
        android:id="@+id/tvTitle"
        android:layout_width="wrap_content"
        android:layout_height="30dp"
        android:layout_alignParentTop="true"
        android:singleLine="true"
        android:gravity="center_vertical"
        android:layout_toRightOf="@+id/ivAlbum"
        android:text="原来我不知道你是谁"/>
    
    <TextView 
        android:id="@+id/tvSinger"
        android:layout_width="wrap_content"
        android:layout_height="20dp"
        android:singleLine="true"
        android:layout_alignLeft="@+id/tvTitle"
        android:layout_below="@+id/tvTitle"
        android:textSize="12dp"
        android:textColor="#666666"
        android:text="那英"/>

</RelativeLayout>
创建音乐适配器类MusicAdapter:

package com.yx.player.adapter;

import java.util.List;

import com.yx.player.entity.Music;
import com.yx.player3.R;

import android.content.Context;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.BaseAdapter;
import android.widget.ImageView;
import android.widget.TextView;

public class MusicAdapter extends BaseAdapter {
	private Context context;
	private List<Music> musics;
	private LayoutInflater inflater;

	public MusicAdapter(Context context, List<Music> musics) {
		super();
		this.context = context;
		this.musics = musics;
		this.inflater = LayoutInflater.from(context);
	}

	@Override
	public int getCount() {
		return musics.size();
	}

	@Override
	public Object getItem(int position) {
		return musics.get(position);
	}

	@Override
	public long getItemId(int position) {
		return position;
	}

	@Override
	public View getView(int position, View convertView, ViewGroup parent) {
		ViewHolder holder = null;
		if (convertView == null) {
			convertView = inflater.inflate(R.layout.item_lv_music, null);
			holder = new ViewHolder();
			holder.ivAlbum = (ImageView) convertView.findViewById(R.id.ivAlbum);
			holder.tvTitle = (TextView) convertView.findViewById(R.id.tvTitle);
			holder.tvSinger = (TextView) convertView.findViewById(R.id.tvSinger);
			convertView.setTag(holder);
		}
		holder = (ViewHolder) convertView.getTag();
		
		//控件的赋值
		Music music = (Music) getItem(position);
		
		holder.tvTitle.setText(music.getTitle());
		holder.tvSinger.setText(music.getAuthor());
		
		return convertView;
	}
	
	class ViewHolder {
		ImageView ivAlbum;
		TextView tvTitle;
		TextView tvSinger;
	}
}
当列表加载完毕后将会调用的回调方法:
package com.yx.player.model;

import java.util.List;

import com.yx.player.entity.Music;

public interface MusicListCallback {
	/**
	 * 当列表加载完毕后将会调用的回掉方法
	 * @param musics
	 */
	void onMusicListLoaded(List<Music> musics);
}
采用回调的方式加载音乐列表,业务处理类MusicModel和NewMusicListFragment修改如下:

package com.yx.player.model;

import java.io.InputStream;
import java.util.List;

import com.yx.player.entity.Music;
import com.yx.player.util.HttpUtils;
import com.yx.player.util.UrlFactory;
import com.yx.player.util.XmlParser;

import android.os.AsyncTask;

/**
 * 音乐相关的业务类
 * @author YX
 *
 */
public class MusicModel {
	/**
	 * 添加新歌榜列表,需要发送http请求
	 * 必须在工作线程中发送请求
	 * @param offset 音乐的起始位置
	 * @param size 向后查询的条目数
	 */
	public void loadNewMusicList(final int offset, final int size, final MusicListCallback callback) {
		AsyncTask<String, String, List<Music>> task = new AsyncTask<String, String, List<Music>>() {

			@Override
			protected List<Music> doInBackground(String... params) {
				try {
					//发送http请求
					String url = UrlFactory.getNewMusicListUrl(offset, size);
					InputStream is = HttpUtils.getInputStream(url);
					//解析is中的xml文档,获取List<Music>
					List<Music> musics = XmlParser.parseMusicList(is);
					return musics;
				} catch (Exception e) {
					e.printStackTrace();
				}
				return null;
			}
			@Override
			protected void onPostExecute(List<Music> result) {
				//Log.i("info", "音乐列表:" + result.toString());
				callback.onMusicListLoaded(result);
			}
		};
		task.execute();
	}
}
package com.yx.player.fragment;

import java.util.List;

import com.yx.player.adapter.MusicAdapter;
import com.yx.player.entity.Music;
import com.yx.player.model.MusicListCallback;
import com.yx.player.model.MusicModel;
import com.yx.player3.R;

import android.os.Bundle;
import android.support.v4.app.Fragment;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ListView;

public class NewMusicListFragment extends Fragment {
	
	private ListView listView;
	private MusicModel model;
	private List<Music> musics;
	private MusicAdapter adapter;
	
	@Override
	public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
		View view = inflater.inflate(R.layout.fragment_music_list, null);
		
		//初始化控件
		setView(view);
		
		//调用业务层的方法,加载新歌榜列表
		model = new MusicModel();
		model.loadNewMusicList(0, 30, new MusicListCallback() {
			//当列表加载完毕后将会调用的回调方法
			@Override
			public void onMusicListLoaded(List<Music> musics) {
				NewMusicListFragment.this.musics = musics;
				setAdapter();
			}
		});
		return view;
	}

	/**
	 * 更新适配器
	 */
	private void setAdapter() {
		adapter = new MusicAdapter(getActivity(), musics);
		listView.setAdapter(adapter);
		
	}
	private void setView(View view) {
		listView = (ListView) view.findViewById(R.id.listView);
	}
}


































创建一个Web音乐播放器项目通常涉及到前端和后端两个部分,这里我会提供一个简化的概述。具体的代码实现会依赖于你选择的技术栈(如HTML, CSS, JavaScript, 和后端框架如Node.js或Python Django等)。 **前端部分:** 1. HTML: 创建页面结构,包括音乐播放区域、歌曲列表、播放/暂停按钮、进度条等。 ```html <div id="player"> <audio id="audioElement"></audio> <div class="controls"> <button id="playPauseBtn">Play</button> <progress id="progressBar"></progress> </div> </div> ``` 2. CSS: 设计样式,使界面美观。 3. JavaScript (使用如jQuery, Vue.js, 或 React): 编写事件处理程序,控制音频播放、暂停、进度更新等。 ```javascript const audioElement = document.getElementById('audioElement'); const playPauseBtn = document.getElementById('playPauseBtn'); const progressBar = document.getElementById('progressBar'); playPauseBtn.addEventListener('click', togglePlayPause); function togglePlayPause() { audioElement.paused ? audioElement.play() : audioElement.pause(); } ``` **后端部分(假设用Node.js和Express):** 1. API设计: 创建RESTful API来管理歌曲列表,比如获取歌曲、上传歌曲、更新播放状态等。 ```javascript app.get('/songs', (req, res) => { // 从数据库或文件系统获取歌曲列表 }); app.post('/songs/upload', (req, res) => { // 处理文件上传 }); app.put('/songs/:id/play', (req, res) => { // 更新歌曲播放状态 }); ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值