页面布局新玩法,用户留存更给力
随着小程序的应用场景越来越丰富,小程序提供更多元的功能,这也意味着有限的页面需要承载更多的内容。以常见的页面布局为例,一屏不仅需要提供多样的功能选项,完成业务链路;还需要占据较大版面曝光近期重点内容,场景化完成宣传。
页面布局示例
对于业务决策者而言,这两个展示渠道同样重要,但如何平衡二者的展示逻辑并不简单。
关注功能选项,则难以搭建曝光位,尤其在多层级功能选项下,无法实现导航栏位置固定
关注宣传曝光,则功能位范围变小,特别影响小屏幕手机用户的使用体验
针对这种页面信息量丰富的情况,应用 小程序渲染框架 的核心能力即可快速实现页面合理布局,保证良好的交互体验与功能需求,吸引用户继续使用,业务流程更丝滑。
无缝切换功能位 & 曝光位
平衡功能位与曝光位的理想状态是:用户能够看到曝光内容,保证成功推广;同时如果用户对曝光内容不感兴趣,曝光内容随着功能位出现而无缝切换,保证良好的交互体验。
实现这种效果仅需应用 worklet 动画效果 和 手势系统,即可实现更贴近原生的交互体验、更丝滑的位置切换效果、更丰富的内容展示。
👉 点击查看代码
// .wxml<pan-gesture-handlertag="pan"simultaneousHandlers="{{['scroll-view']}}"shouldResponseOnMove="shouldPanResponse"onGestureEvent="handlePan"><view class="page"><vertical-drag-gesture-handlertag="scroll-view"native-view="scroll-view"simultaneousHandlers="{{['pan']}}"shouldResponseOnMove="shouldScrollViewResponse"><scroll-viewclass="product-list"type="custom"scroll-yshow-scrollbar="{{false}}"adjustDecelerationVelocity="adjustDeceleration"bindscroll="handleScroll">...</scroll-view></vertical-drag-gesture-handler></view></pan-gesture-handler>// .jshandlePan(e) {'worklet'...if (e.state === GestureState.ACTIVE) {if (this._interactionState.value === InteractionState.UNFOLD) {// 展开状态下,往上滑才折叠起来if (e.absoluteY - this._startY.value < 0) {this._interactionState.value = InteractionState.ANIMATINGthis._translY.value = timing(0.0, { duration: 250 }, () => {'worklet'this._interactionState.value = InteractionState.RESET})}} else {// 其它情况,跟随手指滑动this._translY.value = e.absoluteY - this._startY.value}}// 其他状态下的处理...},// 最外层 .page 往上挪this.applyAnimatedStyle('.page', () => {'worklet'const translY = clamp(this._translY.value, -this._tabsTop.value, 0)return {transform: `translateY(${translY}px)`}})// 改变 .navigation-bar 背景色this.applyAnimatedStyle('.navigation-bar', () => {'worklet'const translY = clamp(this._translY.value, -this._tabsTop.value, 0)const opacity = translY / -this._tabsTop.valuereturn {backgroundColor: `rgba(255, 255, 255, ${opacity})`}})// 输入框:改变宽度并且展示this.applyAnimatedStyle('.search-input', () => {'worklet'const translY = clamp(this._translY.value, -this._tabsTop.value, 0)const percentage = translY / -this._tabsTop.valuereturn {width: `${percentage * 60 + 40}%`,opacity: percentage,}})
除此以外,针对某些必要但应用频率较少的信息,例如外卖小程序显示商家资质等信息,应用 worklet 动画和手势操作可以实现下拉显示更多内容,手势操作更丝滑,减少默认点按操作的滞后感。
👉 点击查看代码
// 商品详情往下拉this.applyAnimatedStyle('.main', () => {'worklet'const translY = clamp(this._translY.value, 0, Number.MAX_VALUE)console.log(222, translY)return {transform: `translateY(${translY}px)`}})// 简单的 header 渐隐// 商品详情展示时,仅显示简单的 header:学堂名称和几个标签this.applyAnimatedStyle('.header-shop-info-simple', () => {'worklet'const min = 50const max = 100const translY = clamp(this._translY.value, min, max) - minreturn {opacity: 1 - (translY / (max - min))}})// 复杂的 header 渐显// 商品详情下拉,显示复杂 header:展示热门活动、公告等等信息this.applyAnimatedStyle('.header-shop-info-detail', () => {'worklet'const min = 100const max = 150const translY = clamp(this._translY.value, min, max) - minreturn {opacity: translY / (max - min)}})
轻松实现吸顶布局
在上述页面下拉过程中,我们可以看到功能位到达页面顶部时,顶部导航栏自动吸顶,进一步扩大功能选项区域的可视范围。
吸顶布局 VS 无吸顶布局
除了导航栏等框架工具,搜索框等常用功能同样可以通过吸顶布局便利用户的使用体验。例如下述动图的通过双重吸顶搜索框和导航栏,方便用户在下滑至后方内容,无需回到顶部进行搜索或分类操作,交互体验更丝滑。
实现以上吸顶能力仅需应用 sticky-header、sticky-section 2 个组件;同时通过巧妙调整搜索框吸顶位置至小程序开关胶囊所在位置,进一步节约页面空间。
👉 点击查看代码
<scroll-viewtype="custom"scroll-yshow-scrollbar="{{false}}"worklet:onstartstart="handleScrollStart"worklet:onscrollupdate="handleScrollUpdate"worklet:onscrollend="handleScrollEnd"><sticky-section push-pinned-header="{{false}}"><sticky-header><!-- 搜索框 -->...</sticky-header><!-- 类目展示 --></sticky-section><sticky-section push-pinned-header="{{false}}" padding="{{[0, 16, 0, 16]}}"><sticky-header><!-- 商品详情热门分类 -->...</sticky-header><grid-view cross-axis-count="2" type="masonry"><!-- 两列的瀑布流 -->...</grid-view></sticky-section></scroll-view>attached() {// nav-bar 隐藏或展示this.applyAnimatedStyle('.nav-bar', () => {'worklet'return {opacity: this.navBarOpactiy.value}})// 改变搜索框宽度this.applyAnimatedStyle('.search', () => {'worklet'return {width: `${this.searchBarWidth.value}%`,}})},// scroll-view 监听函数handleScrollUpdate(evt) {'worklet'const maxDistance = 60const scrollTop = clamp(evt.detail.scrollTop, 0, maxDistance)const progress = scrollTop / maxDistanceconst EasingFn = Easing.cubicBezier(0.4, 0.0, 0.2, 1.0)this.searchBarWidth.value = lerp(100, 70, EasingFn(progress))this.navBarOpactiy.value = lerp(1, 0, progress)},
通过对 小程序渲染框架 的灵活应用,小程序既能轻松实现更贴近原生的交互效果,提升开发效率;又能保证流畅、丝滑的用户体验,高效留存用户,赋能业务发展。
小程序渲染框架 持续支持开发者的渲染需求,实现在多个终端稳定、贴近原生的交互体验,赋能业务发展。欢迎各位开发者关注 小程序渲染框架更新日志 了解更多最新动态或者访问 小程序示例 发现最佳实践。