Flutter组件学习(20)可滚动组件以及ScrollController监听

介绍

ViewPort视口

在很多布局系统中都有ViewPort的概念,在Flutter中,术语ViewPort(视口),如无特别说明,则是指一个Widget的实际显示区域。例如,一个ListView的显示区域高度是800像素,虽然其列表项总高度可能远远超过800像素,但是其ViewPort仍然是800像素。

Scrollbar

Scrollbar是一个Material风格的滚动指示器(滚动条),如果要给可滚动组件添加滚动条,只需将Scrollbar作为可滚动组件的任意一个父级组件即可

CupertinoScrollbar

CupertinoScrollbar是iOS风格的滚动条,如果使用的是Scrollbar,那么在iOS平台它会自动切换为CupertinoScrollbar

基于Sliver的延迟构建

通常可滚动组件的子组件可能会非常多、占用的总高度也会非常大;如果要一次性将子组件全部构建出将会非常昂贵!为此,Flutter中提出一个Sliver(中文为“薄片”的意思)概念,如果一个可滚动组件支持Sliver模型,那么该滚动可以将子组件分成好多个“薄片”(Sliver),只有当Sliver出现在视口中时才会去构建它,这种模型也称为“基于Sliver的延迟构建模型”。可滚动组件中有很多都支持基于Sliver的延迟构建模型,如ListViewGridView,但是也有不支持该模型的,如SingleChildScrollView

ScrollController

ScrollController间接继承自Listenable,我们可以根据ScrollController来监听滚动事件,

可以用ScrollController来控制可滚动组件的滚动位置

offset 可滚动组件 当前的滚动位置

jumpTo

animateTo

跳转到指定的位置,

它们不同之处在于,后者在跳转时会执行一个动画,而前者不会

dispose 为了避免内存泄露,需要调用 controller.dispose

demo

import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';

void main() {
  runApp(MyAppText());
}

class MyAppText extends StatefulWidget {

  @override
  ListViewClass createState() {
    return ListViewClass();
  }
}

class ListViewClass extends State {

  ScrollController _controller=new ScrollController();

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

  @override
  void initState() {
    // TODO: implement initState
    super.initState();
    _controller.addListener((){
      print(_controller.offset);
    });
  }

  @override
  Widget build(BuildContext context) {
    // TODO: implement build
    List<String> list = new List();
    for (int i = 0; i < 100; i++) {
      list.add("我和我的祖国$i");
    }

    return MaterialApp(
      home: Scaffold(
        appBar: AppBar(
          backgroundColor: Colors.red,
          title: Text('Controller练习'),
          textTheme:
              TextTheme(title: TextStyle(fontSize: 18, color: Colors.yellow)),
        ),
        body: Scrollbar(
          child: ListView.separated(
            controller: _controller,
            separatorBuilder: (BuildContext context, int dex) {
              return Divider(
                color: Colors.blue,
                height: 1,
              );
            },
            itemCount: list.length,
            itemBuilder: (BuildContext context, int dex) {
              return ListTile(
                title: Text('${list[dex]}'),
              );
            },
          ),
        ),

        floatingActionButton: FloatingActionButton(
          child: Icon(Icons.arrow_upward),
          onPressed: (){
//            _controller.jumpTo(0);//点击按钮回调顶部
            _controller.animateTo(0,
                duration: Duration(
                  milliseconds: 300
                ),
                curve: Curves.ease);
          },
        ),
      ),
    );
  }
}

 

 

 

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章