状态栏点击底部导航中选定的选项卡后,颤动滚动到顶部

问题描述 投票:0回答:1

在 Flutter 中,我们可以通过将

PrimaryScrollController
从根
Scaffold
传递到
ScrollView
,在点击状态栏后滚动到顶部。但是,我的应用程序有一个带有 4 个选项卡的底部导航,每个选项卡都包含一个 ScrollView。当我点击状态栏时,所有 4 个选项卡都会滚动到顶部,但我只想滚动当前选定的选项卡。

按照这个帖子,似乎没有官方的方法可以做到这一点 https://github.com/flutter/flutter/issues/85603#issuecomment-876798161

是否有任何解决方法或替代方法可以在点击状态栏后仅将选定的选项卡滚动到顶部?

ios flutter
1个回答
0
投票

我不久前遇到了同样的问题,并提出了自己的解决方案。它可能不完全是您正在寻找的,但它对我来说非常有效。

这里是示例应用程序代码,您可以根据需要进行测试:

import 'package:flutter/material.dart';

void main() {
  runApp(const MyApp());
}

class MyApp extends StatelessWidget {
  const MyApp({super.key});

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Flutter Demo',
      theme: ThemeData(
        colorScheme: ColorScheme.fromSeed(seedColor: Colors.deepPurple),
        useMaterial3: true,
      ),
      home: const MyHomePage(title: 'Flutter Demo Home Page'),
    );
  }
}

class MyHomePage extends StatefulWidget {
  const MyHomePage({super.key, required this.title});

  final String title;

  @override
  State<MyHomePage> createState() => _MyHomePageState();
}

class _MyHomePageState extends State<MyHomePage> {
  int _currentIndex = 0;

  final ScrollController scrollController = ScrollController();
  List<double> offsets = [];

  @override
  void initState() {
    // Number of options in the bottomNavigationBar
    offsets.addAll([0, 0, 0]);
    super.initState();
  }

  final List<Widget> _pages = [
    SingleChildScrollView(
      child: Column(
        children: List.generate(
            20, (index) => ListTile(title: Text('Home Item $index'))),
      ),
    ),
    SingleChildScrollView(
      child: Column(
        children: List.generate(
            20, (index) => ListTile(title: Text('Search Item $index'))),
      ),
    ),
    SingleChildScrollView(
      child: Column(
        children: List.generate(
            20, (index) => ListTile(title: Text('Profile Item $index'))),
      ),
    ),
  ];

  void _scrollToTop() {
    scrollController.jumpTo(0);
  }

  void _onTabTapped(int index) {
    // Select the offset for the selected page
    offsets[_currentIndex] = scrollController.offset;
    setState(() {
      _currentIndex = index;
      scrollController.jumpTo(offsets[index]);
    });
  }

  @override
  Widget build(BuildContext context) {
    return PrimaryScrollController(
      controller: scrollController,
      child: Scaffold(
        appBar: AppBar(
          title: Text('BottomNavigationBar + Scroll'),
        ),
        body: _pages[_currentIndex],
        bottomNavigationBar: BottomNavigationBar(
          currentIndex: _currentIndex,
          onTap: _onTabTapped,
          items: [
            BottomNavigationBarItem(
              icon: Icon(Icons.home),
              label: 'Home',
            ),
            BottomNavigationBarItem(
              icon: Icon(Icons.search),
              label: 'Search',
            ),
            BottomNavigationBarItem(
              icon: Icon(Icons.person),
              label: 'Profile',
            ),
          ],
        ),
        floatingActionButton: Column(
          mainAxisAlignment: MainAxisAlignment.end,
          children: [
            FloatingActionButton(
              onPressed: _scrollToTop,
              child: Icon(Icons.arrow_upward),
              tooltip: 'Scroll to Top',
            ),
          ],
        ),
      ),
    );
  }
}
© www.soinside.com 2019 - 2024. All rights reserved.