RecyclerView 的使用以及多布局的实例

  RecyclerView 是在Android5.0之后推出的,是一个比ListView更加灵活更加高效的适配器类型控件。但是RecyclerView不同于其他类型的适配器,它还需要一个LayoutManager进行页面控制展示。RecyclerView提供了三种布局管理器:
  1、LinearLayoutManager:线性布局管理器,支持水平和垂直效果。
  2、GridLayoutManager:网格布局管理器,支持水平和垂直效果。
  3、StaggeredGridLayoutManager:分布型管理器,瀑布流效果 RecyclerView的使用:
  1、引入RecyclerView依赖包,V7下的,兼容到API17.
  2、在xml布局中声明,在Java代码中初始化。
  3、设置布局管理器
  4、创建适配器,设置数据源,绑定适配器
    具体创建适配器:①创建一个类,继承RecyclerView.Adapter<ViewHolder>.
            ②创建一个类ViewHolder,继承RecyclerView。VIewHolder,该类需要创建一个匹配父类的构造。
            ③重写适配器中的方法:getItemCount():获取数据源的个数(item的数量);onCreateViewHolder():该方法中导入布局,实例化VIewHolder;onBindViewHolder():绑定VIewHolder,加载数据。
注意一点:RecyclerView的LinearLayoutManager不同于一般的适配器的布局,RecyclerView的item最外层的布局参数是有效的,如高度宽度等,所以在使用的时候,第一种方法是在导入View的时候指定没有parent(不推荐使用),第二种方法是在item布局的最外层指定具体的参数。
RecyclerView 为开发者提供了强大的复用机制,但是所有的点击事件都丢了,没有提供默认的点击事件,所以需要我们自己为RecyclerView手动实现点击。
看一个简单的例子,后面讲解下多布局的RecyclerView。效果图如下(不要吐槽,我知道很丑,能达到效果就好^_^):

第一步:创建布局,需要导入依赖包:android.support.v7.widget.RecyclerView

activity_main.xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout 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"
tools:context="com.zcl.day40_recyleview01.MainActivity">
<android.support.v7.widget.RecyclerView
android:id="@+id/teach_recycler"
android:layout_width="match_parent"
android:layout_height="match_parent"/>
</LinearLayout>

item.xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="horizontal" android:layout_width="match_parent"
android:background="@drawable/backgroud_shap"
android:layout_height="match_parent">
<ImageView
android:src="@mipmap/ic_launcher"
android:layout_width="80dp"
android:layout_height="80dp" />
<TextView
android:id="@+id/teach_item_name"
android:gravity="center"
android:layout_width="match_parent"
android:layout_height="80dp" />
</LinearLayout>

Model.java

public class Model {
private String name;
private int height; public int getHeight() {
return height;
} public void setHeight(int height) {
this.height = height;
} public String getName() {
return name;
} public void setName(String name) {
this.name = name;
}
}

MainActivity.java

public class MainActivity extends AppCompatActivity implements RecyclerAdapter.OnItemClickListener {
private static final String TAG = MainActivity.class.getSimpleName();
private RecyclerView mRecyclerView;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
initView();
}
private void initView() {
mRecyclerView = (RecyclerView) findViewById(R.id.teach_recycler);
//设置布局管理器
//1、第一种LinearLayoutManager
// LinearLayoutManager layoutManager = new LinearLayoutManager(this);
//2、第二种 GridLayoutManager
// GridLayoutManager layoutManager=new GridLayoutManager(this,3);
//3、第三种
StaggeredGridLayoutManager layoutManager = new StaggeredGridLayoutManager(2, StaggeredGridLayoutManager.VERTICAL);
// //设置布局的排版方向
// layoutManager.setOrientation(GridLayoutManager.HORIZONTAL);
mRecyclerView.setLayoutManager(layoutManager);
//绑定适配器
RecyclerAdapter adapter = new RecyclerAdapter(this, getData());
mRecyclerView.setAdapter(adapter);
adapter.setOnItemClickListener(this);//将接口传递到数据产生的地方
} /**
* 获取数据源
*
* @return
*/
public List<Model> getData() {
List<Model> data = new ArrayList<>();
for (int i = 0; i < 30; i++) {
Model model = new Model();
model.setName("猴子请来的都比---" + i);
model.setHeight(((int) (Math.random() * 100 + 200)));
data.add(model);
}
return data;
} @Override
public void onItemClick(int position, Model model) {
Log.e(TAG, "onItemClick: " + position);
}
}

适配器

public class RecyclerAdapter extends RecyclerView.Adapter<RecyclerAdapter.ViewHolder> implements View.OnClickListener {
private static final String TAG = RecyclerAdapter.class.getSimpleName();
private List<Model> data;
private LayoutInflater inflater;
private RecyclerView mRecyclerView;//用来计算Child位置
private OnItemClickListener onItemClickListener;
//对外提供接口初始化方法
public void setOnItemClickListener(OnItemClickListener onItemClickListener){
this.onItemClickListener=onItemClickListener;
} public RecyclerAdapter(Context context,List<Model> data) {
this.data = data;
inflater= (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
} public static class ViewHolder extends RecyclerView.ViewHolder{
TextView name; public ViewHolder(View itemView) {
super(itemView);
name= (TextView) itemView.findViewById(R.id.teach_item_name);
}
} /**
* 创建VIewHolder,导入布局,实例化itemView
* @param parent
* @param viewType
* @return
*/
@Override
public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View itemView = inflater.inflate(R.layout.item, parent, false);
//导入itemView,为itemView设置点击事件
itemView.setOnClickListener(this);
return new ViewHolder(itemView);
} /**
* 绑定VIewHolder,加载数据
* @param holder
* @param position
*/
@Override
public void onBindViewHolder(ViewHolder holder, int position) {
holder.name.setText(data.get(position).getName());//加载数据
ViewGroup.LayoutParams layoutParams = holder.itemView.getLayoutParams();
layoutParams.height=data.get(position).getHeight();
holder.itemView.setLayoutParams(layoutParams);
} /**
* 数据源的数量,item的个数
* @return
*/
@Override
public int getItemCount() {
return data!=null?data.size():0;
} /**
* 适配器绑定到RecyclerView 的时候,回将绑定适配器的RecyclerView 传递过来
* @param recyclerView
*/
@Override
public void onAttachedToRecyclerView(RecyclerView recyclerView) {
super.onAttachedToRecyclerView(recyclerView);
mRecyclerView=recyclerView;
} /**
*
* @param v 点击的View
*/
@Override
public void onClick(View v) {
//RecyclerView可以计算出这是第几个Child
int childAdapterPosition = mRecyclerView.getChildAdapterPosition(v);
Log.e(TAG, "onClick: "+childAdapterPosition );
if (onItemClickListener!=null) {
onItemClickListener.onItemClick(childAdapterPosition,data.get(childAdapterPosition));
}
} /**
* 接口回调
* 1、定义接口,定义接口中的方法
* 2、在数据产生的地方持有接口,并提供初始化方法,在数据产生的时候调用接口的方法
* 3、在需要处理数据的地方实现接口,实现接口中的方法,并将接口传递到数据产生的地方
*/
public interface OnItemClickListener{
void onItemClick(int position,Model model);
}
}

多布局的RecyclerView ---------------------------------------------------------------

先看下效果图:

这是

分析下该页面布局,三种布局,第一种是标题文字+内容简介文字占一个item,第二种是图片+标题占一个item,第三种是标题+内容,并且一个item中有两个这样的布局。那么可以用网格布局,分为两列,第一种跟第二种布局各自占两列,第三种布局占一列。那么怎么设置item可以横跨两列呢,就要用到gridLayoutManager.setSpanSizeLookup来设置,具体看代码:

activity_main.xml

<?xml version="1.0" encoding="utf-8"?>
<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"
tools:context="com.zcl.day40_task2.MainActivity">
<android.support.v7.widget.RecyclerView
android:id="@+id/recycler_view"
android:layout_width="match_parent"
android:layout_height="match_parent"/>
</RelativeLayout>

item1.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="200dp">
<ImageView
android:id="@+id/iv_item1"
android:src="@mipmap/ic_launcher"
android:layout_width="match_parent"
android:layout_height="200dp" />
<TextView
android:id="@+id/tv_item1"
android:text="title"
android:textColor="#e5ffffff"
android:textSize="20sp"
android:textStyle="bold"
android:layout_marginLeft="15dp"
android:layout_marginTop="20dp"
android:layout_marginRight="15dp"
android:layout_width="match_parent"
android:layout_height="wrap_content" /> </RelativeLayout>

item2.xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical" android:layout_width="match_parent"
android:layout_height="200dp">
<TextView
android:id="@+id/tv_item2_title"
android:textSize="20sp"
android:textStyle="bold"
android:text="title"
android:layout_marginLeft="15dp"
android:layout_marginTop="20dp"
android:layout_marginRight="15dp"
android:layout_width="match_parent"
android:layout_height="wrap_content" />
<TextView
android:id="@+id/tv_item2_content"
android:layout_marginLeft="15dp"
android:layout_marginTop="10dp"
android:text="content"
android:layout_marginBottom="10dp"
android:layout_marginRight="15dp"
android:layout_width="match_parent"
android:layout_height="wrap_content" />
</LinearLayout>

item3.xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical" android:layout_width="match_parent"
android:layout_height="200dp">
<TextView
android:id="@+id/tv_item3_title"
android:textSize="20sp"
android:lines="2"
android:ellipsize="end"
android:text="title"
android:layout_marginLeft="15dp"
android:layout_marginTop="10dp"
android:layout_marginRight="15dp"
android:layout_width="match_parent"
android:layout_height="60dp" />
<TextView
android:id="@+id/tv_item3_content"
android:lines="2"
android:ellipsize="end"
android:text="content"
android:layout_marginLeft="15dp"
android:layout_marginTop="10dp"
android:layout_marginRight="15dp"
android:layout_width="match_parent"
android:layout_height="60dp" /> </LinearLayout>

MainActivity.java

public class MainActivity extends AppCompatActivity implements MyAdapter.OnItemClickLietener{

    private static final String TAG = MainActivity.class.getSimpleName();
private RecyclerView mRecyclerView;
private MyAdapter adapter;
private List<Model> data;
public static final String URL_PATH="http://dxy.com/app/i/feed/index/list?hardName=Google%20Nexus%205%20-%205.1.0%20-%20API%2022%20-%201080x1920&u=&bv=2015&ac=d5424fa6-adff-4b0a-8917-4264daf4a348&vc=5.1.9&vs=5.1&mc=00000000600ba4e6ffffffff99d603a9"; @Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
initView();
} private void initView() {
ImageLoader.init(this);
mRecyclerView = (RecyclerView) findViewById(R.id.recycler_view);
//设置布局管理器
GridLayoutManager gridLayoutManager = new GridLayoutManager(this, 2);
Log.e(TAG, "initView:----1 " );
gridLayoutManager.setSpanSizeLookup(new GridLayoutManager.SpanSizeLookup() {
@Override
public int getSpanSize(int position) {
int spansize=1;
switch (adapter.getItemViewType(position)) {
case 1:
spansize=2;
break;
case 2:
spansize=2;
break;
}
return spansize;
}
});
Log.e(TAG, "initView: -----2" );
mRecyclerView.setLayoutManager(gridLayoutManager); adapter = new MyAdapter(this, getData());
mRecyclerView.setAdapter(adapter);
adapter.setClickLietener(this);
Log.e(TAG, "initView: 4" );
} public List<Model> getData() {
Log.e(TAG, "getData: 3" );
HttpUtil.getStringAsync(URL_PATH, new HttpUtil.RequestCallBack() {
@Override
public void onFailure() {
Log.e(TAG, "onFailure: " );
} @Override
public void onSuccess(String result) {
Gson gson = new Gson();
ModelData modelData = gson.fromJson(result, ModelData.class);
List<Model> data =modelData.getData().getItems();
Log.e(TAG, "onSuccess: "+data );
adapter.addRes(data);
} @Override
public void onFinish() {
Log.e(TAG, "onFinish: " );
}
}); return data;
} @Override
public void setItemClickListener(int position) {
Log.e(TAG, "setItemClickListener: "+position );
}
}
MyAdapter.java
public class MyAdapter extends RecyclerView.Adapter<MyAdapter.ViewHolder> implements View.OnClickListener {

    private List<Model> data;
private LayoutInflater inflater;
private RecyclerView mRecyclerView;
private OnItemClickLietener clickLietener; public void setClickLietener(OnItemClickLietener clickLietener){
this.clickLietener=clickLietener;
} public MyAdapter(Context context, List<Model> data) {
this.data = data;
inflater = LayoutInflater.from(context);
} @Override
public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View itemView = null;
switch (viewType) {
case 1:
itemView = inflater.inflate(R.layout.item1, parent, false);
break;
case 2:
itemView = inflater.inflate(R.layout.item2, parent, false);
break;
case 8:
itemView = inflater.inflate(R.layout.item3, parent, false);
break;
//设置监听
}
itemView.setOnClickListener(this);
return new ViewHolder(itemView);
} @Override
public void onBindViewHolder(ViewHolder holder, int position) {
switch (getItemViewType(position)) {
case 1:
ImageView imageView = (ImageView) holder.getView(R.id.iv_item1);
TextView textView = (TextView) holder.getView(R.id.tv_item1);
textView.setText(data.get(position).getTitle());
String picPath = data.get(position).getCover();
ImageLoader.display(imageView, picPath);
break;
case 2:
TextView item2Title = (TextView) holder.getView(R.id.tv_item2_title);
TextView item2Content = (TextView) holder.getView(R.id.tv_item2_content);
item2Title.setText(data.get(position).getTitle());
item2Content.setText(data.get(position).getContent());
break;
case 8:
TextView item3Title = (TextView) holder.getView(R.id.tv_item3_title);
TextView item3Content = (TextView) holder.getView(R.id.tv_item3_content);
item3Title.setText(data.get(position).getTitle());
item3Content.setText(data.get(position).getContent());
break;
}
} @Override
public int getItemCount() {
return data != null ? data.size() : 0;
} @Override
public int getItemViewType(int position) {
return data.get(position).getShow_type();
} @Override
public void onAttachedToRecyclerView(RecyclerView recyclerView) {
super.onAttachedToRecyclerView(recyclerView);
mRecyclerView=recyclerView;
} public void addRes(List<Model> data) {
if (data != null) {
this.data = data;
notifyDataSetChanged();
}
} @Override
public void onClick(View v) {
int childAdapterPosition = mRecyclerView.getChildAdapterPosition(v);
if (clickLietener!=null) {
clickLietener.setItemClickListener(childAdapterPosition);
}
} public static class ViewHolder extends RecyclerView.ViewHolder { private Map<Integer, View> mCacheView; public ViewHolder(View itemView) {
super(itemView);
mCacheView = new HashMap<>();
} public View getView(int resId) {
View view;
if (mCacheView.containsKey(resId)) {
view = mCacheView.get(resId);
} else {
view = itemView.findViewById(resId);
mCacheView.put(resId, view);
}
return view;
}
} public interface OnItemClickLietener{
void setItemClickListener(int position);
}
}

代码中使用的网络数据的请求以及图片的加载是自己封装的类库,大家可以忽略,用自己的代码填充,能理解RecyclerView就好,另外数据的实体类太简单,也没有贴上代码。最后不要忘了配置网络权限哦。

我的github:https://github.com/SiberiaDante

RecyclerView 的介绍以及多布局的实例的更多相关文章

  1. Flex 布局教程:实例

    分类: 开发者手册 Flex 布局教程:实例篇   作者: 阮一峰 日期: 2015年7月14日 上一篇文章介绍了Flex布局的语法,今天介绍常见布局的Flex写法. 你会看到,不管是什么布局,Fle ...

  2. Flex 布局:实例篇

    上一篇文章介绍了Flex布局的语法,今天介绍常见布局的Flex写法.你会看到,不管是什么布局,Flex往往都可以几行命令搞定. ​ 我只列出代码,详细的语法解释请查阅<Flex布局教程:语法篇& ...

  3. Flex 布局教程实例

    Flex 布局教程实例 一.Flex 布局是什么? Flex 是 Flexible Box 的缩写,意为"弹性布局",用来为盒状模型提供最大的灵活性. 任何一个容器都可以指定为 F ...

  4. RecyclerView的介绍与使用

    一.什么是RecyclerView 新的视图控件,是Android-support-v7-21版本中新增的一个Widgets,官方对于它的介绍则是:RecyclerView是ListView的升级版本 ...

  5. Android5.0新控件RecyclerVIew的介绍和兼容使用的方法

    第一部分 RecyclerVIew是一个可以替代listview和Gallery的有效空间而且在support-v7中有了低版本支持,具体使用方式还是规规矩矩的适配器加控件模式.我们先来看看官网的介绍 ...

  6. android新组件RecyclerView使用介绍和进阶使用,替用Gallery

    简介: RecyclerView是support-v7包中的新组件,是一个强大的滑动组件,与经典的ListView相比,同样拥有item回收复用的功能,但是直接把viewholder的实现封装起来,用 ...

  7. 【转】android新组件RecyclerView使用介绍和进阶使用,替用Gallery

    简介: RecyclerView是support-v7包中的新组件,是一个强大的滑动组件,与经典的ListView相比,同样拥有item回收复用的功能,但是直接把viewholder的实现封装起来,用 ...

  8. RecyclerView使用介绍

    来源 http://jinyudong.com/2014/11/13/Introduce-RecyclerView-%E4%B8%80/ 编辑推荐:稀土掘金,这是一个针对技术开发者的一个应用,你可以在 ...

  9. Slickflow.NET 开源工作流引擎基础介绍(七) -- 并行分支多实例模式实现

    前言:并行审批是比较常见的流程模式,在工作流模式介绍中,通常是多个分支通过网关(Gateway)来控制实现.默认的分支类型是静态定义好的.本文扩展了并行网关的控制方式,实现了动态多实例的并行分支网关, ...

随机推荐

  1. web前端的春天 or 噩梦

    「 微信应用号可以做什么」 简单说,微信"小程序"可以为开发者提供基于微信的表单.导航.地图.媒体和位置等开发组件,让他们在微信的网页里构建一个 HTML 5 应用.同时微信还开放 ...

  2. Spring集成MyBatis

    本文原创,原文地址为http://www.cnblogs.com/fengzheng/p/5045105.html 如果觉得Hibernate不够灵活,可以尝试用Mybatis.相比于Hibernat ...

  3. ABP框架 - 多层结构

    文档目录 本节内容: 简介 ABP结构 多层 其它层(通用) 领域(Core)层 应用层 基础层 Web & 表示层 其它 总结 简介 一个应用的代码库的分层是一个广为接受的技术,用来减少复杂 ...

  4. 【Win 10 应用开发】InkToolBar——涂鸦如此简单

    从WPF开始,就有个InkCanvas控件,封装了数字墨迹处理相关的功能,Silverlight到Win 8 App,再到UWP应用,都有这个控件,所以,老周说了3688遍,凡是.net基础扎实者,必 ...

  5. HTTP权威指南-基础知识

    1.URL,URI 统一资源标识符?统一标识定位符?   2.http,https,ftp http://<host>:<port>/<path>/?<que ...

  6. copy()之绝版应用

    我选用了一个稍稍复杂一点的例子,它的大致功能是:从标准输入设备(一般是键盘)读入一些整型数据,然后对它们进行排序,最终将结果输出到标准输出设备(一般是显示器屏幕).这是一种典型的处理方式,程序本身具备 ...

  7. Ubuntu-server 下Apache2 配置.htaccess 隐藏thinkPHP项目index.php

    需要开启Apache2的rewrite模块 1.打开/etc/apache2/apache2.conf 将文件中的AllowOverride None改为AllowOverride All 2.修改m ...

  8. Hawk 1.2 快速入门2 (大众点评18万美食数据)

    本文将讲解通过本软件,获取大众点评的所有美食数据,可选择任一城市,也可以很方便地修改成获取其他生活门类信息的爬虫. 本文将省略原理,一步步地介绍如何在20分钟内完成爬虫的设计,基本不需要编程,还能自动 ...

  9. SharePoint 2103 Check user permission on list

    一.需求: check user 对SharePoint list 的permission 代码如下: private static string GetListPermission(SPList l ...

  10. SQLServer学习笔记系列1

    一.前言 一直自己没有学习做笔记的习惯,所以为了加强自己对知识的深入理解,决定将学习笔记写下来,希望向各位大牛们学习交流! 不当之处请斧正!在此感谢!这边就先从学习Sqlserver写起,自己本身对数 ...