【自学Flutter】23 滚动监听和 NotificationListener的使用

23 滚动监听和 NotificationListener的使用

1.源代码
import 'package:flutter/material.dart';

void main () => runApp(MyApp());

class MyApp extends StatefulWidget {
  @override
  _MyAppState createState() => _MyAppState();
}

class _MyAppState extends State<MyApp> {

  ScrollController scrollController = new ScrollController();
  bool toTop = false;
  String percent = "0%";

  @override
  void initState() {
    scrollController.addListener((){
          print(scrollController.offset);
          if(scrollController.offset<1000 && toTop){
            setState(() {
              toTop = false;
            });
          }else if(scrollController.offset>=1000 && toTop == false){
            setState(() {
              toTop = true;
            });
          }
        }
    );
  }

  @override
  void dispose() {
    scrollController.dispose();
    super.dispose();
  }

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
        home: Scaffold(
          appBar: AppBar(title: Text("滚动监听"),),
          body: Scrollbar(
            child: NotificationListener<ScrollNotification>(
                onNotification: (ScrollNotification sn){
                  double progress = sn.metrics.pixels / sn.metrics.maxScrollExtent;
                  setState(() {
                    percent = "${(progress*100).toInt()}%";
                  });
                },
                child: Stack(
                  alignment: Alignment.center,
                  children: <Widget>[
                    ListView.builder(
                      itemCount: 100,
                      itemExtent: 50,
                      controller: scrollController,
                      itemBuilder: (context,index){
                        return ListTile(title: Text("编号:$index"),);
                      },
                    ),
                    CircleAvatar(
                      backgroundColor: Colors.black12,
                      radius: 30,
                      child: Text(percent,style: TextStyle(color: Colors.red),),
                    )
                  ],
                )
            )
          ),
          floatingActionButton: !toTop ? null : FloatingActionButton(
            onPressed: (){
              scrollController.animateTo(
                  0,
                  duration: Duration(seconds: 2),
                  curve: Curves.ease);
            },
            child: Icon(Icons.arrow_upward),
          ),
        )
    );
  }
}

2.解释源代码
import 'package:flutter/material.dart';

void main () => runApp(MyApp());

class MyApp extends StatefulWidget {
  @override
  _MyAppState createState() => _MyAppState();
}

class _MyAppState extends State<MyApp> {
  //声明controller
  ScrollController scrollController = new ScrollController();
  //标识是否显示返回最顶按钮
  bool toTop = false;
  //滚动位置百分比
  String percent = "0%";

  @override
  void initState() {
    scrollController.addListener((){
    	  //打印监听位置
          print(scrollController.offset);
          if(scrollController.offset<1000 && toTop){
            //更新状态
            setState(() {
              toTop = false;
            });
          }else if(scrollController.offset>=1000 && toTop == false){
            setState(() {
              toTop = true;
            });
          }
        }
    );
  }
  
  //为了避免内存泄露,需要调用_controller.dispose
  @override
  void dispose() {
    scrollController.dispose();
    super.dispose();
  }

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
        home: Scaffold(
          appBar: AppBar(title: Text("滚动监听"),),
          body: Scrollbar(
            child: NotificationListener<ScrollNotification>(
                onNotification: (ScrollNotification sn){
                  //计算
                  double progress = sn.metrics.pixels / sn.metrics.maxScrollExtent;
                  //重新构建
                  setState(() {
                    percent = "${(progress*100).toInt()}%";
                  });
                },
                child: Stack(
                  alignment: Alignment.center,
                  children: <Widget>[
                    ListView.builder(
                      itemCount: 100,
                      itemExtent: 50,
                      controller: scrollController,
                      itemBuilder: (context,index){
                        return ListTile(title: Text("编号:$index"),);
                      },
                    ),
                    CircleAvatar(
                      backgroundColor: Colors.black12,
                      radius: 30,
                      child: Text(percent,style: TextStyle(color: Colors.red),),
                    )
                  ],
                )
            )
          ),
          floatingActionButton: !toTop ? null : FloatingActionButton(
            onPressed: (){
              返回到顶部时执行动画
              scrollController.animateTo(
                  0,
                  duration: Duration(seconds: 2),
                  curve: Curves.ease);
            },
            child: Icon(Icons.arrow_upward),
          ),
        )
    );
  }
}

3.效果图

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值