前几天去面试了一波,被虐的没有最惨 只要更惨,遂 先暂停面试 来学点东西 在出去浪吧,
有好几个面试官拿出一张这样的界面 问我怎么实现?就是下面这张
我说这个很简单的,最外层一个RecycleView,轮播图是一个item,横向的选项卡是一个item,title是一个item,下面的商品是一个gridView,然后面试官 微微一笑,说 你说的对,回去等我电话通知你哈,我就屁颠屁颠的走了,然后就没有然后了.......
我一直觉得这样做并没有问题的,直到有一位面试官 跟我说 你这样RecycleView嵌套Gridview 会使RecycleView的复用机制失效,我一时语塞,回赶紧查查别人是咋实现的,
其实很简单的,我们来看一下RecycleView平常是怎么使用的,
mRecyclerView = mView.findViewById(R.id.list);
// 设置布局管理器
layoutManager = new GridLayoutManager(getActivity(), 2);
mRecyclerView.setLayoutManager(layoutManager);
很简单 设置个布局管理器就行,布局管理器 这里用的是GridLayoutManager,第二个参数spanCount意思为 一行两个item,
这样就能实现类似于GridView的效果,那么刚刚开头那个问题的解决思路就是, 将本来一行两个item的布局,能不能利用什么手段 可以动态设置变成一个/两个,这样就相当于用一个RecycleVIew实现这个效果,这样就不会有效率问题了,
答案当然是可以的了,要不然 我费什么话呀,
重点:GridLayoutManager有个setSpanSizeLookup方法,
layoutManager.setSpanSizeLookup(new GridLayoutManager.SpanSizeLookup() {
@Override
public int getSpanSize(int position) {
return 0;
}
});
可以看出getSpanSize是有返回值的 默认是0 ,这个返回值的意思就是第position这个item占的一个权重,
比如说,刚刚设置的spanCount为2,那么getSpanSize返回1的话就是一行的1/2,那么假如getSpanSize返回2的话 就是占这一行的2/2 也就是占满当前一行了,所以说呢,我们可以通过设置getSpanSize来设置当前item占着一行的多少,
回到上面那个例子 也就是说 设置 轮播图item || 横向滑动的选项卡 || title 的getSpanSize为2,而商品的getSpanSize为1就能实现了,
下面我模拟一下 简单点 就要title和商品;我想让一个title下面六个商品 那就是当position为0/7/14的时候 设置getSpanSize为2
mRecyclerView = mView.findViewById(R.id.list);
// 设置布局管理器
layoutManager = new GridLayoutManager(getActivity(), 2);
layoutManager.setSpanSizeLookup(new GridLayoutManager.SpanSizeLookup() {
@Override
public int getSpanSize(int position) {
if (position == 0 || position == 7 || position == 14) {
return 2;
} else {
return 1;
}
}
});
mRecyclerView.setLayoutManager(layoutManager);
然后再adapter中,
private static final int ITEM_VIEW_TYPE_HEADER = 0;
private static final int ITEM_VIEW_TYPE_ITEM = 1;
@Override
public int getItemViewType(int position) {
return isTitle(position) ? ITEM_VIEW_TYPE_HEADER : ITEM_VIEW_TYPE_ITEM;
}
private boolean isTitle(int position) {
return position==0||position==7||position==14;
}
@Override
public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int position) {
final int itemPosition = position;
View view =null;
RecyclerView.ViewHolder holder=null;
if(isTitle(position)){
view = LayoutInflater.from(mAdapterContext).inflate(R.layout.adapter_item_handler,
parent, false);
holder = new ViewHeadHolder(view);
}else {
view = LayoutInflater.from(mAdapterContext).inflate(R.layout.adapter_item,
parent, false);
holder = new ViewHolder(view);
}
return holder;
}
根据不同的item展示不同的布局,
运行一下
好了,这就完了