android RecycleView复杂多条目的布局

来源:互联网 发布:破解 经淘宝排查认定 编辑:程序博客网 时间:2024/05/22 09:38

用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;@Overrideprotected void onCreate(Bundle savedInstanceState) {// TODO Auto-generated method stubsuper.onCreate(savedInstanceState);setContentView(R.layout.activity_recycle);rcv = (RecyclerView) findViewById(R.id.rcv);// 设置布局管理GridLayoutManager manager = new GridLayoutManager(this, 2);// 设置布局管理一条数据占用几行,如果是头布局则头布局自己占用一行manager.setSpanSizeLookup(new SpanSizeLookup() {@Overridepublic 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);}}


布局文件activity_recycle.xml

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"    xmlns:tools="http://schemas.android.com/tools"    android:layout_width="match_parent"    android:layout_height="match_parent">    <android.support.v7.widget.RecyclerView        android:id="@+id/rcv"        android:layout_width="match_parent"        android:layout_height="wrap_content" /></RelativeLayout>


头布局文件head.xml

<?xml version="1.0" encoding="utf-8"?><RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"    android:layout_width="match_parent"    android:layout_height="match_parent" >    <ImageView        android:id="@+id/iv_head"        android:layout_width="80dp"        android:layout_height="80dp"        android:layout_margin="10dp"        android:src="@drawable/head" />    <TextView        android:id="@+id/tv_head"        android:layout_width="wrap_content"        android:layout_height="wrap_content"        android:layout_alignTop="@+id/iv_head"        android:layout_toRightOf="@+id/iv_head"        android:text="这是一张熊猫的图片" />    <ImageView        android:id="@+id/iv_head_bottom"        android:layout_width="wrap_content"        android:layout_height="wrap_content"        android:layout_alignBottom="@+id/iv_head"        android:layout_toRightOf="@+id/iv_head"        android:src="@drawable/type" /></RelativeLayout>



适配器MyRecycleAdapter.java

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 extendsRecyclerView.Adapter<MyRecycleAdapterHolder> {private View headView;private Context mContext;private int count;MyRecycleAdapter(Context mContext, int count) {this.count = count;this.mContext = mContext;}/** * 设置数据源总的条目 */@Overridepublic int getItemCount() {//返回条目数加头布局个数return count + 1;}@Overridepublic 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() {@Overridepublic void onClick(View v) {Toast.makeText(mContext, (position - 1) + "", 0).show();}});}}@Overridepublic 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;}@Overridepublic int getItemViewType(int position) {if (position == 0) {return RecycleViewWithHead.HEADER_RECYCLER_VIEW_ITEM;} else {return RecycleViewWithHead.NORMAL_RECYCLER_VIEW_ITEM;}}}


普通条目的布局文件item.xml

<?xml version="1.0" encoding="utf-8"?><LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"    android:id="@+id/ll_list"    android:layout_width="wrap_content"    android:layout_height="wrap_content"    android:layout_marginLeft="2dp"    android:layout_marginRight="2dp"    android:layout_marginTop="5dp"    android:orientation="vertical" >    <ImageView        android:id="@+id/iv_item_icon"        android:layout_width="wrap_content"        android:layout_height="wrap_content"        android:src="@drawable/item" />    <TextView        android:id="@+id/tv_item"        android:layout_width="wrap_content"        android:layout_height="wrap_content"        android:layout_gravity="center_horizontal"        android:layout_marginTop="5dp"        android:text="这是一只熊猫" /></LinearLayout>



普通条目的ViewHolder

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;@Overrideprotected void onCreate(Bundle savedInstanceState) {// TODO Auto-generated method stubsuper.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() {@Overridepublic 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);// 设置当前ViewTypeadapter.setSpanSize(RecycleViewWithHead.RECYCLER_VIEW_ITEM_DOUBLE);adapter.addHeadView(view);rcv.setAdapter(adapter);}@Overridepublic 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() {@Overridepublic 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() {@Overridepublic 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());}}}


布局文件activity_recycle.xml

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"    xmlns:tools="http://schemas.android.com/tools"    android:layout_width="match_parent"    android:layout_height="match_parent">    <android.support.v7.widget.RecyclerView        android:id="@+id/rcv"        android:layout_width="match_parent"        android:layout_height="wrap_content" />        <ImageView         android:id="@+id/iv_switch"        android:layout_width="wrap_content"        android:layout_height="wrap_content"android:layout_alignParentTop="true"        android:layout_alignParentRight="true"        android:layout_margin="20dp"        android:src="@drawable/more"        /></RelativeLayout>


适配器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 extendsRecyclerView.Adapter<MyRecycleAdapterHolder> {public View headView;public Context mContext;public int count;private int spanSize;// 当前每行显示几列public MyRecycleAdapter(Context mContext, int count) {this.count = count;this.mContext = mContext;}/** * 设置数据源总的条目 */@Overridepublic int getItemCount() {// 返回条目数加头布局个数return count + 1;}@Overridepublic 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() {@Overridepublic 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() {@Overridepublic void onClick(View v) {Toast.makeText(mContext,"单列," + (position - 1) + "", 0).show();}});}}}@Overridepublic 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;}@Overridepublic 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);}}}

头布局文件head.xm没有任何变化

条目的布局拆分为2个item_double.xml和item_single.xml

item_double.xml和之前的item.xml一样。


item_single.xml

<?xml version="1.0" encoding="utf-8"?><LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"    android:id="@+id/ll_list"    android:layout_width="wrap_content"    android:layout_height="wrap_content"    android:layout_marginLeft="2dp"    android:layout_marginRight="2dp"    android:layout_marginTop="5dp"    android:orientation="horizontal" >    <ImageView        android:id="@+id/iv_item_icon_single"        android:layout_width="wrap_content"        android:layout_height="wrap_content"        android:src="@drawable/item" />    <TextView        android:id="@+id/tv_item_single"        android:layout_width="wrap_content"        android:layout_height="wrap_content"        android:layout_gravity="center_vertical"        android:layout_marginTop="5dp"        android:text="这是一只熊猫" /></LinearLayout>


源码地址:http://download.csdn.net/detail/linder_qzy/9491370



0 0
原创粉丝点击