当我更改选项卡时调用基于文本小部件的构建

Call build on Text widget when i change tab

当我从一个选项卡切换到另一个选项卡时,我想更改 appBar 中的标题。在我当前的代码中不要这样做,因为在更改选项卡上不会调用构建。

感谢大家!!

  

      import 'package:flutter/material.dart';
        import 'package:provider/provider.dart';
        
        import '../models/task.dart';
        import '../widgets/tasks_list_mob.dart';
        import '../widgets/new_task.dart';
        
        class TaskListName {
          final String shortName;
          final String longName;
          TaskListName(this.shortName, this.longName);
        }
        
        class TaksScreen extends StatefulWidget {
          @override
          _TaksScreenState createState() => _TaksScreenState();
        }
        
        class _TaksScreenState extends State with TickerProviderStateMixin {
          TabController _tabController;
          final Map tasksListLabels = {
            0: TaskListName('Backlog', 'Tasks in backlog'),
            1: TaskListName('Tomorrow', 'Planed tasks for tomorrow'),
            2: TaskListName('Today', 'Your tasks for today'),
            3: TaskListName('Last work day', 'Tasks completed last working day'),
            4: TaskListName('Completed', 'Completed Tasks'),
            5: TaskListName('Backlog', 'Archived not completed tasks'),
          };
        
          @override
          void initState() {
            super.initState();
            _tabController = TabController(length: 6, vsync: this, initialIndex: 2);
          }
        
          @override
          void dispose() {
            _tabController.dispose();
            super.dispose();
          }
        
          Future showAddTaskDialog(BuildContext context) async {
            print(_tabController);
            await showDialog(
              context: context,
              builder: (context) => SimpleDialog(
                children: [NewTask(TaksBucket.backlog)],
              ),
            );
          }
        
          @override
          Widget build(BuildContext context) {
            final tasks = Provider.of>(context);
            return Scaffold(
              appBar: AppBar(
                title: Text(tasksListLabels[_tabController.index].longName),
                bottom: TabBar(
                  controller: _tabController,
                  isScrollable: true,
                  tabs: [
                    Tab(text: tasksListLabels[0].shortName),
                    Tab(text: tasksListLabels[1].shortName),
                    Tab(text: tasksListLabels[2].shortName),
                    Tab(text: tasksListLabels[3].shortName),
                    Tab(text: tasksListLabels[4].shortName),
                    Tab(text: tasksListLabels[5].shortName),
                  ],
                ),
              ),
              body: TabBarView(
                controller: _tabController,
                children: [
                  TasksListMob(tasks, TaksBucket.backlog),
                  TasksListMob(tasks, TaksBucket.tomorrow),
                  TasksListMob(tasks, TaksBucket.today),
                  TasksListMob(tasks, TaksBucket.completed),
                  TasksListMob(tasks, TaksBucket.completed),
                  TasksListMob(tasks, TaksBucket.archived),
                ],
              ),
              floatingActionButton: FloatingActionButton(
                child: Icon(Icons.add),
                onPressed: () => showAddTaskDialog(context),
              ),
              floatingActionButtonLocation: FloatingActionButtonLocation.centerDocked,
            );
          }
        }
    
    

@mkobuolys 解决方案实施后 - 滚动手柄仍然缺失...


    import 'package:flutter/material.dart';
    import 'package:provider/provider.dart';
    
    import '../models/task.dart';
    import '../widgets/tasks_list_mob.dart';
    import '../widgets/new_task.dart';
    
    class TaskListName {
      final String shortName;
      final String longName;
      TaskListName(this.shortName, this.longName);
    }
    
    class TaksScreen extends StatefulWidget {
      @override
      _TaksScreenState createState() => _TaksScreenState();
    }
    
    class _TaksScreenState extends State with TickerProviderStateMixin {
      TabController _tabController;
      var _tabIndex = ValueNotifier(2);
      final Map tasksListLabels = {
        0: TaskListName('Backlog', 'Tasks in backlog'),
        1: TaskListName('Tomorrow', 'Planed tasks for tomorrow'),
        2: TaskListName('Today', 'Your tasks for today'),
        3: TaskListName('Last work day', 'Tasks completed last working day'),
        4: TaskListName('Completed', 'Completed Tasks'),
        5: TaskListName('Backlog', 'Archived not completed tasks'),
      };
    
      @override
      void initState() {
        super.initState();
        _tabController = TabController(length: 6, vsync: this, initialIndex: 2);
      }
    
      Future showAddTaskDialog(BuildContext context) async {
        await showDialog(
          context: context,
          builder: (context) => SimpleDialog(
            children: [NewTask(TaksBucket.backlog)],
          ),
        );
      }
    
      @override
      Widget build(BuildContext context) {
        final tasks = Provider.of>(context);
        return Scaffold(
          appBar: AppBar(
            title: **ValueListenableBuilder(
              valueListenable: _tabIndex,
              builder: (context, value, child) =>
                  Text(tasksListLabels[value].longName),
            ),**
            bottom: TabBar(
              controller: _tabController,
              isScrollable: true,
              onTap: (value) {
                _tabIndex.value = _tabController.index;
              },
              tabs: [
                Tab(text: tasksListLabels[0].shortName),
                Tab(text: tasksListLabels[1].shortName),
                Tab(text: tasksListLabels[2].shortName),
                Tab(text: tasksListLabels[3].shortName),
                Tab(text: tasksListLabels[4].shortName),
                Tab(text: tasksListLabels[5].shortName),
              ],
            ),
          ),
          body: TabBarView(
            controller: _tabController,
            children: [
              TasksListMob(tasks, TaksBucket.backlog),
              TasksListMob(tasks, TaksBucket.tomorrow),
              TasksListMob(tasks, TaksBucket.today),
              TasksListMob(tasks, TaksBucket.completed),
              TasksListMob(tasks, TaksBucket.completed),
              TasksListMob(tasks, TaksBucket.archived),
            ],
          ),
          floatingActionButton: FloatingActionButton(
            child: Icon(Icons.add),
            onPressed: () => showAddTaskDialog(context),
          ),
        );
      }
    }

最后真的很容易搞定!

TabBar 小部件中,使用 setState 方法添加 onTap 回调以触发重建,从而更新名称:

...
appBar: AppBar(
  title: Text(tasksListLabels[_tabController.index].longName),
  bottom: TabBar(
    controller: _tabController,
    isScrollable: true,
    tabs: [
      Tab(text: tasksListLabels[0].shortName),
      Tab(text: tasksListLabels[1].shortName),
      Tab(text: tasksListLabels[2].shortName),
      Tab(text: tasksListLabels[3].shortName),
      Tab(text: tasksListLabels[4].shortName),
      Tab(text: tasksListLabels[5].shortName),
    ],
    onTap: (_) {
      setState((){});
    },
  ),
),
...

您也可以在列表的帮助下切换标签页时使用相同的文本

您可以使用提供程序 make/view 更改而无需重建整个页面