首页 > 解决方案 > 滚动未来的 ListView

问题描述

我正在创建一个包含项目列表的页面。我想在列表呈现后滚动到页面底部。问题是我正在使用 FutureBuilder 来获取列表。如果我使用WidgetsBinding.addPostFrameCallback它似乎在build()方法完成之前被调用(可能是因为它仍在获取数据的过程中)。

有没有办法确定 Future 已经完成,列表已经呈现,然后才触发滚动到底部?

@override
void initState() {

  WidgetsBinding.instance.addPostFrameCallback((_) => _postInit());

  super.initState();
}

Future<void> _postInit() async {
 _scrollController.jumpTo(_scrollController.position.maxScrollExtent);
}

@override
Widget build(BuildContext context) {
  return Scaffold(
    body: FutureBuilder(
      future: _getList(),
      builder: (BuildContext context, AsyncSnapshot snapshot) {
        switch(snapshot.connectionState) {
          case ConnectionState.none:
          case ConnectionState.waiting:
            return Center(child: SizedBox(height: 100, width: 100, child: new CircularProgressIndicator()));
            break;
          default:
            if(snapshot.hasError) {
              return Container();
            } else {
              return _buildListView(snapshot.data);
            }
          }
      }

    )
  );
}

Widget _buildListView(list) {
  return Column(
    children: <Widget>[
      Expanded(
        child: ListView(
          controller: _scrollController,
          shrinkWrap: true,
          children: list,
        ),
      ),
    ],
  );
}

标签: flutterdart

解决方案


尝试WidgetsBinding.instance.addPostFrameCallback((_) => _postInit());从您的initState方法中删除。

之后,delayed在您的方法中添加一个函数_postInit(),并在收到数据时调用它以显示您的列表,如下所示:

Future<void> _postInit() async {
   await Future.delayed(Duration(milliseconds: 100));
 _scrollController.jumpTo(_scrollController.position.maxScrollExtent);
}


@override
Widget build(BuildContext context) {
  return Scaffold(
    body: FutureBuilder(
      future: _getList(),
      builder: (BuildContext context, AsyncSnapshot snapshot) {
        switch(snapshot.connectionState) {
          case ConnectionState.none:
          case ConnectionState.waiting:
            return Center(child: SizedBox(height: 100, width: 100, child: new CircularProgressIndicator()));
            break;
          default:
            if(snapshot.hasError) {
              return Container();
            } else {
              _postInit();
              return _buildListView(snapshot.data);
            }
          }
      }

    )
  );
}

推荐阅读