Android 超简单音乐播放器(九)搜索网络歌曲,获得热门榜单(GridView)(易源api的使用)(JSON的解析)(刷新)
首先感谢易源API!
提供了QQ音乐的接口~
咳咳...
明天要写文档..看来..哎..我的歌词要等假期了?
回归正题~
首先上一下我的界面啊实现啊啥的~
点击榜单会出现对应的歌曲~
可以搜索网络歌曲~
可以刷新~
先写榜单的实现~
首先是net这个Fragment的布局代码~
<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:orientation="vertical" android:layout_width="match_parent" android:layout_height="match_parent"> <LinearLayout android:layout_width="match_parent" android:layout_height="45dp" android:background="#edebeb"> <EditText android:imeOptions="actionSearch" android:maxLines="1" android:id="@+id/et_findlocal" android:textSize="13sp" android:hint="搜索网络歌曲" android:gravity="center" android:layout_marginRight="10dp" android:layout_marginLeft="10dp" android:background="@drawable/btn_white" android:layout_width="0dp" android:layout_weight="1" android:layout_height="30dp" android:layout_gravity="center"/> <ImageView android:id="@+id/iv_findNet" android:layout_marginRight="5dp" android:layout_gravity="center" android:layout_width="0dp" android:layout_weight="0.1" android:layout_height="30dp" android:background="@drawable/find"/> </LinearLayout> <RelativeLayout android:id="@+id/rl_scroll" android:layout_width="match_parent" android:layout_height="wrap_content"> <GridView android:id="@+id/main_gridview" android:layout_width="match_parent" android:layout_height="240dp" android:layout_marginTop="2dp" android:gravity="center" android:horizontalSpacing="0dp" android:numColumns="3" android:scrollbars="none" android:verticalSpacing="0dp" > </GridView> </RelativeLayout> <ImageView android:id="@+id/iv_translateAnimation" android:layout_gravity="right" android:layout_width="25dp" android:layout_height="25dp" android:src="@drawable/less" /> <View android:id="@+id/vv_xian" android:layout_width="match_parent" android:layout_height="5dp" android:background="#edebeb"/> <com.scwang.smartrefresh.layout.SmartRefreshLayout android:id="@+id/sr_fragment_net" android:layout_width="match_parent" android:layout_height="match_parent"> <android.support.v7.widget.RecyclerView android:layout_marginTop="5dp" android:layout_width="match_parent" android:id="@+id/rv_net_song" android:layout_height="wrap_content"> </android.support.v7.widget.RecyclerView> </com.scwang.smartrefresh.layout.SmartRefreshLayout> </LinearLayout>
然后就是写item_gridview_song.xml的代码~
<?xml version="1.0" encoding="utf-8"?> <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="100dp" android:layout_height="80dp" android:layout_margin="1dp"> <ImageView android:id="@+id/iv_item_main_gird" android:layout_width="50dp" android:layout_height="50dp" android:layout_centerInParent="true" android:src="@drawable/find" /> <TextView android:id="@+id/tv_item_main_grid" android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_alignParentBottom="true" android:gravity="center" android:text="民谣" /> </RelativeLayout>好啦~界面部分就大功告成~~~然后要给gridview写一个适配器~
package com.music.adapter; import android.content.Context; import android.util.SparseArray; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; import android.widget.BaseAdapter; import android.widget.ImageView; import android.widget.TextView; import com.music.R; /** * Created by 雅倩宝宝 on 2017/9/19. */ public class MusicGridAdapter extends BaseAdapter{ private SparseArray<String> gridItems; private ViewHolder holder = null; private Context context; private int[] ids = { R.drawable.rege26,R.drawable.gaotai6,R.drawable.kge36,
R.drawable.liuxing4,R.drawable.neidi5,R.drawable.net28, R.drawable.oumei3,
R.drawable.xingge26,R.drawable.yinyueren32}; //把图片放入一个字符组
@Override
public int getCount() {
return gridItems.size() > 0 ? gridItems.size() : 0; }
public MusicGridAdapter (SparseArray<String> gridItems, Context context) {
this.gridItems = gridItems;
this.context = context;
}
@Override
public Object getItem(int i) {
return gridItems.get(i); }
@Override
public long getItemId(int i) {
return 0; }
@Override
public View getView(int i, View view, ViewGroup viewGroup) {
if(view == null){
view = LayoutInflater.from(context).inflate(
R.layout.item_gridview_song,viewGroup,false);
holder = new ViewHolder(view); }
holder.tvItemMainGrid.setText(gridItems.get(i)+"");
holder.ivItemMainGird.setImageResource(ids[i]);
return view; }
private class ViewHolder {
public ImageView ivItemMainGird;
public TextView tvItemMainGrid;
public ViewHolder(View convertView) {
ivItemMainGird = convertView.findViewById(R.id.iv_item_main_gird);
tvItemMainGrid = convertView.findViewById(R.id.tv_item_main_grid);
} }}忘记说了..
根据API给到的数据我们要创建一个musicmodle类~(补一个api地址https://www.showapi.com/api/lookPoint/213)
(哎呀 史上最乱写博主...)
public class MusicModle implements Serializable { /** * "albumid": 1181789, * "downUrl": "http://tsmusic24.tc.qq.com/104778928.mp3", * "seconds": 265, * "singerid": 12744, * "singername": "小沈阳", * "songid": 104778928, * "songname": "八戒八戒 (《西游记之孙悟空三打白骨精》电影推广曲)", * "url": "http://ws.stream.qqmusic.qq.com/104778928.m4a?fromtag=46" */ private int albumid; private String downUrl; private int seconds; private int singerid; private String singername; private int songid; private String songname; private String url; public int getAlbumid() { return albumid; } public void setAlbumid(int albumid) { this.albumid = albumid; } public String getDownUrl() { return downUrl; } public void setDownUrl(String downUrl) { this.downUrl = downUrl; } public int getSeconds() { return seconds; } public void setSeconds(int seconds) { this.seconds = seconds; } public int getSingerid() { return singerid; } public void setSingerid(int singerid) { this.singerid = singerid; } public String getSingername() { return singername; } public void setSingername(String singername) { this.singername = singername; } public int getSongid() { return songid; } public void setSongid(int songid) { this.songid = songid; } public String getSongname() { return songname; } public void setSongname(String songname) { this.songname = songname; } public String getUrl() { return url; } public void setUrl(String url) { this.url = url; } }
接下来我们需要添加两个依赖0 0.
都是第一行代码中提到过的~
阿里嘎多~
compile 'com.squareup.okhttp3:okhttp:3.9.0'//HTTP访问网络
compile 'com.google.code.gson:gson:2.7'
第一个就是连接网络!(我是这样理解的~)
第二个就是解析gson的数据~
首先0 0.创建一个HttpUtil~
由于我们用了那个啥okhttp 然后他不仅方便 还帮我们写好了回调的函数0 0.美滋滋 啊啊啊啊所以我们只需要调用callback就可以了
这应该很简单看懂了吧~
感觉自己的密匙啊啥的~填入URL的相应位置~还有榜单的序号传入 就可以获得对应的数据!~
public class HttpUtil { public static void requestStringData(final int topid ,okhttp3.Callback callback) { OkHttpClient client = new OkHttpClient(); Request request = new Request.Builder() .url("http://route.showapi.com/213-4?showapi_appid=46426&topid="+topid+"&showapi_sign=f908983676e94a34a11a56eb71400f79") .build(); client.newCall(request).enqueue(callback); }}
我的想法就是在回调中解析数据!所以在这里我又新建了一个MusicModleUtil
虽然我也不知道我为啥要这样做...可能是后面播放起来好处理吧 我是想像我之前写本地音乐那样写~喵呜~~
package com.music.util; import android.util.Log; import com.music.bean.MusicModle; import org.json.JSONArray; import org.json.JSONObject; import java.util.ArrayList; import java.util.List; import okhttp3.Response; /** * Created by 雅倩宝宝 on 2017/9/20. */ public class MusicModleUtil { public static List<MusicModle> list1; public static List<MusicModle> parseJOSNWithGSON (Response response){ Log.i("TAG", "onCreate:5"+""); list1 = new ArrayList<>(); try{ String ResponsData = response.body().string(); JSONObject jsonObject = new JSONObject(ResponsData); String error = jsonObject.getString("showapi_res_error"); if (!error.equals("")) { Log.i("TAG","error");} String body = jsonObject.getString("showapi_res_body"); JSONObject jsonObject1 = new JSONObject(body); String pagebean = jsonObject1.getString("pagebean"); JSONObject jsonObject2 = new JSONObject(pagebean); String songlist = jsonObject2.getString("songlist"); JSONArray jsonArray = new JSONArray(songlist); for (int i = 0; i < jsonArray.length() ; i++) { MusicModle musicModle = new MusicModle(); JSONObject jsonObject3 = jsonArray.getJSONObject(i); musicModle.setDownUrl(jsonObject3.getString("downUrl")); musicModle.setSingername(jsonObject3.getString("singername")); musicModle.setSongname(jsonObject3.getString("songname")); musicModle.setUrl(jsonObject3.getString("url")); list1.add(musicModle); Log.i("TAG", "onCreate:4 "+musicModle.getDownUrl()); } }catch (Exception e ){ e.printStackTrace(); } return list1; } }解析数据这里要注意了,要一步步进行解析哦~
不要越过~否则会解析不成功的~
我觉得代码都很简单了!!美滋滋~
然后我们就可以回到NetFragment中写代码了~
private Dialog progressDialog;//加载条 private boolean isHide;//判断Gridview是否隐藏
private SparseArray<String> gridItems = new SparseArray<String>(); private Map<String, Integer> maps = new HashMap<String, Integer>(); MusicGridAdapter musicGridAdapter;第一个呢 是用来传对应的名字~
第二个是点击事件跳转的时候可以把对应的topid传过去~
第三个就是声明啦~
public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) { View view = inflater.inflate(R.layout.fragment_network, container, false); initData(); musicGridAdapter = new MusicGridAdapter(gridItems, getContext()); mainGridview = view.findViewById(R.id.main_gridview); mainGridview.setAdapter(musicGridAdapter); mainGridview.setOnItemClickListener(new mainGridviewListener()); ButterKnife.bind(this, view); return view; } public void showProgressDialog() {//请求网络的时候显示
if (progressDialog == null) { progressDialog = new Dialog(getContext(), R.style.Pro); progressDialog.setContentView(R.layout.dialog_loading); progressDialog.getWindow().setBackgroundDrawableResource(android.R.color.transparent); TextView msg = (TextView) progressDialog.findViewById(R.id.id_tv_loadingmsg); msg.setText("(σ'・д・)σ"); progressDialog.show(); } progressDialog.show(); } public void dissmiss() { //请求网络后消失 if (progressDialog != null) { progressDialog.dismiss(); } } private void initData() { //把对应的榜单名字传入 gridItems.put(0, getString(R.string.msuic_fenlei_rege)); gridItems.put(1, getString(R.string.music_fenlei_gantai)); gridItems.put(2, getString(R.string.music_fenlei_Kge)); gridItems.put(3, getString(R.string.music_fenlei_liuxing)); gridItems.put(4, getString(R.string.music_fenlei_neidi)); gridItems.put(5, getString(R.string.music_fenlei_net)); gridItems.put(6, getString(R.string.music_fenlei_oumei)); gridItems.put(7, getString(R.string.music_fenlei_xingge)); gridItems.put(8, getString(R.string.music_fenlei_yinyueren)); getFenlei(); } @OnClick({R.id.iv_findNet, R.id.iv_translateAnimation}) public void onViewClicked(View view) { switch (view.getId()) { case R.id.iv_findNet:
case R.id.iv_translateAnimation: if (isHide) { //对是否隐藏VIEW进行判断 如果隐藏点击则会显示 否则会隐藏 mainGridview.setVisibility(view.VISIBLE); vvXian.setVisibility(view.VISIBLE); ivTranslateAnimation.setImageResource(R.drawable.less); isHide = false; } else { // mainGridview.setVisibility(view.GONE); vvXian.setVisibility(view.GONE); ivTranslateAnimation.setImageResource(R.drawable.more_unfold); isHide = true; } break; } } /** * GirdView点击事件 */ private class mainGridviewListener implements AdapterView.OnItemClickListener { @Override public void onItemClick(AdapterView<?> parent, View view, int position, long id) { Intent intent = new Intent(getContext(), MusicListActivity.class);
//将topid传过去 intent.putExtra("musictype", maps.get(gridItems.get(position))); startActivity(intent); } } public void getFenlei() { maps.put(getString(R.string.msuic_fenlei_rege), 26); maps.put(getString(R.string.music_fenlei_gantai), 6); maps.put(getString(R.string.music_fenlei_Kge), 36); maps.put(getString(R.string.music_fenlei_liuxing), 4); maps.put(getString(R.string.music_fenlei_neidi), 5); maps.put(getString(R.string.music_fenlei_net), 28); maps.put(getString(R.string.music_fenlei_oumei), 3); maps.put(getString(R.string.music_fenlei_xingge), 27); maps.put(getString(R.string.music_fenlei_yinyueren), 32); // 热歌 26 } @Override public void onDestroyView() { super.onDestroyView(); ButterKnife.unbind(this); } }差不多就是酱紫了
0 0.。。额 剩下的我就帖MusicListActivity 的代码吧0 0适配器啊其他什么的都是和之前的一样的~
public class MusicListActivity extends BaseActivity { @Bind(R.id.tv_toolbar) TextView tvToolbar; @Bind(R.id.tb_main) Toolbar tbMain; private int typeid = 5; List<MusicModle> list; @Bind(R.id.rv_fenlei_list) RecyclerView rvFenleiList; MusicFenAdapter musicFenAdapter; private SparseArray<String> maps = new SparseArray<String>(); @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_music_list); ButterKnife.bind(this); initTypes(); typeid = getIntent().getIntExtra("musictype", 5); setToolBar(R.id.tb_main);
//设置榜单名为标题名字
tvToolbar.setText(maps.get(typeid));
initWhiteHome();
Log.i("TAG", "onCreate: " + typeid);
showProgressDialog();
HttpUtil.requestStringData(typeid, new Callback() {
@Override
public void onFailure(Call call, IOException e) {
Log.i("TAG", "onCreate:2 " + e);
dissmiss(); }
@Override
public void onResponse(Call call, Response response) throws IOException {
musicFenAdapter = new MusicFenAdapter(MusicModleUtil.parseJOSNWithGSON(response));
//更新界面要回到主线程进行更新~ runOnUiThread(new Runnable() { @Override public void run() { rvFenleiList.setLayoutManager(new LinearLayoutManager(getBaseContext())); rvFenleiList.setItemAnimator(new DefaultItemAnimator()); rvFenleiList.setAdapter(musicFenAdapter); dissmiss(); } }); } }); }
//设置标题栏的名字为榜单 private void initTypes() { maps.put(26,getString(R.string.msuic_fenlei_rege)); maps.put(6,getString(R.string.music_fenlei_gantai)); maps.put(36,getString(R.string.music_fenlei_Kge)); maps.put(4,getString(R.string.music_fenlei_liuxing) ); maps.put(5,getString(R.string.music_fenlei_neidi)); maps.put(28,getString(R.string.music_fenlei_net)); maps.put(3,getString(R.string.music_fenlei_oumei)); maps.put(27,getString(R.string.music_fenlei_xingge)); maps.put(32,getString(R.string.music_fenlei_yinyueren)); } }觉得自己真的写得好没实用...有点难过了..
那个歌曲搜索其实和榜单实现差不多..
我就不写了..
只是在解析的时候记得要把页数提取出来..
直接上一下我的完整的NetFragment吧
里面的刷新用了开源库..
compile 'com.android.support:appcompat-v7:25.3.1'//版本随意 compile 'com.scwang.smartrefresh:SmartRefreshLayout:1.0.3' compile 'com.scwang.smartrefresh:SmartRefreshHeader:1.0.3'//没有使用特殊Header,可以不加这行
public class NetFragment extends Fragment { @Bind(R.id.et_findlocal) EditText etFindlocal; @Bind(R.id.main_gridview) GridView mainGridview; @Bind(R.id.rv_net_song) RecyclerView rvNetSong; @Bind(R.id.iv_findNet) ImageView ivFindNet; @Bind(R.id.iv_translateAnimation) ImageView ivTranslateAnimation; @Bind(R.id.vv_xian) View vvXian; @Bind(R.id.rl_scroll) RelativeLayout rlScroll; @Bind(R.id.sr_fragment_net) SmartRefreshLayout srFragmentNet; private SparseArray<String> gridItems = new SparseArray<String>(); private Map<String, Integer> maps = new HashMap<String, Integer>(); MusicGridAdapter musicGridAdapter; FindMusicAdapter findMusicAdapter; private Dialog progressDialog; private boolean isHide; private int page = 1; private int totalPage; private String name; // Animation showAction, hideAction; @Nullable @Override public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) { View view = inflater.inflate(R.layout.fragment_network, container, false); initData(); musicGridAdapter = new MusicGridAdapter(gridItems, getContext()); mainGridview = view.findViewById(R.id.main_gridview); mainGridview.setAdapter(musicGridAdapter); mainGridview.setOnItemClickListener(new mainGridviewListener()); ButterKnife.bind(this, view); return view; } public void showProgressDialog() { if (progressDialog == null) { progressDialog = new Dialog(getContext(), R.style.Pro); progressDialog.setContentView(R.layout.dialog_loading); progressDialog.getWindow().setBackgroundDrawableResource(android.R.color.transparent); TextView msg = (TextView) progressDialog.findViewById(R.id.id_tv_loadingmsg); msg.setText("(σ'・д・)σ"); progressDialog.show(); } progressDialog.show(); } public void initView() { srFragmentNet.setOnRefreshLoadmoreListener(new OnRefreshLoadmoreListener() { @Override public void onLoadmore(final RefreshLayout refreshlayout) { MusicFindUtil.getInstance().getPage(); Log.i("totalPage2", "totalPage " + totalPage); page++; if (page<=totalPage){ HttpUtil.requestSongData(name, page, new Callback() { @Override public void onFailure(Call call, IOException e) { refreshlayout.finishLoadmore(); } @Override public void onResponse(Call call, Response response) throws IOException { refreshlayout.finishLoadmore(); findMusicAdapter.addData(MusicFindUtil.parseJOSNWithGSON(response)); getActivity().runOnUiThread(new Runnable() { @Override public void run() { findMusicAdapter.addDataChange(); } }); }}); }else { Toast.makeText(getContext(), "没有更多了~~", Toast.LENGTH_SHORT).show(); refreshlayout.finishLoadmore();//记得要加这个!!!结束 } } @Override public void onRefresh(final RefreshLayout refreshlayout) { HttpUtil.requestSongData(name, 1, new Callback() { @Override public void onFailure(Call call, IOException e) { refreshlayout.finishRefresh(); Log.i("TAG", "onCreate:2 " + e); dissmiss(); } @Override public void onResponse(Call call, Response response) throws IOException { refreshlayout.finishRefresh();
//记得要加这个!!!结束
findMusicAdapter = new FindMusicAdapter(MusicFindUtil.parseJOSNWithGSON(response), getContext()); Log.i("TAG2", "onCreate:2 "); getActivity().runOnUiThread(new Runnable() { @Override public void run() { Log.i("TAG2", "onCreate:3 "); rvNetSong.setLayoutManager(new LinearLayoutManager(getContext())); rvNetSong.setItemAnimator(new DefaultItemAnimator()); rvNetSong.setAdapter(findMusicAdapter); } }); } }); } }); } public void dissmiss() { if (progressDialog != null) { progressDialog.dismiss(); } } private void initData() { gridItems.put(0, getString(R.string.msuic_fenlei_rege)); gridItems.put(1, getString(R.string.music_fenlei_gantai)); gridItems.put(2, getString(R.string.music_fenlei_Kge)); gridItems.put(3, getString(R.string.music_fenlei_liuxing)); gridItems.put(4, getString(R.string.music_fenlei_neidi)); gridItems.put(5, getString(R.string.music_fenlei_net)); gridItems.put(6, getString(R.string.music_fenlei_oumei)); gridItems.put(7, getString(R.string.music_fenlei_xingge)); gridItems.put(8, getString(R.string.music_fenlei_yinyueren)); getFenlei(); } @OnClick({R.id.iv_findNet, R.id.iv_translateAnimation}) public void onViewClicked(View view) { switch (view.getId()) { case R.id.iv_findNet: page = 1; name = etFindlocal.getText().toString(); etFindlocal.setText(""); MusicFindUtil.getInstance().deleteDate(); showProgressDialog(); HttpUtil.requestSongData(name, 1, new Callback() { @Override public void onFailure(Call call, IOException e) { Log.i("TAG", "onCreate:2 " + e); dissmiss(); } @Override public void onResponse(Call call, Response response) throws IOException { Log.i("TAG2", "onCreate:1 "); totalPage = MusicFindUtil.getInstance().getPage(); Log.i("totalPage", "totalPage1 " + totalPage); findMusicAdapter = new FindMusicAdapter(MusicFindUtil.parseJOSNWithGSON(response), getContext()); Log.i("TAG2", "onCreate:2 "); getActivity().runOnUiThread(new Runnable() { @Override public void run() { Log.i("TAG2", "onCreate:3 "); rvNetSong.setLayoutManager(new LinearLayoutManager(getContext())); rvNetSong.setItemAnimator(new DefaultItemAnimator()); rvNetSong.setAdapter(findMusicAdapter); initView(); srFragmentNet.setRefreshHeader(new ClassicsHeader(getContext())); } }); dissmiss(); Log.i("totalPage", "totalPage3 " + totalPage); } }); break; case R.id.iv_translateAnimation: if (isHide) {// mainGridview.startAnimation(showAction); mainGridview.setVisibility(view.VISIBLE); vvXian.setVisibility(view.VISIBLE); ivTranslateAnimation.setImageResource(R.drawable.less); isHide = false; } else {// mainGridview.startAnimation(hideAction); mainGridview.setVisibility(view.GONE); vvXian.setVisibility(view.GONE); ivTranslateAnimation.setImageResource(R.drawable.more_unfold); isHide = true; } break; } } /** * GirdView点击事件 */ private class mainGridviewListener implements AdapterView.OnItemClickListener { @Override public void onItemClick(AdapterView<?> parent, View view, int position, long id) { Intent intent = new Intent(getContext(), MusicListActivity.class); intent.putExtra("musictype", maps.get(gridItems.get(position))); startActivity(intent); } } public void getFenlei() { maps.put(getString(R.string.msuic_fenlei_rege), 26); maps.put(getString(R.string.music_fenlei_gantai), 6); maps.put(getString(R.string.music_fenlei_Kge), 36); maps.put(getString(R.string.music_fenlei_liuxing), 4); maps.put(getString(R.string.music_fenlei_neidi), 5); maps.put(getString(R.string.music_fenlei_net), 28); maps.put(getString(R.string.music_fenlei_oumei), 3); maps.put(getString(R.string.music_fenlei_xingge), 27); maps.put(getString(R.string.music_fenlei_yinyueren), 32); // 热歌 26 } @Override public void onDestroyView() { super.onDestroyView(); ButterKnife.unbind(this); }}
好吧。。。我真是一个不走心的人。。。。
好好加油。。。
慢慢写出好的文。。。
加油学习。。。
静心。。。
冷静。。
~o( =∩ω∩= )m