用RecycleView来实现布局形式,默认只能指定一种布局格式,但是实际中我们的布局经常会用到多种类型的布局方式。如何实现呢?
今天来说下常用的2钟方式。
第一种:
通过自定义addHeadView方法来添加头布局
RecycleViewWithHead.Java
import android.app.Activity;
import android.os.Bundle;
import android.support.v7.widget.GridLayoutManager;
import android.support.v7.widget.GridLayoutManager.SpanSizeLookup;
import android.support.v7.widget.RecyclerView;
import android.view.View;
public class RecycleViewWithHead extends Activity {
private RecyclerView rcv;
// 当前的条目是recyclerView的头布局
public static final int HEADER_RECYCLER_VIEW_ITEM = 0;
// 当前的条目是普通recyclerView的条目
public static final int NORMAL_RECYCLER_VIEW_ITEM = 1;
@Override
protected void onCreate(Bundle savedInstanceState) {
// TODO Auto-generated method stub
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_recycle);
rcv = (RecyclerView) findViewById(R.id.rcv);
// 设置布局管理
GridLayoutManager manager = new GridLayoutManager(this, 2);
// 设置布局管理一条数据占用几行,如果是头布局则头布局自己占用一行
manager.setSpanSizeLookup(new SpanSizeLookup() {
@Override
public int getSpanSize(int postion) {
if (postion == 0) {
return 2;
} else {
return 1;
}
}
});
rcv.setLayoutManager(manager);
MyRecycleAdapter adapter = new MyRecycleAdapter(
RecycleViewWithHead.this, 20);
View view = View.inflate(this, R.layout.head, null);
adapter.addHeadView(view);
rcv.setAdapter(adapter);
}
}
import android.content.Context;
import android.support.v7.widget.RecyclerView;
import android.support.v7.widget.RecyclerView.ViewHolder;
import android.view.LayoutInflater;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.ViewGroup;
import android.widget.Toast;
public class MyRecycleAdapter extends
RecyclerView.Adapter {
private View headView;
private Context mContext;
private int count;
MyRecycleAdapter(Context mContext, int count) {
this.count = count;
this.mContext = mContext;
}
/**
* 设置数据源总的条目
*/
@Override
public int getItemCount() {
//返回条目数加头布局个数
return count + 1;
}
@Override
public void onBindViewHolder(MyRecycleAdapterHolder holder,
final int position) {
int itemViewType = getItemViewType(position);
// 头部
if (itemViewType == RecycleViewWithHead.HEADER_RECYCLER_VIEW_ITEM) {
return;
} else if (itemViewType == RecycleViewWithHead.NORMAL_RECYCLER_VIEW_ITEM) {//普通条目
holder.iv_item_icon.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
Toast.makeText(mContext, (position - 1) + "", 0).show();
}
});
}
}
@Override
public MyRecycleAdapterHolder onCreateViewHolder(ViewGroup parent,
int viewType) {
View root = null;
if (viewType == RecycleViewWithHead.HEADER_RECYCLER_VIEW_ITEM) {
root = headView;
} else {
root = LayoutInflater.from(mContext).inflate(R.layout.item, parent,
false);
}
return new MyRecycleAdapterHolder(root, viewType);
}
/**
* 添加自定义头部
*/
public void addHeadView(View view) {
this.headView = view;
}
@Override
public int getItemViewType(int position) {
if (position == 0) {
return RecycleViewWithHead.HEADER_RECYCLER_VIEW_ITEM;
} else {
return RecycleViewWithHead.NORMAL_RECYCLER_VIEW_ITEM;
}
}
}
import android.support.v7.widget.RecyclerView;
import android.view.View;
import android.widget.ImageView;
import android.widget.TextView;
public class MyRecycleAdapterHolder extends RecyclerView.ViewHolder{
public ImageView iv_item_icon;
public TextView tv_item;
public MyRecycleAdapterHolder(View itemView) {
super(itemView);
}
public MyRecycleAdapterHolder(View itemView,int viewType) {
super(itemView);
initView(itemView,viewType);
}
private void initView(View itemView, int viewType) {
iv_item_icon = (ImageView) itemView.findViewById(R.id.iv_item_icon);
tv_item = (TextView) itemView.findViewById(R.id.tv_item);
}
}
还有一种情况类似于淘宝的商品展示我们可以切换每行显示的数量,其实也很简单
先看下要实现的效果:
我先说下大致的实现思路:
1.给adapter设置一个当前显示多行还是单行的标记。
2.每次切换视图时重置标记,并重置RecycleView的LayoutManager。
3.调用adapter.notifyItemRangeChanged(2, adapter.getItemCount());(第一个参数是动画开始的位置索引)
好了再来看下RecycleViewWithHead.java
import com.example.myrecycleviewdemo.adapter.MyRecycleAdapter;
import android.app.Activity;
import android.os.Bundle;
import android.support.v7.widget.GridLayoutManager;
import android.support.v7.widget.GridLayoutManager.SpanSizeLookup;
import android.support.v7.widget.RecyclerView;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.ImageView;
public class RecycleViewWithHead extends Activity implements OnClickListener {
private RecyclerView rcv;
// 当前的条目是recyclerView的头布局
public static final int HEADER_RECYCLER_VIEW_ITEM = 0;
// 当前的条目是普通recyclerView的条目
public static final int NORMAL_RECYCLER_VIEW_ITEM = 1;
// 一行显示一个
public static final int RECYCLER_VIEW_ITEM_SINGLE = 3;
// 一行显示两个
public static final int RECYCLER_VIEW_ITEM_DOUBLE = 4;
private ImageView iv_switch;// 视图转换
private MyRecycleAdapter adapter;
private GridLayoutManager manager;
@Override
protected void onCreate(Bundle savedInstanceState) {
// TODO Auto-generated method stub
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_recycle);
rcv = (RecyclerView) findViewById(R.id.rcv);
iv_switch = (ImageView) findViewById(R.id.iv_switch);
iv_switch.setOnClickListener(this);
manager = new GridLayoutManager(this, 2);
// 设置布局管理一条数据占用几行,如果是头布局则头布局自己占用一行
manager.setSpanSizeLookup(new SpanSizeLookup() {
@Override
public int getSpanSize(int postion) {
if (postion == 0) {
return 2;
} else {
return 1;
}
}
});
rcv.setLayoutManager(manager);
adapter = new MyRecycleAdapter(RecycleViewWithHead.this, 20);
View view = View.inflate(this, R.layout.head, null);
// 设置当前ViewType
adapter.setSpanSize(RecycleViewWithHead.RECYCLER_VIEW_ITEM_DOUBLE);
adapter.addHeadView(view);
rcv.setAdapter(adapter);
}
@Override
public void onClick(View v) {
switch (v.getId()) {
case R.id.iv_switch:
changeRecycleViewList();
break;
default:
break;
}
}
/**
* 改变RecycleView的显示列数
*/
private void changeRecycleViewList() {
if (adapter != null) {
int spanSize = adapter.getSpanSize();
// 当前一行显示一列
if (spanSize == RecycleViewWithHead.RECYCLER_VIEW_ITEM_SINGLE) {
manager.setSpanSizeLookup(new GridLayoutManager.SpanSizeLookup() {
@Override
public int getSpanSize(int position) {
if (adapter.getItemViewType(position) == RecycleViewWithHead.HEADER_RECYCLER_VIEW_ITEM) {
return 2;
} else {
return 1;
}
}
});
adapter.setSpanSize(RecycleViewWithHead.RECYCLER_VIEW_ITEM_DOUBLE);
}
// 当前一行显示两列
else if (spanSize == RecycleViewWithHead.RECYCLER_VIEW_ITEM_DOUBLE) {
manager.setSpanSizeLookup(new GridLayoutManager.SpanSizeLookup() {
@Override
public int getSpanSize(int position) {
if (adapter.getItemViewType(position) == RecycleViewWithHead.HEADER_RECYCLER_VIEW_ITEM) {
return 2;
} else {
return 2;
}
}
});
adapter.setSpanSize(RecycleViewWithHead.RECYCLER_VIEW_ITEM_SINGLE);
}
// 第一个参数是动画开始的位置索引
adapter.notifyItemRangeChanged(2, adapter.getItemCount());
}
}
}
适配器MyRecycleAdapter.java
import com.example.myrecycleviewdemo.R;
import com.example.myrecycleviewdemo.RecycleViewWithHead;
import com.example.myrecycleviewdemo.R.layout;
import android.content.Context;
import android.support.v7.widget.RecyclerView;
import android.support.v7.widget.RecyclerView.ViewHolder;
import android.view.LayoutInflater;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.ViewGroup;
import android.widget.Toast;
public class MyRecycleAdapter extends
RecyclerView.Adapter {
public View headView;
public Context mContext;
public int count;
private int spanSize;// 当前每行显示几列
public MyRecycleAdapter(Context mContext, int count) {
this.count = count;
this.mContext = mContext;
}
/**
* 设置数据源总的条目
*/
@Override
public int getItemCount() {
// 返回条目数加头布局个数
return count + 1;
}
@Override
public void onBindViewHolder(MyRecycleAdapterHolder holder,
final int position) {
int itemViewType = getItemViewType(position);
// 头部
if (itemViewType == RecycleViewWithHead.HEADER_RECYCLER_VIEW_ITEM) {
return;
} else {// 普通条目
if (itemViewType == RecycleViewWithHead.RECYCLER_VIEW_ITEM_DOUBLE) {// 一行两列视图
holder.iv_item_icon.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
Toast.makeText(mContext, "2列," + (position - 1) + "", 0)
.show();
}
});
} else if (itemViewType == RecycleViewWithHead.RECYCLER_VIEW_ITEM_SINGLE) {// 一行一列视图
holder.iv_item_icon_single.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
Toast.makeText(mContext,"单列," + (position - 1) + "", 0).show();
}
});
}
}
}
@Override
public MyRecycleAdapterHolder onCreateViewHolder(ViewGroup parent,
int viewType) {
View root = null;
// 头部
if (viewType == RecycleViewWithHead.HEADER_RECYCLER_VIEW_ITEM) {
root = headView;
} else {// 普通条目
/** 一行显示一条 */
if (viewType == RecycleViewWithHead.RECYCLER_VIEW_ITEM_SINGLE) {
root = LayoutInflater.from(mContext).inflate(R.layout.item_single, parent, false);
}
/** 一行显示两条 */
else {
root = LayoutInflater.from(mContext).inflate(R.layout.item_double, parent, false);
}
}
return new MyRecycleAdapterHolder(root, viewType);
}
/**
* 添加自定义头部
*/
public void addHeadView(View view) {
this.headView = view;
}
@Override
public int getItemViewType(int position) {
if (position == 0) {
return RecycleViewWithHead.HEADER_RECYCLER_VIEW_ITEM;
} else {
/** 一行显示一条 */
if (spanSize == RecycleViewWithHead.RECYCLER_VIEW_ITEM_SINGLE) {
return RecycleViewWithHead.RECYCLER_VIEW_ITEM_SINGLE;
/** 一行显示两条 */
} else {
return RecycleViewWithHead.RECYCLER_VIEW_ITEM_DOUBLE;
}
}
}
public int getSpanSize() {
return spanSize;
}
public void setSpanSize(int spanSize) {
this.spanSize = spanSize;
}
}
普通条目的ViewHolder
import com.example.myrecycleviewdemo.R;
import com.example.myrecycleviewdemo.R.id;
import com.example.myrecycleviewdemo.RecycleViewWithHead;
import android.support.v7.widget.RecyclerView;
import android.view.View;
import android.widget.ImageView;
import android.widget.TextView;
public class MyRecycleAdapterHolder extends RecyclerView.ViewHolder{
//一行两列视图
public ImageView iv_item_icon;
public TextView tv_item;
//一行一列视图
public ImageView iv_item_icon_single;
public TextView tv_item_single;
public MyRecycleAdapterHolder(View itemView) {
super(itemView);
}
public MyRecycleAdapterHolder(View itemView,int viewType) {
super(itemView);
initView(itemView,viewType);
}
private void initView(View itemView, int viewType) {
if(viewType == RecycleViewWithHead.RECYCLER_VIEW_ITEM_DOUBLE){
iv_item_icon = (ImageView) itemView.findViewById(R.id.iv_item_icon);
tv_item = (TextView) itemView.findViewById(R.id.tv_item);
}else if(viewType == RecycleViewWithHead.RECYCLER_VIEW_ITEM_SINGLE){
iv_item_icon_single = (ImageView) itemView.findViewById(R.id.iv_item_icon_single);
tv_item_single = (TextView) itemView.findViewById(R.id.tv_item_single);
}
}
}
条目的布局拆分为2个item_double.xml和item_single.xml
item_double.xml和之前的item.xml一样。
item_single.xml
源码地址:http://download.csdn.NET/detail/linder_qzy/9491370