/** * @description 吸顶效果的view */ public class CeilingRecyclerView<T extends View> extends FrameLayout { private RecyclerView carTypeRv; private FrameLayout flHeader; private CellingListener<T> cellingListener; private T headerView; public CeilingRecyclerView(@NonNull Context context) { super(context); init(); } public CeilingRecyclerView(@NonNull Context context, @Nullable AttributeSet attrs) { super(context, attrs); init(); } public CeilingRecyclerView(@NonNull Context context, @Nullable AttributeSet attrs, int defStyleAttr) { super(context, attrs, defStyleAttr); init(); } private void init() { LayoutInflater.from(getContext()).inflate(R.layout.view_celling, this, true); carTypeRv = findViewById(R.id.recycler_view); carTypeRv.addOnScrollListener(new RecyclerView.OnScrollListener() { @Override public void onScrolled(@NonNull RecyclerView carTypeRv, int dx, int dy) { super.onScrolled(carTypeRv, dx, dy); int[] visibleRange = findVisibleRange(carTypeRv.getLayoutManager()); if (cellingListener != null) { headerView.setTag(visibleRange[0]); cellingListener.setCurrentHeaderViewData(headerView, visibleRange[0]); int currentHeaderViewHeight = cellingListener.getCurrentHeaderViewHeight(headerView, visibleRange[0]); int nextCellingViewTop = cellingListener.getNextCellingViewTop(visibleRange[0]); if (nextCellingViewTop != -1 && nextCellingViewTop <= currentHeaderViewHeight) { flHeader.setTranslationY(nextCellingViewTop - currentHeaderViewHeight); flHeader.setVisibility(View.VISIBLE); } else { flHeader.setTranslationY(0); flHeader.setVisibility(View.VISIBLE); } } } @Override public void onScrollStateChanged(RecyclerView recyclerView, int newState) { super.onScrollStateChanged(recyclerView, newState); if(newState == RecyclerView.SCROLL_STATE_IDLE){ SystemLog.d("CarSelectOrScroll", "carRv scroll finish"); EventBusUtils.post(new CarViewScrollOrSelectEvent()); } } }); flHeader = findViewById(R.id.fl_header); } public RecyclerView getRecyclerView() { return carTypeRv; } public interface CellingListener<T extends View> { // 给当前的headerView设置数据: void setCurrentHeaderViewData(T headerView, int position); // 获取当前header的高度: int getCurrentHeaderViewHeight(T headerView, int position); // 获取当前位置后的第一个需要吸顶的View的top值 int getNextCellingViewTop(int currentPosition); } public void initInfo(CellingListener<T> cellingListener, T headerView) { this.cellingListener = cellingListener; if (headerView != null) { if (headerView.getParent() != null) { ViewGroup viewGroup = (ViewGroup) headerView.getParent(); viewGroup.removeView(headerView); } this.headerView = headerView; flHeader.addView(headerView); } } private int[] findVisibleRange(RecyclerView.LayoutManager layoutManager) { int[] range = new int[2]; if (layoutManager instanceof LinearLayoutManager) { // LinearLayoutManger或GridLayoutManager LinearLayoutManager linearLayoutManager = (LinearLayoutManager) layoutManager; range[0] = linearLayoutManager.findFirstVisibleItemPosition(); range[1] = linearLayoutManager.findLastVisibleItemPosition(); } else if (layoutManager instanceof StaggeredGridLayoutManager) { // 流布局StaggeredGridLayoutManager StaggeredGridLayoutManager staggeredGridLayoutManager = (StaggeredGridLayoutManager) layoutManager; int[] startPos = new int[staggeredGridLayoutManager.getSpanCount()]; int[] endPos = new int[staggeredGridLayoutManager.getSpanCount()]; // 流布局第一个和最后一个可见的item位置是个数组: staggeredGridLayoutManager.findFirstVisibleItemPositions(startPos); staggeredGridLayoutManager.findLastVisibleItemPositions(endPos); int start = startPos[0]; int end = endPos[0]; for (int i = 1; i < startPos.length; i++) { // 从第一个可见数组中找到最小的位置,作为第一个可见位置; if (start > startPos[i]) { start = startPos[i]; } } for (int i = 1; i < endPos.length; i++) { // 从最后一个可见数组中找到最大的位置,作为最后一个可见位置; if (end < endPos[i]) { end = endPos[i]; } } range[0] = start; range[1] = end; } return range; } }
android 吸顶效果的RecyclerView
最新推荐文章于 2023-12-14 21:37:55 发布