前些天产品经理提出了这个需求,花了1天时间终于实现,但最终没有运用到app中,但效果不错,在此记录,以备以后需要。

指定位置滚动置顶

private void smoothMoveToPosition(final int position) {
        //获取第一个跟最后一个可见item
        int firstItem = reGoods.getChildLayoutPosition(reGoods.getChildAt(0));
        int lastItem = reGoods.getChildLayoutPosition(reGoods.getChildAt(reGoods.getChildCount() - 1));
        if (position < firstItem) {
            // 如果要跳转的位置在第一个可见项之前,则smoothScrollToPosition可以直接跳转
            reGoods.smoothScrollToPosition(position);
        } else if (position <= lastItem) {
            // 如果要跳转的位置在第一个可见项之后,且在最后一个可见项之前
            // smoothScrollToPosition根本不会动,此时调用smoothScrollBy来滑动到指定位置
            int movePosition = position - firstItem;
            if (movePosition >= 0 && movePosition < reGoods.getChildCount()) {
                int top = reGoods.getChildAt(movePosition).getTop();
                reGoods.smoothScrollBy(0, top);
        } else {
            // 如果要跳转的位置在最后可见项之后,则先调用smoothScrollToPosition将要跳转的位置滚动到可见位置
            // 再通过onScrollStateChanged控制再次调用smoothMoveToPosition,进入上一个控制语句
            reGoods.smoothScrollToPosition(position);
            mShouldScroll = true;
            mToPosition = position;

重写OnScrollListener实现二次滚动和头部悬停

    private RecyclerView.OnScrollListener mOnScrollListener = new RecyclerView.OnScrollListener() {
        @Override
        public void onScrolled(RecyclerView recyclerView, int dx, int dy) {
            //找到第二个item 离顶部距离 小于头部高度
            View view = linearLayoutManager.findViewByPosition(mCurrentPosition + 1);
            if (view != null) {
                //如果小于等于 view的高度
                if (view.getTop() <= mSuspensionHeight) {
                    //设置悬停view的位置
                    tvGroup.setY(-(mSuspensionHeight - view.getTop()));
                } else {
                    //否则设置悬停就在顶部
                    tvGroup.setY(0);
            //当前位置不等于第一个可见位置  更新悬停view
            if (mCurrentPosition != linearLayoutManager.findFirstVisibleItemPosition()) {
                //当前位置为第一个可见位置
                mCurrentPosition = linearLayoutManager.findFirstVisibleItemPosition();
                //头部悬停
                tvGroup.setY(0);
                if (!change) {
                    typesAdapter.setSelect(mCurrentPosition);
                tvGroup.setText(goodsGroups.get(mCurrentPosition).getGroupName());
        @Override
        public void onScrollStateChanged(RecyclerView recyclerView, int newState) {
            super.onScrollStateChanged(recyclerView, newState);
            //测量头部悬停view的高度
            mSuspensionHeight = tvGroup.getHeight();
            if (newState == RecyclerView.SCROLL_STATE_IDLE) {
                //是否需要二次滚动
                if (mShouldScroll) {
                    mShouldScroll = false;
                    //重新滚动
                    smoothMoveToPosition(mToPosition);
                } else {
                    change = false;
可以看到,我点击之后,慢慢滑倒顶部了。上面是用的一个 RecyclerView 的控件实现的多种布局。
好了不说废话了,实现比较简单,直接看关键代码吧(不是完整代码,完整代码去下载,下面有链接):
    //目标项是否在最后一个可见项之后
    private boolean mShouldScroll;
    //记录目标项位置
需要将列表中的第二个子view滑动到顶端之后悬停在顶部,下拉之后取消悬停顶部,实现后效果如下图中所示,当上滑时候需要将列表中的综合销量价格选择栏目固定在顶部,当下拉后恢复列表中位置
实现过程:
看到这样的需求首先想到的一个词就是recycleview顶部吸附效果,在大略查找recycleview可用方法之后,发现没有这样的方法可以直接使用,google之后搜索到很多相似内容,都是st...
在Recyview的嵌套使用时,还有ScrollView嵌套RecyclerView(不推荐),还有本篇标题那样的添加header,会出现RecyclerView自动滚动的问题,这里记录一下!
出现这样的问题原因,就是嵌套的RecyclerView自动获得焦点导致的!
这里网上其实是有一些方案的,常见的有以下3种:
① 让Recycler自动滚动到顶部
scrollview.post(  
    new Runnable() {  
        public void run() { 
				
诸如联系人列表、分类页商品类表等分组场景,都可能需要悬浮吸顶的效果。Android 官方并未提供原生的组件来实现这个功能,因此需要我们自定义实现。 网上看到的基本实现思路都是通过 ItemDecoration ,在滑动过程中去根据当前滑动位置,绘制吸顶的视图。 如果只是需要简单的绘制,确实通过这个方式要简单的多。但是通过这种方式无法支持 Touch 事件。感兴趣的可以参考一下这个:https:/...
①NestedScrollViewRecyclerView嵌套,导致滚动惯性消失 解决:mRecyclerView.setNestedScrollingEnabled(false); ②NestedScrollView中嵌套其他布局和RecyclerView后,不会滚动到屏幕顶部 解决给最顶部的布局View设置下requestFocus(); xml version="1.0
Android RecyclerView 实现滑动悬停是通过使用 ItemDecoration 来实现的。在 RecyclerView滑动悬停需要满足两个条件:一是要有一个能够进行悬停View,二是要能够动态地根据 RecyclerView滚动来改变悬停 View位置实现滑动悬停的步骤如下: 1. 首先,我们需要创建一个继承自 RecyclerView.ItemDecoration 的类,例如名为 StickyHeaderDecoration 的类,来实现悬停 View。 2. 在 StickyHeaderDecoration 类中,我们需要重写 getItemOffsets() 方法,该方法会在每次绘制 RecyclerView 的子项时被调用。在该方法中,我们可以根据子项的位置和需要悬停的条件来判断是否需要为该子项添加偏移量,从而实现悬停的效果。 3. 接下来,在 RecyclerView 的 Adapter 类中,我们需要重写两个方法:getItemViewType() 和 onCreateHolder()。 4. 在 getItemViewType() 方法中,我们可以根据当前子项的位置来判断是否需要为该子项设置一种特殊的 ViewType,用于标识悬停 View。例如当子项为要悬停位置时,我们可以返回一个特定的 ViewType 值。 5. 在 onCreateHolder() 方法中,我们需要根据 ViewType 的不同创建不同的 ViewHolder。例如当 ViewType 为悬停 View 的类型时,我们可以创建一个单独的 ViewHolder 类来确定悬停 View 的样式。 6. 最后,在 RecyclerView 的布局文件中,我们需要将 StickyHeaderDecoration 添加到 RecyclerView 中,并设置它的布局参数。 通过以上步骤,我们就可以实现滑动悬停的效果了。当滚动 RecyclerView 时,悬停 View 会根据 RecyclerView滚动位置动态地改变自己的位置,从而实现滑动悬停的效果。