【问题标题】:Flutter - Update ListView and reset scroll positionFlutter - 更新 ListView 并重置滚动位置
【发布时间】:2019-09-07 03:33:58
【问题描述】:

我有一个 ListView,我通过单击一个按钮来更改列表中的项目。现在的问题是,当我向下滚动到列表末尾然后单击按钮时,项目会发生变化,但列表的位置仍然相同(所以当我向下滚动并且我之前列表的第 2 项位于顶部,则新列表的第 2 项也将位于顶部)。 我想要的是列表再次从顶部开始,我必须再次向下滚动。

我的 main.dart:

import 'package:flutter/material.dart';

void main() => runApp(MyApp());

class MyApp extends StatefulWidget {
  @override
  _MyAppState createState() => _MyAppState();
}

class _MyAppState extends State<MyApp> {
  List _list;
  List _list1 = ['Item 1', 'Item 2', 'Item 3', 'Item 4', 'Item 5', 'Item 6'];
  List _list2 = ['Element A', 'Element B', 'Element C', 'Element D', 'Element E', 'Element F'];
  bool _isList1;

  @override
  void initState() {
    _list = _list1;
    _isList1 = true;
    super.initState();
  }

  void _changeList() {
    setState(() {
      if (_isList1) {
        _list = _list2;
        _isList1 = false;
      } else {
        _list = _list1;
        _isList1 = true;
      }
    });
  }

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
        title: 'Schürer',
        home: Scaffold(
          appBar: AppBar(
            title: Text('ListView'),
          ),
          body: Column(
            children: <Widget>[
              RaisedButton(
                child: Text("Change List"),
                onPressed: _changeList,
              ),
              Expanded(
                child: ListView(
                  children: _list
                      .map(
                        (item) => Card(
                              child: Container(
                                padding: EdgeInsets.all(50),
                                color: Colors.black26,
                                child: Text(item),
                              ),
                            ),
                      )
                      .toList(),
                ),
              ),
            ],
          ),
        ));
  }
}

【问题讨论】:

    标签: dart flutter


    【解决方案1】:

    这里你必须为 ListView 提供 key 来区分两个不同的 listview。如果您不提供 key 则颤振认为两者都是相同的列表视图,并且它会使用它的索引来跟踪列表视图。

    如果我们将列表的第一个元素视为键,您的情况可能是什么解决方案。

    ....
    child: ListView(
                  key: ObjectKey(_list[0]),
                  children: _list
    .....
    

    【讨论】:

    • 如果您对答案感到满意,请接受并为社区投票。
    • 谢谢,这行得通。对于我的其他用例,我必须添加一个带有 keepScrollOffset: false 的 ScrollController,所以我的 ListView 现在有 key: ObjectKey(_list.hashCode),controller: ScrollController(keepScrollOffset: false),
    • 完美运行!我有一个提供程序,用作列表上的过滤器,我在 ListViewBuilder 上将活动过滤列表属性设置为 Key('property'),因此略有不同。
    【解决方案2】:

    这项技术对我有用:

    创建ScrollController 变量:

    ScrollController _scrollController = ScrollController();
    ...
    ...
    _scrollController.animateTo(0, duration: Duration(milliseconds: 500), curve: Curves.fastOutSlowIn);
    

    这是flutteranimateTo()的描述:

    将位置从当前值动画到给定值。

    每当textfield 值更改时,我都会调用此函数。

    【讨论】:

      【解决方案3】:

      使用滚动控制器,您可以执行以下操作,将您带到 ListView 的顶部:

      ScrollController _scrollController = ScrollController();
      ...
      ...
      _scrollController.jumpTo(0);
      
      

      当然,您可以将索引从 0 更改为任何 ListTile 索引,以跳转到您希望在 ListView 中使用的任何 ListTile。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2019-06-01
        • 2018-01-02
        • 2018-02-23
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2012-03-04
        • 2010-10-12
        相关资源
        最近更新 更多