您的位置:首页 > 移动开发 > Android开发

RecyclerView下实现 ListView嵌套GridView 复杂效果

2016-07-02 12:57 501 查看

导言:

         RecyclerView使用也有一段时间了
他的出现是对ListView,GridView的进化。但是我们要实现一些复杂的布局,比如

这个布局,那我们该怎么办呢?别急,不是说了RecyclerView是对ListView,GridView的进化吗?那么ListView和GridView能实现的效果,RecyclerView肯定能实现,甚至ListView嵌套GridView这个2B的方式也是能实现的,甚至还有ListView和GridView的复用功能。(如果你急于找答案,那就先提示,请使用GridLayoutManager的setSpanSizeLookup的方法,设置单个Item的跨度,如果你有时间,就往下看,谢谢支持)

分析:

 
    当我们美工给我们类似导言里面的效果图时,我们不要一脸懵逼,应该对美工妹纸说:你的这效果图真和你一样漂亮,今晚下班能一起研究研究吗?美工妹纸肯定说:哎呀,臭屌丝!滚。  好吧,程序猿果真是苦逼的命啊,那我们只能低头下来研究技术吧。于是程序猿开始研究了效果图,这看上去有ListView的效果,又有GridView的效果,能不嵌套起来将就一下呢?但是程序猿又想到嵌套了复用的机制又没有了,如果Item是图片,多起来OOM岂不是很没面子。程序猿又想到了RecyclerView最近不是很火吗?不是说RecyclerView是对ListView,GridView的进化吗?
但是RecyclerView的LayoutManager只有GridLayoutManager(一行多个ITEM)
和LinearLayoutManager(一行一个Item)呀?会不会有第三种布局管理呢?程序猿好像抓住了生命的稻草似的打开了API文档。找呀找,竟然没有,哎......一脸失望的开着API,突然眼前好像看到了GridLayoutManager的的构造器有个
int类型的spanCount,还有个setSpanSizeLookup的方法。
看了文档描述,卧槽,上天被程序猿的真诚感动了啊。

文档说明:

 
      public GridLayoutManager(android.content.Context context, int spanCount)
Creates a vertical GridLayoutManager
param
context Current context, will be used to access resources.
param
spanCount The number of columns in the grid// <span style="color: rgb(51, 51, 51); font-family: arial; font-size: 18px; line-height: 20px;">网格中的列数</span>spanCount 就是一行有多少列,比如导言中的图片一行中最多的有2列,那么我们应该传入参数2:,
前方高能,请打开AndroidStudio:

 setSpanSizeLookup(android.support.v7.widget.GridLayoutManager$SpanSizeLookup spanSizeLookup)
Sets the source to get the number of spans occupied by each item in the adapter.
param
spanSizeLookup {@link SpanSizeLookup} instance to be used to query number of spans occupied by each item<span style="font-weight: bold;">

</span>这方法就是设置单个Item的跨度(跨度?就是相当于一个LinearLayout里面设置了weightSum为5,一个子控件的layout_weight=4
 ,那么这个这个item的跨度就是这个LinearLayout的 4/5),同理导言中的图片中我们拿出item0 和item1 ,item2出来分析。

 
item2的宽度大概是item1的一半,item1大概是item0 的2/3, 那么我们大概知道了,item0的跨度为3,item1的跨度为2,item2的跨度为1。是多少
GridLayoutManager manager = new GridLayoutManager(this, 3);
manager.setSpanSizeLookup(new GridLayoutManager.SpanSizeLookup() {
@Override
public int getSpanSize(int position) {
return (3 - position % 3);
}
});
recyclerView.setLayoutManager(manager);return
(3-position%3); 我们来看这个,当position为0的时候,返回的跨度为3,就是说item占3个跨度。OK,一切都很明朗了。

拓展:

 
    上面只是demo,到现实的项目中,该怎么变通呢?? 现实项目的item各种各样,那么我们继续往下看,现实项目中我们可以配合RecyclerView.Adapter<RecyclerView.ViewHolder> 中的

 //// 加载Item View的时候根据不同TYPE加载不同的布局
@Override
public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent,
int viewType) {

if (viewType == 0) {
return new ItemTypeViewHolder(mLayoutInflater.inflate(
R.layout.item_recommend_title, parent, false));
} else if (viewType == 1 || viewType == 4) {
return new ItemListViewHolder(mLayoutInflater.inflate(
R.layout.item_book_info, parent, false));
} else {
return new ItemGridViewHolder(mLayoutInflater.inflate(
R.layout.item_recommend_hor, parent, false));
}
}

// 初始化不同的布局。
@Override
public void onBindViewHolder(RecyclerView.ViewHolder holder,
final int position) {

if (holder instanceof ItemTypeViewHolder) {
ItemTypeViewHolder tempholder = (ItemTypeViewHolder) holder;
tempholder.mBookNameTv.setText(mBeans.get(position)
.getRecommendtypename());

return;
} else if (holder instanceof ItemListViewHolder) {
ItemListViewHolder tempholder = (ItemListViewHolder) holder;
if (mOnItemClickLitener != null) {
tempholder.itemView.setOnClickListener(new OnClickListener() {

@Override
public void onClick(View v) {
mOnItemClickLitener.onItemClick(v, position);
}
});
}
tempholder.mBookAuthorTv.setText(mBeans.get(position)
.getBookauthor());
tempholder.mBookNameTv.setText(mBeans.get(position).getBookname());
tempholder.mBookSummry.setText(mBeans.get(position).getSummary());

Picasso.with(mContext).load(mBeans.get(position).getBookCoverURL())
.placeholder(R.drawable.bookcover)
.error(R.drawable.bookcover).into(tempholder.mBookCoverImg);
return;
} else if (holder instanceof ItemGridViewHolder) {
ItemGridViewHolder tempholder = (ItemGridViewHolder) holder;
if (mOnItemClickLitener != null) {
tempholder.itemView.setOnClickListener(new OnClickListener() {

@Override
public void onClick(View v) {
mOnItemClickLitener.onItemClick(v, position);
}
});
}
tempholder.mBookAuthorTv.setText(mBeans.get(position)
.getBookauthor());
tempholder.mBookNameTv.setText(mBeans.get(position).getBookname());
Picasso.with(mContext).load(mBeans.get(position).getBookCoverURL())
.placeholder(R.drawable.bookcover)
.error(R.drawable.bookcover).into(tempholder.mBookCoverImg);
return;
}
}

// 设置ITEM类型,可以自由发挥,返回Item的样式。
@Override
public int getItemViewType(int position) {
//返回当前的数据类型,可以在bean模型类中设置一个字段。
//
// return (3 - position % 3);
return mBeans.get(position).getRecommendtype();
}
最后在Fragment或者 Activity中:

mAdapter = new RecommendAdapter(getActivity());
mAdapter.setOnItemClickLitener(this);
mListView = (RecyclerView) mRootView.findViewById(R.id.list);
GridLayoutManager layoutManager = new GridLayoutManager(
getActivity(), 6);
layoutManager.setSpanSizeLookup(new SpanSizeLookup() {

@Override
public int getSpanSize(int position) {
switch (mAdapter.getItemViewType(position)) {
case 0:
return 6; // 宽度为6, item满屏
case 1:
return 6;// 宽度为6, item满屏
case 2:
return 3;// 宽度为3,item为屏幕的宽的一半,这一行可以显示2个item
case 3:
return 2;// 宽度为3,item为屏幕的宽的1/3,这一行可以显示3个item
case 4:
return 6;// 宽度为6, item满屏
default:
return -1;
}
}
});
mListView.setLayoutManager(layoutManager);
mListView.setAdapter(mAdapter);

大功告成。谢谢阅读.

------Android开发基友群:64026923,众多妹纸、基友等着你哟。加的是群,涨的是技术:
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息