关于折叠滑动吸顶tab置顶问题(recyclerView嵌套与CollapsingToolbarLayout冲突)
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了关于折叠滑动吸顶tab置顶问题(recyclerView嵌套与CollapsingToolbarLayout冲突)相关的知识,希望对你有一定的参考价值。
参考技术A
使用CoordinatorLayout+AppBarLayout+CollapsingToolbarLayout+TabLayout可以实现tab滑动吸顶效果。
完整布局文件如下:RecyclerView也可以用NestedScrollView。
遇到问题:当RecyclerView中还嵌套了RecyclerView时,手指触摸嵌套内的RecyclerView会导致折叠失效。
解决方法:给嵌套内的RecyclerView设置rv.setNestedScrollingEnabled(false);
[Vant] van-tabs标签页吸顶/粘性布局在移动端适配上的一些尝试
官方文档地址:
问题描述
在开发中使用Vant标签页van-tabs组件时,遇到了一个关于标签页的粘性布局的屏幕适配问题。
原因是van-tabs的offset-top属性限制单位为px,会导致在不同屏幕尺寸下出现布局问题。
在移动端适配过程中,开发者通常会采取rem,vw/vh的适配方案。因此当vant-tabs的offset-top属性值为一个确定的数字时,布局会变得不再稳定。
解决策略
事实上如果该vant-tabs组件的offset-top属性能支持移动端适配方案,则这个问题就不会出现。
但是既然页面问题已经出现了,当时能想到的解决问题的策略有如下几个:
-
生写一个原生的tabs标签页
这个方案逻辑上的实现难度小到可以忽略,唯一的难点或许是点击未激活tabs标题时底部条的动画。如果只是一个页面用到了这个组件,生写一个原生的tabs似乎并不是一个很划算的选择(即使个人能力能得到锻炼)。
-
修改源码
问题出现的原因已经知道了,修改源码如果能成功的话确实是一个最强势的方案。但是极有可能会导致解决了一个问题又创造了另一个新问题。
-
将vant-tabs元素移入.header
将vant-tabs元素移入.header,让.header元素引导tabs标题栏的粘性布局。
此外要放弃vant-tabs预设的内容区默认插槽(就是说不要在van-tab那个双标签里写标签页内容,默认插槽在页面上的元素类名是.van-tabs__content),在.header元素的同级手写一个内容区div进行每个标签页的展示,通过v-show="active==='a/b/c/d'"进行切换。
这个解决方案是四个方案中最稳定最具性价比的,但是缺点是vant-tabs关于标签页内容区的动画效果等附加内容几乎全部被阉割。
-
通过js动态获取到.header元素的实际渲染高度,手动为offset-top赋值
只需要在合适的生命周期函数中拿到想要的高度值,在赋值给offset-top后让van-tabs渲染出来即可。
这个方案看起来几乎几乎是完美的,但是具体实现有一个致命的缺陷是在第一次上拉时标题栏大概率出现一次不明原因的瞬间抖动,持续的上拉会引起.header的不明原因高频抖动。
解决方案的代码示例
第三个解决方案的代码示例
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 | <template> <div class="container"> <div class="header"> Lorem ipsum dolor sit amet consectetur adipisicing elit. Odio, a assumenda ratione harum sapiente itaque non perferendis reiciendis, corrupti <van-tabs v-model="active"> <van-tab title="标签 1" name="a"></van-tab> <van-tab title="标签 2" name="b"></van-tab> <van-tab title="标签 3" name="c"></van-tab> <van-tab title="标签 4" name="d"></van-tab> </van-tabs> </div> <div class="tabs-content"> <div v-show="active=='a'"> <span> Lorem Lorem Lorem Lorem Lorem Lorem Lorem Lorem Lorem Lorem Lorem Lorem Lorem Lorem Lorem Lorem Lorem Lorem Lorem Lorem Lorem Lorem Lorem Lorem Lorem Lorem Lorem Lorem Lorem Lorem Lorem Lorem Lorem Lorem Lorem Lorem Lorem Lorem Lorem Lorem Lorem Lorem Lorem Lorem Lorem Lorem Lorem Lorem Lorem Lorem Lorem Lorem Lorem Lorem Lorem Lorem Lorem Lorem Lorem Lorem Lorem Lorem Lorem Lorem Lorem Lorem Lorem Lorem Lorem Lorem Lorem Lorem Lorem Lorem Lorem Lorem Lorem Lorem Lorem Lorem Lorem Lorem Lorem Lorem Lorem Lorem Lorem Lorem Lorem Lorem Lorem Lorem Lorem Lorem Lorem Lorem Lorem Lorem Lorem Lorem Lorem Lorem Lorem Lorem </span> </div> <div v-show="active=='b'"> <span> bbbbb bbbbb bbbbb bbbbb bbbbb bbbbb bbbbb bbbbb bbbbb bbbbb bbbbb bbbbb bbbbb bbbbb bbbbb bbbbb bbbbb bbbbb bbbbb bbbbb bbbbb bbbbb bbbbb bbbbb bbbbb bbbbb bbbbb bbbbb bbbbb bbbbb bbbbb bbbbb bbbbb bbbbb </span> </div> <div v-show="active=='c'"> <span> ccccc ccccc ccccc ccccc ccccc ccccc ccccc ccccc ccccc ccccc ccccc ccccc ccccc ccccc ccccc ccccc ccccc ccccc ccccc ccccc ccccc ccccc ccccc ccccc ccccc ccccc ccccc ccccc </span> </div> <div v-show="active=='d'"> <span> ddddd ddddd ddddd ddddd ddddd ddddd ddddd ddddd ddddd ddddd ddddd ddddd ddddd ddddd ddddd ddddd ddddd ddddd ddddd ddddd ddddd ddddd ddddd ddddd ddddd ddddd ddddd ddddd </span> </div> </div> </div> </template>
<script> export default data() return active: 'a' </script>
<style scoped> .container position: relative; height: 100%; overflow: scroll; background-color: lightgreen; background-repeat: no-repeat; background-size: 100%; .header background-color: #fff; position: sticky; top: 0; z-index: 999; overflow: hidden; </style> |
第四个解决方案的代码示例
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 | <template> <div class="container"> <div class="header" ref="header" >Lorem ipsum dolor sit amet consectetur adipisicing elit. Odio, a assumenda ratione harum sapiente itaque non perferendis reiciendis, corrupti sapiente itaque non perferendis reiciendis, corrupti</div> <!-- :offset-top="offsetTop" --> <van-tabs v-if="offsetTop" v-model="active" sticky :offset-top="offsetTop"> <van-tab title="标签 1" name="a"> <div> <span>Lorem Lorem Lorem Lorem Lorem Lorem Lorem Lorem Lorem Lorem Lorem Lorem Lorem Lorem Lorem Lorem Lorem Lorem Lorem Lorem Lorem Lorem Lorem Lorem Lorem Lorem Lorem Lorem Lorem Lorem Lorem Lorem Lorem Lorem Lorem Lorem Lorem Lorem Lorem Lorem Lorem Lorem Lorem Lorem Lorem Lorem Lorem Lorem Lorem Lorem Lorem Lorem Lorem Lorem Lorem Lorem Lorem Lorem Lorem Lorem Lorem Lorem Lorem Lorem Lorem Lorem Lorem Lorem Lorem Lorem Lorem Lorem Lorem Lorem Lorem Lorem Lorem Lorem Lorem Lorem Lorem Lorem Lorem Lorem Lorem Lorem Lorem Lorem Lorem Lorem Lorem Lorem Lorem Lorem Lorem Lorem Lorem Lorem Lorem Lorem Lorem Lorem Lorem Lorem</span> </div> </van-tab> <van-tab title="标签 2" name="b"> <div> <span>bbbbb bbbbb bbbbb bbbbb bbbbb bbbbb bbbbb bbbbb bbbbb bbbbb bbbbb bbbbb bbbbb bbbbb bbbbb bbbbb bbbbb bbbbb bbbbb bbbbb bbbbb bbbbb bbbbb bbbbb bbbbb bbbbb bbbbb bbbbb bbbbb bbbbb bbbbb bbbbb bbbbb bbbbb</span> </div> </van-tab> <van-tab title="标签 3" name="c"> <div> <span>ccccc ccccc ccccc ccccc ccccc ccccc ccccc ccccc ccccc ccccc ccccc ccccc ccccc ccccc ccccc ccccc ccccc ccccc ccccc ccccc ccccc ccccc ccccc ccccc ccccc ccccc ccccc ccccc</span> </div> </van-tab> <van-tab title="标签 4" name="d"> <div> <span>ddddd ddddd ddddd ddddd ddddd ddddd ddddd ddddd ddddd ddddd ddddd ddddd ddddd ddddd ddddd ddddd ddddd ddddd ddddd ddddd ddddd ddddd ddddd ddddd ddddd ddddd ddddd ddddd</span> </div> </van-tab> </van-tabs> </div> </template>
<script> export default data() return active: 'a', offsetTop: '' , mounted() console.log(this.$refs.header.offsetHeight); this.offsetTop = this.$refs.header.offsetHeight </script>
<style scoped> .container position: relative; height: 100%; overflow: scroll; background-color: lightgreen; background-repeat: no-repeat; background-size: 100%; .header background-color: #fff; height: 200px; position: sticky; top: 0; z-index: 999; overflow: hidden; </style> |
支线
笔者在工程中用的适配插件是postcss-px2rem
在写这篇文章时产生了一个疑问,为什么offset-top的属性值不会被适配插件修改?
如果能让适配插件对动态赋值的像素单位进行转换,或许能从根本上解决这一问题。
以上是关于关于折叠滑动吸顶tab置顶问题(recyclerView嵌套与CollapsingToolbarLayout冲突)的主要内容,如果未能解决你的问题,请参考以下文章
CSS3 移动端 滚动置顶 吸顶
webview 和 React Native 中吸顶效果实现
[Vant] van-tabs标签页吸顶/粘性布局在移动端适配上的一些尝试
[Vant] van-tabs标签页吸顶/粘性布局在移动端适配上的一些尝试
el-scrollbar监听滚动条滚动事件,处理el-tabs滚动到顶部header吸顶效果
uni-app 实现置顶悬浮框功能