赞
踩
按照惯例 先看看效果图
最上面是一个轮播图,然后下面是一个横向滑动的频道,然后下面就是一个GridView,再下面就是正常的布局显示了
当然这还不算是很复杂的布局,我这边只是讲讲原理和实现步骤,更多复杂布局可以根据这个去扩展
给不同position的item设置不同的layout布局, 绑定不同的ViewHolder
1,定义不同的viewType常量(非必须)
2,在getItemViewType方法中根据position来返回不同的viewType
3,根据getItemViewType方法返回的不同的viewType在onCreateViewHolder创建不同的ViewHolder
4,onBindViewHolder方法里面用instanceof判断不同的ViewHolder来做不通的赋值处理
5,注意getItemCount的返回值
1,定义不同的viewType常量
上面的图片上可以看出,一共有4个type,轮播图,频道,美女,正常4个,下面是定义的常量
private final int BANNER_VIEW_TYPE = 0;//轮播图
private final int CHANNEL_VIEW_TYPE = 1;//频道
private final int GIRL_VIEW_TYPE = 2;//美女
private final int NORMAL_VIEW_TYPE = 3;//正常布局
2,在getItemViewType方法中根据position来返回不同的viewType
/**
* 获取item的类型
*
* @param position item的位置
* @return item的类型
* 有几种type就回在onCreateViewHolder方法中引入几种布局,也就是创建几个ViewHolder
*/
@Override
public int getItemViewType(int position) {
/*
区分item类型,返回不同的int类型的值
在onCreateViewHolder方法中用viewType来创建不同的ViewHolder
*/
if (position == 0) {//第0个位置是轮播图
return BANNER_VIEW_TYPE;
} else if (position == 1) {//第一个是频道布局
return CHANNEL_VIEW_TYPE;
} else if (position == 2) {//第2个位置是美女布局
return GIRL_VIEW_TYPE;
} else {//其他位置返回正常的布局
return NORMAL_VIEW_TYPE;
}
}
position就是每个item的位置,根据不同的位置来返回不同的布局type,可以根据你的需求自己穿插的来返回不同的viewType
3,根据getItemViewType方法返回的不同的viewType在onCreateViewHolder创建不同的ViewHolder
从这一步开始就是重头戏了
以轮播图为例子,每一个viewType都要有这几个步骤
a,写xml布局:既然有轮播图就肯定有轮播图的布局,我这里用的是第三方的轮播图,看布局
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="match_parent">
<com.youth.banner.Banner
android:id="@+id/banner"
android:layout_width="match_parent"
android:layout_height="175dp"
app:delay_time="3000"
app:scroll_time="1500"
app:indicator_margin="5dp"
app:indicator_height="6dp"
app:indicator_width="6dp"
app:indicator_drawable_selected="@color/colorPrimary"
app:indicator_drawable_unselected="@color/colorAccent"
/>
</LinearLayout>
没什么别的,就是你要展示的布局文件
b,创建ViewHolder内部类,继承RecyclerView.ViewHolder,在里面实例化你要赋值的控件
/**
* 轮播图的ViewHolder
*/
public static class BannerHolder extends RecyclerView.ViewHolder {
Banner banner;
public BannerHolder(View itemView) {
super(itemView);
banner = (Banner) itemView.findViewById(R.id.banner);
}
}
c,引入布局,new出ViewHolder并将引入的布局传递进去,在onCreateViewHolder方法里面
if (viewType == BANNER_VIEW_TYPE) {//如果viewType是轮播图就去创建轮播图的viewHolder
View view = View.inflate(context, R.layout.item_banner, null);
BannerHolder bannerHolder = new BannerHolder(view);
return bannerHolder;
}
以上就是为一种布局创建ViewHodler
下面是完整的onCreateViewHolder方法里面判断不同的viewType创建不同的ViewHolder的代码
/**
* 创建ViewHolder,根据getItemViewType方法里面返回的几种类型来创建
*
* @param viewType 就是getItemViewType返回的type
* @return 返回自己创建的ViewHolder
*/
@Override
public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View view;
if (viewType == BANNER_VIEW_TYPE) {//如果viewType是轮播图就去创建轮播图的viewHolder
view = getView(R.layout.item_banner);
BannerHolder bannerHolder = new BannerHolder(view);
return bannerHolder;
} else if (viewType == CHANNEL_VIEW_TYPE) {//频道的type
view = getView(R.layout.item_channel);
return new ChannelHolder(view);
} else if (viewType == GIRL_VIEW_TYPE) {//美女
view = getView(R.layout.item_girl);
return new GirlHolder(view);
} else {//正常
view = getView(R.layout.item_normal);
RecyclerView.LayoutParams lp = new RecyclerView.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT);
view.setLayoutParams(lp);
return new NormalHolder(view);
}
}
/**
* 用来引入布局的方法
*/
private View getView(int view) {
View view1 = View.inflate(context, view, null);
return view1;
}
4,onBindViewHolder方法里面用instanceof判断不同的ViewHolder来做不通的赋值处理
直接上代码了,注释很清楚了
@Override
public void onBindViewHolder(RecyclerView.ViewHolder holder, final int position) {
//判断不同的ViewHolder做不同的处理
if (holder instanceof BannerHolder) {//轮播图
BannerHolder bannerHolder = (BannerHolder) holder;
//调用设置轮播图相关方法
setBanner(bannerHolder);
} else if (holder instanceof ChannelHolder) {//频道
ChannelHolder channelHolder = (ChannelHolder) holder;
//设置频道
setChannel(channelHolder);
} else if (holder instanceof GirlHolder) {//美女
GirlHolder girlHolder = (GirlHolder) holder;
GridViewAdapter adapter = new GridViewAdapter(context, girlList);
girlHolder.gridView.setAdapter(adapter);
girlHolder.gridView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
@Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
Toast.makeText(context, "美女" + position, Toast.LENGTH_SHORT).show();
}
});
} else if (holder instanceof NormalHolder) {//正常布局
NormalHolder normalHolder = (NormalHolder) holder;
normalHolder.textView.setText(normalList.get(position - 3));
normalHolder.textView.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Toast.makeText(context, "点击了" + normalList.get(position - 3), Toast.LENGTH_SHORT).show();
}
});
}
}
5,注意getItemCount的返回值
稍微不注意就越界了,+3是因为除了正常的布局还有3个不同的布局
如果是服务器请求数据的话就得不同的情况不同处理了
@Override
public int getItemCount() {
return normalList.size() + 3;
}
下面贴出 整个RecyclerView的adapter的代码
package duanlian.multiplerecyclerviewdemo;
import android.content.Context;
import android.support.v7.widget.RecyclerView;
import android.view.View;
import android.view.ViewGroup;
import android.widget.AdapterView;
import android.widget.GridView;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.TextView;
import android.widget.Toast;
import com.bumptech.glide.Glide;
import com.youth.banner.Banner;
import com.youth.banner.BannerConfig;
import com.youth.banner.Transformer;
import com.youth.banner.loader.ImageLoader;
import java.util.List;
import java.util.Map;
/**
* 程序猿: 段炼
* 创建日期: 2017/4/19
* 创建时间: 9:30
* 本类功能:recyclerView的Adapter
*/
public class RecyclerAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder> {
private Context context;
private List<String> picList;
private List<Map<String, Object>> channelList;
private List<Integer> girlList;
private List<String> normalList;
private final int BANNER_VIEW_TYPE = 0;//轮播图
private final int CHANNEL_VIEW_TYPE = 1;//频道
private final int GIRL_VIEW_TYPE = 2;//美女
private final int NORMAL_VIEW_TYPE = 3;//正常布局
public RecyclerAdapter(Context context, List<String> picList, List<Map<String, Object>> channelList,
List<Integer> girlList, List<String> normalList) {
this.context = context;
this.picList = picList;
this.channelList = channelList;
this.girlList = girlList;
this.normalList = normalList;
}
/**
* 获取item的类型
*
* @param position item的位置
* @return item的类型
* 有几种type就回在onCreateViewHolder方法中引入几种布局,也就是创建几个ViewHolder
*/
@Override
public int getItemViewType(int position) {
/*
区分item类型,返回不同的int类型的值
在onCreateViewHolder方法中用viewType来创建不同的ViewHolder
*/
if (position == 0) {//第0个位置是轮播图
return BANNER_VIEW_TYPE;
} else if (position == 1) {//第一个是频道布局
return CHANNEL_VIEW_TYPE;
} else if (position == 2) {//第2个位置是美女布局
return GIRL_VIEW_TYPE;
} else {//其他位置返回正常的布局
return NORMAL_VIEW_TYPE;
}
}
/**
* 创建ViewHolder,根据getItemViewType方法里面返回的几种类型来创建
*
* @param viewType 就是getItemViewType返回的type
* @return 返回自己创建的ViewHolder
*/
@Override
public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View view;
if (viewType == BANNER_VIEW_TYPE) {//如果viewType是轮播图就去创建轮播图的viewHolder
view = getView(R.layout.item_banner);
BannerHolder bannerHolder = new BannerHolder(view);
return bannerHolder;
} else if (viewType == CHANNEL_VIEW_TYPE) {//频道的type
view = getView(R.layout.item_channel);
return new ChannelHolder(view);
} else if (viewType == GIRL_VIEW_TYPE) {//美女
view = getView(R.layout.item_girl);
return new GirlHolder(view);
} else {//正常
view = getView(R.layout.item_normal);
RecyclerView.LayoutParams lp = new RecyclerView.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT);
view.setLayoutParams(lp);
return new NormalHolder(view);
}
}
/**
* 用来引入布局的方法
*/
private View getView(int view) {
View view1 = View.inflate(context, view, null);
return view1;
}
@Override
public void onBindViewHolder(RecyclerView.ViewHolder holder, final int position) {
//判断不同的ViewHolder做不同的处理
if (holder instanceof BannerHolder) {//轮播图
BannerHolder bannerHolder = (BannerHolder) holder;
//调用设置轮播图相关方法
setBanner(bannerHolder);
} else if (holder instanceof ChannelHolder) {//频道
ChannelHolder channelHolder = (ChannelHolder) holder;
//设置频道
setChannel(channelHolder);
} else if (holder instanceof GirlHolder) {//美女
GirlHolder girlHolder = (GirlHolder) holder;
GridViewAdapter adapter = new GridViewAdapter(context, girlList);
girlHolder.gridView.setAdapter(adapter);
girlHolder.gridView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
@Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
Toast.makeText(context, "美女" + position, Toast.LENGTH_SHORT).show();
}
});
} else if (holder instanceof NormalHolder) {//正常布局
NormalHolder normalHolder = (NormalHolder) holder;
normalHolder.textView.setText(normalList.get(position - 3));
normalHolder.textView.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Toast.makeText(context, "点击了" + normalList.get(position - 3), Toast.LENGTH_SHORT).show();
}
});
}
}
/**
* 设置频道
*
* @param channelHolder
*/
private void setChannel(ChannelHolder channelHolder) {
//动态添加View
for (int i = 0; i < channelList.size(); i++) {
View view = View.inflate(context, R.layout.item_channel_view, null);
ImageView ivLogo = (ImageView) view.findViewById(R.id.iv_logo);
TextView tvChannel = (TextView) view.findViewById(R.id.tv_channel);
Glide.with(context).load(channelList.get(i).get("pic")).into(ivLogo);
tvChannel.setText(channelList.get(i).get("title").toString());
LinearLayout.LayoutParams params = new LinearLayout.LayoutParams(LinearLayout.LayoutParams.WRAP_CONTENT, LinearLayout.LayoutParams.WRAP_CONTENT);
view.setLayoutParams(params);
params.setMargins(24, 0, 24, 0);
view.setTag(i);
final int finalI = i;
view.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Toast.makeText(context, channelList.get(finalI).get("title").toString(), Toast.LENGTH_SHORT).show();
}
});
channelHolder.linearLayout.addView(view);
}
}
/**
* 设置轮播图
*
* @param bannerHolder
*/
private void setBanner(BannerHolder bannerHolder) {
//设置banner样式
bannerHolder.banner.setBannerStyle(BannerConfig.CIRCLE_INDICATOR);
//设置图片加载器
bannerHolder.banner.setImageLoader(new GlideImageLoader());
//设置图片集合
bannerHolder.banner.setImages(picList);
//设置banner动画效果
bannerHolder.banner.setBannerAnimation(Transformer.Default);
//设置标题集合(当banner样式有显示title时)
// bannerHolder.banner.setBannerTitles(titles);
//设置自动轮播,默认为true
bannerHolder.banner.isAutoPlay(true);
//设置轮播时间
// bannerHolder.banner.setDelayTime(3500);
//设置指示器位置(当banner模式中有指示器时)
bannerHolder.banner.setIndicatorGravity(BannerConfig.CENTER);
//banner设置方法全部调用完毕时最后调用
bannerHolder.banner.start();
}
public class GlideImageLoader extends ImageLoader {
@Override
public void displayImage(Context context, Object path, ImageView imageView) {
//Glide 加载图片简单用法
Glide.with(context).load(path).into(imageView);
}
}
@Override
public int getItemCount() {
return normalList.size() + 3;
}
/*****************************************下面是为不同的布局创建不同的ViewHolder*******************************************************/
/**
* 轮播图的ViewHolder
*/
public static class BannerHolder extends RecyclerView.ViewHolder {
Banner banner;
public BannerHolder(View itemView) {
super(itemView);
banner = (Banner) itemView.findViewById(R.id.banner);
}
}
/**
* 频道列表的ViewHolder
*/
public static class ChannelHolder extends RecyclerView.ViewHolder {
LinearLayout linearLayout;
public ChannelHolder(View itemView) {
super(itemView);
linearLayout = (LinearLayout) itemView.findViewById(R.id.ll_channel);
}
}
/**
* 美女的ViewHolder
*/
public static class GirlHolder extends RecyclerView.ViewHolder {
GridView gridView;
public GirlHolder(View itemView) {
super(itemView);
gridView = (GridView) itemView.findViewById(R.id.gridview);
}
}
/**
* 正常布局的ViewHolder
*/
public static class NormalHolder extends RecyclerView.ViewHolder {
TextView textView;
public NormalHolder(View itemView) {
super(itemView);
textView = (TextView) itemView.findViewById(R.id.text);
}
}
}
还有些细节就不说了,请下载demo
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。