如何在flutter web中滚动到SingleChildScrollView内的小部件?

时间:2021-02-03 12:33:33

标签: flutter scroll flutter-web

我正在做一个 Flutter 网络项目。

当用户点击一个项目时,我需要主 SingleChildScrollView 向下滚动到特定的小部件。

我该怎么做?

1 个答案:

答案 0 :(得分:0)

要滚动到特定的小部件,您主要需要两件事:

1- 目标小部件的位置。这可以通过获取小部件的 RenderBox 来实现(您需要先使用 GlobalKey 引用它)。

2- 分配给您的 SingleChildScrollView 的 ScrollController

在下面的示例中,您将找到 3 个垂直滚动主 SingleChildScrollView 的按钮(我也在网络中对其进行了测试,并且可以正常工作)。

import 'package:flutter/material.dart';

void main() {
  runApp(MaterialApp(
      home: MyApp()));
}

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

class _MyAppState extends State<MyApp> {
  ScrollController scrollController;
  GlobalKey _keyGreen = GlobalKey();
  GlobalKey _keyOrange = GlobalKey();
  GlobalKey _keyIndigo = GlobalKey();
  double _containerHeight = 400;

  @override
  void initState() {
    scrollController = ScrollController();
    super.initState();
  }

  @override
  Widget build(BuildContext context) {
    return SingleChildScrollView(
          controller: scrollController,
          child: SafeArea(
            child: Column(
              children: [
                Row(
                  children: [
                    ElevatedButton(
                      onPressed: () {
                        Offset _offset = _getPositions(_keyGreen);
                        scrollController.animateTo(_offset.dy, duration: Duration(milliseconds: 500), curve: Curves.ease);
                      },
                      child: Text("Go green"),
                    ),
                    ElevatedButton(
                      onPressed: () {
                        Offset _offset = _getPositions(_keyOrange);
                        scrollController.animateTo(_offset.dy, duration: Duration(milliseconds: 500), curve: Curves.ease);
                      },
                      child: Text("Go orange"),
                    ),
                    ElevatedButton(
                      onPressed: () {
                        Offset _offset = _getPositions(_keyIndigo);
                        scrollController.animateTo(_offset.dy, duration: Duration(milliseconds: 500), curve: Curves.ease);
                      },
                      child: Text("Go indigo"),
                    ),
                  ],
                ),
                Container(
                  color: Colors.lightBlue,
                  height: _containerHeight,
                ),
                Container(
                  color: Colors.blue,
                  height: _containerHeight,
                ),
                Container(
                  color: Colors.lightGreen,
                  height: _containerHeight,
                  key: _keyGreen,
                ),
                Container(
                  color: Colors.yellow,
                  height: _containerHeight,
                ),
                Container(
                  color: Colors.orange,
                  height: _containerHeight,
                  key: _keyOrange,
                ),
                Container(
                  color: Colors.redAccent,
                  height: _containerHeight,
                ),
                Container(
                  color: Colors.pink,
                  height: _containerHeight,
                ),
                Container(
                  color: Colors.indigoAccent,
                  height: _containerHeight,
                ),
                Container(
                  color: Colors.indigo,
                  height: _containerHeight,
                  key: _keyIndigo,
                ),
              ],
            ),
          ),
        );
  }

  Offset _getPositions(GlobalKey key) {
    RenderBox renderBoxRed = key.currentContext.findRenderObject();
    renderBoxRed.localToGlobal(Offset.zero);
    return renderBoxRed.localToGlobal(Offset.zero);
  }

}