Flutter:ScrollController 的 initialScrollOffset 不起作用

5

我正在尝试使用自定义的ScrollController初始化一个SingleChildScrollView,使其从特定位置开始。我认为我可以使用initialScrollOffset并在init方法中设置初始值。但是当SingleChildScrollView渲染时,它只会在第一次构建时跳转到initialOffset,然后当我导航到此小部件的另一个实例时,它不会跳转到initialOffset位置。

我不知道原因,如果我幸运的话,也许你们其中之一有答案。

以下是我的代码:

class Artiklar extends StatefulWidget {
  final String path;
  final double arguments;

  Artiklar({
    this.path,
    this.arguments,
  });

  @override
  _ArtiklarState createState() => _ArtiklarState(arguments: arguments);
}

class _ArtiklarState extends State<Artiklar> {
  final double arguments;

  _ArtiklarState({this.arguments});

  ScrollController _scrollController;
  double scrollPosition;

  @override
  void initState() {
    super.initState();
    double initialOffset = arguments != null ? arguments : 22.2;
    _scrollController = ScrollController(initialScrollOffset: initialOffset);
  }

  @override
  void dispose() {
    _scrollController.dispose();
    super.dispose();
  }

  @override
  Widget build(BuildContext context) {
    final bool isAdmin = Provider.of<bool>(context) ?? false;

    var pathElements = widget.path.split('/');
    String tag;
    if (pathElements.length == 2) {
      tag = null;
    } else if (pathElements.length == 3) {
      tag = pathElements[2];
    } else {
      tag = null;
    }

    return StreamBuilder<List<ArtikelData>>(
      stream: DatabaseService(tag: tag).artiklarByDate,
      builder: (context, snapshot) {
        if (snapshot.connectionState == ConnectionState.active) {
          return GlobalScaffold(
            body: SingleChildScrollView(
              child: Container(
                child: Center(
                  child: Container(
                    padding: EdgeInsets.symmetric(horizontal: 20, vertical: 15),
                    child: Column(
                      crossAxisAlignment: CrossAxisAlignment.start,
                      children: <Widget>[
                        GradientHeading(text: "Artiklar", large: true),
                        isAdmin
                            ? NormalButton(
                                text: "Skapa ny artikel",
                                onPressed: () {
                                  Navigator.pushNamed(
                                      context, createNewArtikelRoute);
                                },
                              )
                            : Container(),
                        SizedBox(height: 10),
                        SingleChildScrollView(
                          controller: _scrollController,
                          scrollDirection: Axis.horizontal,
                          child: TagList(path: tag),
                        ),
                        SizedBox(height: 10),
                        LatestArtiklar(
                          snapshot: snapshot,
                          totalPosts: snapshot.data.length,
                          numberOfPosts: 10,
                        ),
                      ],
                    ),
                  ),
                ),
              ),
            ),
          );
        } else if (!snapshot.hasData) {
          return GlobalScaffold(
            body: SingleChildScrollView(
              child: Container(
                child: Center(
                  child: Container(
                    padding: EdgeInsets.symmetric(horizontal: 20, vertical: 15),
                    child: Column(
                      crossAxisAlignment: CrossAxisAlignment.start,
                      children: <Widget>[
                        GradientHeading(text: "Artiklar", large: true),
                        SizedBox(height: 10),
                        SingleChildScrollView(
                          scrollDirection: Axis.horizontal,
                          child: TagList(path: tag),
                        ),
                        SizedBox(height: 10),
                        LatestArtiklar(hasNoPosts: true)
                      ],
                    ),
                  ),
                ),
              ),
            ),
          );
        } else {
          return GlobalScaffold(
            body: Center(child: CircularProgressIndicator()),
          );
        }
      },
    );
  }
}
2个回答

1

keepScrollOffset: false

如果将此属性设置为false,则不会保存滚动偏移量,并且initialScrollOffset始终用于初始化滚动偏移量。


我使用了多个带有PageStorageKey的ListView。将keepScrollOffset设置为false解决了我的问题。 - undefined

0

这是因为该小部件已经构建在树上,因此initState不会再次为该小部件调用。

您可以重写didUpdateWidget方法,每次重建该小部件时都会触发它,并使其跳转到那里,例如。

@override
void didUpdateWidget(Widget old){
  super.didUpdateWidget(old);
  _scrollController.jumpTo(initialOffset);
}

不,不是这样的。也许我表达不清楚,但我并不是在重建小部件时尝试更新initialScrollOffset,而是从一个小部件Artiklar()的实例导航到另一个新的小部件Artiklar()的实例。我已经检查过,在进行此导航时,initState()按预期运行,并且initialScrollOffset似乎具有新值。但它没有正确更新常规偏移量。我无法理解发生了什么... - Rasmus Lian
我不确定我已经理解你想要实现的内容。所以,基本上,你正在创建一个新的小部件实例,并在该新实例中设置初始偏移量,但它没有到达那里?就是这样吗? - Miguel Ruivo
是的,就是这样,这就是奇怪的地方。 - Rasmus Lian

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接