前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >Flutter跨平台移动端开发丨SingleChildScrollView、ListView......

Flutter跨平台移动端开发丨SingleChildScrollView、ListView......

作者头像
码脑
发布2019-05-25 09:25:03
8.6K0
发布2019-05-25 09:25:03
举报
文章被收录于专栏:大前端大前端

SingleChildScrollView(可滑动 View)

SingleChildScrollView 类似 Android 中的 scrollview ,且同样的只可包含有一个子元素

代码语言:javascript
复制
  const SingleChildScrollView({
    Key key,
    this.scrollDirection = Axis.vertical,
    this.reverse = false,
    this.padding,
    bool primary,
    this.physics,
    this.controller,
    this.child,
    this.dragStartBehavior = DragStartBehavior.down,
  }) : assert(scrollDirection != null),
       assert(dragStartBehavior != null),
       assert(!(controller != null && primary == true),
          'Primary ScrollViews obtain their ScrollController via inheritance from a PrimaryScrollController widget. '
          'You cannot both set primary to true and pass an explicit controller.'
       ),
       primary = primary ?? controller == null && identical(scrollDirection, Axis.vertical),
       super(key: key);
  • key:当前元素的唯一标识符(类似于 Android 中的 id)
  • scrollDirection:滚动方向,默认是垂直
  • reverse:是否按照阅读方向相反的方向滑动。
  • padding:填充距离
  • primary:是否使用 widget 树中默认的 PrimaryScrollController 。当滑动方向为垂直方向(scrollDirection值为Axis.vertical)并且controller没有指定时,primary默认为true
  • physics:此属性接受一个ScrollPhysics对象,它决定可滚动Widget如何响应用户操作,比如用户滑动完抬起手指后,继续执行动画;或者滑动到边界时,如何显示。默认情况下,Flutter会根据具体平台分别使用不同的ScrollPhysics对象,应用不同的显示效果,如当滑动到边界时,继续拖动的话,在iOS上会出现弹性效果,而在Android上会出现微光效果。如果你想在所有平台下使用同一种效果,可以显式指定,Flutter SDK中包含了两个ScrollPhysics的子类可以直接使用: ClampingScrollPhysics→Android下微光效果 / BouncingScrollPhysics→iOS下弹性效果
  • controller:此属性接受一个ScrollController对象。ScrollController的主要作用是控制滚动位置和监听滚动事件
  • child:子元素
代码语言:javascript
复制
import 'package:flutter/material.dart';

/**
 * @des Scroll Widget
 * @author liyongli 20190506
 * */
class SingleChildScrollViewWidget extends StatefulWidget{

  @override
  State<StatefulWidget> createState() => new _StackState();

}

/**
 * @des Scroll Widget State
 * @author liyongli 20190506
 * */
class _StackState extends State<SingleChildScrollViewWidget>{

  String numberStr = "12345678909876543210123456789";

  @override
  Widget build(BuildContext context) {
    return new MaterialApp(
      home: new Scaffold(

        appBar: new AppBar(
          title: new Text("Scroll Widget"),
        ),

        body: Scrollbar(
          child: SingleChildScrollView(
            scrollDirection: Axis.horizontal,
            child: Center(
              child: Row(
                children: numberStr.split("").map((c) => Text(c, textScaleFactor: 2.0,)).toList(),
              ),
            ),
          ),
        )
      ),
    );
  }
}
代码语言:javascript
复制
import 'package:flutter/material.dart';

/**
 * @des Scroll Widget
 * @author liyongli 20190506
 * */
class SingleChildScrollViewWidget extends StatefulWidget{

  @override
  State<StatefulWidget> createState() => new _StackState();

}

/**
 * @des Scroll Widget State
 * @author liyongli 20190506
 * */
class _StackState extends State<SingleChildScrollViewWidget>{

  String numberStr = "1234567890987654321";

  @override
  Widget build(BuildContext context) {
    return new MaterialApp(
      home: new Scaffold(

        appBar: new AppBar(
          title: new Text("Scroll Widget"),
        ),

        body: Scrollbar(
          child: SingleChildScrollView(
            child: Center(
              child: Column(
                children: numberStr.split("").map((c) => Text(c, textScaleFactor: 2.0,)).toList(),
              ),
            ),
          ),
        )
      ),
    );
  }
}

ListView(列表 View)

ListView 可以构建一个列表视图

代码语言:javascript
复制
  ListView({
    Key key,
    Axis scrollDirection = Axis.vertical,
    bool reverse = false,
    ScrollController controller,
    bool primary,
    ScrollPhysics physics,
    bool shrinkWrap = false,
    EdgeInsetsGeometry padding,
    this.itemExtent,
    bool addAutomaticKeepAlives = true,
    bool addRepaintBoundaries = true,
    bool addSemanticIndexes = true,
    double cacheExtent,
    List<Widget> children = const <Widget>[],
    int semanticChildCount,
    DragStartBehavior dragStartBehavior = DragStartBehavior.down,
  }) : childrenDelegate = SliverChildListDelegate(
         children,
         addAutomaticKeepAlives: addAutomaticKeepAlives,
         addRepaintBoundaries: addRepaintBoundaries,
         addSemanticIndexes: addSemanticIndexes,
       ),
       super(
         key: key,
         scrollDirection: scrollDirection,
         reverse: reverse,
         controller: controller,
         primary: primary,
         physics: physics,
         shrinkWrap: shrinkWrap,
         padding: padding,
         cacheExtent: cacheExtent,
         semanticChildCount: semanticChildCount ?? children.length,
         dragStartBehavior: dragStartBehavior,
       );
  • key:当前元素的唯一标识符(类似于 Android 中的 id)
  • scrollDirection:滚动方向,默认是垂直
  • reverse:是否按照阅读方向相反的方向滑动。
  • controller:控制器对象,主要作用是控制滚动位置和监听滚动事件
  • primary:是否使用 widget 树中默认的 PrimaryScrollController 。当滑动方向为垂直方向(scrollDirection值为Axis.vertical)并且controller没有指定时,primary默认为true
  • physics:此属性接受一个ScrollPhysics对象,它决定可滚动Widget如何响应用户操作,比如用户滑动完抬起手指后,继续执行动画;或者滑动到边界时,如何显示。默认情况下,Flutter会根据具体平台分别使用不同的ScrollPhysics对象,应用不同的显示效果,如当滑动到边界时,继续拖动的话,在iOS上会出现弹性效果,而在Android上会出现微光效果。如果你想在所有平台下使用同一种效果,可以显式指定,Flutter SDK中包含了两个ScrollPhysics的子类可以直接使用: ClampingScrollPhysics→Android下微光效果 / BouncingScrollPhysics→iOS下弹性效果
  • shrinkWrap:表示是否根据子 widget 的总长度设置 listview 的长度,默认为 false。
  • padding:填充距离
  • itemExtent:强制 listview 的 children 的长度 为 itemExtent 的值。指定 itemExtent 的值比让子元素决定自身长度在绘制时更高效,特别是在滚动位置频繁变化的状态下,因为设置 itemExtent 可以让滚动系统提前知道列表的长度。
  • addAutomaticKeepAlives:表示是否将列表项包裹在 AutomaticKeepAlive widget 中。(在懒加载时,如果设置了包裹那么在此列表项滑出屏幕外时不会被GC。如果此列表项需要自己维护 KeepAlive 状态,那么此参数需为 false)
  • addRepaintBoundaries:表示是否将列表项包裹在 RepaintBoundary 中。(当选择将列表项包裹在 RepaintBoundary 时,在滚动过程中可以避免重绘,如果此列表项需要自己维护 KeepAlive 状态,那么此参数需为 false)
  • addSemanticIndexes:表示是否给子元素添加索引,默认为 true
  • cacheExtent:设置预加载的区域,范围在窗口可见范围之前与之后。如果设置为 0.0,表示关闭预加载
  • children:列表项集合
  • semanticChildCount:提供语义信息的孩子的数量
item 数量固定的 listview 示例

listview 构造方法中的参数 children 表示子列表集,使用这种方式构建列表需要我们提前准备好子 widget 集合。这种方式只适合实现少量且数量固定的列表展示需求

代码语言:javascript
复制
import 'package:flutter/material.dart';


/**
 * @des Listview Widget
 * @author liyongli 20190506
 * */
class ListViewWidget extends StatefulWidget{

  @override
  State<StatefulWidget> createState() {
    return new _ListViewWigetState();
  }

}

/**
 * @des Listview Widget State
 * @author liyongli 20190506
 * */
class _ListViewWigetState extends State<ListViewWidget>{

  @override
  Widget build(BuildContext context) {
    return Scaffold(

        appBar: new AppBar(
          title: new Text("Scroll Widget"),
        ),

        body: ListView(
          shrinkWrap: true,
          padding: const EdgeInsets.all(20.0),
          children: <Widget>[
            const Text("1111111111111111111111111111111111", style: TextStyle(color: Colors.blue)),
            const Text("2222222222222222222222222222222222", style: TextStyle(color: Colors.blue)),
            const Text("3333333333333333333333333333333333", style: TextStyle(color: Colors.blue)),
            const Text("4444444444444444444444444444444444", style: TextStyle(color: Colors.blue)),
            const Text("5555555555555555555555555555555555", style: TextStyle(color: Colors.blue)),
            const Text("6666666666666666666666666666666666", style: TextStyle(color: Colors.blue)),
            const Text("7777777777777777777777777777777777", style: TextStyle(color: Colors.blue)),
            const Text("8888888888888888888888888888888888", style: TextStyle(color: Colors.blue)),
          ],
        ),
    );
  }

}
ListView.builder

当 listview 的列表项较多或数量未知时,就需要使用 ListView.builder 来构建列表了

代码语言:javascript
复制
import 'package:flutter/material.dart';


/**
 * @des Listview.builder Widget
 * @author liyongli 20190506
 * */
class ListViewBuilderWidget extends StatefulWidget{

  @override
  State<StatefulWidget> createState() {
    return new _ListViewBuilderWidget ();
  }

}

/**
 * @des Listview.builder Widget State
 * @author liyongli 20190506
 * */
class _ListViewBuilderWidget  extends State<ListViewBuilderWidget>{

  @override
  Widget build(BuildContext context) {
    return Scaffold(

        appBar: new AppBar(
          title: new Text("ListviewBuilder Widget"),
        ),

        body: ListView.builder(
            itemCount: 100,
            itemExtent: 50.0, //强制高度为50.0
            itemBuilder: (BuildContext context, int index) {
              return ListTile(title: Text(" $index - "));
            }
        ),
    );
  }

}
ListView.separated

当 listview 的 item 间需要分割线时,我们就需要用到 ListView.separated

代码语言:javascript
复制
import 'package:flutter/material.dart';


/**
 * @des Listview.builder Widget
 * @author liyongli 20190506
 * */
class ListViewBuilderWidget extends StatefulWidget{

  @override
  State<StatefulWidget> createState() {
    return new _ListViewBuilderWidget ();
  }

}

/**
 * @des Listview.builder Widget State
 * @author liyongli 20190506
 * */
class _ListViewBuilderWidget  extends State<ListViewBuilderWidget>{

  @override
  Widget build(BuildContext context) {
    return Scaffold(

        appBar: new AppBar(
          title: new Text("ListviewBuilder Widget"),
        ),

        body: ListView.separated(
            itemCount: 100,
            itemBuilder: (BuildContext context, int index) {
              return ListTile(title: Text(" $index - ", style: TextStyle(color: Colors.blue),));
            },

            separatorBuilder: (BuildContext context, int index) {
              return Divider(color: Colors.blue, height: 10,);
            }
        ),
    );
  }

}
ListView 分页加载

工程 yaml 文件中要添加 english_words 的依赖

代码语言:javascript
复制
  # The following adds the Cupertino Icons font to your application.
  # Use with the CupertinoIcons class for iOS style icons.
  cupertino_icons: ^0.1.2
  english_words: ^3.1.0
代码语言:javascript
复制
import 'package:flutter/material.dart';
import 'package:english_words/english_words.dart';


/**
 * @des Listview  Widget
 * @author liyongli 20190507
 * */
class InfiniteListView extends StatefulWidget {
  @override
  _InfiniteListViewState createState() => new _InfiniteListViewState();
}

/**
 * @des Listview  Widget State
 * @author liyongli 20190507
 * */
class _InfiniteListViewState extends State<InfiniteListView> {
  static const loadingTag = "##loading##"; //表尾标记
  var _words = <String>[loadingTag];

  @override
  void initState() {
    _retrieveData();
  }

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: Scaffold(
        appBar: AppBar(
          title: Text("listview 分页加载"),
        ),

        body: ListView.separated(
          itemCount: _words.length,
          itemBuilder: (context, index) {
            //如果到了表尾
            if (_words[index] == loadingTag) {
              //不足100条,继续获取数据
              if (_words.length - 1 < 100) {
                //获取数据
                _retrieveData();
                //加载时显示loading
                return Container(
                  padding: const EdgeInsets.all(16.0),
                  alignment: Alignment.center,
                  child: SizedBox(
                      width: 24.0,
                      height: 24.0,
                      child: CircularProgressIndicator(strokeWidth: 2.0)
                  ),
                );
              } else {
                //已经加载了100条数据,不再获取数据。
                return Container(
                    alignment: Alignment.center,
                    padding: EdgeInsets.all(16.0),
                    child: Text("没有更多了", style: TextStyle(color: Colors.grey),)
                );
              }
            }
            //显示单词列表项
            return ListTile(title: Text(_words[index], style: TextStyle(color: Colors.blue),));
          },
          separatorBuilder: (context, index) => Divider(height: 1, color: Colors.blue,),
        ),
      ),

    );
  }

  void _retrieveData() {
    Future.delayed(Duration(seconds: 2)).then((e) {
      _words.insertAll(_words.length - 1,
          //每次生成20个单词
          generateWordPairs().take(20).map((e) => e.asPascalCase).toList()
      );
      setState(() {
        //重新构建列表
      });
    });
  }

}

GridView(网格 View)

GridView 可以构建一个网格列表视图

代码语言:javascript
复制
  GridView.builder({
    Key key,
    Axis scrollDirection = Axis.vertical,
    bool reverse = false,
    ScrollController controller,
    bool primary,
    ScrollPhysics physics,
    bool shrinkWrap = false,
    EdgeInsetsGeometry padding,
    @required this.gridDelegate,
    @required IndexedWidgetBuilder itemBuilder,
    int itemCount,
    bool addAutomaticKeepAlives = true,
    bool addRepaintBoundaries = true,
    bool addSemanticIndexes = true,
    double cacheExtent,
    int semanticChildCount,
  }) : assert(gridDelegate != null),
       childrenDelegate = SliverChildBuilderDelegate(
         itemBuilder,
         childCount: itemCount,
         addAutomaticKeepAlives: addAutomaticKeepAlives,
         addRepaintBoundaries: addRepaintBoundaries,
         addSemanticIndexes: addSemanticIndexes,
       ),
       super(
         key: key,
         scrollDirection: scrollDirection,
         reverse: reverse,
         controller: controller,
         primary: primary,
         physics: physics,
         shrinkWrap: shrinkWrap,
         padding: padding,
         cacheExtent: cacheExtent,
         semanticChildCount: semanticChildCount ?? itemCount,
       );
  • key:当前元素的唯一标识符(类似于 Android 中的 id)
  • scrollDirection:滚动方向,默认是垂直
  • reverse:是否按照阅读方向相反的方向滑动。
  • controller:控制器对象,主要作用是控制滚动位置和监听滚动事件
  • primary:是否使用 widget 树中默认的 PrimaryScrollController 。当滑动方向为垂直方向(scrollDirection值为Axis.vertical)并且controller没有指定时,primary默认为true
  • physics:此属性接受一个ScrollPhysics对象,它决定可滚动Widget如何响应用户操作,比如用户滑动完抬起手指后,继续执行动画;或者滑动到边界时,如何显示。默认情况下,Flutter会根据具体平台分别使用不同的ScrollPhysics对象,应用不同的显示效果,如当滑动到边界时,继续拖动的话,在iOS上会出现弹性效果,而在Android上会出现微光效果。如果你想在所有平台下使用同一种效果,可以显式指定,Flutter SDK中包含了两个ScrollPhysics的子类可以直接使用: ClampingScrollPhysics→Android下微光效果 / BouncingScrollPhysics→iOS下弹性效果
  • shrinkWrap:表示是否根据子 widget 的总长度设置 listview 的长度,默认为 false。
  • padding:填充距离
  • itemCount:子元素数量
  • addAutomaticKeepAlives:表示是否将列表项包裹在 AutomaticKeepAlive widget 中。(在懒加载时,如果设置了包裹那么在此列表项滑出屏幕外时不会被GC。如果此列表项需要自己维护 KeepAlive 状态,那么此参数需为 false)
  • addRepaintBoundaries:表示是否将列表项包裹在 RepaintBoundary 中。(当选择将列表项包裹在 RepaintBoundary 时,在滚动过程中可以避免重绘,如果此列表项需要自己维护 KeepAlive 状态,那么此参数需为 false)
  • addSemanticIndexes:表示是否给子元素添加索引,默认为 true
  • cacheExtent:设置预加载的区域,范围在窗口可见范围之前与之后。如果设置为 0.0,表示关闭预加载
  • semanticChildCount:提供语义信息的孩子的数量
GridView 固定列数
代码语言:javascript
复制
import 'package:flutter/material.dart';

/**
 * @des GridView 固定列数
 * @author liyongli 20190508
 * */
class GridViewTest extends StatefulWidget{

  @override
  State<StatefulWidget> createState() => new _GridViewState();

}

/**
 * @des GridView Widget State
 * @author liyongli 20190508
 * */
class _GridViewState extends State<GridViewTest>{

  @override
  Widget build(BuildContext context) {
    return new MaterialApp(
      home: new Scaffold(

        appBar: new AppBar(
          title: new Text("GridView 固定列数"),
        ),

        body: GridView.count(
          crossAxisCount: 4,
          childAspectRatio: 0.7,
          children: <Widget>[
            Icon(Icons.add_a_photo),
            Icon(Icons.add_a_photo),
            Icon(Icons.add_a_photo),
            Icon(Icons.add_a_photo),
            Icon(Icons.add_a_photo),
            Icon(Icons.add_a_photo),
            Icon(Icons.add_a_photo),
            Icon(Icons.add_a_photo),
            Icon(Icons.add_a_photo),
            Icon(Icons.add_a_photo),
            Icon(Icons.add_a_photo),
            Icon(Icons.add_a_photo),
          ],
        ),
      ),
    );
  }
}
代码语言:javascript
复制
import 'package:flutter/material.dart';

/**
 * @des GridView 等分宽度
 * @author liyongli 20190508
 * */
class GridViewTest extends StatefulWidget{

  @override
  State<StatefulWidget> createState() => new _GridViewState();

}

/**
 * @des GridView Widget State
 * @author liyongli 20190508
 * */
class _GridViewState extends State<GridViewTest>{

  @override
  Widget build(BuildContext context) {
    return new MaterialApp(
      home: new Scaffold(

        appBar: new AppBar(
          title: new Text("GridView 等分宽度"),
        ),

        body: GridView.extent(
          maxCrossAxisExtent: 200,
          childAspectRatio: 1.0,
          children: <Widget>[
            Icon(Icons.add_a_photo),
            Icon(Icons.add_a_photo),
            Icon(Icons.add_a_photo),
            Icon(Icons.add_a_photo),
            Icon(Icons.add_a_photo),
          ],
        ),
      ),
    );
  }
}
GridView 分页加载
代码语言:javascript
复制
import 'package:flutter/material.dart';

/**
 * @des GridView 分页加载
 * @author liyongli 20190508
 * */
class GridViewTest extends StatefulWidget{

  @override
  State<StatefulWidget> createState() => new _GridViewState();

}

/**
 * @des GridView Widget State
 * @author liyongli 20190508
 * */
class _GridViewState extends State<GridViewTest>{

  List<IconData> _iconList = [];

  @override
  void initState() {
    _getData();
  }

  @override
  Widget build(BuildContext context) {
    return new MaterialApp(
      home: new Scaffold(

        appBar: new AppBar(
          title: new Text("GridView 分页加载"),
        ),

        body: GridView.builder(
          itemCount: _iconList.length,
            gridDelegate: SliverGridDelegateWithFixedCrossAxisCount(crossAxisCount: 5, childAspectRatio: 1.0),
            itemBuilder: (context, index){
              if(index == _iconList.length - 1 && _iconList.length < 200){
                _getData();
              }
              return Icon(_iconList[index]);
            }
        )
      ),
    );
  }

  // 请求数据
  void _getData(){
    Future.delayed(Duration(milliseconds: 200)).then((e) {
      setState(() {
        _iconList.addAll([
          Icons.add_a_photo,
          Icons.add_a_photo,
          Icons.add_a_photo,
          Icons.add_a_photo, Icons.cake,
          Icons.add_a_photo
        ]);
      });
    });
  }
}

CustomScrollView(自定义滑动 View)

Sliver

Sliver 是分片、分区的意思。当我们需要将不同的可滑动组件组合在一起时,就需要使用此对象来完成。ListView 和 GridView 都有对应的组合对象如:SliverList 和 SliverGrid。

代码语言:javascript
复制
import 'package:flutter/material.dart';

/**
 * @des CustomScrollView Widget
 * @author liyongli 20190509
 * */
class CustomScrollViewTest extends StatelessWidget{


  @override
  Widget build(BuildContext context) {
    return Material(
      child: CustomScrollView(
        slivers: <Widget>[

          // 跟随页面滑动的导航栏
          SliverAppBar(
            pinned: true, // 是否固定
            expandedHeight: 200.0, // 高度
            flexibleSpace: FlexibleSpaceBar(
              title: Text("title"),
              background: Image.asset("images/custom_scroll_title.png", fit: BoxFit.cover,)
            ),
          ),

          // Grid
          SliverPadding(
            padding: EdgeInsets.all(10.0),
            sliver: SliverGrid(
              gridDelegate: SliverGridDelegateWithFixedCrossAxisCount(
                crossAxisCount: 3, // 4行
                mainAxisSpacing: 20.0,
                crossAxisSpacing: 10.0,
                childAspectRatio: 5.0,
              ),
              delegate: SliverChildBuilderDelegate(
                  (BuildContext context, int index){
                    return Container(
                      alignment: Alignment.center,
                      color: Colors.blue,
                      child: Text("grid Item $index", style: TextStyle(color: Colors.white),),
                    );
                  },
                childCount: 12
              ),
            ),
          ),

          // List
          SliverFixedExtentList(
            itemExtent: 20,
            delegate: SliverChildBuilderDelegate((BuildContext context , int index){
              return Container(
                alignment: Alignment.center,
                color: Colors.blue,
                child: Text("list Item $index", style: TextStyle(color: Colors.white),),
              );
            },
              childCount: 30
            ),
          ),
        ],
      ),
    );
  }

}

ScrollController(控制器)

可设置滑动 View 的滚动位置,还可监听并获取滑动 View 的滚动状态及数据

代码语言:javascript
复制
  ScrollController({
    double initialScrollOffset = 0.0,
    this.keepScrollOffset = true,
    this.debugLabel,
  }) : assert(initialScrollOffset != null),
       assert(keepScrollOffset != null),
       _initialScrollOffset = initialScrollOffset;
  • initialScrollOffset:初始位置
  • keepScrollOffset:是否保存滚动位置
  • ScrollController.jumpTo(0.0):直接滚动至指定位置
  • ScrollController.animateTo(0.0, duration: Duration(milliseconds: 500), curve: Curves.decelerate):带动画滚动至指定位置
代码语言:javascript
复制
import 'package:flutter/material.dart';

/**
 * des ScrollController Test
 * @author liyongli 20190513
 * */
class ScrollControllerTest extends StatefulWidget{

  @override
  State<StatefulWidget> createState() {
    return new _ScrollControllerTestState();
  }

}

/**
 * des ScrollController Test State
 * @author liyongli 20190513
 * */
class _ScrollControllerTestState extends State<ScrollControllerTest>{

  ScrollController _controller = new ScrollController();
  double oldOffset = -1;

  @override
  void initState() {
    super.initState();

    _controller.addListener((){
      print("$_controller.offset" + " / " + "$oldOffset");

      if(oldOffset > _controller.offset){
        print("向下滑");
      }else{
        print("向上滑");
      }

      oldOffset = _controller.offset;
    });

  }

  @override
  void dispose() {
    super.dispose();
    _controller.dispose(); // 释放资源
  }

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: Scaffold(

        appBar: AppBar(
          title: Text("ScrollController"),

        ),

        body: Scrollbar(
            child: ListView.builder(
                controller: _controller, // 控制器
                itemCount: 50, // item count
                itemExtent: 100.0, // item height
                itemBuilder: (context, index){
                  return ListTile(title:Text("$index", style: TextStyle(color: Colors.blue),));
                }
            )
        ),

        floatingActionButton: FloatingActionButton(
          onPressed: _up,
          child: Icon(Icons.arrow_upward)
        ),
      ),
    );
  }

//  滚动
  void _up(){
    // 带动画滚动
    _controller.animateTo(0.0, duration: Duration(milliseconds: 500), curve: Curves.decelerate);
    // 无动画滚动
//    _controller.jumpTo(0.0);
  }

}
本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2019.05.24 ,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • SingleChildScrollView(可滑动 View)
  • ListView(列表 View)
    • item 数量固定的 listview 示例
      • ListView.builder
        • ListView.separated
          • ListView 分页加载
          • GridView(网格 View)
            • GridView 固定列数
              • GridView 分页加载
              • CustomScrollView(自定义滑动 View)
                • Sliver
                • ScrollController(控制器)
                领券
                问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档