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

Mar*_*ark 2 flutter

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

截图

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

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

这是滚动到列表视图末尾的答案,但如果我颠倒了列表的顺序,那么有时在顶行上有"缺少"项目看起来很奇怪.

这是我的代码:

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),
      ),
    );
  }
}
Run Code Online (Sandbox Code Playgroud)

Fab*_*ese 9

声明一个滚动控制器并使用它移动到您想要的点.这是滚动到最后一个元素的示例.请注意,滚动控制器是显式声明的,因此您无法发出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),
      ),
    );
  }
}
Run Code Online (Sandbox Code Playgroud)

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

var cursor = i/(# items) * _scrollController.position.maxScrollExtent
Run Code Online (Sandbox Code Playgroud)

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