5

I'm trying to initialize a SingleChildScrollView to start at a certain position with a custom ScrollController. I thought I could use initialScrollOffset and set an initial value in the init method. But somehow when the SingleChildScrollView renders, it only jumps to initialOffset at first build, then when I navigate to another instance of this Widget it doesn't jump to the initialOffset position.

I don't know why, and if I'm lucky maybe one of you have the answer.

Here's my code:

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 Answers 2

1

keepScrollOffset: false

If this property is set to false, the scroll offset is never saved and initialScrollOffset is always used to initialize the scroll offset.

Sign up to request clarification or add additional context in comments.

1 Comment

I used multiple listviews with PageStorageKey. Set keepScrollOffset to false solved my problem.
0

That's because that widget is already built on the tree and thus, initState won't be called again for that widget.

You can override the didUpdateWidget method that will trigger each time that widget is rebuilt and make it jump on there, for example.

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

3 Comments

No, that's not it. Maybe I was unclear, but I'm not trying to update initialScrollOffset when rebuilding a widget, I'm navigating from one instance of the widget Artiklar() to another, new, instance of the widget Artiklar(). I've checked and the initState() is run as expected when doing this navigation, and the initialScrollOffset seems to have the new value. But it doesn't update correctly the regular offset. I can't grasp what's going on...
I'm not sure I have already got what you are trying to achieve. So, basically, you are creating a new widget instance and in that new instance, you are also setting the initial offset and it doesn't go to there? Is that it?
Yeah, that's it, and that's the weird part.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.