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="@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;
}
}
}
普通条目的布局文件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);
} }
效果图:
另一种情况类似于淘宝的商品展示我们能够切换每行显示的数量,事实上也非常easy
先看下要实现的效果:
我先说下大致的实现思路:
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="@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="@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
android RecycleView复杂多条目的布局的更多相关文章
- Android RecycleView多种布局实现(工厂模式)
RecycleView是个很常用的控件,很多APP中都可以看到它的身影,同时它也是个很难用的控件,主要就难在多种布局的实现. 在<第一行代码—Android>这本书里边有个RecycleV ...
- Android RecycleView实现混合Item布局
首先来看看效果吧: 效果预览.png 本实例来自于慕课网的视屏http://www.imooc.com/video/13046,实现步骤可以自己去观看视屏,这里只记录了下实现的代码. 添加依赖: (1 ...
- [Android] Android RecycleView和ListView 自定义Adapter封装类
在网上查看了很多对应 Android RecycleView和ListView 自定义Adapter封装类 的文章,主要存在几个问题: 一).网上代码一大抄,复制来复制去,大部分都运行不起来,或者 格 ...
- Android的学习第六章(布局一LinearLayout)
今天我们来说一下Android五大布局-LinearLayout布局(线性布局) 含义:线性布局,顾名思义,指的是整个Android布局中的控件摆放方式是以线性的方式摆放的, 主要作用:主要对整个界面 ...
- Android开发之详解五大布局
http://bbs.chinaunix.net/thread-3654213-1-1.html 为了适应各式各样的界面风格,Android系统提供了5种布局,这5种布局分别是: LinearLayo ...
- Android中常用的5大布局详述
Android的界面是有布局和组件协同完成的,布局好比是建筑里的框架,而组件则相当于建筑里的砖瓦.组件按照布局的要求依次排列,就组成了用户所看见的界面. 所有的布局方式都可以归类为ViewGroup的 ...
- Android 开发之旅:深入分析布局文件&又是“Hello World!”
http://www.cnblogs.com/skynet/archive/2010/05/20/1740277.html 引言 上篇可以说是一个分水岭,它标志着我们从Android应用程序理论进入实 ...
- android listview需要呈现多个布局
android listview需要呈现多个布局 之前的做法很笨 在getView()方法里面,不仅将viewHolder作为tag属性设置给convertView 还将当前的position作为ta ...
- Android进阶(二十七)Android原生扰人烦的布局
Android原生扰人烦的布局 在开发Android应用时,UI布局是一件令人烦恼的事情.下面主要讲解一下Android中的界面布局. 一.线性布局(LinearLayout) 线性布局分为: (1) ...
随机推荐
- sgen.exe 未能运行
指定的任务可执行文件“sgen.exe”未能运行.文件名或扩展名太长. 解决方式,右键项目属性->生成 把下图红框的“开”设置成“自动”
- 关于php ‘==’ 与 '===' 遇见的坑
两个的区别所有PHPer都知道, 今天在遍历 xmlNode时,自己写的代码就碰坑了 想遍历xmlNode为数组 得到的xmlNode为 想要把所有的simpleXmlElement对象都遍历转成数组 ...
- 都系坤坤-微信助手V 0.1,解放双手发信息
端午节刚过,相信大家在端午节都收到不少微信祝福信息,有复制长篇大论的祝福语群发的,有人工手打的简单祝福群发,我更喜欢人工手打带上称呼的祝福信息,这样看起来更加亲切. 那么问题来了,当你的通讯录里好友多 ...
- javascript之进阶
一 模态框 1 什么是模态框 模态框(Modal)是覆盖在父窗体上的子窗体.指在用户想要对对话框以外的应用程序进行操作时,必须首先对该对话框进行响应.如单击[确定]或[取消]按钮等将该对话框关闭. 2 ...
- hdu 1087 最大上升子序列的和(dp或线段树)
Super Jumping! Jumping! Jumping! Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 ...
- javaweb学习总结(十)——HttpServletRequest对象(一)(转)
(每天都会更新至少一篇以上,有兴趣的可以关注)转载自孤傲苍狼 一.HttpServletRequest介绍 HttpServletRequest对象代表客户端的请求,当客户端通过HTTP协议访问服务器 ...
- [LeetCode] Minimum Window Substring 散列映射问题
题目: Given a string S and a string T, find the minimum window in S which will contain all the charact ...
- .net EF框架
https://blog.csdn.net/u012235352/article/details/82768897 model first https://blog.csdn.net/u0101783 ...
- Scrapy学习-20-数据收集
Scrapy的数据收集功能 定义 Scrapy提供了方便的收集数据的机制.数据以key/value方式存储,值大多是计数值. 该机制叫做数据收集器(Stats Collector),可以通过 Craw ...
- Scrapy学习-13-使用DownloaderMiddleware设置IP代理池及IP变换
设置IP代理池及IP变换方案 方案一: 使用国内免费的IP代理 http://www.xicidaili.com # 创建一个tools文件夹,新建一个py文件,用于获取代理IP和PORT from ...