android RecycleView复杂多条目的布局

男儿欲遂平生志,六经勤向窗前读。这篇文章主要讲述android RecycleView复杂多条目的布局相关的知识,希望能为你提供帮助。
用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); } }




布局文件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=https://www.songbingjia.com/android/" @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 extends RecyclerView.Adapter< MyRecycleAdapterHolder> { 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; } } }

【android RecycleView复杂多条目的布局】


普通条目的布局文件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=https://www.songbingjia.com/android/" @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); }}


效果图:
android RecycleView复杂多条目的布局

文章图片







另一种情况类似 于淘宝的商品展示我们能够切换每行显示的数量,事实上也非常easy
先看下要实现的效果:
android RecycleView复杂多条目的布局

文章图片


我先说下大致的实现思路:
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()); } } }




布局文件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=https://www.songbingjia.com/android/" @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 extends RecyclerView.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; } /** * 设置数据源总的条目 */ @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); } } }



头布局文件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=https://www.songbingjia.com/android/" @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



































    推荐阅读