美文网首页
flutter 滚动隐藏悬浮按钮

flutter 滚动隐藏悬浮按钮

作者: Faith_K | 来源:发表于2020-04-09 11:00 被阅读0次

    flutter 滚动隐藏悬浮按钮

    Untitled.gif
    • 实现思路,当开始滚动的时候,执行动画让中间的悬浮按钮向右移动。当滚动结束的时候复位动画

    监听滚动的方法有两种

    第一种 NotificationListener 在widget树中,子widget滚动时会向上发送notification,通过NotificationListener可以监控到该notification。NotificationListener也是一个widget,可以将被监控的widget放入其child内。
    NotificationListener
    const NotificationListener({
        Key key,
        @required this.child,  被监控的子widget树
        this.onNotification,  监控到notification后的回调方法。
      }) 
    

    onNotification(ScrollNotification notification) , 此方法需要一个返回值,表示是否拦截住notification,如果是true,那么notifcation到此为止;如果是false,那么notification会继续向更外层widget传递。参数ScrollNotification包含了监听到的信息。
    ScrollNotification

    ScrollNotification({
        @required this.metrics,   所有信息都在这里存储 ScrollMetrics
        @required this.context,
      });
    
    第二种是通过ScrollController来监听

    ScrollController 常用方法

    • addListener 滑动监听方法,在initState中监听
    • _scrollController.position.pixels 滑动距离
    • _scrollController.offset 滚动的偏移量
    • _scrollController.position.maxScrollExtent 最大可滑动距离,滑动组件内容长度
    • -_scrollController.position.minScrollExtent 最小可滑动距离,0
    • _scrollController.position.viewportDimension 滑动视图所占长度
    • _scrollController.dispose() 销毁监听,在dispose方法中调用
    • _scrollController.jumpTo 控制滑动组件的滑动距离,无动画
    • _scrollController.animateTo(10); 控制滑动组件的滑动距离,有动画
    • _scrollController.position.jumpTo 同上
    • _scrollController.position.animateTo 同上
      controller.addListener((){
          print(controller......)
       });
    

    下面我们开始实现我们的效果

    第一步

    我们使用Scaffold floatingActionButton 来添加我们widget ,配合 floatingActionButtonLocation 设置下位置,

    Scaffold(
         appBar: PreferredSize(
           child: _getAppBar(),
           preferredSize: Size(double.infinity,44),
         ),
         backgroundColor: Colors.white,
         floatingActionButton: AnimationWidget(),
         floatingActionButtonLocation: FloatingActionButtonLocation.centerFloat,
         body: ...,
    
       );
    

    创建悬浮按钮 AnimationWidget

    import 'package:flutter/material.dart';
    import 'package:provider/provider.dart';
    //状态管理
    class NotifierAnimation extends ChangeNotifier{
    //回调方法
     ValueChanged stopValueChanged;
     void animationStartAndEnd(isStop){
       stopValueChanged(isStop);
       notifyListeners();
     }
    }
    
    class AnimationWidget extends StatefulWidget {
     @override
     _AnimationWidgetState createState() => _AnimationWidgetState();
    }
    
    class _AnimationWidgetState extends State<AnimationWidget> with SingleTickerProviderStateMixin{
     AnimationController _animationController;
     Animation<Offset> _animation;
     @override
     void initState() {
       super.initState();
       //实例化动画
       _animationController = new AnimationController(vsync: this,duration: new Duration(milliseconds: 240));
       _animation = Tween(begin: Offset(0,0), end: Offset(0.8, 0)).animate(_animationController);
     }
    
     @override
     void didChangeDependencies() {
       //Provider 状态管理 得到回调如果true 那就是开始动画
       final counter = Provider.of<NotifierAnimation>(context);
       if (counter !=null) {
         Provider.of<NotifierAnimation>(context,listen: false).stopValueChanged=((v){
           if(v){
             //开始动画
             _animationController.forward();
           }else{
             //复位动画
             _animationController.reverse();
    
           }
         });
       }
    
     }
     @override
     Widget build(BuildContext context) {
       return Align(
         alignment: Alignment.centerRight,
         child: Column(
           mainAxisAlignment: MainAxisAlignment.center,
           children: <Widget>[
             SizedBox(height: 100),
             SlideTransition(
               child: Container(
                 width: 50,
                 height: 50,
                 decoration: BoxDecoration(
                     color: Colors.red
                 ),
               ),position: _animation,),
           ],
         )
       );
     }
    }
    
    

    这么这里使用到的是NotificationListener,因为ScrollController不能得到什么时候开始滚动什么时候结束滚动,
    第二步 创建 NotificationListener child就是你的滚动视图 可以是 ListView CustomScrollView,也可以包裹 三方插件 SmartRefresher

    NotificationListener<ScrollNotification>(
          onNotification: (notification){
            if( notification.depth == 0){
              switch (notification.runtimeType){
                case ScrollStartNotification:{
                  //开始滚动 执行动画
                    Provider.of<NotifierAnimation>(context,listen: false).animationStartAndEnd(true);
                }
                break;
                case ScrollUpdateNotification: print("正在滚动") ; break;
                case ScrollEndNotification:{
                  print("滚动停止");
                  //滚动停止 结束动画 复位
                  Provider.of<NotifierAnimation>(context,listen: false).animationStartAndEnd(false);
    
                } break;
                case OverscrollNotification: print("滚动到边界"); break;
              }
            }
            return;
          },
          child: ListView()
        );
    
    我们这里通过三方插件Provider状态共享来执行动画 ,当然了你也可以使用其他方法,无非就是一个回调,调用我们封装好的widget 来执行动画

    Main

    //Provider
    void main() {
      NotifierAnimation notifierAnimation = NotifierAnimation();
        runApp(MultiProvider(
          providers: [
            ChangeNotifierProvider.value(value: notifierAnimation),
    
          ],
          child: MyApp(),
        ));
    }
    

    相关文章

      网友评论

          本文标题:flutter 滚动隐藏悬浮按钮

          本文链接:https://www.haomeiwen.com/subject/auuqmhtx.html