Flutter SingleChildScrollView 滚动控件
Flutter中的SingleChildScrollView
类似于Android中的ScrollView
,它只能接收一个子组件。
1、属性及含义
SingleChildScrollView({
this.scrollDirection = Axis.vertical, //滚动方向,默认是垂直方向
this.reverse = false, //决定可滚动组件的初始滚动位置是在“头”还是“尾”,false在“头”,true在“尾”
this.padding, //内边距
bool primary, //是否使用widget树中默认的`PrimaryScrollController`
this.physics, //决定可滚动组件如何响应用户操作,滑动到边界时,出现弹性(ios)还是微光(android)
this.controller,//接受一个ScrollController对象。ScrollController的主要作用是控制滚动位置和监听滚动事件。默认是PrimaryScrollController。
this.child,//子控件,只能包含一个。
})
SingleChildScrollView常用属性值 |
含义 |
---|---|
scrollDirection |
滚动方向,默认是垂直方向 |
reverse |
决定可滚动组件的初始滚动位置是在“头”还是“尾”,false在“头”,true在“尾”,默认false |
padding |
内边距 |
primary |
是否使用widget树中默认的PrimaryScrollController,当scrollDirection值为Axis.vertical,并且没有指定controller时,primary默认为true. |
physics |
决定可滚动组件如何响应用户操作,滑动到边界时,出现弹性(ios)还是微光(android),ClampingScrollPhysics:Android下微光效果。BouncingScrollPhysics:iOS下弹性效果。 |
controller |
接受一个ScrollController对象。ScrollController的主要作用是控制滚动位置和监听滚动事件。默认是PrimaryScrollController。 |
child |
子控件,只能包含一个。 |
需要注意的是,通常SingleChildScrollView
只应在期望的内容不会超过屏幕太多时使用,这是因为SingleChildScrollView
不支持基于Sliver的延迟实例化模型,所以如果预计视口可能包含超出屏幕尺寸太多的内容时,那么使用SingleChildScrollView
将会非常昂贵(性能差),此时应该使用一些支持Sliver延迟加载的可滚动组件,如ListView
。
2、基本概念:基于Sliver的延迟构建
通常可滚动组件的子组件可能会非常多、占用的总高度也会非常大;如果要一次性将子组件全部构建出将会非常昂贵!为此,Flutter中提出一个Sliver(中文为”薄片“的意思)概念,如果一个可滚动组件支持Sliver模型,那么该滚动可以将子组件分成好多个”薄片“(Sliver),只有当Sliver出现在视口中时才会去构建它,这种模型也称为”基于Sliver的延迟构建模型“。可滚动组件中有很多都支持基于Sliver的延迟构建模型,如ListView、GridView,但是也有不支持该模型的,如SingleChildScrollView。
3、示例
- 垂直滚动
下面是一个将大写字母A-Z沿垂直方向显示的例子。
String str =
"ABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUVWXYZ";
return Scaffold(
// 显示进度条
appBar: new AppBar(title: new Text("滚动控件")),
body: SingleChildScrollView(
scrollDirection: Axis.vertical,
padding: EdgeInsets.all(16.0),
child: Center(
child: Column(
//动态创建一个List<Widget>
children: str
.split("")
//每一个字母都用一个Text显示,字体为原来的两倍
.map((c) => Text(
c,
textScaleFactor: 2.0,
))
.toList(),
),
),
),
);
垂直滚动效果图:
- 水平滚动
下面是一个将大写字母A-Z沿水平方向显示的例子。
Widget build(BuildContext context) {
String str = "ABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUVWXYZ";
return Scaffold(
// 显示进度条
appBar: new AppBar(title: new Text("滚动控件")),
body: SingleChildScrollView(
scrollDirection: Axis.horizontal,
padding: EdgeInsets.all(16.0),
child: Center(
child: Row(
//动态创建一个List<Widget>
children: str
.split("")
//每一个字母都用一个Text显示,字体为原来的两倍
.map((c) => Text(
c,
textScaleFactor: 2.0,
))
.toList(),
),
),
),
);
水平滚动效果图:
4、ScrollController监听滚动
通过ScrollController
可以监听SingleChildScrollView滚动。
简易监听示例:
ScrollController mController = new ScrollController();
mController.addListener(() {
//监听滚动事件,打印滚动位置
mController.addListener(() {
print(mController.offset); //打印滚动位置
});
});
SingleChildScrollView(
……
controller: mController,
child: ……
),
5、实现“回到顶部”功能
通过ScrollController
监听SingleChildScrollView滚动,实现“回到顶部”功能。
- 完整示例 import 'package:flutter/material.dart'; class SingleChildScrollViewDemo extends StatefulWidget { @override SingleChildScrollViewDemoState createState() { return SingleChildScrollViewDemoState(); } } class SingleChildScrollViewDemoState extends State<SingleChildScrollViewDemo> { ScrollController mController = new ScrollController(); bool showToTopBtn = false; //是否显示“返回到顶部”按钮 @override void initState() { //监听滚动事件,打印滚动位置 mController.addListener(() { print(mController.offset); //打印滚动位置 if (mController.offset < 200 && showToTopBtn) { setState(() { showToTopBtn = false; }); } else if (mController.offset >= 200 && showToTopBtn == false) { setState(() { showToTopBtn = true; }); } }); } @override Widget build(BuildContext context) { String str = "ABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUVWXYZ"; return Scaffold( // 显示进度条 appBar: new AppBar(title: new Text("滚动控件")), floatingActionButton: !showToTopBtn ? null : FloatingActionButton( child: Icon(Icons.arrow_upward), onPressed: () { //返回到顶部时执行动画 mController.animateTo(.0, duration: Duration(milliseconds: 200), curve: Curves.ease); }), body: Column( children: <Widget>[ Expanded( child: SingleChildScrollView( scrollDirection: Axis.vertical, padding: EdgeInsets.all(16.0), controller: mController, child: Center( child: Column( //动态创建一个List<Widget> children: str .split("") //每一个字母都用一个Text显示,字体为原来的两倍 .map((c) => Text( c, textScaleFactor: 2.0, )) .toList(), ), ), ), ) ], )); } } void main() { runApp(new MaterialApp( title: "滚动控件案例", theme: new ThemeData(primaryColor: Colors.deepOrangeAccent), home: new SingleChildScrollViewDemo(), )); }
“回到顶部”效果图:
- MongoDB系列6:MongoDB索引的介绍
- 文本数据处理的终极指南-[NLP入门]
- 神经网络思想建立LR模型(DL公开课第二周答案)
- 如何用卷积神经网络从歌曲中提取纯人声?这里有教程+代码
- 排序算法对比、总结(Python代码)
- 记一道未能答出的算法面试题
- 关于numpy mean函数的axis参数
- 在Keras+TF环境中,用迁移学习和微调做专属图像识别系统
- Tensorflow的LRN是怎么做的
- 存储Tensorflow训练网络的参数
- 用Ansible部署ELK STACK
- 十六个有用的Linux命令行技巧
- keras系列︱深度学习五款常用的已训练模型
- 基于VGG19的识别中国人、韩国人、日本人分类器
- JavaScript 教程
- JavaScript 编辑工具
- JavaScript 与HTML
- JavaScript 与Java
- JavaScript 数据结构
- JavaScript 基本数据类型
- JavaScript 特殊数据类型
- JavaScript 运算符
- JavaScript typeof 运算符
- JavaScript 表达式
- JavaScript 类型转换
- JavaScript 基本语法
- JavaScript 注释
- Javascript 基本处理流程
- Javascript 选择结构
- Javascript if 语句
- Javascript if 语句的嵌套
- Javascript switch 语句
- Javascript 循环结构
- Javascript 循环结构实例
- Javascript 跳转语句
- Javascript 控制语句总结
- Javascript 函数介绍
- Javascript 函数的定义
- Javascript 函数调用
- Javascript 几种特殊的函数
- JavaScript 内置函数简介
- Javascript eval() 函数
- Javascript isFinite() 函数
- Javascript isNaN() 函数
- parseInt() 与 parseFloat()
- escape() 与 unescape()
- Javascript 字符串介绍
- Javascript length属性
- javascript 字符串函数
- Javascript 日期对象简介
- Javascript 日期对象用途
- Date 对象属性和方法
- Javascript 数组是什么
- Javascript 创建数组
- Javascript 数组赋值与取值
- Javascript 数组属性和方法
- 生产环境优雅的重启基于Nginx、Tornado的Web服务进程
- nginx记录post body/payload数据 日志用打印出结果
- nginx的location、rewrite玩法详解
- Redis Lua脚本调试
- 安装elasticsearch 5.x, 6.x 常见问题(坑)的解决
- 轻松搞懂elasticsearch概念
- 深入Golang调度器之GMP模型
- 深入Golang之sync.Pool详解
- 一次对电视盒子的漏洞分析
- MQ选型之RabbitMQ
- httprouter与 fasthttp 的性能对比
- Nmap 脚本研究
- Nmap NSE 库分析 >>> http
- Nmap NSE 库分析 >>> httpspider
- Nmap NSE 库分析 >>> url