8

Flutter 页面滚动吸顶详解(NestedScrollView)

 3 years ago
source link: https://segmentfault.com/a/1190000040961263
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.
neoserver,ios ssh client

在业务开发中我们经常会有滚动吸顶的效果,目前Flutter也有很多种实现方式,这里介绍一下本人在开发中使用到的基于NestedScrollView实现的滚动吸顶组件;以及中间涉及的各种定位的布局操作;

NestedScrollView

首先了解一下NestedScrollView滚动组件;

NestedScrollView:支持嵌套滑动的ScrollView;

属性说明默认值controller滚动监听无scrollDirection滚动方向Axis.vertical 默认垂直方向reverse是都倒叙false 默认值physics控制用户滚动视图的交互AlwaysScrollableScrollPhysics 总是可以滑动
NeverScrollableScrollPhysics 禁止滚动
BouncingScrollPhysics 内容超过一屏上拉有回弹效果
ClampingScrollPhysics 包裹内容不会有回弹headerSliverBuilder折叠头部无body滚动组件实体无

NestedScrollView折叠部分使用SliverAppBar来实现

SliverAppBar

NestedScrollView(
    controller: _scrollController,
    headerSliverBuilder: _headerSliverBuilder,
    body: buildSliverBody(context)
)
///页面滚动头部处理
List<Widget> _headerSliverBuilder(BuildContext context, bool innerBoxIsScrolled) {
  return <Widget> [
    buildSliverAppBar(context)
  ];
}
///导航部分渲染
Widget buildSliverAppBar(BuildContext context) {
  return SliverAppBar(
    //当此值为true时 SliverAppBar 会固定在页面顶部
    //当此值为fase时 SliverAppBar 会随着滑动向上滑动
    pinned: true,
    //滚动是是否拉伸图片
    stretch: true,
    //展开区域的高度
    expandedHeight: 500,
    //当snap配置为true时,向下滑动页面,SliverAppBar(以及其中配置的flexibleSpace内容)会立即显示出来,
    //反之当snap配置为false时,向下滑动时,只有当ListView的数据滑动到顶部时,SliverAppBar才会下拉显示出来。
    snap: false,
    //阴影
    elevation: 0,
    //背景颜色
    backgroundColor: headerWhite? Colors.white : Color(0xFFF4F5F7),
    //App bar 的亮度,有白色和黑色两种主题,默认值为 ThemeData.primaryColorBrightness
    brightness: Brightness.light,
    //在标题左侧显示的一个控件,在首页通常显示应用的 logo;在其他界面通常显示为返回按钮
    leading: IconButton(
        icon: Image.network(backIcon, height: 22, width: 22,),
        onPressed: (){
          //TODO: 返回事件处理
        }
    ),
        //一个显示在 AppBar 下方的控件,高度和 AppBar 高度一样, // 可以实现一些特殊的效果,该属性通常在 SliverAppBar 中使用
    flexibleSpace: FlexibleSpaceBar(
      title: headerWhite ? Text('长津湖', style: TextStyle(
          color: Color(0xFF333333),
          fontWeight: FontWeight.w700,
          fontSize: 17,
          fontFamily: 'PingFangSC-Semibold'
      ),) : Text(''),
      //标题居中
      centerTitle: true,
      background: buildAppBarBackground(context),
    ),
  );
}
const SliverAppBar({
    Key key,
    this.leading,         //在标题左侧显示的一个控件,在首页通常显示应用的 logo;在其他界面通常显示为返回按钮
    this.automaticallyImplyLeading = true,//? 控制是否应该尝试暗示前导小部件为null
    this.title,               //当前界面的标题文字
    this.actions,          //一个 Widget 列表,代表 Toolbar 中所显示的菜单,对于常用的菜单,通常使用 IconButton 来表示;对于不常用的菜单通常使用 PopupMenuButton 来显示为三个点,点击后弹出二级菜单
    this.flexibleSpace,        //一个显示在 AppBar 下方的控件,高度和 AppBar 高度一样, // 可以实现一些特殊的效果,该属性通常在 SliverAppBar 中使用
    this.bottom,         //一个 AppBarBottomWidget 对象,通常是 TabBar。用来在 Toolbar 标题下面显示一个 Tab 导航栏
    this.elevation,            //阴影
    this.forceElevated = false, 
    this.backgroundColor,       //APP bar 的颜色,默认值为 ThemeData.primaryColor。改值通常和下面的三个属性一起使用
    this.brightness,   //App bar 的亮度,有白色和黑色两种主题,默认值为 ThemeData.primaryColorBrightness
    this.iconTheme,  //App bar 上图标的颜色、透明度、和尺寸信息。默认值为 ThemeData().primaryIconTheme
    this.textTheme,    //App bar 上的文字主题。默认值为 ThemeData().primaryTextTheme
    this.primary = true,  //此应用栏是否显示在屏幕顶部
    this.centerTitle,     //标题是否居中显示,默认值根据不同的操作系统,显示方式不一样,true居中 false居左
    this.titleSpacing = NavigationToolbar.kMiddleSpacing,//横轴上标题内容 周围的间距
    this.expandedHeight,     //展开高度
    this.floating = false,       //是否随着滑动隐藏标题
    this.pinned = false,  //是否固定在顶部
    this.snap = false,   //与floating结合使用
  })

flexibleSpace

flexibleSpace: FlexibleSpaceBar(
  //是否展示标题
  title: headerWhite ? Text('长津湖', style: TextStyle(
      color: Color(0xFF333333),
      fontWeight: FontWeight.w700,
      fontSize: 17,
      fontFamily: 'PingFangSC-Semibold'
  ),) : Text(''),
  //标题居中
  centerTitle: true,
  //折叠部分背景图片
  background: Container(
      height: 400,
      width: ScreenUtil().screenWidth,
      decoration: BoxDecoration(
          image: DecorationImage(
              image: NetworkImage('https://p0.meituan.net/movie/0e81560dc9910a6a658a82ec7a054ceb5075992.jpg@464w_644h_1e_1c'),
              fit: BoxFit.fill
          )
      ),
    ),
)

展示标题如下:

image-20211115145812098

不展示标题滚动到某个位置时在展示 如下:

image-20211115145916035

完整代码


Recommend

  • 71
    • 掘金 juejin.im 6 years ago
    • Cache

    Vue开发——实现吸顶效果

    因为项目需求,最近开始转到微信公众号开发,接触到了Vue框架,这个效果的实现虽说是基于Vue框架下实现的,但是同样也可以借鉴到其他地方,原理都是一样的。 进入正题,先看下效果图: 其实js做这个效果还是挺简单的,因为在css中我们可以设置一个元素的posit

  • 26

  • 93

    前言 我入职第二家公司接到的第一个需求就是修复之前外包做的滚动吸顶效果。我当时很纳闷为何一个滚动吸顶会有 bug,后来我查看代码才发现直接用的是 offsetTop 这个属性,而且并没有做兼容性处理。 offsetTop 用于获得当前元素到定位父级( elem

  • 47

    前言 近日,在做活动页的过程中遇到两层吸顶的需求,并且要兼容 IE9 及以上的浏览器。乍一看不就是个吸顶嘛,应该不难吧,事实证明还是踩了很多坑才出来。兼容性问题多到吐血,我太难了。废话不多说,先看一下两层吸顶的最终实...

  • 26

    基于 Vue 的两层吸顶踩坑总结 2019-11-17 发布于 ...

  • 34
    • 掘金 juejin.im 5 years ago
    • Cache

    tab切换+页面滚动

    这几天写需求,写了一个tab切换+页面滚动的联动效果,虽然不难,但是觉得还挺有必要记录一下的,因为这种场景也挺常见的,这样下次遇到类似的,就可以直接使用了. 下面是页面效果: 代码: &lt;template&gt; &lt;div class="box

  • 14

    NestedScrollView 是用于替代 ScrollView 来解决嵌套滑动过程中的滑动事件的冲突。作为开发者,你会发现很多地方会用到嵌套滑动的逻辑,比如下拉刷新页面,京东或者淘宝的各种商品页面。 那为什么要去了解 NestedScrollView 的源...

  • 5

    NestedScrollView 仿照 H5 锚点实现 2022-09-23 因为一些原因,需要在原生仿照一个 H5 的锚点效果,很不幸的是,在一个迭代后,效果又被砍掉了,不过实现还是记录下。由于 tab 点击以及 pager...

  • 6

    V2EX  ›  路由器 两室一厅标户,吸顶 ap 效果如何?  

  • 5

    iPhone兼容性修复:吸顶效果的Tabs标签页组件的完美自定义 作者:王晶 2023-10-11 08:14:43 在这篇文章中,我将与大家分享我的实际开发经验,重点关注如何自定义实现吸顶效果的Tabs标签页组件。通过本文,您将了解...

About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK