RecyclerView 可以在有限的布局中显示很多数据。类似ListView, GridView,之前看过一点没总结,现在重新温习一下,会记录一些常用的使用技巧。
首先本文会总结一下其使用流程。
(1) RecyclerView的使用流程
(2) 使用GridLayoutManager.setSpanSizeLookup, 控制列数 使用场景,一些视频APP的布局。
一、RecyclerView的使用流程
1. 下载依赖jar包
android studio 中build.gradle 中配置一下信息,并sync
compile 'com.android.support:recyclerview-v7:26.0.0-alpha1'
2. 在布局中使用
当jar包已经下载完毕之后,在布局中直接调用jar包中的RecyclerView控件
<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>
3. 创建item 的布局,可以是很多个,因为在adapter中有viewtype,可根据其不同返回值,加载不同布局
4. 创建Adapter
当布局建立完毕之后,就开始建立Adapter,与ListView类似,需继成RecyclerView.Adapter,重写下面几个方法
(1)RecyclerView.ViewHolder onCreateViewHolder 创建ViewHolder 用来获取布局中控件对象
(2)void onBindViewHolder 对布局中控件进行设置值等
(3)int getItemCount 获得显示的item个数
(4)int getItemViewType 返回每个item的type (如果就一个布局可以不写)
(5)void setSourceData 这是自己定义的方法,目的用于传递数据
(6)创建内部类ViewHolder,extends RecyclerView.Holder 用于对获取控件对象
package com.example.stormxz.justtext;
import android.content.Context;
import android.support.v7.widget.RecyclerView;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.TextView;
import java.util.ArrayList;
import java.util.List;
/**
* Created by stormxz on 2017/10/11.
*/
public class RecyclerAdapterTest extends RecyclerView.Adapter<RecyclerAdapterTest.MyHolder> {
private Context mContext = null;
private List<String> lists = new ArrayList<String>();
public RecyclerAdapterTest(Context context) {
mContext = context;
}
@Override //可根据不同viewType加载不同布局,可创建多个Holder
public MyHolder onCreateViewHolder(ViewGroup parent, int viewType) {
MyHolder myHolder = new MyHolder(LayoutInflater.from(mContext).inflate(R.layout.recycler_item_layout, parent, false));
return myHolder;
}
@Override
public void onBindViewHolder(MyHolder holder, int position) {
holder.textView.setText(lists.get(position));
}
@Override
public int getItemViewType(int position) { //给不同位置设置不同的type
return super.getItemViewType(position);
}
@Override
public int getItemCount() {
return lists.size();
}
public void setSource(List<String> list){ //传递的数据
lists = list;
}
class MyHolder extends RecyclerView.ViewHolder{
private TextView textView = null;
public MyHolder(View itemView) {
super(itemView);
textView = itemView.findViewById(R.id.texts);
}
}
}
5. 使用
在使用过程中,可以想象我们需要的,比如 整个RecyclerView中item的布局情况、每个item之间的间隔样式、数据的传递等
(1) 系统提供的布局
LinearLayoutManager 线性布局,适合一行或一列排布
GridViewLayoutManager 网格布局,与普通GridView不同的是,其可以配置每行的item个数
StaggeredGridLayoutManager 瀑布流布局
(2) 设置间隔 addItemDecoration
系统提供的间隔为DividerItemDecoration
自定义间隔 extends RecyclerView.ItemDecoration
recyclerView = (RecyclerView) findViewById(R.id.recycler_view); //获得实例
recyclerView.setLayoutManager(new LinearLayoutManager(this, LinearLayoutManager.HORIZONTAL, false)); //创建其布局
mClassifyTeleplayDecoration = new ClassifyTeleplayDecoration((int) this.getResources().getDimension(R.dimen.classify_teleplay_fiml_category_spacing_8dp));
recyclerView.addItemDecoration(mClassifyTeleplayDecoration); //设置间隔
recyclerAdapter = new RecyclerAdapterTest(this);
recyclerAdapter.setSource(lists); //传递参数
recyclerView.setAdapter(recyclerAdapter); //设置Adapter
二、自由控制每行的item个数
使用RecyclerView中默认的三种布局,会发现设置的每行或每列的item数量都是写固定不变的,那么项目中需要每行列数不同时,如何处理?
其实三种默认布局中,GridViewLayoutManager可以做到,通过设置其方法setSpanSizeLookup,如下,实现的方法getSpanSize,其返回值 / totalCount 指的是该position占整行的百分比。比如下面2张图就是实现不同位置item所占的位置大小
代码解析:
首先创建GridLayoutManager,设置方法setSpanSizeLookup,重写getSpanSize方法,这个方法的返回值,就是对应position所占的宽度
当position = 0, 7 时,return 6, 此时并不是我们想象中的占6分之一,而是 6 / 6 = 1, 占一整行
当position > 7 时,return 3, 此时3 / 6 = 0.5 ,占二分之一行
当position > 0 && position < 7 ,return 2, 此时 2 / 6, 占三分之一
理解上面这段,就能清楚的知道其使用原理了。可通过position 以及 view的type进行判断操作
GridLayoutManager gridLa = new GridLayoutManager(this, 6);
gridLa.setSpanSizeLookup(new GridLayoutManager.SpanSizeLookup() {
@Override
public int getSpanSize(int position) {
if (position == 0 || position == 7) {
return 6;
}else if (position > 7) {
return 3;
}
return 2;
}
});
(1) 通过Type创建不同布局
(2) 自定义间隔