目录:
1.什么是花样布局?
2.实现原理与要点分析
3.RecyclerView多类型item布局实现分类电影展示
1.什么是花样布局?
花样布局也就是我们经常说的多布局,一个RecyclerView实现多种布局样式,有时候业务需求或者说是解决UI单调性我们需要不同的布局
来显示不同的数据。
2.
实现原理与要点分析
实现原理:简单来讲就是通过不同的数据来加载不同的布局显示,说起来简单做起来就不辣么容易了。
要点分析:假设大家都会简单使用RecyclerView并实现简单的布局,如果不懂可以先看看我之前的文章
Android抢Listview饭碗之RecyclerView浅析
以及
RecyclerView分割线
对RecyclerView有个简单的了解。前面两篇文章都是简单的单一布局使用,而并没有用到今天的猪脚getItemViewType(),下面我们来看看源码对他的描述。
/**
* Return the view type of the item at <code>position</code> for the purposes
* of view recycling.
*
* <p>The default implementation of this method returns 0, making the assumption of
* a single view type for the adapter. Unlike ListView adapters, types need not
* be contiguous. Consider using id resources to uniquely identify item view types.
*
* @param position position to query
* @return integer value identifying the type of the view needed to represent the item at
* <code>position</code>. Type codes need not be contiguous.
*/
public int getItemViewType(int position) {
return 0;
}
源码描述该方法的大概意思是说该方法返回指定位置(position)的view类型(viewType)。其实细心的朋友可能看到
onCreateViewHolder(ViewGroup parent, int viewType)中有viewType参数
,对,你猜的没错,该方法就是根据getItemViewType()方法返回的类型,然后根据不同的类型去选择加载不同的布局,以此来达到显示不同布局的效果。
接下来我们来实现一个
多类型item布局实现分类电影展示。
3.RecyclerView多类型item布局实现分类电影展示
先上几张效果图(图片都来自时光网,非商用只做学习所用,应该不犯法吧?)
我都忍不住夸我寄几,炫酷吧,其实关键还是时光网的设计师NB,必须表个白,说一句我爱你,哈哈哈!
下面贴出代码,注释都在代码里面,废话不多说。
3.1 自定义适配器类MultiRecyclerViewAdapter.java
package com.example.recyclerviewdemo;
import android.content.Context;
import android.support.v7.widget.RecyclerView;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ImageView;
import android.widget.TextView;
import java.util.ArrayList;
import java.util.HashMap;
/**
* Created by elimy on 2017-01-10.
*/
public class MultiRecyclerViewAdapter extends RecyclerView.Adapter {
private Context context;
/* final int TITLE_LAYOUT=1;*/
final int TITLE_ONE_LAYOUT=1;
final int TITLE_TWO_LAYOUT=4;
final int NEWS_LAYOUT=2;
final int MOVIES_LAYOUT=3;
ArrayList<TitleObject> titleList;
ArrayList<NewsObject> newsList;
ArrayList<MoviesObject> movieList;
ArrayList<Integer> typeArray=new ArrayList<>();
HashMap<Integer,Integer> typePosition=new HashMap<>();
public MultiRecyclerViewAdapter(Context context, ArrayList<TitleObject> titleList, ArrayList<NewsObject> newsList, ArrayList<MoviesObject> moviesList) {
this.context=context;
this.titleList=titleList;
this.newsList=newsList;
this.movieList=moviesList;
//addTypeListToTypeArray(titleList,TITLE_LAYOUT);
//这里我为了把标题拆分开,所以没用直接调用上面这句代码,上一段代码的效果将导致标题占据第一、二条而没有到达我们
// 想要的效果
typePosition.put(TITLE_ONE_LAYOUT,typeArray.size());
typeArray.add(TITLE_ONE_LAYOUT);
Log.d("TAG","size="+typeArray.size());
addTypeListToTypeArray(newsList,NEWS_LAYOUT);
Log.d("TAG","size="+typeArray.size());
typePosition.put(TITLE_TWO_LAYOUT,typeArray.size());
typeArray.add(TITLE_TWO_LAYOUT);
Log.d("TAG","size="+typeArray.size());
addTypeListToTypeArray(moviesList,MOVIES_LAYOUT);
Log.d("TAG","size="+typeArray.size());
}
/*
* 将item位置与类型对应保存起来,同时保存每一种类型数据的起始位置
* 方便后面绑定数据的时候获取到对应类型的对应位置数据
* */
private void addTypeListToTypeArray(ArrayList list,int type){
//记录每一种类型的初始记录位置
typePosition.put(type,typeArray.size());
//相当于把3类List放入一个统一的List,建立起了typeArray下标和list类型的对应关系
for (int i=0;i<list.size();i++){
typeArray.add(type);
}
}
/*
* 根据不同的类型加载不同的布局
* */
@Override
public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View view=null;
if (viewType==TITLE_ONE_LAYOUT){
view= LayoutInflater.from(context).inflate(R.layout.title_item_layout,parent,false);
return new TitleViewHolder(view);
}else if(viewType==TITLE_TWO_LAYOUT){
view= LayoutInflater.from(context).inflate(R.layout.title_item_layout,parent,false);
return new TitleViewHolder(view);
} else if(viewType==NEWS_LAYOUT){
view=LayoutInflater.from(context).inflate(R.layout.news_item_layout,parent,false);
return new NewsViewHolder(view);
}else{
view=LayoutInflater.from(context).inflate(R.layout.movies_item_layout,parent,false);
return new MovieViewHolder(view);
}
}
@Override
public void onBindViewHolder(RecyclerView.ViewHolder holder, int position) {
//这里的position是等同于在typeArray的位置,实际的position需要减去该类型在typeArray的起始位置值,这样得出
// 的结果才是在自己的List中的位置
int truePosition=position-typePosition.get(getItemViewType(position));
if (holder instanceof TitleViewHolder){