本文介绍了 Android RecyclerView 悬浮效果,具体如下:
实现思路:
- 利用RecyclerView.ItemDecoration绘制Province(就像绘制分割线一样)
- 同一组的City,只绘制一个Province
- 计算偏移,将当前Province固定在顶部
- 根据列表滑动,实现偏移效果
实现
1. 定义一个接口,根据 position 通过接口方法 getGroupName 获取当前省名(由Activity实现)
public interface GroupListener {
String getGroupName(int position);
}
2. 创建 BaseDecoration 继承 RecyclerView.ItemDecoration
public abstract class BaseDecoration extends RecyclerView.ItemDecoration {
/**
* group背景色,默认透明
*/
@ColorInt
int mGroupBackground = Color.parseColor("#48BDFF");
/**
* 悬浮栏高度
*/
int mGroupHeight = 120;
/**
* 分割线颜色,默认灰色
*/
@ColorInt
int mDivideColor = Color.parseColor("#CCCCCC");
/**
* 分割线宽度
*/
int mDivideHeight = 0;
/**
* RecyclerView头部数量
* 最小为0
*/
int mHeaderCount;
Paint mDividePaint;
/**
* 缓存分组第一个item的position
*/
private SparseIntArray firstInGroupCash = new SparseIntArray(100);
protected OnGroupClickListener mOnGroupClickListener;
protected boolean mSticky = true;
public BaseDecoration() {
mDividePaint = new Paint();
mDividePaint.setColor(mDivideColor);
}
/**
* 设置点击事件
*
* @param listener
*/
protected void setOnGroupClickListener(OnGroupClickListener listener) {
this.mOnGroupClickListener = listener;
}
/**
* 获取分组名
*
* @param realPosition realPosition
* @return group
*/
abstract String getGroupName(int realPosition);
/**
* 获取真实的position
* @param position
* @return
*/
protected int getRealPosition(int position) {
return position - mHeaderCount;
}
@Override
public void getItemOffsets(@NonNull Rect outRect, @NonNull View view, @NonNull RecyclerView parent, @NonNull RecyclerView.State state) {
super.getItemOffsets(outRect, view, parent, state);
int position = parent.getChildAdapterPosition(view);
int realPosition = getRealPosition(position);
RecyclerView.LayoutManager manager = parent.getLayoutManager();
if (manager instanceof GridLayoutManager) {
//网格布局
int spanCount = ((GridLayoutManager) manager).getSpanCount();
if (!isHeader(realPosition)) {
if (isFirstLineInGroup(realPosition, spanCount)) {
//为悬浮view预留空间
outRect.top = mGroupHeight;
} else {
//为分割线预留空间
outRect.top = mDivideHeight;
}
}
} else {
//其他的默认为线性布局
//只有是同一组的第一个才显示悬浮栏
if (!isHeader(realPosition)) {
if (isFirstInGroup(realPosition)) {
//为悬浮view预留空间
outRect.top = mGroupHeight;
} else {
//为分割线预留空间
outRect.top = mDivideHeight;
}
}
}
}
/**
* 判断是不是组中的第一个位置
* 根据前一个组名,判断当前是否为新的组
* 当前为groupId为null时,则与上一个为同一组
*/
protected boolean isFirstInGroup(int realPosition) {
if (realPosition < 0) {
//小于header数量,不是第一个
return false;
} else if (realPosition == 0) {
//等于header数量,为第一个
return true;
}
String preGroupId;
if (realPosition <= 0) {
preGroupId = null;
} else {
preGroupId = getGroupName(realPosition - 1);
}
String curGroupId = getGroupName(realPosition);
if (curGroupId == null) {
return false;
}
return !TextUtils.equals(preGroupId, curGroupId);
}
/**
* 是否在RecyclerView处于第一个(header部分不算)
*
* @param realPosition 总的position
* @param index RecyclerView中的Index
* @return
*/
protected boolean isFirstInRecyclerView(int realPosition, int index) {
return realPosition >= 0 && index == 0;
}
/**
* 是否为Header
*
*/
protected boolean isHeader(int realPosition) {
return realPosition < 0;
}
/**
* 判断是不是新组的第一行(GridLayoutManager使用)
* 利用当前行的第一个对比前一个组名,判断当前是否为新组的第一样
*/
protected boolean isFirstLineInGroup(int realPosition, int spanCount) {
if (realPosition < 0) {
//小于header数量,不是第一个
return false;
} else if (realPosition == 0) {
return true;
} else {
int posFirstInGroup = getFirstInGroupWithCash(realPosition);
if (realPosition - posFirstInGroup < spanCount) {
return true;
} else {
return false;
}
}
}
/**
* 网格布局需要调用
*
* @param recyclerView recyclerView
* @param gridLayoutManager gridLayoutManager
*/
public void resetSpan(RecyclerView recyclerView, GridLayoutManager gridLayoutManager) {
if (recyclerView == null) {
throw new NullPointerException("recyclerView not allow null");
}
if (gridLayoutManager == null) {
throw new NullPointerException("gridLayoutManager not allow null");
}
final int spanCount = gridLayoutManager.getSpanCount();
//相当于weight
GridLayoutManager.SpanSizeLookup lookup = new GridLayoutManager.SpanSizeLookup() {
@Override
public int getSpanSize(int position) {
int span;
int realPosition = getRealPosition(position);
if (realPosition < 0) {
//小于header数量
span = spanCount;
} else {
String curGroupId = getGroupName(realPosition);
String nextGroupId;
try {
//防止外面没判断,导致越界
nextGroupId = getGroupName(realPosition + 1);
} catch (Exception e) {
nextGroupId = curGroupId;
}
if (!TextUtils.equals(curGroupId, nextGroupId)) {
//为本行的最后一个
int posFirstInGroup = getFirstInGroupWithCash(realPosition);
span = spanCount - (realPosition - posFirstInGroup) % spanCount;
} else {
span = 1;
}
}
return span;
}
};
gridLayoutManager.setSpanSizeLookup(lookup);
}
/**
* down事件在顶部悬浮栏中
*/
private boolean mDownInHeader;
/**
* RecyclerView onInterceptEvent中down事件调用,用于处理点击穿透问题
*
* @param event
*/
public void onEventDown(MotionEvent event) {
if (event == null) {
mDownInHeader = false;
return;
}
mDownInHeader = event.getY() > 0 && event.getY() < mGroupHeight;
}
/**
* RecyclerView onInterceptEvent中up事件调用,用于处理点击穿透问题
*
* @param event
* @return
*/
public boolean onEventUp(MotionEvent event) {
if (mDownInHeader) {
float y = event.getY();
boolean isInHeader = y > 0 && y < mGroupHeight;
if (isInHeader) {
return onTouchEvent(event);
}
}
return false;
}
/**
* 得到当前分组第一个item的position
*
* @param realPosition realPosition
*/
protected int getFirstInGroupWithCash(int realPosition) {
return getFirstInGroup(realPosition);
}
/**
* 得到当前分组第一个item的position
*
* @param realPosition realPosition
*/
private int getFirstInGroup(int realPosition) {
if (realPosition <= 0) {
return 0;
} else {
if (isFirstInGroup(realPosition)) {
return realPosition;
} else {
return getFirstInGroup(realPosition - 1);
}
}
}
/**
* 判断自己是否为group的最后一行
*
* @param recyclerView recyclerView
* @param realPosition realPosition
* @return
*/
protected boolean isLastLineInGroup(RecyclerView recyclerView, int realPosition) {
if (realPosition < 0) {
return true;
} else {
String curGroupName = getGroupName(realPosition);
String nextGroupName;
RecyclerView.LayoutManager manager = recyclerView.getLayoutManager();
//默认往下查找的数量
int findCount = 1;
if (manager instanceof GridLayoutManager) {
int spanCount = ((GridLayoutManager) manager).getSpanCount();
int firstPositionInGroup = getFirstInGroupWithCash(realPosition);
findCount = spanCount - (realPosition - firstPositionInGroup) % spanCount;
}
try {
nextGroupName = getGroupName(realPosition + findCount);
} catch (Exception e) {
nextGroupName = curGroupName;
}
if (nextGroupName == null) {
return true;
}
return !TextUtils.equals(curGroupName, nextGroupName);
}
}
@Override
public void onDrawOver(Canvas c, RecyclerView parent, RecyclerView.State state) {
super.onDrawOver(c, parent, state);
//点击事件处理
if (gestureDetector == null) {
gestureDetector = new GestureDetector(parent.getContext(), gestureListener);
parent.setOnTouchListener(new View.OnTouchListener() {
@Override
public boolean onTouch(View v, MotionEvent event) {
return gestureDetector.onTouchEvent(event);
}
});
}
stickyHeaderPosArray.clear();
}
/**
* 点击事件调用
*
* @param realPosition realPosition
*/
private void onGroupClick(int realPosition, int viewId) {
if (mOnGroupClickListener != null) {
mOnGroupClickListener.onClick(realPosition, viewId);
}
}
/**
* 记录每个头部和悬浮头部的坐标信息【用于点击事件】
* 位置由子类添加
*/
protected HashMap<Integer, ClickInfo> stickyHeaderPosArray = new HashMap<>();
private GestureDetector gestureDetector;
private GestureDetector.OnGestureListener gestureListener = new GestureDetector.OnGestureListener() {
@Override
public boolean onDown(MotionEvent e) {
return false;
}
@Override
public void onShowPress(MotionEvent e) {
}
@Override
public boolean onSingleTapUp(MotionEvent e) {
return onTouchEvent(e);
}
@Override
public boolean onScroll(MotionEvent e1, MotionEvent e2, float distanceX, float distanceY) {
return false;
}
@Override
public void onLongPress(MotionEvent e) {
}
@Override
public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX, float velocityY) {
return false;
}
};
/**
* 对touch事件处理,找到点击事件
*
* @param e
* @return
*/
private boolean onTouchEvent(MotionEvent e) {
for (Map.Entry<Integer, ClickInfo> entry : stickyHeaderPosArray.entrySet()) {
ClickInfo value = stickyHeaderPosArray.get(entry.getKey());
float y = e.getY();
float x = e.getX();
if (value.mBottom - mGroupHeight <= y && y <= value.mBottom) {
//如果点击到分组头
if (value.mDetailInfoList == null || value.mDetailInfoList.size() == 0) {
//没有子View的点击事件
onGroupClick(entry.getKey(), value.mGroupId);
} else {
List<ClickInfo.DetailInfo> list = value.mDetailInfoList;
boolean isChildViewClicked = false;
for (ClickInfo.DetailInfo detailInfo : list) {
if (detailInfo.top <= y && y <= detailInfo.bottom
&& detailInfo.left <= x && detailInfo.right >= x) {
//当前view被点击
onGroupClick(entry.getKey(), detailInfo.id);
isChildViewClicked = true;
break;
}
}
if (!isChildViewClicked) {
//点击范围不在带有id的子view中,则表示整个groupView被点击
onGroupClick(entry.getKey(), value.mGroupId);
}
}
return true;
}
}
return false;
}
/**
* 绘制分割线
*
* @param c
* @param parent
* @param childView
* @param realPosition
* @param left
* @param right
*/
protected void drawDivide(Canvas c, RecyclerView parent, View childView, int realPosition, int left, int right) {
if (mDivideHeight != 0 && !isHeader(realPosition)) {
RecyclerView.LayoutManager manager = parent.getLayoutManager();
if (manager instanceof GridLayoutManager) {
int spanCount = ((GridLayoutManager) manager).getSpanCount();
if (!isFirstLineInGroup(realPosition, spanCount)) {
float bottom = childView.getTop() + parent.getPaddingTop();
//高度小于顶部悬浮栏时,跳过绘制
if (bottom >= mGroupHeight) {
c.drawRect(left, bottom - mDivideHeight, right, bottom, mDividePaint);
}
}
} else {
float bottom = childView.getTop();
//高度小于顶部悬浮栏时,跳过绘制
if (bottom >= mGroupHeight) {
c.drawRect(left, bottom - mDivideHeight, right, bottom, mDividePaint);
}
}
}
}
protected void log(String content) {
if (false) {
Log.i("StickDecoration", content);
}
}
}
3. StickyDecoration.java
public class StickyDecoration extends BaseDecoration {
@ColorInt
private int mGroupTextColor = Color.WHITE;//字体颜色,默认黑色
private int mSideMargin = 10; //边距 左边距
private int mTextSize = 50; //字体大小
private GroupListener mGroupListener;
private TextPaint mTextPaint;
private Paint mGroutPaint;
private StickyDecoration(GroupListener groupListener) {
super();
this.mGroupListener = groupListener;
//设置悬浮栏的画笔---mGroutPaint
mGroutPaint = new Paint();
mGroutPaint.setColor(mGroupBackground);
//设置悬浮栏中文本的画笔
mTextPaint = new TextPaint();
mTextPaint.setAntiAlias(true);
mTextPaint.setTextSize(mTextSize);
mTextPaint.setColor(mGroupTextColor);
mTextPaint.setTextAlign(Paint.Align.LEFT);
}
@Override
public void onDrawOver(Canvas c, RecyclerView parent, RecyclerView.State state) {
super.onDrawOver(c, parent, state);
final int itemCount = state.getItemCount();
final int childCount = parent.getChildCount();
final int left = parent.getPaddingLeft();
final int right = parent.getWidth() - parent.getPaddingRight();
for (int i = 0; i < childCount; i++) {
View childView = parent.getChildAt(i);
int position = parent.getChildAdapterPosition(childView);
int realPosition = getRealPosition(position);
if (isFirstInGroup(realPosition) || isFirstInRecyclerView(realPosition, i)) {
//绘制悬浮
int bottom = !mSticky ? childView.getTop() : Math.max(mGroupHeight, (childView.getTop() + parent.getPaddingTop()));//决定当前顶部第一个悬浮Group的bottom
if (mSticky && position + 1 < itemCount) {
//下一组的第一个View接近头部
int viewBottom = childView.getBottom();
if (isLastLineInGroup(parent, realPosition) && viewBottom < bottom) {
bottom = viewBottom;
}
}
drawDecoration(c, realPosition, left, right, bottom);
if (mOnGroupClickListener != null) {
stickyHeaderPosArray.put(realPosition, new ClickInfo(bottom));
}
} else {
//绘制分割线
drawDivide(c, parent, childView, realPosition, left, right);
}
}
}
/**
* 绘制悬浮框
*
* @param c
* @param realPosition
* @param left
* @param right
* @param bottom
*/
private void drawDecoration(Canvas c, int realPosition, int left, int right, int bottom) {
String curGroupName; //当前item对应的Group
int firstPositionInGroup = getFirstInGroupWithCash(realPosition);
curGroupName = getGroupName(firstPositionInGroup);
//根据top绘制group背景
c.drawRect(left, bottom - mGroupHeight, right, bottom, mGroutPaint);
if (curGroupName == null) {
return;
}
Paint.FontMetrics fm = mTextPaint.getFontMetrics();
//文字竖直居中显示
float baseLine = bottom - (mGroupHeight - (fm.bottom - fm.top)) / 2 - fm.bottom;
//获取文字宽度
mSideMargin = Math.abs(mSideMargin);
c.drawText(curGroupName, left + mSideMargin, baseLine, mTextPaint);
}
/**
* 获取组名
*
* @param realPosition realPosition
* @return 组名
*/
@Override
String getGroupName(int realPosition) {
if (mGroupListener != null) {
return mGroupListener.getGroupName(realPosition);
} else {
return null;
}
}
public static class Builder {
private StickyDecoration mDecoration;
private Builder(GroupListener groupListener) {
mDecoration = new StickyDecoration(groupListener);
}
public static Builder init(GroupListener groupListener) {
return new Builder(groupListener);
}
/**
* 设置Group背景
*
* @param background 背景色
*/
public Builder setGroupBackground(@ColorInt int background) {
mDecoration.mGroupBackground = background;
mDecoration.mGroutPaint.setColor(mDecoration.mGroupBackground);
return this;
}
/**
* 设置字体大小
*
* @param textSize 字体大小
*/
public Builder setGroupTextSize(int textSize) {
mDecoration.mTextSize = textSize;
mDecoration.mTextPaint.setTextSize(mDecoration.mTextSize);
return this;
}
/**
* 设置Group高度
*
* @param groutHeight 高度
* @return this
*/
public Builder setGroupHeight(int groutHeight) {
mDecoration.mGroupHeight = groutHeight;
return this;
}
/**
* 组TextColor
*
* @param color 颜色
* @return this
*/
public Builder setGroupTextColor(@ColorInt int color) {
mDecoration.mGroupTextColor = color;
mDecoration.mTextPaint.setColor(mDecoration.mGroupTextColor);
return this;
}
/**
* 设置边距
* 靠左时为左边距 靠右时为右边距
*
* @param leftMargin 左右距离
* @return this
*/
public Builder setTextSideMargin(int leftMargin) {
mDecoration.mSideMargin = leftMargin;
return this;
}
/**
* 设置分割线高度
*
* @param height 高度
* @return this
*/
public Builder setDivideHeight(int height) {
mDecoration.mDivideHeight = height;
return this;
}
/**
* 设置分割线颜色
*
* @param color color
* @return this
*/
public Builder setDivideColor(@ColorInt int color) {
mDecoration.mDivideColor = color;
mDecoration.mDividePaint.setColor(color);
return this;
}
/**
* 设置点击事件
*
* @param listener 点击事件
* @return this
*/
public Builder setOnClickListener(OnGroupClickListener listener) {
mDecoration.setOnGroupClickListener(listener);
return this;
}
/**
* 重置span
*
* @param recyclerView recyclerView
* @param gridLayoutManager gridLayoutManager
* @return this
*/
public Builder resetSpan(RecyclerView recyclerView, GridLayoutManager gridLayoutManager) {
mDecoration.resetSpan(recyclerView, gridLayoutManager);
return this;
}
/**
* 设置头部数量
* 用于顶部Header不需要设置悬浮的情况(仅LinearLayoutManager)
* @param headerCount
* @return
*/
public Builder setHeaderCount(int headerCount) {
if (headerCount >= 0) {
mDecoration.mHeaderCount = headerCount;
}
return this;
}
/**
* 设置是否需要悬浮
* @param sticky
* @return
*/
public Builder setSticky(boolean sticky) {
mDecoration.mSticky = sticky;
return this;
}
public StickyDecoration build() {
return mDecoration;
}
}
}
4. 数据类
public class ClickInfo {
public int mBottom;
public int mGroupId = View.NO_ID;
/**
* 详细信息
* 对应的子view坐标信息
*/
public List<DetailInfo> mDetailInfoList;
public ClickInfo(int bottom) {
this.mBottom = bottom;
}
public ClickInfo(int bottom, List<DetailInfo> detailInfoList) {
mBottom = bottom;
mDetailInfoList = detailInfoList;
}
public static class DetailInfo {
public int id;
public int left;
public int right;
public int top;
public int bottom;
public DetailInfo(int id, int left, int right, int top, int bottom) {
this.id = id;
this.left = left;
this.right = right;
this.top = top;
this.bottom = bottom;
}
}
}
CityUtil.java
public class CityUtil {
private static final String[] CITYS = {"福建省", "安徽省", "浙江省", "江苏省"};
/**
* 获取城市名
*
* @return
*/
public static List<City> getCityList() {
List<City> dataList = new ArrayList<>();
final String FU_JIAN = CITYS[0];
final int FU_JIAN_ICON = R.mipmap.city1;
dataList.add(new City("福州", FU_JIAN, FU_JIAN_ICON));
dataList.add(new City("厦门", FU_JIAN, FU_JIAN_ICON));
dataList.add(new City("泉州", FU_JIAN, FU_JIAN_ICON));
dataList.add(new City("宁德", FU_JIAN, FU_JIAN_ICON));
dataList.add(new City("漳州", FU_JIAN, FU_JIAN_ICON));
final String AN_HUI = CITYS[1];
final int AN_HUI_ICON = R.mipmap.city2;
dataList.add(new City("合肥", AN_HUI, AN_HUI_ICON));
dataList.add(new City("芜湖", AN_HUI, AN_HUI_ICON));
dataList.add(new City("蚌埠", AN_HUI, AN_HUI_ICON));
final String ZHE_JIANG = CITYS[2];
final int ZHE_JIANG_ICON = R.mipmap.city3;
dataList.add(new City("杭州", ZHE_JIANG, ZHE_JIANG_ICON));
dataList.add(new City("宁波", ZHE_JIANG, ZHE_JIANG_ICON));
dataList.add(new City("温州", ZHE_JIANG, ZHE_JIANG_ICON));
dataList.add(new City("嘉兴", ZHE_JIANG, ZHE_JIANG_ICON));
dataList.add(new City("绍兴", ZHE_JIANG, ZHE_JIANG_ICON));
dataList.add(new City("金华", ZHE_JIANG, ZHE_JIANG_ICON));
dataList.add(new City("湖州", ZHE_JIANG, ZHE_JIANG_ICON));
dataList.add(new City("舟山", ZHE_JIANG, ZHE_JIANG_ICON));
final String JIANG_SU = CITYS[3];
final int JIANG_SU_ICOM = R.mipmap.city4;
dataList.add(new City("南京", JIANG_SU, JIANG_SU_ICOM));
return dataList;
}
/**
* 获取城市名
*
* @return
*/
public static List<City> getRandomCityList() {
List<City> dataList = new ArrayList<>();
Random random = new Random();
int provinceSize = random.nextInt(5) + 3;
for (int i = 0; i < provinceSize; i++) {
String province = getRandomCityName();
int citySize = random.nextInt(3) + 1;
for (int j = 0; j < citySize; j++) {
dataList.add(new City(province + " : city " + j, province, R.mipmap.city4));
}
}
return dataList;
}
private static String getRandomCityName() {
Random random = new Random();
return CITYS[random.nextInt(4)];
}
}
5. MyRecyclerView.java
public class MyRecyclerView extends RecyclerView {
private BaseDecoration mDecoration;
public MyRecyclerView(Context context) {
super(context);
}
public MyRecyclerView(Context context, @Nullable AttributeSet attrs) {
super(context, attrs);
}
public MyRecyclerView(Context context, @Nullable AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
}
@Override
public void addItemDecoration(ItemDecoration decor) {
if (decor != null && decor instanceof BaseDecoration) {
mDecoration = (BaseDecoration) decor;
}
super.addItemDecoration(decor);
}
@Override
public boolean onInterceptTouchEvent(MotionEvent e) {
if (mDecoration != null) {
switch (e.getAction()) {
case MotionEvent.ACTION_DOWN:
mDecoration.onEventDown(e);
break;
case MotionEvent.ACTION_UP:
if (mDecoration.onEventUp(e)) {
return true;
}
break;
default:
}
}
return super.onInterceptTouchEvent(e);
}
}
6. StickyActivity.java
public class StickyActivity extends BaseActivity {
@BindView(R.id.rv)
MyRecyclerView mRecyclerView;
QuickAdapter mAdapter;
List<City> dataList = new ArrayList<>();
@Override
protected int getLayoutId() {
return R.layout.activity_sticky;
}
@Override
protected void initView() {
//模拟数据
dataList.addAll(CityUtil.getCityList());
dataList.addAll(CityUtil.getCityList());
StickyDecoration decoration = StickyDecoration.Builder
.init(new GroupListener() {
@Override
public String getGroupName(int position) {
//组名回调
if (dataList.size() > position && position > -1) {
//获取组名,用于判断是否是同一组
return dataList.get(position).getProvince();
}
return null;
}
})
.setGroupBackground(Color.parseColor("#48BDFF"))
.setGroupHeight(DensityUtil.dip2px(this, 35))
.setDivideColor(Color.parseColor("#EE96BC"))
.setDivideHeight(DensityUtil.dip2px(this, 2))
.setGroupTextColor(Color.BLACK)
.setGroupTextSize(DensityUtil.sp2px(this, 15))
.setTextSideMargin(DensityUtil.dip2px(this, 10))
.setOnClickListener(new OnGroupClickListener() {
@Override
public void onClick(int position, int id) { //Group点击事件
String content = "onGroupClick --> " + dataList.get(position).getProvince();
Toast.makeText(StickyActivity.this, content, Toast.LENGTH_SHORT).show();
}
})
.build();
mAdapter = new QuickAdapter();
mAdapter.setOnItemClickListener(new OnItemClickListener() {
@Override
public void onItemClick(@NonNull BaseQuickAdapter<?, ?> adapter, @NonNull View view, int position) {
City city = dataList.get(position);
Toast.makeText(StickyActivity.this,
"item click " + position + " : " + city.getProvince() + " - " + city.getName(),
Toast.LENGTH_SHORT).show();
}
});
RecyclerView.LayoutManager manager;
manager = new LinearLayoutManager(this, LinearLayoutManager.VERTICAL, false);
// header
TextView header = new TextView(this);
header.setText("header");
header.setGravity(Gravity.CENTER);
ViewGroup.MarginLayoutParams params = new LinearLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, 200);
header.setLayoutParams(params);
//((QuickAdapter) mAdapter).addHeaderView(header);
decoration.resetSpan(mRecyclerView, new GridLayoutManager(this, 3));
mRecyclerView.setLayoutManager(manager);
mRecyclerView.addItemDecoration(decoration);
mRecyclerView.setAdapter(mAdapter);
}
class QuickAdapter extends BaseQuickAdapter<City, BaseViewHolder> {
public QuickAdapter() {
super(R.layout.item_recycler_view, dataList);
}
@Override
protected void convert(@Nullable BaseViewHolder holder, City item) {
holder.setText(R.id.tv, item.getName());
}
}
}