首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >如何在颤振中动态添加和删除制表符?

如何在颤振中动态添加和删除制表符?
EN

Stack Overflow用户
提问于 2022-08-22 17:38:21
回答 1查看 118关注 0票数 0

我试图在TabBar中动态添加和删除制表符,但是当添加选项卡会抛出异常时,它通常会工作。我想我做错了什么,但是并不明显--如果标签是静态定义的,一切都很好,当动态添加时,我执行以下两个步骤:

  1. I更新模型(TabsConfig类)
  2. i通过setState.

触发UI更新

该选项卡是可视化的,但是在控制台中有下面的例外:

代码语言:javascript
复制
═══════ Exception caught by widgets library ═══════════════════════════════════
The following assertion was thrown building TabBar(dirty, dependencies: [_LocalizationsScope-[GlobalKey#f57c6], _TabControllerScope, _InheritedTheme, Directionality], state: _TabBarState#cf630):
Controller's length property (4) does not match the number of tabs (3) present in TabBar's tabs property.

The relevant error-causing widget was
TabBar
lib\main.dart:317
When the exception was thrown, this was the stack
#0      _TabBarState.build.<anonymous closure>
package:flutter/…/material/tabs.dart:1159
#1      _TabBarState.build
package:flutter/…/material/tabs.dart:1165
#2      StatefulElement.build
package:flutter/…/widgets/framework.dart:4919
#3      ComponentElement.performRebuild
package:flutter/…/widgets/framework.dart:4806
#4      StatefulElement.performRebuild
package:flutter/…/widgets/framework.dart:4977
#5      Element.rebuild
package:flutter/…/widgets/framework.dart:4529
#6      BuildOwner.buildScope
package:flutter/…/widgets/framework.dart:2659
#7      WidgetsBinding.drawFrame
package:flutter/…/widgets/binding.dart:891
#8      RendererBinding._handlePersistentFrameCallback
package:flutter/…/rendering/binding.dart:370
#9      SchedulerBinding._invokeFrameCallback
package:flutter/…/scheduler/binding.dart:1146
#10     SchedulerBinding.handleDrawFrame
package:flutter/…/scheduler/binding.dart:1083
#11     SchedulerBinding._handleDrawFrame
package:flutter/…/scheduler/binding.dart:997
#15     _invoke (dart:ui/hooks.dart:151:10)
#16     PlatformDispatcher._drawFrame (dart:ui/platform_dispatcher.dart:308:5)
#17     _drawFrame (dart:ui/hooks.dart:115:31)
(elided 3 frames from dart:async)
════════════════════════════════════════════════════════════════════════════════

下面是代码的简化版本:

代码语言:javascript
复制
import 'package:flutter/material.dart';

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

class TabsConfig {
  static List<String> tabs = [];
  static int selectedTabIndex = 0;
}

class MyApp extends MaterialApp {
  MyApp({Key? key})
      : super(
          key: key,
          home: const MainWidget(),
        );
}

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

  @override
  State<MainWidget> createState() => MainWidgetState();
}

class MainWidgetState extends State<MainWidget>
    with SingleTickerProviderStateMixin {
  void updateTabs() {
    try {
      setState(() {});
    } catch (on) {
      print(on); // TODO: rem
    }
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: DefaultTabController(
        length: TabsConfig.tabs.length,
        initialIndex: TabsConfig.selectedTabIndex,
        child: CustomScrollView(
          slivers: <Widget>[
            getSliverTabBar(),
          ],
        ),
      ),
      floatingActionButton: FloatingActionButton(
        child: Icon(Icons.add),
        onPressed: () {
          TabsConfig.tabs.add('New tab');
          updateTabs();
        },
      ),
    );
  }

  Widget getSliverTabBar() {
    print('tabs: ${TabsConfig.tabs.length}'); //TODO: rem

    return SliverAppBar(
      pinned: true,
      backgroundColor: Colors.blue,
      title: Align(
        alignment: AlignmentDirectional.topStart,
        child: TabBar(
          indicatorColor: Colors.white,
          isScrollable: true,
          onTap: ((int selected) {
            TabsConfig.selectedTabIndex = selected;
          }),
          tabs: TabsConfig.tabs
              .map(
                (e) => Tab(text: e),
              )
              .toList(),
        ),
      ),
    );
  }
}

有什么想法可以让它发挥作用,或者是什么原因?谢谢!

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2022-08-22 18:59:20

要动态生成选项卡,您可能必须使用自定义控制器,使用TickerProviderStateMixin代替SingleTickerProver,并在更新屏幕时更新控制器。做了个演示,让你开始

代码语言:javascript
复制
import 'package:flutter/material.dart';

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

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Flutter Demo',
      home: MainWidget(),
    );
  }
}

class TabsConfig {
  static List<String> tabs = [];
  static int selectedTabIndex = 0;
}

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

  @override
  State<MainWidget> createState() => MainWidgetState();
}

class MainWidgetState extends State<MainWidget> with TickerProviderStateMixin {
  late TabController controller;
  @override
  void initState() {
    // TODO: implement initState
    controller = TabController(
      length: TabsConfig.tabs.length,
      vsync: this,
      initialIndex: TabsConfig.selectedTabIndex,
    );
    super.initState();
  }

  void updateTabs() {
    try {
      controller = TabController(
        length: TabsConfig.tabs.length,
        vsync: this,
        initialIndex: TabsConfig.selectedTabIndex,
      );
      setState(() {});
    } catch (on) {
      print(on); // TODO: rem
    }
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: SafeArea(
        child: Column(
          children: <Widget>[
            TabBar(
              isScrollable: true,
              controller: controller,
              labelColor: Theme.of(context).primaryColor,
              unselectedLabelColor: Theme.of(context).hintColor,
              indicator: BoxDecoration(
                border: Border(
                  bottom: BorderSide(
                    color: Theme.of(context).primaryColor,
                    width: 2,
                  ),
                ),
              ),
              tabs: List.generate(
                TabsConfig.tabs.length,
                (index) => Text("${TabsConfig.tabs[index]}"),
              ),
            ),
            Expanded(
              child: TabBarView(
                controller: controller,
                children: List.generate(
                  TabsConfig.tabs.length,
                  (index) => Center(
                    child: Text("${TabsConfig.tabs[index]}"),
                  ),
                ),
              ),
            ),
          ],
        ),
      ),
      floatingActionButton: FloatingActionButton(
        child: Icon(Icons.add),
        onPressed: () {
          TabsConfig.tabs.add('New tab ${TabsConfig.tabs.length}');
          // setState(() {});
          updateTabs();
        },
      ),
    );
  }
}
票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/73449029

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档