如何自动滚动到网格视图的结尾?

时间:2017-10-21 15:17:16

标签: flutter

当我将项目添加到网格视图的末尾时,我希望用户看到已添加的内容。这是我的意思的一个例子:

screenshot

用户通过按+图标添加项目。问题是在第14项之后没有反馈表明已添加任何项目。将其添加到列表后,如何自动滚动到最后一项?

(加分点:如何在列表中间的某处添加时滚动到第n个项目)

Here is an answer for scrolling to the end of a list view,但是如果我颠倒了列表的顺序,那么有时会遗漏“#39;排在第一行的项目。

这是我的代码:

import 'package:flutter/material.dart';

void main() {
  runApp(new MyApp());
}

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return new MaterialApp(
      title: 'Flutter Demo',
      theme: new ThemeData(
        primarySwatch: Colors.blue,
      ),
      home: new MyHomePage(),
    );
  }
}

class MyHomePage extends StatefulWidget {
  @override
  _MyHomePageState createState() => new _MyHomePageState();
}

class _MyHomePageState extends State<MyHomePage> {
  int _counter = 0;

  @override
  Widget build(BuildContext context) {
    List items = [];
    for (int i = 0; i < _counter; i++) {
      items.add(new Text("Item $i"));
    }
    return new Scaffold(
      appBar: new AppBar(title: new Text("Scroll To End Test")),
      body: new GridView.extent(
        primary: true,
        maxCrossAxisExtent: 150.0,
        children: items,
      ),
      floatingActionButton: new FloatingActionButton(
        onPressed: () {
          setState(() {
            _counter++;
          });
        },
        tooltip: 'Increment',
        child: new Icon(Icons.add),
      ),
    );
  }
}

1 个答案:

答案 0 :(得分:8)

声明一个滚动控制器并使用它移动到您想要的点。这是滚动到最后一个元素的示例。请注意,滚动控制器是明确声明的,因此您无法发出primary: true

import 'package:flutter/material.dart';

void main() {
  runApp(new MyApp());
}

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return new MaterialApp(
      title: 'Flutter Demo',
      theme: new ThemeData(
        primarySwatch: Colors.blue,
      ),
      home: new MyHomePage(),
    );
  }
}

class MyHomePage extends StatefulWidget {
  @override
  _MyHomePageState createState() => new _MyHomePageState();
}

class _MyHomePageState extends State<MyHomePage> {
  int _counter = 0;

  ScrollController _scrollController;                                 // NEW

  @override                                                           // NEW
  void initState() {                                                  // NEW
    super.initState();                                                // NEW
    _scrollController = new ScrollController(                         // NEW
      initialScrollOffset: 0.0,                                       // NEW
      keepScrollOffset: true,                                         // NEW
    );
  }

  void _toEnd() {                                                     // NEW
    _scrollController.animateTo(                                      // NEW
      _scrollController.position.maxScrollExtent,                     // NEW
      duration: const Duration(milliseconds: 500),                    // NEW
      curve: Curves.ease,                                             // NEW
    );                                                                // NEW
  }                                                                   // NEW

  @override
  Widget build(BuildContext context) {
    List items = [];
    for (int i = 0; i < _counter; i++) {
      items.add(new Text("Item $i"));
    }
    return new Scaffold(
      appBar: new AppBar(
        title: new Text("Scroll To End Test"),
        actions: <Widget>[                                            // NEW
          new IconButton(                                             // NEW
              icon: new Icon(Icons.arrow_downward), onPressed: _toEnd)// NEW
        ],                                                            // NEW
      ),
      body: new GridView.extent(
        //primary: true, // REMOVED
        maxCrossAxisExtent: 150.0,
        children: items,
        controller: _scrollController,                                // NEW
      ),
      floatingActionButton: new FloatingActionButton(
        onPressed: () {
          setState(() {
            _counter++;
          });
        },
        tooltip: 'Increment',
        child: new Icon(Icons.add),
      ),
    );
  }
}

关于“奖励点”我对ScrollControllers不是很熟练但是据我所知,.animateTo( )方法要求为double的第一个输入,在那里设置滚动点:原则上,放置 i-th 项目要滚动到

var cursor = i/(# items) * _scrollController.position.maxScrollExtent

根据网格每行的对象数量调整此值。我知道这只是一个草图,但我认为它可以引导你到那里。