I want to change title in appBar, when when I switch from one tab to another. In my current code do not do that because on change tab build is not called.
Thanks to all!!
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, ); } }
After @mkobuolys solution implementation - scroll handle is still missinng...
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), ), ); } }
At the end it was really easy to make it done!
I did create ValueNotifier _tabIndex
At init state I addListener on TabControler. Listener set value for _tabIndex(ValueNotifier). I did dispose Listener in dispose...
In build method add ValueListenableBuilder to title.
Final code:
import 'package:flutter/material.dart'; import 'package:provider/provider.dart'; import '../models/task.dart'; import '../widgets/tasks_list_mob.dart'; import './tasks_notifications_screen.dart'; import '../widgets/new_task.dart'; import '../widgets/count_batch_icon_button.dart'; import '../consts/consts.dart'; import '../util/tasks_helper.dart'; class TaskListName { final String shortName; final String longName; final TaksBucket bucket; TaskListName(this.shortName, this.longName, this.bucket); } 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', TaksBucket.backlog), 1: TaskListName( 'Tomorrow', 'Planed tasks for tomorrow', TaksBucket.tomorrow), 2: TaskListName('Today', 'Your tasks for today', TaksBucket.today), 3: TaskListName('Last work day', 'Tasks completed last working day', TaksBucket.completed), 4: TaskListName('Completed', 'Completed Tasks', TaksBucket.completed), 5: TaskListName( 'Archived', 'Archived not completed tasks', TaksBucket.archived), }; @override void initState() { super.initState(); _tabController = TabController(length: 6, vsync: this, initialIndex: 2); _tabController.addListener(() { _tabIndex.value = _tabController.index; }); } @override void dispose() { super.dispose(); _tabController.removeListener(() { _tabIndex.value = _tabController.index; }); } Future showAddTaskDialog(BuildContext context) async { await showDialog( context: context, builder: (context) => SimpleDialog( children: [NewTask(tasksListLabels[_tabController.index].bucket)], ), ); } @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), ), actions: [ CountBatchIconButton( TasksHelper.numberOfTasksForNotification(tasks), Icon(Icons.notifications_none), () => Navigator.of(context).pushNamed(TasksNotifications.routeName), ), ], bottom: TabBar( controller: _tabController, isScrollable: true, indicatorColor: TaskConsts.mainColor, 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, isLastWorkingDay: true, ), TasksListMob(tasks, TaksBucket.completed), TasksListMob(tasks, TaksBucket.archived), ], ), floatingActionButton: FloatingActionButton( backgroundColor: TaskConsts.mainColor, child: Icon(Icons.add), onPressed: () => showAddTaskDialog(context), ), ); } }