I'm developing an App for TV by Flutter.
I need to detect the focus change event of TabBar child, how can I do that? This is a sample code:
import 'package:flutter/material.dart';
import 'package:flutter/widgets.dart';
class TabBarSample extends StatefulWidget {
const TabBarSample({Key? key}) : super(key: key);
@override
State<TabBarSample> createState() => _TabBarSampleState();
}
class _TabBarSampleState extends State<TabBarSample>
with TickerProviderStateMixin{
late TabController _tabController;
final _tabs = ['Tab 01','Tab 02','Tab 03','Tab 04','Tab 05','Tab 06','Tab 07','Tab 08'];
@override
Widget build(BuildContext context) {
_tabController = TabController(length: _tabs.length, vsync: this);
return Scaffold(
body: Center(
child: Container(
child: TabBar(
labelColor: Colors.blue,
labelStyle: TextStyle(color: Colors.blue, fontSize: 36),
unselectedLabelColor: Colors.black54,
unselectedLabelStyle: TextStyle(color: Colors.black, fontSize: 36),
isScrollable: true,
indicator: BoxDecoration(
color: Colors.greenAccent,
borderRadius: BorderRadius.all(Radius.circular(12))),
controller: _tabController,
// onTap: _changeTab,
tabs: _tabs.map((e) => Tab(
height: 36,
text: e)).toList(),
)
),
)
);
}
}
In this screenshot, how can I know 'Tab 06' is focused?
Thank you.
Update:
I changed the child of TabBar from Tab
widget to Focus
Widget, and tried to do something in the child's onFocusChange
callback,like this:
import 'package:flutter/material.dart';
import 'package:flutter/widgets.dart';
class TabBarFocusSample extends StatefulWidget {
const TabBarFocusSample({Key? key}) : super(key: key);
@override
State<TabBarFocusSample> createState() => _TabBarFocusSampleState();
}
class _TabBarFocusSampleState extends State<TabBarFocusSample>
with TickerProviderStateMixin{
late TabController _tabController;
final _tabs = ['Tab 01','Tab 02','Tab 03','Tab 04','Tab 05','Tab 06','Tab 07','Tab 08'];
@override
Widget build(BuildContext context) {
_tabController = TabController(length: _tabs.length, vsync: this);
return Scaffold(
body: Center(
child: Container(
child: TabBar(
labelColor: Colors.blue,
labelStyle: TextStyle(color: Colors.blue, fontSize: 36),
unselectedLabelColor: Colors.black54,
unselectedLabelStyle: TextStyle(color: Colors.black, fontSize: 36),
isScrollable: true,
indicator: BoxDecoration(
color: Colors.greenAccent,
borderRadius: BorderRadius.all(Radius.circular(12))),
controller: _tabController,
// onTap: _changeTab,
tabs: _tabs.map((e) => Focus(
onFocusChange: (focused) {
print('tab onFocusChange,$focused, ${e}');
if (focused) {
_changeTabByCode(e);
}
},
child: Tab(text: e,height: 40,))).toList(),
)
),
)
);
}
void _changeTabByCode(String pageCode) {
print("_changeTabByCode,$pageCode");
var navIndex = _tabs.indexWhere((element) => element == pageCode)?? 0;;
_tabController.animateTo(navIndex, duration: const Duration(microseconds: 300), curve: Curves.ease);
}
}
but there's a new problem, the onFocusChange
function won't be called sometimes.
In this screenshot, I can't animateTo
tab01 by arrow key.
===================== update:
change Focus
to FocusableActionDetector
, the same result, like this:
CodePudding user response:
I belive if you use FocusableActionDetector you can solve this problem
CodePudding user response:
You can use a TabController and add a callback using addListener. For example:
@override
void initState() {
super.initState();
_tabController = TabController(vsync: this, length: myTabs.length);
_tabController.addListener(_handleTabSelection);
}
void _handleTabSelection() {
if (_tabController.indexIsChanging) {
switch (_tabController.index) {
case 0:
Scaffold.of(_context).showSnackBar(SnackBar(
content: Text('Page 1 tapped.'),
duration: Duration(milliseconds: 500),
));
break;
case 1:
Scaffold.of(_context).showSnackBar(SnackBar(
content: Text('Page 2 tapped.'),
duration: Duration(milliseconds: 500),
));
break;
}
}
}