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

导言:

         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,众多妹纸、基友等着你哟。加的是群,涨的是技术:



评论 6
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值