源代码引用地址:https://github.com/yiyibb/Zhihu
此篇博客主要是使用鸿洋大神的万能适配器来构造recyclerview,简化了很多代码,但是感觉鸿洋大大的博客文章写的使用方法不够详细,加上后期他又优化了很多代码,这里我详细写明一篇,希望能帮助到大家。
首先在app的gradle文件中加上引用
compile 'com.android.support:recyclerview-v7:25.3.1'//recyclerview
compile 'com.zhy:base-rvadapter:3.0.3'//鸿洋万能的适配器
效果图
Paste_Image.png接下来看一下项目结构
Paste_Image.png可以看出这是个DrawerLayout,左边的抽屉栏可以用listview实现或者recyclerview,这里采用recyclerview。我把源代码中的一些重要部分代码摘出来了。做出了这个效果。
可以大概分析一下,这个recyclerview有三个不同的item:header,home,content。来看代码
mainActivity
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
ButterKnife.bind(this);
RecyclerView.LayoutManager layoutManager = new LinearLayoutManager(this);
mMainMenuList = new ArrayList<>();
mMainMenuList.add(new DrawerHeaderItem());
mMainMenuList.add(new DrawerHomeItem());
addlist();
mMenuAdapter = new HYDrawerMenuAdapter(this, mMainMenuList);
rc.setLayoutManager(layoutManager);
rc.setAdapter(mMenuAdapter);
mMenuAdapter.setOnItemClickListener(this);//监听接口回调
}
public void addlist(){
for(int i = 0;i < 10;i++){
ThemesEntity.OthersEntity other = new ThemesEntity.OthersEntity();
other.setName("心理学");
mMainMenuList.add(other);
}
}
@Override
public void onDrawerHeaderItemClick() {
Toast.makeText(this, "点击登录事件", Toast.LENGTH_SHORT).show();
}
@Override
public void onItemViewClick(View view, RecyclerView.ViewHolder holder, int position) {
Toast.makeText(this, "点击切换界面", Toast.LENGTH_SHORT).show();
}
@Override
public void onFollowIVClick(View view, RecyclerView.ViewHolder holder, int position, int offset) {
}
抛去杂质看本质,最重要的是给HYDrawerMenuAdapter传入了一个list,这个list里包含了所有item,总共三个类,一个DrawerHeaderItem,一个DrawerHomeItem,还有就是十个 ThemesEntity.OthersEntity。
接下来看适配器代码,这里的适配器继承了鸿洋的MultiItemTypeAdapter
public class HYDrawerMenuAdapter extends MultiItemTypeAdapter<DisplaybleItem> {
private int mSelection = 1;
private onItemClickListener mOnItemClickListener;
public HYDrawerMenuAdapter(Context context, List<DisplaybleItem> datas) {
super(context, datas);
//加入样本item
addItemViewDelegate(new DrawerHeaderItemDelegate());
addItemViewDelegate(new DrawerHomeItemDelegate());
addItemViewDelegate(new DrawerContentItemDelegate());
}
@Override
public void onBindViewHolder(ViewHolder holder, int position) {
super.onBindViewHolder(holder, position);
if (mSelection == position) {
holder.getConvertView().setBackgroundColor(ContextCompat.getColor(mContext, R.color.colorLightGray));
} else if (position > 0){
holder.getConvertView().setBackgroundColor(ContextCompat.getColor(mContext, R.color.colorWhite));
}
}
@Override
protected void setListener(ViewGroup parent, final ViewHolder viewHolder, int viewType) {
switch (viewType) {
case 0:
// ImageView userIcon = (ImageView) viewHolder.getView(R.id.user_icon);
TextView loginTV = (TextView)viewHolder.getView(R.id.login);
Button favoritesBtn = (Button)viewHolder.getView(R.id.action_favorites);
Button downloadBtn = (Button)viewHolder.getView(R.id.action_download);
// userIcon.setOnClickListener(handler);
loginTV.setOnClickListener(handler);//绑定监听事件
favoritesBtn.setOnClickListener(handler);
downloadBtn.setOnClickListener(handler);
break;
case 1:
case 2:
final int offset = 2;
viewHolder.getConvertView().setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
if (mOnItemClickListener != null) {
int position = viewHolder.getAdapterPosition();
mOnItemClickListener.onItemViewClick(v, viewHolder, position);
}
}
});
if (viewType == 2) {
viewHolder.getView(R.id.follow_iv).setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
if (mOnItemClickListener != null) {
int position = viewHolder.getAdapterPosition();
mOnItemClickListener.onFollowIVClick(view, viewHolder, position, offset);
}
}
});
}
break;
}
}
private View.OnClickListener handler = new View.OnClickListener() {
@Override
public void onClick(View view) {
if (mOnItemClickListener != null) {
mOnItemClickListener.onDrawerHeaderItemClick();
}
}
};
public void setSelection(int selection) {
mSelection = selection;
}
public interface onItemClickListener {
void onDrawerHeaderItemClick();
void onItemViewClick(View view, RecyclerView.ViewHolder holder, int position);
void onFollowIVClick(View view, RecyclerView.ViewHolder holder, int position, int offset);
}
public void setOnItemClickListener(onItemClickListener onItemClickListener) {
mOnItemClickListener = onItemClickListener;
}
}
代码有点长,但是关键部分不多,注意看构造方法,这里面虽然就区区几行,但是引入了鸿洋的大量代码。super关键字表示继承了MultiItemTypeAdapter构造方法里的所有函数体。最关键的是要弄明白刚刚传入的list到底有啥用,而这个addItemViewDelegate方法加入了样本item又是干啥的,快捷键进入源码分析。
Paste_Image.png发现这个list集合主要用于确认item的类别,进而点击getItemViewType方法。
Paste_Image.png这里又出现一个delegates。联系上下文,可以看出来刚刚addItemViewDelegate方法加入的对象就是放到了delegates这个集合中,也就是说这个集合承载这所有的item类型,也就是那三种类型。进而将这个集合遍历,对照传入的所有item看符合哪个类型并返回一定的参数。
Paste_Image.png画个草图可能更清楚一些。
再从整体来分析一下,要使用这个适配器来展示三种item,就需要传入两个集合一个是所有的item集合,另外就是这三个item样式的集合。
明白了整体流程以后我们来看一下细节,这个是十个“心理学”的item样式,其他的跟这个差不多,具体项目包看后文链接。
public class DrawerContentItemDelegate implements ItemViewDelegate<DisplaybleItem>{
@Override
public int getItemViewLayoutId() {
return R.layout.item_drawer_menu_content;//用于传入布局文件名
}
@Override
public boolean isForViewType(DisplaybleItem item, int position) {
return item instanceof ThemesEntity.OthersEntity;//用于对比item是否属于这个类型
}
@Override
public void convert(ViewHolder holder, DisplaybleItem displaybleItem, final int position) {
//用于改变item上的文字
holder.setText(R.id.item_theme_list_tv, ((ThemesEntity.OthersEntity)displaybleItem).getName());
}
}
适配器还有监听事件,采用的是接口回调,具体看HYDrawerMenuAdapter中的setListener方法,这里需要注意的是setListener方法并没有使用super。监听的接口回调很简单,不再赘述。
感兴趣的可以关注我最新开的公众号,重在分享!!微信搜索 开发Android的小学生
qrcode_for_gh_c686d73be7e1_430.jpg
网友评论