RecyclerView+Cardview学习探索
1、概述
在support-V7包中引入了很多新的M 控件,其中RccyclerView也是其中一员,它的名字来源于它的工作方式:当一个Item被隐藏起来时候并没有被销毁,当建立新的item时候,组件自动复用item。但与以往经典listview不同的是,RccyclerView直接把viewholder的实现封装起来,因此用户只要实现自己的viewholder即可。
通常一个RccyclerView主要要处理以下几个部分:
LayoutManager :RccyclerView将item布局方式单独放出来供开发者选择,可以把你的item设置成水平或者垂直或者
主要有 LinearLayoutManager(线性)、GridLayoutManager(宫格)、StaggeredGridLayoutManager(瀑布流)
Adapter:适配器,在listview中也有,主要用来提供数据适配
ItemAnimator:负责item的动画播放修改,添加,删除或移动
ItemDecoration:可以用来添加drawings或者改变item的布局,比如添加dividers
ViewHolder:用户实现自己的viewlder即可
点击事件:这个没有提供需要自己写,这个我在后面的例子中会给出说明
再介绍一下Cardview,跟RccyclerView一样也是suooport-v7新控件,可以让我们使用类似卡片的效果,我们还可以设置卡片的圆角和阴影效果,cardview是一个layout继承自frameLayout,因此需要在里面布局其他view控件,下面给出一个cardview常用属性
CardView_cardBackgroundColor 设置背景色
CardView_cardCornerRadius 设置圆角大小
CardView_cardElevation 设置z轴阴影
CardView_cardMaxElevation 设置z轴最大高度值
CardView_cardUseCompatPadding 是否使用CompadPadding
CardView_cardPreventCornerOverlap 是否使用PreventCornerOverlap
CardView_contentPadding 内容的padding
CardView_contentPaddingLeft 内容的左padding
CardView_contentPaddingTop 内容的上padding
CardView_contentPaddingRight 内容的右padding
CardView_contentPaddingBottom 内容的底padding
2、实现一个基本的RecyclerView(结合cardview)
首先在AS中加入依赖
File>project structs,在+号选Library Dependency,加入如下来个依赖库
2.1 首先定义item的bean,主要包括一个主标题和副标题
Item.java
public class Item {
private String maintitle;
private String subtitle;
private boolean active;
public Item(String maintitle, String subtitle, boolean active) {
this.maintitle = maintitle;
this.subtitle = subtitle;
this.active = active;
}
public Item(String maintitle, String subtitle) {
this.maintitle = maintitle;
this.subtitle = subtitle;
}
public String getTitle() {
return maintitle;
}
public String getSubtitle() {
return subtitle;
}
public boolean isActive() {
return active;
}
}
注:isActive是为后面复杂例子准备的
2.2 设置item对应的布局文件
item.xml
<?xml version="1.0" encoding="utf-8"?>
<android.support.v7.widget.CardView
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="match_parent"
app:cardBackgroundColor="#79CDCD"
app:cardCornerRadius="5dp"
app:cardElevation="5dp"
app:cardMaxElevation="8dp"
app:cardUseCompatPadding="true"
app:contentPadding="10dp">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<TextView
android:id="@+id/maintitle"
style="@style/Base.TextAppearance.AppCompat.Headline"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:singleLine="true"
android:text="Title"
android:textColor="#FFFFFF"
/>
<TextView
android:id="@+id/subtitle"
style="@style/Base.TextAppearance.AppCompat.Subhead"
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="1"
android:singleLine="true"
android:text="Subtitle"
android:textColor="#FFFFFF"
/>
</LinearLayout>
</android.support.v7.widget.CardView>
其中对cardview的背景颜色,圆角,z轴阴影做了设定,最需要注意的属性是cardUseCompatPadding,它在5.0以下的系统中默认是true,但在5.0系统中默认为false,如果不设置 app:cardUseCompatPadding=”true”的话会造成在5.0系统的Android手机上不能看到阴影效果。
2.3 适配器recylerAdapter.java
首先我们需要定义自己的viewholder类,这类必须要继承RecyclerView.ViewHolder,内部绑定了所需要引用的数据,这里只有俩个textview
public static class ViewHolder extends RecyclerView.ViewHolder {
TextView maintitle;
TextView subtitle;
public ViewHolder(View itemView) {
super(itemView);
subtitle = (TextView) itemView.findViewById(R.id.subtitle);
maintitle = (TextView) itemView.findViewById(R.id.maintitle);
}
}
然后就是我们recylerAdapter()的构造器,这里我们使用集合添加item
public RecylerAdpater() {
super();
items = new ArrayList<>();
for (int i = 0; i < ITEM_CONUT; i++) {
items.add(new Item("Item" + i, "This is the Item number" + i));
}
}
最后看下我们继承RecyclerView.Adapter需要重写的方法
【1】onCreateViewHolder(ViewGroup parent, int i) 创建视图并且返回一个匹配的viewholder
【2】onBindViewHolder(ViewHolder holder, int position) 用每个item数据来填充viewholder
【3】getItemCount() 返回item的数目
@Override
public ViewHolder onCreateViewHolder(ViewGroup viewGroup, int i) {
View v = mLayoutInflater.from(viewGroup.getContext()).inflate(R.layout.item, viewGroup, false);
return new ViewHolder(v);
}
@Override
public void onBindViewHolder(ViewHolder viewHolder, int position) {
Item item = items.get(position);
viewHolder.maintitle.setText(item.getTitle());
viewHolder.subtitle.setText(item.getSubtitle());
}
@Override
public int getItemCount() {
return items.size();
}
2.4 主布局文件activity_main.xml,只有一个recylerView控件
<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=".MainActivity">
<android.support.v7.widget.RecyclerView
android:id="@+id/recycler_view"
android:layout_width="match_parent"
android:layout_height="match_parent">
</android.support.v7.widget.RecyclerView>
</RelativeLayout>
2.5 在MAinActivity.java中进行逻辑处理
public class MainActivity extends AppCompatActivity {
private RecyclerView recyclerView;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
init();
initEvent();
}
private void init() {
recyclerView = (RecyclerView) findViewById(R.id.recycler_view);
}
private void initEvent() {
recyclerView.setAdapter(new RecylerAdpater());
recyclerView.setItemAnimator(new DefaultItemAnimator());
//recyclerView.setLayoutManager(new LinearLayoutManager(this));//垂直线性布局
//recyclerView.setLayoutManager(new GridLayoutManager(this,2));//线性宫格显示,类似gridview
recyclerView.setLayoutManager(new StaggeredGridLayoutManager(3, OrientationHelper.VERTICAL));//线性宫格显示类似瀑布流
}
}
这里由于长度都一样瀑布流跟线性宫格效果一样,可以看出有圆角阴影效果,android新控件确实视觉效果杠杠滴,Material Design确实多学几招,对改善UI帮助莫大!
3、实现多Item布局
即实现相同的RecyclerView中实现不同样式的item,比如常见的headitem和bottomiItem就是通过这种方式实现的
首先事先定义出几套item的样式,这里使用了2套item样式,这里item布局仅做了颜色区分,当然可以做的更加复杂,这取决于各自的需求,这里只是演示一下多item的布局
然后利用item的isActive对item做标记
recylerAdapter.java中
public RecylerAdpater() {
super();
items = new ArrayList<>();
for (int i = 0; i < ITEM_CONUT; i++) {
if (i == 0)
items.add(new Item("Start Item " + i, "This is the start Item number " + i, true));
if (i == ITEM_CONUT - 1)
items.add(new Item("End Item " + i, "This is the end Item number " + i, true));
else
items.add(new Item(" Item " + i, "This is the Item number " + i, false));
}
}
将第一个和最后一个item单独标记处理,isactive属性标记为true
这里我们也需要重写新的方法
@Override
public int getItemViewType(int position) {
Item item = items.get(position);
return item.isActive() ? ACTIVE : IN_ACTIVE;
}
其中getItemViewType方法是用来获取当前项Item(position参数)是哪种类型的布局
然后我们在viewholder中对itenm布局做选择
@Override
public ViewHolder onCreateViewHolder(ViewGroup viewGroup, int viewType) {
final int layout = (viewType == IN_ACTIVE ? R.layout.item : R.layout.item_active);
//View v = mLayoutInflater.from(viewGroup.getContext()).inflate(R.layout.item, viewGroup, false);
View v = mLayoutInflater.from(viewGroup.getContext()).inflate(layout, viewGroup, false);
return new ViewHolder(v);
}
运行一下,这里只是实现了非常简单的多item布局
4、实现一个带点击相应的瀑布流
4.1 监听事件处理
Recylerview点击事件需要我们自己写这点就比较麻烦
这里我们在适配器中通过接口方式来写自己的itemlistener
RecylerAdapter.java
定义抽象接口
public interface OnItemClickListerner {
void onItemClick(View view, int position);
void onItemLongClick(View view, int position);
}
public void setOnItemClickLitener(OnItemClickListerner mOnItemClickListerner) {
this.mOnItemClickListerner = mOnItemClickListerner;
}
然后在onBindViewHolder中处理监听事件的方法
//如果设置了回调则设施点击事件
if (mOnItemClickListerner != null) {
viewHolder.itemView.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
int pos = viewHolder.getLayoutPosition();
mOnItemClickListerner.onItemClick(viewHolder.itemView, pos);
}
});
viewHolder.itemView.setOnLongClickListener(new View.OnLongClickListener() {
@Override
public boolean onLongClick(View v) {
int pos = viewHolder.getLayoutPosition();
mOnItemClickListerner.onItemLongClick(viewHolder.itemView, pos);
return false;
}
});
}
最后处理集中到MainActivity中来具体处理使用
mRecylerAdpater.setOnItemClickLitener(new RecylerAdpater.OnItemClickListerner() {
@Override
public void onItemClick(View view, int position) {
Toast.makeText(MainActivity.this, "click item" + position, Toast.LENGTH_SHORT).show();
}
@Override
public void onItemLongClick(View view, int position) {
mRecylerAdpater.removeData(position);
Toast.makeText(MainActivity.this, "long click delete item" + position, Toast.LENGTH_SHORT).show();
}
});
4.2 改变item集合(添加删除)
为了更新view,在listview中我们只有一个方法来监听数据item变化notifyDataSetChanged(),而在recylerView的adapter中,有多个方法
notifyItemChanged(int position) : position数据发生了改变,那调用这个方法,就会回调对应position的onBindViewHolder()方法了
notifyItemInserted(int position):这个方法是在第position位置被插入了一条数据的时候可以使用这个方法刷新,注意这个方法调用后会有插入的动画,这个动画可以使用默 认的,也可以自己定义。
notifyItemRemoved(int position):删除position位置上的item
notifyItemMoved(int fromPosition, int toPosition):这个方法是从fromPosition移动到toPosition为止的时候可以使用这个方法刷新
notifyItemRangeChanged(int positionStart, int itemCount):刷新从positionStart开始itemCount数量的item了(这里的刷新指回调onBindViewHolder()方法)
notifyItemRangeInserted(int positionStart, int itemCount):批量插入
notifyItemRangeRemoved(int positionStart, int itemCount):第position个被删除的时候刷新,同样会有动画
notifyDataSetChanged()改变数据视图
我们在Adapter中加入增删函数
/*添加*/
public void addItem(int pos) {
items.add(new Item("new Item", "This is the new Item ", false));
notifyItemInserted(pos);
}
/*删除*/
public void removeData(int pos) {
items.remove(pos);
notifyItemRemoved(pos);
}
然后在MAinactivity中调用即可。
长按删除item
点击弹出Toast提示,长按删除item,点击menu加号添加item
所有demo地址http://download.csdn.net/detail/xsf50717/9314043
RecyclerView+Cardview学习探索的更多相关文章
- RecyclerView,CardView导入和使用(Demo)
简介: 这篇文章是ANDROID L——Material Design详解(UI控件)的一个补充或者说是应用实例,如果有时间建议大家稍微浏览一下上篇文章. 本文主要介绍Android L新增加的两个U ...
- RecyclerView+CardView简单使用
RecyclerView取代Listview用来显示数据,除此之外还能实现瀑布流的布局.CardView让我们的界面更好看,此外还将使用官方的下拉刷新. 添加支持: compile 'com.andr ...
- Material design之New Widgets(RecyclerView CardView)
New Widgets:提供了两个新的控件 RecyclerView CardView 这两个控件包含在了Android L的support library中, 他们可以用于显示复杂的布局而且都默认采 ...
- ANDROID L——RecyclerView,CardView进口和使用(Demo)
转载请注明本文出自大苞米的博客(http://blog.csdn.net/a396901990),谢谢支持! 简单介绍: 这篇文章是ANDROID L--Material Design具体解释(UI控 ...
- App自动化测试框架学习探索--从零开始设计
App自动化测试框架学习探索--从零开始设计---持续更新中,敬请关注 1 批量执行app自动化测试使用多线程设计思路: 1)并发级别选择用methods 2)采用@Test多线程,数据提供类dp单线 ...
- 利用RecyclerView CardView实现新闻卡片样式
引入的包: demo结构: 测试代码: News.java: package com.zzw.testcardview; import java.io.Serializable; public cla ...
- Android学习探索之Java 8 在Android 开发中的应用
前言: Java 8推出已经将近2年多了,引入很多革命性变化,加入了函数式编程的特征,使基于行为的编程成为可能,同时减化了各种设计模式的实现方式,是Java有史以来最重要的更新.但是Android上, ...
- Android学习探索之本地原生渲染 LaTeX数据公式
前言: 一直致力于为公司寻找更加高效的解决方案,作为一款K12在线教育App,功能中难免会有LaTeX数学公式的显示需求,这部分公司已经实现了此功能,只是个人觉得在体验和效率上还是不太好,今天来聊一下 ...
- Android学习探索之运用MVP设计模式实现项目解耦
前言: 一直致力于提高开发效率降低项目耦合,今天想抽空学习一下MVP架构设计模式,学习一下如何运用到项目中. MVP架构设计模式 MVP模式是一种架构设计模式,也是一种经典的界面模式.MVP中的M代表 ...
随机推荐
- Bootstrap3 代码-代码块
多行代码可以使用 <pre> 标签.为了正确的展示代码,注意将尖括号做转义处理. <p>Sample text here...</p> <pre>< ...
- Git之(六)标签管理
发布一个版本时,我们通常先在版本库中打一个标签(tag),这样,就唯一确定了打标签时刻的版本.将来无论什么时候,取某个标签的版本,就是把那个打标签的时刻的历史版本取出来.所以,标签也是版本库的一个快照 ...
- Android适配难题全面总结
支持多种屏幕 Android 可在各种具有不同屏幕尺寸和密度的设备上运行.对于 应用,Android 系统在不同设备中提供一致的开发环境, 可以处理大多数工作,将每个应用的用户界面调整为适应其显示的 ...
- 理解性能的奥秘——应用程序中慢,SSMS中快(4)——收集解决参数嗅探问题的信息
本文属于<理解性能的奥秘--应用程序中慢,SSMS中快>系列 接上文:理解性能的奥秘--应用程序中慢,SSMS中快(3)--不总是参数嗅探的错 前面已经提到过关于存储过程在SSMS中运行很 ...
- Unity UGUI图文混排(五) -- 一张图集对应多个Text
继上一篇说的更新了一张图集对应多个Text的功能,为了节省资源嘛 这里,但是也没有舍弃之前的一个Text一个图集,因为我感觉应该两个都有用,于是我重新写了一个脚本 1.其实大体跟前面的都没变,解析标签 ...
- [ExtJS5学习笔记]第二十五节 利用window.open()函数实现ExtJS5的登陆页面跳转
本文地址:http://blog.csdn.net/sushengmiyan/article/details/40427543 mvvm方式实现登陆的博客:http://blog.csdn.net/s ...
- 5.关于QT中的网络编程,QTcpSocket,QUdpSocket
1 新建一个项目:TCPServer.pro A 修改TCPServer.pro,注意:如果是想使用网络库,需要加上network SOURCES += \ TcpServer.cpp \ T ...
- 返回present的根
//返回四大tab页面 + (void)gobackToTabarController { UINavigationController* selectedTabNavController = (UI ...
- 一个ExtJS实例
聊聊ExtJS 这几天接触了一个项目 前台用的是extjs 发现这个东西还是有点意思的 就把前台的部分 剥离了下来 有兴趣的朋友可以当做模板学习 不多说先上效果图 这篇文章 可以看作是ext知识的一 ...
- Dynamics CRM 电子邮件服务器配置文件Advanced配置中关闭SSL
在新建电子邮件服务器配置文件时Advanced中的Use SSL for Incoming/Outgoing Connection默认都是启用的而且无法编辑,启用SSL当然是为了安全的考虑,但当客户的 ...