### 1.背景
还记得主页上GridView的内容吗?对,是分类信息,在这里将要实现音乐分类的显示播放,在这里使用了v7兼容包下的RecyclerView实现,同时包含两个布局,一个有图的一个没图的!
如下图所示:
![](https://box.kancloud.cn/2016-04-19_5715764e823fc.gif)
### 2.实现步骤
在这里我们的RecyclerView采用了混排的形式,就是根据不同的位置,设置不同的布局实现,我们在这里有两个布局一个有图的View和一个没图的View, 对应两个ViewHolder .
### (1)两个Item 布局实现
1)有图的Item Layout
~~~
<?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="80dp"
android:background="@color/app_color_whrit">
<ImageView
android:id="@+id/mlist_iv_music_songpic"
android:layout_width="80dp"
android:layout_height="match_parent"
android:layout_alignParentLeft="true"
android:scaleType="fitXY"
android:src="@drawable/moren_big" />
<TextView
android:id="@+id/mlist_tv_music_songname"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginLeft="10dp"
android:layout_marginTop="18dp"
android:layout_toRightOf="@+id/mlist_iv_music_songpic"
android:maxLines="2"
android:text="@string/list_item_song_name"
android:textColor="@color/text_color_whrit"
android:textSize="15sp" />
<TextView
android:id="@+id/mlist_tv_music_singer"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true"
android:layout_alignParentRight="true"
android:layout_marginBottom="10dp"
android:layout_marginRight="20dp"
android:text="@string/list_item_singer_name"
android:textColor="@color/app_color_zi"
android:textSize="12sp" />
</RelativeLayout>
~~~
2)没图的Item Layout 实现
~~~
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:background="@color/app_color_whrit"
android:layout_height="70dp" >
<TextView
android:id="@+id/list_item_play"
android:layout_width="30dp"
android:layout_height="50dp"
android:layout_alignParentLeft="true"
android:layout_centerInParent="true"
android:layout_margin="10dp"
android:gravity="center"
android:textColor="@color/app_color"
android:text="@string/main_item_num" />
<TextView
android:id="@+id/tv_item_name"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="18dp"
android:layout_toRightOf="@+id/list_item_play"
android:maxLines="2"
android:text="@string/list_item_song_name"
android:textColor="@color/text_color_whrit"
android:textSize="12sp" />
<TextView
android:id="@+id/tv_item_singer"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true"
android:layout_marginBottom="10dp"
android:layout_toRightOf="@+id/list_item_play"
android:text="@string/list_item_singer_name"
android:textColor="@color/app_color_zi"
android:textSize="12sp" />
<TextView
android:id="@+id/tv_item_heart"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true"
android:layout_alignParentRight="true"
android:layout_marginBottom="10dp"
android:layout_marginRight="20dp"
android:drawablePadding="3dp"
android:drawableRight="@drawable/heart_net"
android:text="@string/list_item_singer_name"
android:textColor="@color/text_color_whrit"
android:textSize="12sp" />
</RelativeLayout>
~~~
### (2)ViewHolder实现
1)有图的ViewHolder实现
~~~
package cn.labelnet.ui;
import android.support.v7.widget.RecyclerView.ViewHolder;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.ImageView;
import android.widget.TextView;
import cn.labelnet.event.MusicListRecyclerOnItemClick;
import cn.labelnet.maskmusic.R;
/**
* 有图 ViewHolder 作者 :原明卓 时间 :2015年12月11日 上午10:19:05 描述 :TODO
*/
public class MusicListBigViewHolder extends ViewHolder implements
OnClickListener {
private ImageView mlist_iv_music_songpic;
private TextView mlist_tv_music_songname, mlist_tv_music_singer;
private MusicListRecyclerOnItemClick itemClick;
public ImageView getMlist_iv_music_songpic() {
return mlist_iv_music_songpic;
}
public TextView getMlist_tv_music_songname() {
return mlist_tv_music_songname;
}
public TextView getMlist_tv_music_singer() {
return mlist_tv_music_singer;
}
public MusicListBigViewHolder(View itemView,MusicListRecyclerOnItemClick itemClick) {
super(itemView);
this.itemClick=itemClick;
initView(itemView);
}
private void initView(View itemView) {
mlist_iv_music_songpic = (ImageView) itemView
.findViewById(R.id.mlist_iv_music_songpic);
mlist_tv_music_songname = (TextView) itemView
.findViewById(R.id.mlist_tv_music_songname);
mlist_tv_music_singer = (TextView) itemView
.findViewById(R.id.mlist_tv_music_singer);
itemView.setOnClickListener(this);
}
@Override
public void onClick(View v) {
itemClick.onRecyclerItemClick(getPosition());
}
}
~~~
2)没图的ViewHolder实现
~~~
package cn.labelnet.ui;
import cn.labelnet.event.MusicListRecyclerOnItemClick;
import cn.labelnet.maskmusic.R;
import android.support.v7.widget.RecyclerView.ViewHolder;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.TextView;
/**
* 无图 ViewHolder
* 作者 :原明卓
* 时间 :2015年12月11日 上午10:20:25
* 描述 :TODO
*/
public class MusicListNoViewHolder extends ViewHolder implements OnClickListener {
private TextView list_item_play,tv_item_name,tv_item_singer,tv_item_heart;
private MusicListRecyclerOnItemClick itemClick;
public TextView getList_item_play() {
return list_item_play;
}
public TextView getTv_item_name() {
return tv_item_name;
}
public TextView getTv_item_singer() {
return tv_item_singer;
}
public MusicListNoViewHolder(View itemView,MusicListRecyclerOnItemClick itemClick) {
super(itemView);
this.itemClick=itemClick;
initView(itemView);
}
private void initView(View itemView) {
list_item_play=(TextView) itemView.findViewById(R.id.list_item_play);
tv_item_name=(TextView) itemView.findViewById(R.id.tv_item_name);
tv_item_singer=(TextView) itemView.findViewById(R.id.tv_item_singer);
tv_item_heart=(TextView) itemView.findViewById(R.id.tv_item_heart);
itemView.setOnClickListener(this);
}
public TextView getTv_item_heart() {
return tv_item_heart;
}
@Override
public void onClick(View v) {
itemClick.onRecyclerItemClick(getPosition());
}
}
~~~
### (3)Recycler.Adapter实现
getItemViewType() 方法 ,返回不同的结果,用来区分不同的item view;
onCreateViewHolder 创建ViewHolder返回子类;
onBindViewHolder 给ViewHolder 绑定数据;
~~~
package cn.labelnet.adapter;
import java.util.List;
import java.util.Random;
import android.content.Context;
import android.support.v7.widget.RecyclerView;
import android.support.v7.widget.RecyclerView.ViewHolder;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ImageView;
import cn.labelnet.event.MusicListRecyclerOnItemClick;
import cn.labelnet.maskmusic.R;
import cn.labelnet.model.MusicModel;
import cn.labelnet.net.MusicAsyncGetUrl;
import cn.labelnet.net.MusicAsyncHandlerGetUrl;
import cn.labelnet.net.MusicRequest;
import cn.labelnet.net.VolleyHttpRequest;
import cn.labelnet.ui.MusicListBigViewHolder;
import cn.labelnet.ui.MusicListNoViewHolder;
import com.android.volley.toolbox.ImageLoader;
import com.android.volley.toolbox.ImageLoader.ImageListener;
/**
* MusicListActivity 适配器 作者 :原明卓 时间 :2015年12月11日 上午10:33:42 描述 :TODO
*/
public class MusicTypeListAdapter extends RecyclerView.Adapter<ViewHolder>
implements MusicAsyncGetUrl {
private List<MusicModel> musics = null;
private Random random = new Random();
private int r = 7;
private Context context;
private MusicModel mm = null;
// 布局控制
private MusicListBigViewHolder bigViewHolder = null;
private MusicListNoViewHolder listNoViewHolder = null;
private MusicListRecyclerOnItemClick itemClick;
// 图片请求
private MusicAsyncHandlerGetUrl musicAsyncHandlerGetUrl;
private ImageListener imageListener = null;
private MusicRequest musicRequest = null;
private ImageView iv_list;
//
private String urlStr = null;
public MusicTypeListAdapter(List<MusicModel> musics, Context context,
MusicListRecyclerOnItemClick itemClick) {
this.musics = musics;
this.context = context;
this.itemClick = itemClick;
// 请求图片资源
musicAsyncHandlerGetUrl = new MusicAsyncHandlerGetUrl();
musicAsyncHandlerGetUrl.setMusicasyncGetUrl(this);
musicRequest = new MusicRequest();
musicRequest.setMusicAsyncHandler(musicAsyncHandlerGetUrl);
}
@Override
public int getItemViewType(int position) {
return position == 0 ? 0 : 1;
}
@Override
public int getItemCount() {
return musics.size() > 0 ? musics.size() : 0;
}
@Override
public ViewHolder onCreateViewHolder(ViewGroup vg, int flag) {
ViewHolder holder = null;
if (flag == 0) {
// 有图的布局
View itemView = LayoutInflater.from(context).inflate(
R.layout.list_item_music_layout, vg, false);
holder = new MusicListBigViewHolder(itemView, itemClick);
} else {
// 没图的布局
View itemView = LayoutInflater.from(context).inflate(
R.layout.list_item_music_no_layout, vg, false);
holder = new MusicListNoViewHolder(itemView, itemClick);
}
return holder;
}
@Override
public void onBindViewHolder(ViewHolder vh, int position) {
mm = musics.get(position);
if (mm != null) {
// 不建议,待优化
if (vh instanceof MusicListNoViewHolder) {
// 无图适配
listNoViewHolder = (MusicListNoViewHolder) vh;
// Log.d("MaskMusic", "无图适配");
listNoViewHolder.getList_item_play().setText("" + position);
listNoViewHolder.getTv_item_singer()
.setText(mm.getSingername());
listNoViewHolder.getTv_item_name().setText(mm.getSongname());
int heartNum = (mm.getSongid() + mm.getSingerid()) / 134;
listNoViewHolder.getTv_item_heart().setText("" + heartNum);
} else {
// 有图适配
bigViewHolder = (MusicListBigViewHolder) vh;
bigViewHolder.getMlist_tv_music_singer().setText(
mm.getSingername());
bigViewHolder.getMlist_tv_music_songname().setText(
mm.getSongname());
if (urlStr == null) {
iv_list = bigViewHolder.getMlist_iv_music_songpic();
imageListener = ImageLoader.getImageListener(iv_list,
R.drawable.moren, R.drawable.moren_big);
musicRequest.setMusicAsyncHandler(musicAsyncHandlerGetUrl);
musicRequest.requestStringData(mm.getSingername() + "");
}
}
}
}
@Override
public void getSongImageURL(String imgUrl) {
urlStr = imgUrl;
VolleyHttpRequest.Image_Loader(imgUrl, imageListener);
}
}
~~~
### 3. 使用
### (1)绑定 RecyclerView
~~~
list_recycler_view = (RecyclerView) findViewById(R.id.list_recycler_view);
// 设置是否固定长度
list_recycler_view.setHasFixedSize(true);
// 添加样式
list_recycler_view.setLayoutManager(new LinearLayoutManager(this,
LinearLayoutManager.VERTICAL, false));
// 添加item动画
list_recycler_view.setItemAnimator(new DefaultItemAnimator());
// 添加item分割线
list_recycler_view.addItemDecoration(new SpacesItemDecoration(2));
// 添加适配器
musicTypeAdapter = new MusicTypeListAdapter(musics, this, this);
list_recycler_view.setAdapter(musicTypeAdapter);
~~~
### (2)点击事件回调
一个接口实现 :
~~~
/**
* MusicListActivity RecycleView点击事件
* 作者 :原明卓
* 时间 :2015年12月11日 下午5:13:55
* 描述 :TODO
*/
public interface MusicListRecyclerOnItemClick {
void onRecyclerItemClick(int position);
}
~~~
具体的步骤是 :
在ViewHolder 中实现OnClickListener 点击事件,在MusicListActivity 中进行回调使用,前面已经有解释了。
### 4.总结
下篇讲实现网络请求数据和实现音乐播放
- 前言
- Android实战 - 音心音乐播放器 (开启篇)
- Android实战 - 音心音乐播发器 (主界面实现)
- Android实战 - 音心播放器 (Music Service 实现)
- Android实战 - 音心播放器 (通知实现音乐的播放/暂停/下一曲控制)
- Android实战 - 音心播发器 (MusicService ,Notification, MainActivity 总结)
- Android实战 - 音心播放器 (MusicActivity-音乐播放页面界面实现)
- Android实战 - 音心播放器 (MusciActivity-专辑图片获得,基本控制实现)
- Android实战 - 音心播放器(MusicActivity - 歌词实现)
- Android实战 - 音心播放器 (MusicActivity - 倒计时 ,进度条实现)
- Android实战 - 音心播放器 (MusicActivity ,MusicNotification,MusicService总结)
- Android实战 - 音心播放器 (MusicListActivity - 分类信息界面实现)
- Android实战 - 音心播放器 (MusicListActivity - 音乐播放和MainActivity的一个问题)
- Android实战 - 音心播放器 (启动页与社交分享(ShareSDK))
- Android实战 - 音心播放器 (优化Service退出,按两下退出应用实现)
- Android实战 - 音心播放器 (项目总结,应用打包发布)