正如上面的标题,我希望我向下滚动的页面在按下底部导航栏(双击)时向上滚动.我成功了,没问题.但是,如果页面上有一个包含选项卡栏的选项,则会出现问题.


例如

HomePageProfilePage


在主页上

FirstTabBarViewSecondTabBarView


问题是当我向下滚动这两个页面时(主页和档案页面位于不同的位置)

这只是一个简单的代码示例,您可以复制粘贴并直接在dart pad上测试它

import 'package:flutter/material.dart';

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

class MyApp extends StatelessWidget {
  const MyApp({Key? key}) : super(key: key);

  static const String _title = 'Flutter Code Sample';

  @override
  Widget build(BuildContext context) {
    return const MaterialApp(
      title: _title,
      home: MyStatefulWidget(),
    );
  }
}

class MyStatefulWidget extends StatefulWidget {
  const MyStatefulWidget({Key? key}) : super(key: key);

  @override
  State<MyStatefulWidget> createState() => _MyStatefulWidgetState();
}

class _MyStatefulWidgetState extends State<MyStatefulWidget> {
  final ScrollController _firstTabBarScrollController = ScrollController();
  final ScrollController _secondTabBarScrollController = ScrollController();
  List<Widget> _widgetOptions = <Widget>[];
  int _selectedIndex = 0;
  
  @override
  void initState(){
    _widgetOptions = <Widget>[
      MyHomePage(
        firstTabBarScrollController: _firstTabBarScrollController, 
        secondTabBarScrollController: _secondTabBarScrollController,
        title: "Home Page",
      ),
      Text('Profile'),
    ];
  }


  void _onItemTapped(int index) {
    setState(() {
      _selectedIndex = index;
    });
    if(index == 0 && _firstTabBarScrollController.hasClients){
       _firstTabBarScrollController.animateTo(0,
            duration: const Duration(milliseconds: 500), curve: Curves.easeOut,);
    }
    
    if(index == 0 && _secondTabBarScrollController.hasClients){
       _secondTabBarScrollController.animateTo(0,
            duration: const Duration(milliseconds: 500), curve: Curves.easeOut,);
    }
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: Center(
        child: _widgetOptions.elementAt(_selectedIndex),
      ),
      bottomNavigationBar: BottomNavigationBar(
        items: const <BottomNavigationBarItem>[
          BottomNavigationBarItem(
            icon: Icon(Icons.home),
            label: 'Home',
          ),
          BottomNavigationBarItem(
            icon: Icon(Icons.business),
            label: 'Profile',
          ),
        ],
        currentIndex: _selectedIndex,
        selectedItemColor: Colors.amber[800],
        onTap: _onItemTapped,
      ),
    );
  }
}

class MyHomePage extends StatefulWidget{
  final ScrollController firstTabBarScrollController;
  final ScrollController secondTabBarScrollController;
  final String title;

  const MyHomePage({
    Key? key,
    required this.title,
    required this.firstTabBarScrollController,
    required this.secondTabBarScrollController,
  }) : super(key: key);

  @override
  _MyHomePageState createState() => _MyHomePageState();
}

class _MyHomePageState extends State<MyHomePage> with TickerProviderStateMixin {
  late TabController _tabController;
  
  @override
  void initState() {
    super.initState();
    _tabController = TabController(length: 2, vsync: this);
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text(widget.title),
        bottom: TabBar(
          controller: _tabController,
          tabs: const <Widget>[
            Tab(
              icon: Icon(Icons.cloud_outlined),
            ),
            Tab(
              icon: Icon(Icons.beach_access_sharp),
            ),
          ],
        ),
      ),
      body: TabBarView(
        controller: _tabController,
        children: <Widget>[
          FirstTabBarView(firstTabScrollController: widget.firstTabBarScrollController),
          SecondTabBarView(secondTabScrollController: widget.secondTabBarScrollController),
        ],
      ),
    );
  }
}

class FirstTabBarView extends StatefulWidget{
  final ScrollController firstTabScrollController;

  const FirstTabBarView({
    Key? key,
    required this.firstTabScrollController,
  }) : super(key: key);

  @override
  _FirstTabBarView createState() => _FirstTabBarView();
}

class _FirstTabBarView extends State<FirstTabBarView> with AutomaticKeepAliveClientMixin<FirstTabBarView> {
 
  @override
  Widget build(BuildContext context) {
    super.build(context);
    return Scaffold(
      body: ListView.builder(
        controller: widget.firstTabScrollController,
        itemCount: 1000,
        itemBuilder: (context, index) {
          return ListTile(
            title: Text('$index'),
          );
        },
      ),
    );
  }
  
  @override
  bool get wantKeepAlive => true;
}


class SecondTabBarView extends StatefulWidget{
  final ScrollController secondTabScrollController;

  const SecondTabBarView({
    Key? key,
    required this.secondTabScrollController,
  }) : super(key: key);

  @override
  _SecondTabBarView createState() => _SecondTabBarView();
}

class _SecondTabBarView extends State<SecondTabBarView> with AutomaticKeepAliveClientMixin<SecondTabBarView> {
 
  @override
  Widget build(BuildContext context) {
    super.build(context);
    return Scaffold(
      backgroundColor: Colors.yellow,
      body: ListView.builder(
        controller: widget.secondTabScrollController,
        itemCount: 1000,
        itemBuilder: (context, index) {
          return ListTile(
            title: Text('$index'),
          );
        },
      ),
    );
  }
  
  @override
  bool get wantKeepAlive => true;
}

注:例如上述代码的情况

  1. 向下滚动第一个选项卡BarView,

  2. 打开第二个TabBarView,然后向下滚动第二个TabBarView,

  3. 双击Home Icon按钮

  4. You will notice that both the FirstTabBarViewSecondTabBarView pages will scroll up. What I want is only the currently open page to scroll to the top (one of them).

推荐答案

您必须将TabController和ScrollController一起抬起.然后使用TabController的索引获取程序判断当前打开的选项卡.

TabController _tabController = TabController(length: 2, vsync: this);

if(index == 0 && _tabController.index == 0){

   //Scroll up the first scroll controller

}

if(index == 0 && _tabController.index == 1){

  //Scroll up the second scroll controller
}

Flutter相关问答推荐

如何在SingleChildScrollView中使用GridView

Flutter -修改子小部件中的AppBar

如何刷新future 的构建器时,没有OBS变量的内部在Ffltter?

为什么Build_Runner的输出为0?

Flutter 翼future 建造者不断开火和重建.它在每次重建时都会生成一个新的随机数--我如何防止这种情况?

Android Studio将不会构建iOS模拟器应用程序,因为plist.info有问题

与FTPS连接时出现Flutter FTPConnect HandshakeException错误

如何从RealmResults获取Flutter Flutter 流?

Flutter 数独网格

摆动更改标记可轻敲文本按钮样式

Flutter:无法构建iOS应用程序-找不到PigeonParser.h文件

Flutter-Riverpod:如何只从提供者读取一次值

如何在Dart中允许正则表达式中有一个空格,但允许其他字符为1或更多?

Flutter Xcode 15 错误(Xcode):DT_TOOLCHAIN_DIR 无法用于判断 LIBRARY_SEARCH_PATHS

打开键盘时屏幕组件会被压扁

NotifierProvider 每次更新都会重新构建并且值不更新

如何使Flutter 边框宽度在外面而不是在里面?

从所有设备注销,因为用户帐户已从 firebase flutter 中删除

如何在 Flutter 中使用 drawLine() 和 drawCircle() 绘制等距离的 4 条线

我无法从 Cloud firestore 访问文档字段并在 statefulwidget 类中显示它