I want to change the title in AppBar, when when I switch from one tab to another. In my current code do not do that because on the 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<TaksScreen> with TickerProviderStateMixin {
TabController _tabController;
final Map<int, TaskListName> 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<void> 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<List<Task>>(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 - the scroll handle is still missing.
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<TaksScreen> with TickerProviderStateMixin {
TabController _tabController;
var _tabIndex = ValueNotifier(2);
final Map<int, TaskListName> 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<void> showAddTaskDialog(BuildContext context) async {
await showDialog(
context: context,
builder: (context) => SimpleDialog(
children: [NewTask(TaksBucket.backlog)],
),
);
}
@override
Widget build(BuildContext context) {
final tasks = Provider.of<List<Task>>(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!
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<TaksScreen> with TickerProviderStateMixin {
TabController _tabController;
var _tabIndex = ValueNotifier(2);
final Map<int, TaskListName> 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<void> 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<List<Task>>(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),
),
);
}
}
Inside the TabBar
widget, add onTap
callback with the setState
method to trigger rebuild, hence updating the name:
...
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((){});
},
),
),
...