首页 > 解决方案 > Flutter:通过 NavigationBar 更改子项中的滚动偏移量

问题描述

我目前有一个主页,它由一个Scaffold, 和一个bottomAppBar用于导航的:

导航栏

body 有 5 页,第一页是 feed,它由一个ListViewWidgets 组成。我想做的和 Instagram 一样:当我向下滚动提要并单击导航栏上的提要按钮时,我希望它ListView自动滚动回顶部。

这是我的代码的一部分:

class HomePage extends StatefulWidget {
  @override
  _HomePageState createState() => _HomePageState();
}

class _HomePageState extends State<HomePage> with WidgetsBindingObserver {
  int _selectedIndex = 0;
  
  @override
  Widget build(BuildContext context) {
  return Scaffold(
    body: [
      HomeFeed(),
      Page2(),
      ...
      ].elementAt(_selectedIndex),
      
    bottomNavigationBar: BottomAppBar(
      child: Row(
        children: <Widget>[
          IconButton(
            icon: FaIcon(FontAwesomeIcons.houseUser),
            onPressed: (){
              if (_selectedIndex == 0) {
                //add logic to make the HomeFeed ListView scroll up
              } else {
                 setState((){
                   _selectedIndex = 0;
                 });
              }
            },
          IconButton(
            icon: FaIcon(FontAwesomeIcons.compass),
            onPressed: (){
              setState((){
                _selectedIndex = 1;
              });
            },
          ...
         ],
        ),
       ),  //BottomAppBar
       
    ), //Scaffold  
       
    }
   

我知道如果我在里面有 HomeFeed 的代码,Scaffold.body那么我可以只使用 aScrollcontrolleranimateTo方法。问题是 Homefeed 是另一个有状态的小部件,即使在单击提要图标时调用了 setState,HomeFeed 小部件也不会重建。我尝试Scrollcontroller在主页中定义 a 并将其传递给 HomeFeed,但它不起作用。

任何人都可以帮助我吗?

标签: flutter

解决方案


您可以为小部件GlobalKey的状态设置一个HomeFeed。使用它GlobalKey,您可以调用HomeFeed小部件状态的功能。

主要代码:

  GlobalKey<HomeFeedState> feedKey = new GlobalKey<HomeFeedState>(); // this is new

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: [
        HomeFeed(key: feedKey), // this is new
        Page3(),
      ].elementAt(_selectedIndex),
      bottomNavigationBar: BottomAppBar(
        child: Row(
          children: <Widget>[
            IconButton(
              icon: FaIcon(FontAwesomeIcons.houseUser),
              onPressed: (){
                if (_selectedIndex == 0) {
                  feedKey.currentState.jumpUp(); // this is new
                } else {
                  setState(() {
                    _selectedIndex = 0;
                  });
                }
              },
            ),
            IconButton(
              icon: FaIcon(FontAwesomeIcons.compass),
              onPressed: (){
                setState(() {
                  _selectedIndex = 1;
                });
              },
            ),
          ],
        ),
      ), //BottomAppBar
    );
  }

主页:

class HomeFeed extends StatefulWidget {
  final GlobalKey<HomeFeedState> key; // this is new
  HomeFeed({this.key}) : super(key: key); // this is new
  @override
  HomeFeedState createState() => HomeFeedState();
}

class HomeFeedState extends State<HomeFeed> {
  var _scrollController = new ScrollController();

  jumpUp() { // this will be called when tapped on the home icon
    _scrollController.animateTo(0,
        duration: Duration(seconds: 2), curve: Curves.ease);
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: ListView.builder(
        shrinkWrap: true,
        controller: _scrollController,
        itemCount: 100,
        itemBuilder: (context, index) {
          return Container(
            height: 300,
            child: Card(
              child: Center(
                child: Text('$index'),
              ),
            ),
          );
        },
      ),
    );
  }
}

推荐阅读