Android RecyclerView详解(一)
Android RecyclerView之ListView显示(二)
Android RecyclerView之GridView显示(三)
Android RecyclerView之瀑布流显示(四)
RecyclerView
Android 5.0之后,谷歌公司推出了RecyclerView控件
一.什么是RecyclerView?
RecylerView是support-v7包中的新组件,是一个强大的滑动组件,与ListView相比,同样拥有item回收复用的功能,并且从它的名字recylerview即回收view也可以看出。其他
可以自己去设置。可以看出其高度的解耦,给予你充分的定制自由。
替代ListView,GridView,可以实现垂直/水平显示的列表/瀑布流的效果,功能强大。在API的14无法使用RecycleView,所以要在项目管理页面,把RecyclerView添加到布局文件并关联兼容包(注意:低版本的安卓系统,要进行兼容包的关联)
步骤:按住control+alt+shift+s出现Project Structure按
二.与ListView相比RecyclerView有什么优点?
1.RecylerView封装了viewholder的回收复用,就是说RecylerView标准化了ViewHolder,编写Adapter面向的是ViewHolder而不再是View了,复用的逻辑被封装了,写起来更加简单。
2.提供了一种插拔式的体验,高度的解耦,异常的灵活,针对一个Item的显示RecylerView专门抽取出了相应的类,来控制Item的显示,使其的扩展性非常强。例如:你想控制横向或者纵向滑动列表效果可以通过LinearLayoutManager这个类来进行控制(与GridView效果对应的是GridLayoutManager,与瀑布流对应的还有StaggeredGridLayoutManager等),也就是说RecylerView不再拘泥于ListView的线性展示方式,可以实现GridView,瀑布流等多种效果。控制Item的分隔线,可以通过继承RecylerView的ItemDecoration这个类,然后针对自己的业务需求去抒写代码。
3.可以控制Item增删的动画,可以通过ItemAnimator这个类进行控制,当然针对增删的动画,RecylerView有其自己默认的实现。
三.RecyclerView用法
了解了RecylerView的优势,首先我们需要明白RecylerView必须导入support-v7包,因为RecylerView高度的解耦,异常的灵活。
谷歌给我们提供了多个类来控制Item的显示
1.
控制显示的方式,可以通过布局管理器LayoutManager(以LinearLayout为例)
2.控制布局方向,可以通过setOrientation
3.控制适配器,可以通过setAdapter
4.控制Item间的间隔(可绘制),可以通过ItemDecoration
5.控制Item增删的动画,可以通过ItemAnimator
LinearLayoutManager layoutManager = new LinearLayoutManager(this );
//设置布局管理器
recyclerView.setLayoutManager(layoutManager);
//设置为垂直布局,这也是默认的
layoutManager.setOrientation(OrientationHelper. VERTICAL);
//设置Adapter
recyclerView.setAdapter( recycleAdapter);
//设置分隔线
recyclerView.addItemDecoration( new DividerGridItemDecoration(this ));
//设置增加或删除条目的动画
recyclerView.setItemAnimator( new DefaultItemAnimator());
RecyclerView还需要一个menu菜单栏
在这里只给出代码,menu菜单栏详解请点击:Munu菜单栏详解
xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto">
<item
android:id="@+id/action_ListView"
android:orderInCategory="100"
android:title="ListView显示"
app:showAsAction="never">
<menu>
<item
android:id="@+id/action_ListView_noraml"
android:orderInCategory="100"
android:title="标准"
app:showAsAction="never"/>
<item
android:id="@+id/action_ListView_vertical_reverse"
android:orderInCategory="100"
android:title="垂直反向"
app:showAsAction="never"/>
<item
android:id="@+id/action_ListView_horizontal"
android:orderInCategory="100"
android:title="水平"
app:showAsAction="never"/>
<item
android:id="@+id/action_ListView_horizontal_reverse"
android:orderInCategory="100"
android:title="水平反向"
app:showAsAction="never"/>
menu>
item>
menu>
还需要新建一个DateBean类用于存储图片和信息
package com.example.recyclerview1.menu;
/**
* Date:2017/3/14
* author:陈箫阳ChenXiaoYang
* furction:
*/
public class DataBean {
public int icon;
public String name;
}
主类MainActivity代码
package com.example.recyclerview1;
import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.support.v7.widget.LinearLayoutManager;
import android.support.v7.widget.RecyclerView;
import android.view.Menu;
import android.view.MenuItem;
import android.widget.Toast;
import com.example.recyclerview1.menu.DataBean;
import java.util.ArrayList;
public class MainActivity extends AppCompatActivity {
private RecyclerView mRecyclerView;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
//A.初始化控件对象
mRecyclerView = (RecyclerView) findViewById(R.id.recycler_view);
}
//A.RecyclerView填充数据
private void loadListData() {
//集合对象
ArrayList datas = new ArrayList<>();
//给bean类放数据,最后把装好数据的bean类放入到集合里
for (int i = 0; i < 20; i++) {
//创建集合对象
DataBean dataBean = new DataBean();
dataBean.icon=R.mipmap.ic_launcher;
dataBean.name="RecyclerView"+i;
datas.add(dataBean);
}
//创建适配器所需参,创建Adapter类及对象(一般最低需要两个,上下文及加载数据集合)
RecyclerViewAdapter recyclerViewAdapter = new RecyclerViewAdapter(this, datas);
//1.设置适配器
mRecyclerView.setAdapter(recyclerViewAdapter);
//布局管理器所需参数,其参数上下文this.
LinearLayoutManager linearLayoutManager = new LinearLayoutManager(this);
//2.设置布局管理器,参数 LinearLayoutManager
mRecyclerView.setLayoutManager(linearLayoutManager);
}
//加载一个菜单的布局
@Override
public boolean onCreateOptionsMenu(Menu menu) {
//加载布局,使用菜单特有方法getMenuInflater,获取inflate对象,参数: 1.菜单显示的布局 2.固定menu
getMenuInflater().inflate(R.menu.menu_main, menu);
return true;
}
//菜单按钮点击事件的处理
@Override
public boolean onOptionsItemSelected(MenuItem item) {
int itemId = item.getItemId();
if (itemId == R.id.action_ListView_noraml) {
//标准展示
loadListData();
Toast.makeText(MainActivity.this, "标准显示", Toast.LENGTH_SHORT).show();
return true;
}
return super.onOptionsItemSelected(item);
}
}
四.RecyclerView.Adapter用法
RecylerView的设置过程,比ListView要复杂,这也是RecylerView高度解耦的表现,虽然代码上有点复杂,但它的扩展性是极高的。
了解RecyclerView的一些控制之后,紧接着是Adapter的写法,RecyclerView的Adapter与ListView的Adapter还是有点区别的,RecyclerView.Adapter,需要实现3个方法:
1.onCreateViewHolder()这个方法主要生成为每个Item inflater出一个View,但是该方法返回的是一个ViewHolder。该方法把View直接封装在ViewHolder中,然后我们面向的是ViewHolder这个实例,当然这个ViewHolder需要我们自己去编写。直接省去了当初的convertView.setTag(holder)和convertView.getTag()这些繁琐的步骤。
2.onBindViewHolder():这个方法主要用于适配渲染数据到View中。方法提供给你了一个viewHolder,而不是原来的convertView。
3.getItemCount()这个方法就类似于BaseAdapter的getCount方法了,即总共有多少个条目。
package com.example.recyclerview1;
import android.content.Context;
import android.support.v7.widget.RecyclerView;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ImageView;
import android.widget.TextView;
import com.example.recyclerview1.menu.DataBean;
import java.util.List;
/**
* Date:2017/3/14
* author:陈箫阳ChenXiaoYang
* furction:
*/
public class RecyclerViewAdapter extends RecyclerView.Adapter {
private Context mContext;
//泛型是RecyclerView所需的bean类
private List mDataBeen;
//构造方法,一般需要接收两个参数,上下文及集合对象.
public RecyclerViewAdapter(Context context,List dataBean) {
mContext=context;
mDataBeen=dataBean;
}
//创建ViewHolder,并把VIewHolder(也可以理解为一个item)返回出去
@Override
public ListViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
//转换一个View布局对象,决定了Item的样子.参数:1.上下文 2.XML布局资源 3.一般为null
View itemView = View.inflate(mContext, R.layout.item_list, null);
//创建一个VIewHolder对象
ListViewHolder listViewHolder = new ListViewHolder(itemView);
//把ViewHolder对象传出去
return listViewHolder;
}
//当VIewHolder和数据绑定时回调
@Override
public void onBindViewHolder(ListViewHolder holder, int position) {
//从集合里拿对应item的数据对象
DataBean dataBean = mDataBeen.get(position);
//给holder里面的控件对象设置数据
holder.setData(dataBean);
}
//决定RecyclerView多少条item
@Override
public int getItemCount() {
//数据不为null,有几条数据就显示几条数据
if(mDataBeen !=null && mDataBeen.size()>0){
return mDataBeen.size();
}
return 0;
}
//自动帮我写的ViewHolder,参数:View布局对象
public class ListViewHolder extends RecyclerView.ViewHolder {
private final ImageView ivIcon;
private final TextView tvName;
public ListViewHolder(View itemView) {
super(itemView);
ivIcon = (ImageView) itemView.findViewById(R.id.item_list_iv_icon);
tvName = (TextView) itemView.findViewById(R.id.item_list_tv_name);
}
public void setData(DataBean data) {
//给imageView设置图片数据
ivIcon.setImageResource(data.icon);
//给TextView设置文本数据
tvName.setText(data.name);
}
}
}
RecyclerView标准化了ViewHolder,编写 Adapter面向的是ViewHoder而不在是View了,复用的逻辑被封装了,写起来更加简单。其实它的写法与BaseAdapter的写法是差不多的,大家可以对比下它与getView方法写法的区别,在onCreateViewHolder方法中初始化了一个View,然后返回一个ViewHolder,这个返回的ViewHolder类似于之前在getView中的convertView.getTag(),然后在onBindViewHolder方法中去给这个ViewHolder中的控件填充值。其实它的原理跟getView是差不多的,只是做了封装,写起来比较简洁。
5.主类布局文件activity_main和行布局item_list代码
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:id="@+id/activity_main"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context="com.example.recyclerview1.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>
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/item_list_iv_icon"
android:layout_width="75dp"
android:layout_height="75dp"
android:src="@mipmap/ic_launcher"/>
<TextView
android:id="@+id/item_list_tv_name"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textSize="20sp"
android:textStyle="bold"
android:text="图片描述"
android:layout_toRightOf="@id/item_list_iv_icon"
android:layout_centerVertical="true"/>
RelativeLayout>