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) ...
随机推荐
- python列出指定目录下的所有目录和文件
import os import docx def scanfile(rootdir): result = [] for f in os.walk(rootdir): for files in f[2 ...
- How to install redis server on CentOS 7 / RHEL 7
在本教程中,我们将学习如何在CentOS 7 / RHEL 7上安装Redis服务器. redis的缩写是REmote DIctionary Server. 它是最流行的开源,高级键值缓存和存储之一. ...
- 设计模式之单例模式 Singleton
核心作用 保证一个类只有一个实例,并且提供一个访问该实例的全局访问点. 常见应用场景 优点 由于单例模式只生成一个实例,减少了系统性开销,当一个对象的产生需要比较多的资源时,如读取配置,产生其他依赖对 ...
- Educational Codeforces Round 36 (Rated for Div. 2)
A. Garden time limit per test 1 second memory limit per test 256 megabytes input standard input outp ...
- Ubuntu搭建Http服务器用于下载Ubuntu文件
首先安装Apache $ sudo apt-get install apache2 Apache2的默认访问端口为80,当端口被占用时需要更改其访问端口 进入apache2的安装目录 /etc/ap ...
- JDBC 学习笔记(七)—— CallableStatement
在大型关系型数据库中,有一组为了完成特定功能的 SQL 语句集被称为存储过程(Stored Procedure),它是数据库中的对象. JDBC 使用 CallableStatement 对象,完成对 ...
- iOS启动动画效果实现
原理 在window上加一个UIImageView它的图片和启动图的图片一样,然后再调整动画 运行展示 demo百度云连接:http://pan.baidu.com/s/1c0QcYu0 more:网 ...
- [bzoj2302][HNOI2011]problem c 递推,dp
[HAOI2011]Problem c Time Limit: 30 Sec Memory Limit: 256 MBSubmit: 949 Solved: 519[Submit][Status] ...
- Windows connect to mysql failed: can't get hostname for your address
My mysql is on Linux platform. When I used my laptop connect to mysql, I got error message like &quo ...
- scrapy之download middleware
官方文档:https://docs.scrapy.org/en/latest/topics/downloader-middleware.html 一 write your own downloader ...