RecyclerView粘性头部
1.实现原理:在外部添加一个与RecyclerView对齐的headerView,动态添加需要展示的header
2.支持线性和网格布局
3.支持item添加和删除(无需再次排序)
博主文笔太菜,不想多说,直接上项目链接
github: https://github.com/PPQingZhao/StickyHeaderDemo
需要的伙伴自行看源码,主要实现在 StickyHeaderScrollerListener 滑动监听类中
下面贴出关键代码:
package com.pp.stickyheaderdemo.adapter;
import android.support.annotation.NonNull;
import android.support.v7.widget.RecyclerView;
import android.util.Log;
import android.util.SparseArray;
import android.view.View;
import android.view.ViewGroup;
import com.pp.stickyheaderdemo.mutilitem.StickyHeader;
/**
* @author qing
* 滑动监听
* 用于实现粘性头部
*/
public class StickyHeaderScrollerListener extends RecyclerView.OnScrollListener {
private static final String TAG = "StickyHeaderScroller";
private final StickHeaderContainer mHeaderContainer;
private final SparseArray<RecyclerView.ViewHolder> mHolderMap;
public StickyHeaderScrollerListener(StickHeaderContainer container) {
if (null == container) {
throw new RuntimeException("StickHeaderContainer must not be null.");
}
this.mHeaderContainer = container;
mHolderMap = new SparseArray<>();
}
@Override
public void onScrolled(@NonNull RecyclerView recyclerView, int dx, int dy) {
if (null == mHeaderAdapter) {
throw new RuntimeException("StickyHeaderAdapter must not be null.");
}
if (dy > 0) {
int headerHeight = mHeaderContainer.getMeasuredHeight();
// header top边下的view
View viewTop = recyclerView.findChildViewUnder(mHeaderContainer.getMeasuredWidth() * 0.5f, 1);
// 获取view 在列表中的位置
int positionTop = recyclerView.getChildAdapterPosition(viewTop);
StickyHeader topHeaderItem = mHeaderAdapter.getHeaderItem(positionTop);
boolean isHeaderTop = null != topHeaderItem && topHeaderItem.isHeader();
// header交换时机: viewTop是header 并且 viewTop.getTop() <= 0
if (isHeaderTop && viewTop.getTop() <= 0) {
if (positionTop != mHeaderContainer.getHeaderPosition()) {
// 更新old header记录
mHeaderContainer.setOldHeaderPosition(mHeaderContainer.getHeaderPosition());
// 更新当前header记录
mHeaderContainer.setHeaderPosition(positionTop);
// 更新map , key:当前header value: 当前header的前一个header
mHeaderContainer.putPreviousValue(mHeaderContainer.getOldHeaderPosition());
RecyclerView.ViewHolder holder = getHolder(mHeaderContainer.getHeaderPosition());
if (null != holder && null == holder.itemView.getParent()) {
// 更新headerview
addHeaderView(holder);
}
}
}
// header bottom边下的view
View viewBottom = recyclerView.findChildViewUnder(mHeaderContainer.getMeasuredWidth() * 0.5f, headerHeight);
// 获取view 在列表中的位置
int positionBottom = recyclerView.getChildAdapterPosition(viewBottom);
StickyHeader bottomHeaderItem = mHeaderAdapter.getHeaderItem(positionBottom);
boolean isHeaderBottom = null != bottomHeaderItem && bottomHeaderItem.isHeader();
int viewBottomTop = null == viewBottom ? 0 : viewBottom.getTop();
if (isHeaderBottom && 0 <= viewBottomTop && viewBottomTop <= headerHeight) {
mHeaderContainer.setHeaderTranslationY(viewBottomTop - headerHeight);
} else {
mHeaderContainer.setHeaderTranslationY(0);
}
} else if (dy <= 0) {
int headerHeight = mHeaderContainer.getMeasuredHeight();
View viewUnder = null;
// dy 等于0时,取mHeaderContainer top边下的item,通常是 删除/添加 itme时触发
if (0 == dy) {
viewUnder = recyclerView.findChildViewUn

这篇博客介绍了如何在RecyclerView中实现粘性头部,支持线性和网格布局,并且在item添加和删除时无需重新排序。作者提供了项目的GitHub链接,读者可以查看源码,重点关注StickyHeaderScrollerListener滑动监听类中的实现。
最低0.47元/天 解锁文章
1160

被折叠的 条评论
为什么被折叠?



