Flutter实现固定header底部滑动页效果示例

目录
  • 正文
  • 实现

正文

实现的效果是这样的:

刚开始的时候,是在dev上找了两个轮子,简单测了下,都不太满意,滑动事件处理的比较粗糙,总有bug。就在想着,要不要拿源码改一版的时候,让我无意间看到了这个帖子

里面的想法,大开眼界,是通过 DraggableScrollableSheet 和 IgnorePointer 来完美实现上面的效果。

实现

这是 DraggableScrollableSheet 的代码,

DraggableScrollableSheet(
  maxChildSize: 0.8,
  minChildSize: 0.25, // 注意都是占父组件的比例
  initialChildSize: 0.25,
  expand: true,
  builder: (BuildContext context, ScrollController controller) {
    return Stack(); // body列表和header栏都在stack内
  },
)

这是 body 列表和 header,这里的 body 是个 list,

Stack(
  children: [
    Container(
      color: Colors.blue,
      child: Body( // ListView.separated
        controller: controller,
        paddingTop: headerHeight, // 防止压盖
      ),
    ),
    const IgnorePointer( // 这里不接收事件,所以拖动 header 也能够滑动页面
      child: Header( // Container[Center[Text]]
        height: headerHeight,
      ),
    ),
  ],
)

但如果我们想在 header 内加点击事件呢?那在 Stack header 上层再加 widget 就好了。

代码就这点,我放在了 gitHub 上,感兴趣的可以看下。

2022.8.23 补充:

这是在上面功能基础上的一个小扩展,即当滑动距离超过一半则自动滚至顶部,反之回到底部,来看下效果:

思路也很简单,首先我要知道当前滚动的距离或其占比,DraggableScrollableController 提供了这个能力:

void _draggableScrollListener() {
  // [_currStale] 记录下当前的占比
  // [_controller.size] 即占比, 范围[minChildSize,maxChildSize]
  // [_controller.pixels] 即距离
  if (_currStale != _controller.size) {
    _currStale = _controller.size;
  }
  debugPrint('[listener] size: ${_controller.size}'
      ', pixels : ${_controller.pixels}');
}

其次要知道用户何时停止了滚动,我们可以使用 NotificationListener 来监听 DraggableScrollableSheet 的滚动状态:

NotificationListener<ScrollNotification>(
  onNotification: (ScrollNotification notification) {
    ...
    return false;
  },
child: DraggableScrollableSheet(...),

之后在用户停止滚动的时候,我们判断当前距离,并根据结果让 DraggableScrollableSheet 自动滚动到顶部或底部。

onNotification: (ScrollNotification notification) {
  if (_animation) { // 动画中,不处理状态
    return false;
  }
  if (notification is ScrollStartNotification) {
    debugPrint('start scroll');
  } else if (notification is ScrollEndNotification) {
    debugPrint('stop scroll');
    // 通过 [_controller.animateTo] 方法滚动
    _scrollAnimation();
  }
  return false;

在 _scrollAnimation 内就是滚动的方法了,这里要注意的是,不能直接使用 await Feature,我测试在频繁不同方向滑动时,可能会导致方法被挂起。在这直接 dedelayed(duration: xx) 即可:

Future<void> _scrollAnimation() async {
  if (_animation) {
    return;
  }
  _animation = true;
  //debugPrint('async start');
  final int duration;
  // `await`ing the returned Feature(of [animateTo]) may cause the method to hang
  // So, Start a timer to set [_animation].
  if (_currStale >= (_maxScale + _minScale) * 0.5) {
    duration =
        (_duration * ((_maxScale - _currStale) / (_maxScale - _minScale)))
            .toInt();
    if (duration == 0) {
      _animation = false;
      return;
    } else {
      // [duration] control speed, Avoid situations where it's equal to 0
      _animationTo(_maxScale, duration);
    }
  } else {
    duration =
        (_duration * ((_currStale - _minScale) / (_maxScale - _minScale)))
            .toInt();
    if (duration == 0) {
      _animation = false;
      return;
    } else {
      _animationTo(_minScale, duration);
    }
  }
  Future.delayed(
    Duration(milliseconds: duration),
  ).then((value) => {
        //debugPrint('async stop'),
        _animation = false,
      });
}

其中 _animationTo 是实际控制控件滚动的方法:

void _animationTo(double scale, int duration) {
  _controller.animateTo(
    scale,
    duration: Duration(milliseconds: duration),
    curve: Curves.ease,
  );
}

2022.9.24 补充:

那如果再提供一种通过点击按钮来控制 DraggableScrollableSheet 收起和弹出的方法呢?

我们可以直接这样,是不是很简单:

Future<void> _scrollAnimation2() async {
  if (_animation) {
    return;
  }
  if (_currStale > (_maxScale + _minScale) * 0.5) {
    _animationTo(_minScale, _duration);
  } else {
    _animationTo(_maxScale, _duration);
  }
}

以上就是Flutter实现固定header底部滑动页效果示例的详细内容,更多关于Flutter固定header底部滑动页的资料请关注我们其它相关文章!

(0)

相关推荐

  • Header组件热门搜索栏的实现示例

    目录 1. 基本布局 1.1 热门搜索框 1.2 热门搜索Title和换一换图标 1.3 热门Tag 2. 控制展示 3. 使用 Ajax 请求获取 Tag 数据 3.1 使用 redux-thunk 返回函数 3.2 使用 Immutable 的数组进行 state 统一更新 3.3 使用 map 方法循环展示内容 4. 优化 reducer 1. 基本布局 本次任务是实现热门搜索模块的布局和展示控制功能. 1.1 热门搜索框 在布局过程中,我们发现热门搜索框并没有出现.这可能是由于外部组件存

  • VSCode多行注释插件KoroFileHeader使用示例

    目录 1.简介 主要功能 2.安装 3.使用 默认快捷键 文件头部注释快捷键 函数注释快捷键 图案注释快捷键 自定义快捷键 4.插件自定义配置 1.简介 VSCode插件: 用于一键生成文件头部注释并自动更新最后编辑人和编辑时间.函数注释自动生成和参数提取. 插件可以帮助用户养成良好的编码习惯,规范整个团队风格. 主要功能 自动生成文件头部注释,自动更新最后编辑人.最后编辑时间等. 一键生成函数注释,支持函数参数自动提取并列到注释中. 支持添加佛祖保佑永无bug.神兽护体.甩葱少女等好玩有趣的图

  • Vue header组件开发详解

    一. header 组件开发 之数据的传递 1. App.vue 引入组件 import header from './components/header/header' 2. App.vue 中注册组件 export default { components:{ v-header:header } } 3. 使用组件 <v-header :sell="sellerObj"></v-header> 解释::sell="sellerObj",这

  • resty更新header控制api版本数据源读写分离

    目录 前言 1.使用header来控制api版本 2.读写分离的数据源支持 前言 Resty目前积累到450 star,还有1个多月满一年了,在没有推广的情况下如果能积累到500 star,真是棒棒的,如果觉得不错可以给颗心(https://github.com/Dreampie/Resty),希望大家多多鼓励,也希望有心的同学参与维护,开源说明它属于大家,无论你使用或者作为一个框架的基础学习还是从中得到灵感做出好用的东西 都希望你能和大家一起分享 开源希望大家互相帮助. 本次更新说大不大说小不

  • NSURLSession跨域重定向透传HTTP Header问题解决

    目录 背景 系统库如何设计的 解决方案 方案一 方案二 背景 在源网页通过服务器重定向打开某个三方网页,网络层出现了 -1005 (NSURLErrorNetworkConnectionLost) 错误码,排查差异后发现是由于给这个三方服务带了源网页特有的 HTTP Header,导致服务器检查异常从而断开连接. 核心原因是跨域重定向场景透传了 Header 带到了三方服务,这有些不符合常理,会带来两个明显的问题: 敏感 HTTP Header 传递给三方服务,存在隐私安全问题: 服务收到未预期

  • 详解Vue后台管理系统开发日常总结(组件PageHeader)

    在后台管理系统的日常开发过程中发现对于同一个业务下面的版块不同的开发同事每次都会重复写页面标题的样式,而且不同的页面标题还不太一样.虽然有的页面标题栏承载的元素不一样,但是也有通用的部分,经过多个项目的迭代慢慢地总结与积累完善出了一个通用的页面标题组件<PageHeader/>. 下面是一个最常见的标题设计原型: 下面是同事给出的封装方案: 使用方式 <router-back class="router-back" text="详情" />

  • Go结构体SliceHeader及StringHeader作用详解

    目录 引言 SliceHeader 疑问 坑 StringHeader 0 拷贝转换 总结 引言 在 Go 语言中总是有一些看上去奇奇怪怪的东西,咋一眼一看感觉很熟悉,但又不理解其在 Go 代码中的实际意义,面试官却爱问... 今天要给大家介绍的是 SliceHeader 和 StringHeader 结构体,了解清楚他到底是什么,又有什么用,并且会在最后给大家介绍 0 拷贝转换的内容. 一起愉快地开始吸鱼之路. SliceHeader SliceHeader 如其名,Slice + Heade

  • 好用的VSCode头部注释插件Fileheader Pro

    目录 动机 安装与使用 如何获得它 让它默默添加头部注释 自定义模板 配置项 FileheaderPro.disableFileds FileheaderPro.companyName FileheaderPro.currentUserName和FileheaderPro.currentUserEmail FileheaderPro.dateFormat FileheaderPro.autoInsertOnCreateFile FileheaderPro.autoUpdateOnSave 它是怎

  • Vue实现固定定位图标滑动隐藏效果

    写在前面 移动端页面,有时候会出现一些固定定位在底部图标,比如购物车等.这时候如果添加一个滑动页面,图标透明度变低,同时 移动到屏幕边进行隐藏,效果如下. 所用原理 监听滑动事件,每次进行滑动时,触发动画,添加定时器,1.4s后显示该图标.具体代码如下: <template> <section class="fixed-icon" :style="{ bottom: bottom + 'rem' }" :class="[ !transit

  • Android使用BottomTabBar实现底部导航页效果

    1. 导依赖 compile 'com.hjm:BottomTabBar:1.1.1' 2. 在所实现的XML中定义一下该控件 <com.hjm.bottomtabbar.BottomTabBar android:id="@+id/bottom_tab_bar" android:layout_width="match_parent" android:layout_height="match_parent" > </com.hjm

  • vue 实现滚动到底部翻页效果(pc端)

    pc端vue 滚动到底部翻页 效果,具体内容如下所示: html: <div class="list" ref="scrollTopList"> <div class="listsmall" v-for="(item,index) of list" :key="index" @click="getDeviceInfo(item.id)"> <span cla

  • Flutter Animation实现缩放和滑动动画效果

    本文实例为大家分享了Flutter Animation实现缩放和滑动动画的具体代码,供大家参考,具体内容如下 Animation对象是Flutter动画库中的一个核心类,它生成指导动画的值.Animation对象知道动画的当前状态(例如,它是开始.停止还是向前或向后移动),但它不知道屏幕上显示的内容.AnimationController管理Animation.CurvedAnimation 将过程抽象为一个非线性曲线.Tween在正在执行动画的对象所使用的数据范围之间生成值.例如,Tween可

  • Android实现局部图片滑动指引效果示例

    今天发布本文的原因是应一个网友要求,就是实现局部的图片滑动指引效果.这种效果一般是在新闻客户端上比较常见,其功能是: 1.顶部单张图片左右拖拉滑动: 2.带指引: 3.仅滑动顶部单张图片,不滑动页面,下面的图文内容不动: 4.类似于新闻客户端的功能 为了大家能更好的理解,我们先来看下要实现的效果图: 以上便是实现的效果图,其实实现原理也并不难,我们只需要将android-support-v4.jar包中ViewPager控件设置成局部就可以,只是处理界面时稍微有点麻烦,不过看完本篇之后,大家以后

  • jQuery实现的滑块滑动导航效果示例

    本文实例讲述了jQuery实现的滑块滑动导航效果.分享给大家供大家参考,具体如下: <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>www.jb51.net jquery滑动导航</title> <style> *{margin: 0;padding: 0;box-sizing: border

  • jQuery+CSS实现的标签页效果示例【测试可用】

    本文实例讲述了jQuery+CSS实现的标签页效果.分享给大家供大家参考,具体如下: CSS代码: #tabs{ width:600px; height:250px; background:white; margin:20px; } #tabs ul{ float:left; margin:20px 0 0 20px; padding:0; } #tabs li{ width:80px; height:40px; line-height:40px; display:inline-block; t

  • Android应用中利用ViewPager实现多页面滑动切换效果示例

    1.添加android support包 因为上面的几个类都是在android support包中才提供,我们先添加包. 在Eclipse->Window->Android SDK Manager,选择列表中Extras->Android Support Library进行安装.下载完后在android-sdk\extras\android\support目录下,这里我们选择v4版本,进入v4目录,拷贝其中的android-support-v4.jar文件到工程的libs目录(若没有新建

  • 使用jQueryMobile实现滑动翻页效果的方法

    本文实例讲述了使用jQueryMobile实现滑动翻页效果的方法.分享给大家供大家参考.具体分析如下: 滑动手势在移动设备是很流行的,在移动设备中滑动翻页中很常见 虽然这个功能可以在jQueryMobile中实现,但是个人与之前一篇[jQuery手机浏览器中拖拽动作的艰难性分析]中的观点一致,由于这是在手机浏览器中浏览,而不是安卓的一个独立APP,所以不要经常除点击以外的移动设备手势,以免跟手机浏览器与手机系统本身的手势发生冲突. 那么,使用jQueryMobile实现滑动翻页的效果到底怎么做呢

  • 如何利用Flutter仿写微信搜索页效果

    目录 效果图 顶部搜索栏 SearchBar 实现细节 左边搜索框实现 右边取消按钮实现 内容的检索 内容的传递 内容的检索 搜索列表实现 总结 效果图 如上图所示,我们用 Flutter 来仿写搜索页面,这里聊天首页点击搜索栏会跳转到搜索页,搜索页面包含顶部搜索框跟底部 ListView,在搜索框内我们输入搜索词会检索聊天列表模型中 name 属性中包含搜索词的模型,并在底部列表中展示,且搜索词高亮显示.下面我们分别来介绍下这些功能的实现. 顶部搜索栏 class SearchBar exte

随机推荐