更改徽章编号
Posted
技术标签:
【中文标题】更改徽章编号【英文标题】:Change badge number 【发布时间】:2020-01-11 18:15:49 【问题描述】:在 MainPage 中,它有 2 个底部导航栏。一个是带有文字的图标,另一个是带有文字和徽章编号的图标。当我的应用程序启动时,徽章在第二个选项卡中显示为 3。这很好用。
class MainPage extends StatefulWidget
@override
State<StatefulWidget> createState()
return _MainPageState();
method(int num) => _MainPageState().showBadge(num);
class _MainPageState extends State<MainPage>
with SingleTickerProviderStateMixin
int _selectedIndex = 0;
int count = 0;
TabController _tabController;
PageController _pageController;
@override
void initState()
super.initState();
_tabController = TabController(length: 5, vsync: this);
_pageController = PageController(initialPage: _selectedIndex);
showBadge(3);
void showBadge(int number)
setState(()
count = number;
);
void onPageChange(int index)
setState(()
_selectedIndex = index;
);
void _onItemTapped(int index)
_pageController.animateToPage(index,
duration: kTabScrollDuration, curve: Curves.ease);
@override
Widget build(BuildContext context)
return WillPopScope(
child: Scaffold(
body: FixTabBarView(
pageController: _pageController,
onPageChange: onPageChange,
tabController: _tabController,
children: <Widget>[
TabA(),
TabB(),
]),
bottomNavigationBar: BottomNavigationBar(
type: BottomNavigationBarType.fixed,
items: <BottomNavigationBarItem>[
BottomNavigationBarItem(
icon: Icon(Icons.A), title: Text('TabA')),
BottomNavigationBarItem(
icon: Stack(children: <Widget>[
Icon(
Icons.B,
),
Positioned(
top: 1.0,
right: 0.0,
child: Stack(
children: <Widget>[
Icon(Icons.brightness_1, size: 18, color: Colors.red),
Positioned(
top: 1.0,
right: 4.0,
child: new Text(count.toString(),
style: new TextStyle(
color: Colors.white,
fontSize: 15.0,
fontWeight: FontWeight.w500)),
)
],
),
)
]),
title: Text('TabB'),
),
],
currentIndex: _selectedIndex,
fixedColor: Colors.blue,
onTap: _onItemTapped,
),
),
onWillPop: () ,
);
当点击标签 2 时,我希望徽章更改为 1,但它会引发错误。
class TabB extends StatefulWidget
@override
State<StatefulWidget> createState() => _TabBState();
class _TabBState extends State<TabB>
@override
void initState()
super.initState();
_bloc.callApi().then((onValue)
MainPage().method(onValue); // onValue is the number return from server
);
@override
Widget build(BuildContext context)
return Scaffold(
appBar: AppBar(
title: Text("Tab 2"),
));
错误
════════ 小部件库捕获的异常 ═══════════════════════════════════抛出以下断言 构建通知监听器:setState() 在构造函数中调用:_MainPageState#6ed53(生命周期状态:已创建, 没有小部件,没有安装)
当您在小部件的 State 对象上调用 setState() 时会发生这种情况 尚未插入到小部件树中。它不是 必须在构造函数中调用 setState(),因为状态是 在最初创建时已经假定它是脏的。
【问题讨论】:
【参考方案1】:在加载子窗口小部件时,不要尝试从父窗口小部件调用函数来修改徽章,而应向 _tabController 添加监听器并在选择选项卡时更改徽章,如下所示:
@override
void initState()
super.initState();
_tabController = TabController(length: 5, vsync: this);
_tabController.addListener(()
if(_tabController.index == 1)
setState(()
showBadge(1);
);
);
_pageController = PageController(initialPage: _selectedIndex);
showBadge(3);
确保为要匹配的标签索引调整if
。
在您的TabB
上,您可以声明它接受Function
作为其构造函数的一部分,然后调用该函数:
class TabB extends StatefulWidget
final Function showBadge;
TabB(this.showBadge);
@override
State<StatefulWidget> createState() => _TabBState();
class _TabBState extends State<TabB>
@override
void initState()
super.initState();
_bloc.callApi().then((onValue)
widget.showBadge(onValue); // onValue is the number return from server
);
@override
Widget build(BuildContext context)
return Scaffold(
appBar: AppBar(
title: Text("Tab 2"),
)
);
在您的主小部件上:
FixTabBarView(
pageController: _pageController,
onPageChange: onPageChange,
tabController: _tabController,
children: <Widget>[
TabA(),
TabB(showBadge: showBadge,),
]
)
【讨论】:
看起来我必须先从 PageB 调用 MainPage 中的 Widget 构建,然后再调用setState
请检查我对回复的更改。你不需要让你的代码变得这么复杂。有更简单的方法可以监听选项卡上的变化。
您好,感谢您的回答。但在实际情况下,出于某种原因,我需要在选项卡 2 initState
中调用一个 api。该数字应该从 tabB 返回到 tabA。
您不需要调用父 Widget 的整个实例来调用其中一个方法。您可以将方法向下传递给子 Widget。我会将其添加到响应中。
请检查我添加到回复中的额外解释和代码。如果它对您有所帮助并解决了您的问题。确保将其标记为正确。以上是关于更改徽章编号的主要内容,如果未能解决你的问题,请参考以下文章