我正在尝试实现一个底部导航栏,但我无法完成它,我正在使用 Get 来处理应用程序的路由和状态。
我是 flutter 新手,但阅读文档我仍然不明白
这是主要的小部件。
Widget build(BuildContext context) {
return SafeArea(
child: Scaffold(
appBar: AppBar(
backgroundColor: AppColors.black,
title: Center(
child: CommonAssetImage(
asset: 'logo.png',
color: AppColors.white,
height: 30,
),
),
),
body: BodyTabsScreen(),
bottomNavigationBar: HomeScreenBottomNavigatorBar()),
);
}
然后,我有这个小部件可以调用其他小部件。在这个小部件中我使用了 Obs。
class HomeScreenBottomNavigatorBar extends StatelessWidget {
const HomeScreenBottomNavigatorBar({Key key}) : super(key: key);
@override
Widget build(BuildContext context) {
return Material(
elevation: 10,
color: AppColors.white,
child: Container(
height: 60,
padding: const EdgeInsets.symmetric(horizontal: 27),
color: AppColors.white,
child: Obx(() {
return Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
TabsScreenBottomNavigationTab(
isActive: true,
label: 'Buy',
icon: Icons.home,
onTap: () {}),
TabsScreenBottomNavigationTab(
label: 'My account',
// icon: IkramIcons.user,
// iconSize: 20,
icon: (Icons.home),
onTap: () {}),
],
);
}),
),
);
}
}
class TabsScreenBottomNavigationTab extends StatelessWidget {
final String label;
final IconData icon;
final Widget image;
final VoidCallback onTap;
final bool isActive;
final double iconSize;
const TabsScreenBottomNavigationTab({
Key key,
this.label,
this.icon,
this.image,
this.onTap,
this.isActive,
this.iconSize = 20,
}) : super(key: key);
@override
Widget build(BuildContext context) {
final _inactiveTextStyle = Theme.of(context).textTheme.bodyText2;
final _activeTextStyle =
_inactiveTextStyle.copyWith(color: AppColors.white);
const _commonDuration = Duration(milliseconds: 200);
final _availableSpace = MediaQuery.of(context).size.width - 27 * 2;
final _inactiveWidth = _availableSpace * .2;
final _activeWidth = _availableSpace * .35;
return AnimatedContainer(
duration: _commonDuration,
width: isActive ? _activeWidth : _inactiveWidth,
height: 35,
child: Material(
color: Colors.transparent,
shape: const StadiumBorder(),
clipBehavior: Clip.antiAlias,
child: AnimatedContainer(
duration: _commonDuration,
child: Material(
color: Colors.transparent,
child: InkWell(
onTap: onTap,
child: AnimatedDefaultTextStyle(
style: isActive ? _activeTextStyle : _inactiveTextStyle,
duration: _commonDuration,
child: Row(
mainAxisAlignment: MainAxisAlignment.center,
children: [
if (icon != null)
Icon(
icon,
size: iconSize,
color: isActive ? AppColors.white : AppColors.black,
),
if (image != null) image,
if (isActive)
Container(
margin: const EdgeInsets.only(left: 8),
child: Text(label),
)
],
),
),
),
),
),
),
);
}
}
答案 0 :(得分:0)
当您使用 Obx
或 Getx
小部件而不插入该小部件的可观察变量时,Getx 将始终抛出该错误。因此,如果您不尝试根据存在于扩展 GetxController
的类中的变量的更新值重建小部件,则不要使用 Getx 小部件。
如果您只是尝试使用 Getx
进行路由,请确保将您的 MaterialApp
更改为 GetMaterialApp
并像这样定义您的路由。
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return GetMaterialApp(
home: Page1(),
getPages: [
GetPage(name: Page1.id, page: () => Page1()), // add: static const id = 'your_page_name'; on each page to avoid using raw strings for routing
GetPage(name: Page2.id, page: () => Page2()),
],
);
}
}
然后在底部导航栏的 onTap
中使用
Get.to(Page2());
答案 1 :(得分:0)
只需像这样删除包裹您的 Row 小部件的 Obx 小部件:
class HomeScreenBottomNavigatorBar extends StatelessWidget {
const HomeScreenBottomNavigatorBar({Key key}) : super(key: key);
@override
Widget build(BuildContext context) {
return Material(
elevation: 10,
color: AppColors.white,
child: Container(
height: 60,
padding: const EdgeInsets.symmetric(horizontal: 27),
color: AppColors.white,
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
TabsScreenBottomNavigationTab(
isActive: true,
label: 'Buy',
icon: Icons.home,
onTap: () {}),
TabsScreenBottomNavigationTab(
label: 'My account',
// icon: IkramIcons.user,
// iconSize: 20,
icon: (Icons.home),
onTap: () {}),
],
);
),
);
}
}
为什么?因为您没有在小部件树中使用任何可观察 (obs/Rx) 变量,这会在值更改时触发重建。所以 GetX 有充分的理由抱怨。