如何自动滚动到网格视图的末尾? [英] How to automatically scroll to end of grid view?

查看:84
本文介绍了如何自动滚动到网格视图的末尾?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

When I add items to the end of a grid view I want the user to see what has been added. Here's an example of what I mean:

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

The user adds items by pressing the + icon. The problem is that after Item 14 there is no feedback to show that any item has been added. How can I automatically scroll to the last item when it is added to the list?

(奖励点:将第n个项目添加到列表的中间位置时,如何滚动至该项目)

(Bonus points: how can I scroll to the nth item when it is added somewhere in the middle of the list)

这是滚动到列表视图末尾的答案,但是如果我颠倒了列表的顺序,那么有时在第一行的缺失"项会显得很奇怪.

Here is an answer for scrolling to the end of a list view, but if I reverse the order the list then it will look strange to sometimes have 'missing' items on the top row.

这是我的代码:

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),
      ),
    );
  }
}

推荐答案

声明一个滚动控制器,并使用它来移动到所需的位置.这是滚动到最后一个元素的示例.请注意,滚动控制器已明确声明,因此您不能发出primary: true

Declare a scroll controller and use it to move to the point you desire. Here is an example scrolling to the last element. Notice that the scroll controller is declared explicitly thus you can't issue 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 -您要滚动到的项目

About the "bonus point" I am not so skilled with ScrollControllers but as far as i got, the .animateTo( ) method asks as first input for a double, setting there the scrollpoint: in principle, putting the i-th item you want to scroll to

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

根据网格每行有多少个对象来调整此值.我知道这只是一个草图,但我认为它可以带您到那里.

adjusting this value depending on how many objects per row your grid has. I know this is just a sketch but I think it can lead you there.

这篇关于如何自动滚动到网格视图的末尾?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆