'error [Get] the improper use of a GetX has been detected. using bottomNavigationBar
I'm trying to implement a bottomNavigationBar, but I can't finish it, I'm using Get to handle the routes and the state of the application.
I'm new to flutter, but reading the documentation I still don't understand
This is the main widget.
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()),
);
}
then,I have this widget where call other widget.In this widget I using 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),
)
],
),
),
),
),
),
),
);
}
}
Solution 1:[1]
Getx will always throw that error when you use Obx or Getx widget without inserting an observable variable that widget. So if you are NOT trying to rebuild a widget based on an updated value of a variable that lives inside a class that exends GetxController, then don't use a Getx widget.
If you're just trying to use Getx for routing, then make sure to change your MaterialApp to GetMaterialApp and define your routes, like so.
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()),
],
);
}
}
Then in the onTap of your bottom navigation bar just use
Get.to(Page2());
Solution 2:[2]
Just remove the Obx widget wrapping your Row widget like this:
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: () {}),
],
);
),
);
}
}
Why? Because you are not using any observable (obs/Rx) variable in your widget tree which would trigger a rebuild when the value changes. So GetX is complaining and for good reason.
Solution 3:[3]
The controller should be inside Obx other wise its shows this error.
LeaderBoardController controller = Get.put(getIt<LeaderBoardController>());
Obx(()=>controller.leadBoardModel != null
? Column(
children: [
Container(
height: 180,
child: Row(
mainAxisAlignment: MainAxisAlignment.start,
crossAxisAlignment: CrossAxisAlignment.start,
children: [
LeadBoardImage(type: LEADTYPE.NORMAL),
LeadBoardImage(type: LEADTYPE.CROWN),
LeadBoardImage(type: LEADTYPE.NORMAL)
]),
),
Expanded(
flex: 4,
child: ListView(
padding: EdgeInsets.symmetric(horizontal: 10.w),
children: [
for (int i = 4; i < controller.leadBoardModel!.data.result.length; i++)
LeaderBoardListItem(result:controller.leadBoardModel!.data.result[i])
],
),
)
],
)
: LoadingContainer()),
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
| Solution | Source |
|---|---|
| Solution 1 | Loren.A |
| Solution 2 | S. M. JAHANGIR |
| Solution 3 | parmeet singh |
