Flutter tabController 监听器滑动时响应缓慢

Pro*_*tic 11 flutter

我有一个变量“currentTabName”来指示 tabPage 的名称。当切换选项卡时,会触发tablistener更新变量和setstate。如果通过单击选项卡栏来切换选项卡,它将立即更新,但是当我通过滑动切换选项卡时遇到了麻烦。执行侦听器操作似乎存在延迟。

这是在 initstate 中添加的侦听器的示例代码。

void _tabListener(){
   currentTabName = tabPage.name;
   setState((){});

}
Run Code Online (Sandbox Code Playgroud)

小智 7

您可以在 tabController.animation 上使用侦听器,这将在拖动手势开始时立即触发。请参阅我使用它来更改选项卡栏图标的示例。一旦执行了必要的拖动的一半,它就会改变,如果反向拖动,它就会变回来。当用户点击选项卡栏图标时,它也会发生变化,从而产生更多的 if else 子句和布尔值。

class _TabTestState extends State<TabTest> with SingleTickerProviderStateMixin {
  late TabController _tabController;
  bool _swipeIsInProgress = false;
  bool _tapIsBeingExecuted = false;
  int _selectedIndex = 1;
  int _prevIndex = 1;

  @override
  void initState() {
    super.initState();
    _tabController = TabController(initialIndex: _selectedIndex, length: 3, vsync: this);
    _tabController.animation?.addListener(() {
      if (!_tapIsBeingExecuted &&
          !_swipeIsInProgress &&
          (_tabController.offset >= 0.5 || _tabController.offset <= -0.5)) {
        // detects if a swipe is being executed. limits set to 0.5 and -0.5 to make sure the swipe gesture triggered
        log("swipe  detected");
        int newIndex = _tabController.offset > 0 ? _tabController.index + 1 : _tabController.index - 1;
        _swipeIsInProgress = true;
        _prevIndex = _selectedIndex;
        setState(() {
          _selectedIndex = newIndex;
        });
      } else {
        if (!_tapIsBeingExecuted &&
            _swipeIsInProgress &&
            ((_tabController.offset < 0.5 && _tabController.offset > 0) ||
                (_tabController.offset > -0.5 && _tabController.offset < 0))) {
          // detects if a swipe is being reversed. the
          log("swipe reverse detected");
          _swipeIsInProgress = false;
          setState(() {
            _selectedIndex = _prevIndex;
          });
        }
      }
    });
    _tabController.addListener(() {
      _swipeIsInProgress = false;
      setState(() {
        _selectedIndex = _tabController.index;
      });
      if (_tapIsBeingExecuted == true) {
        _tapIsBeingExecuted = false;
      } else {
        if (_tabController.indexIsChanging) {
          // this is only true when the tab is changed via tap
          _tapIsBeingExecuted = true;
        }
      }
    });
  }

  @override
  void dispose() {
    super.dispose();
    _tabController.dispose();
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: const Text('Tabs Demo'),
      ),
      bottomNavigationBar: TabBar(
        controller: _tabController,
        tabs: [
          Icon(_selectedIndex == 0 ? Icons.directions_car : Icons.directions_car_outlined),
          Icon(_selectedIndex == 1 ? Icons.directions_transit : Icons.directions_transit_outlined),
          Icon(_selectedIndex == 2 ? Icons.directions_bike : Icons.directions_bike_outlined),
        ],
      ),
      body: TabBarView(
        controller: _tabController,
        children: const [
          Tab(icon: Icon(Icons.directions_car)),
          Tab(icon: Icon(Icons.directions_transit)),
          Tab(icon: Icon(Icons.directions_bike)),
        ],
      ),
    );
  }
}
Run Code Online (Sandbox Code Playgroud)


Imr*_* Sk -4

不需要监听当前选项卡,只需在 tabBarView 中以这种方式使用它即可。它将消除缓慢的问题

body: TabBarView(
      children: [CricketScreen(), FootballScreen()],
    ),
Run Code Online (Sandbox Code Playgroud)