error [Get] обнаружено неправильное использование GetX. используя bottomNavigationBar
Я пытаюсь реализовать bottomNavigationBar, но не могу его закончить, я использую Get для обработки маршрутов и состояния приложения.
Я новичок в трепете, но, читая документацию, все еще не понимаю
Это основной виджет.
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),
)
],
),
),
),
),
),
),
);
}
}
6 ответов
Getx всегда будет выдавать эту ошибку, когда вы используете
Obx
или виджет без вставки наблюдаемой переменной этого виджета. Итак, если вы НЕ пытаетесь перестроить виджет на основе обновленного значения переменной, которая находится внутри класса, который расширяет
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());
Это происходит, когда вы не используете значение контроллера в своем виджете. Вот почему он выдает ошибку, потому что нет смысла использовать виджет Obx или Getx()
MainController controller = Get.find();
return Obx(
()
{
return Column(
children: [
Text("My pretty text")
],
);
}
);
Решение :
MainController controller = Get.find();
Obx(
()
{
return Column(
children: [
Text(controller.text)
],
);
}
);
Контроллер должен быть внутри Obx, иначе он показывает эту ошибку.
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()),
Просто удалите виджет Obx, обертывающий виджет Row следующим образом:
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 жалуется, и на то есть веские причины.
Обратите внимание, что есть два обязательных аспекта: 1) расширение из GetXController и 2) поле/метод, возвращающее значение из контроллера, должно быть вычислено из типа Rx. В моем случае я сделал подкласс GetXController для теста, и возвращаемое значение было жестко запрограммировано (не основано на значении Rx), и возникла ошибка ObX.
Для текущего сценария
You dont need to use getx for this page
(Это неправильная реализация). пожалуйста, удалите 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: () {}),
],
);
}),
),
}