Related
good evening. I am currently doing a To-do List in Flutter and I want to pass the Title of my List and the Description of my List when I click on a new screen but upon setting up Routes and and declaring the values on my next, it shows the "2 positional arguments expected, but 0 found" on the routes I've set up. Here are my codes:
Here is my 1st screen:
import 'package:flutter/material.dart';
import 'package:todo_list/details.dart';
import 'package:todo_list/note.dart';
class MyApp extends StatelessWidget {
final String text;
final int number;
final String listDescription;
const MyApp(
{super.key,
required this.text,
required this.number,
required this.listDescription});
#override
Widget build(BuildContext context) {
return MaterialApp(
routes: {
DetailsPage.routeName: (ctx) => DetailsPage(),
},
home: CustomListTile(
text: text,
number: number,
listDescription: listDescription,
),
);
}
}
class CustomListTile extends StatelessWidget {
final String text;
final int number;
final String listDescription;
const CustomListTile(
{super.key,
required this.text,
required this.number,
required this.listDescription});
#override
Widget build(BuildContext context) {
return InkWell(
onTap: () {
Navigator.pushNamed(context, DetailsPage.routeName,
arguments: Note(title: text, description: listDescription));
},
/* onTap: () {
Widget okButton = TextButton(
child: const Text("CLOSE"),
onPressed: () {
Navigator.of(context).pop();
},
);
AlertDialog alert = AlertDialog(
title: Text(text),
content: Text('This item in the list contains $listDescription'),
actions: [
okButton,
]);
showDialog(
context: context,
builder: (BuildContext context) {
return alert;
});
}, */
child: Padding(
padding: const EdgeInsets.only(left: 20.0, right: 20.0, top: 20.0),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Text("$number. $text",
style: const TextStyle(
fontSize: 20,
)),
const Icon(Icons.chevron_right)
],
),
Text(
listDescription,
style: const TextStyle(fontSize: 14, color: Colors.grey),
),
const Divider()
],
),
),
);
}
}
and here is my 2nd screen:
import 'package:flutter/material.dart';
import 'note.dart';
class DetailsPage extends StatefulWidget {
static const String routeName = "/details";
final String text;
final String listDescription;
const DetailsPage(this.text, this.listDescription, {super.key});
#override
State<DetailsPage> createState() => _DetailsPageState();
}
class _DetailsPageState extends State<DetailsPage> {
late Note params;
#override
void didChangeDependencies() {
params = ModalRoute.of(context)!.settings.arguments! as Note;
super.didChangeDependencies();
}
#override
Widget build(BuildContext context) {
Widget titleSection = Container(
padding: const EdgeInsets.all(32),
child: Row(
children: [
Expanded(
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Container(
padding: const EdgeInsets.only(bottom: 0),
child: Text(
params.title,
style: const TextStyle(
fontWeight: FontWeight.bold,
fontSize: 25,
),
),
),
],
),
),
],
),
);
Color color = Theme.of(context).primaryColor;
Widget buttonSection = Row(
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
children: [
_buildButtonColumn(
color,
Icons.edit,
'EDIT',
),
_buildButtonColumn(color, Icons.delete, 'DELETE'),
],
);
Widget textSection = Padding(
padding: const EdgeInsets.all(20),
child: Text(
params.description,
softWrap: true,
),
);
return MaterialApp(
title: 'Layout for a New Screen',
theme: ThemeData(
primarySwatch: Colors.brown,
),
home: Scaffold(
appBar: AppBar(
leading: IconButton(
icon: const Icon(Icons.arrow_back),
onPressed: () {
Navigator.pop(context);
},
),
title: Text(params.title),
),
body: ListView(
children: [
Image.asset(
'lib/images/placeholder.jpg',
width: 600,
height: 240,
fit: BoxFit.cover,
),
titleSection,
buttonSection,
textSection,
],
),
),
);
}
Column _buildButtonColumn(
Color color,
IconData icon,
String label,
) {
return Column(
mainAxisSize: MainAxisSize.min,
mainAxisAlignment: MainAxisAlignment.center,
children: [
Icon(icon, color: color),
Container(
margin: const EdgeInsets.only(top: 8),
child: Text(
label,
style: TextStyle(
fontSize: 12,
fontWeight: FontWeight.w400,
color: color,
),
),
),
],
);
}
}
/* return Scaffold(
appBar: AppBar(title: Text(text)),
body: Center(
child: Row(
children: [Text(description)],
),
));
}
} */
How do I make it so that the data I'll pass such as the Title and the Description will appear on the 2nd screen without the error "2 positional argument(s) expected, but 0 found.
Try adding the missing arguments." appearing.
I tried the Quick Fixes on VS Code such as adding a const modifier but I think the const modifier wouldn't do a fix since both data I'm trying to pass are dynamic and may change from time to time.
As you've define details page
class DetailsPage extends StatefulWidget {
static const String routeName = "/details";
final String text;
final String listDescription;
const DetailsPage(this.text, this.listDescription, {super.key});
You need to pass two string as positional argument.
So it can be
routes: {
DetailsPage.routeName: (ctx) => DetailsPage("text","description"),
},
also while you are using route arguments, you can remove theses from widget class and just accept from state class context with ModalRoute.
You can check this example and development/ui/navigation .
I'm struggling hard with Flutter's sizing constraints.
I'm trying to make a custom scaffold like screen with a custom appbar and a stack below it with the lowest layer being a listview, and then maybe floating buttons on top if that.
I can't figure out what the proper solution would be to make the listview not throw "vertical viewport was given unbounded height" error.
Here's my code:
import 'package:flutter/material.dart';
import 'package:flutter/src/widgets/container.dart';
import 'package:flutter/src/widgets/framework.dart';
import 'package:my/model.dart';
import 'package:my/widgets/menucard.dart';
import 'package:my/screens/my1.dart';
import 'package:my/screens/my2.dart';
import 'package:my/screens/my3.dart';
import 'package:my/provider.dart';
class myAppBar extends StatelessWidget {
myAppBar(
{super.key,
required double height,
required String title,
bool autoImplyBack = true})
: _height = height,
_title = title,
_autoback = autoImplyBack;
#override
Widget build(BuildContext context) {
return Container(
width: double.infinity,
height: _height,
color: Colors.pink,
child: SizedBox(
width: double.infinity,
height: _height,
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
SizedBox(
width: _height,
height: _height,
child: Navigator.canPop(context) && _autoback
? IconButton(
onPressed: () {
Navigator.pop(context);
},
icon: Icon(Icons.arrow_back),
)
: null,
),
Center(
child: Text(_title),
),
SizedBox(
width: _height,
height: _height,
child: IconButton(
onPressed: () {
Navigator.pop(context);
},
icon: Icon(Icons.close),
),
),
],
),
),
);
}
double _height;
String _title;
bool _autoback;
}
class myMenu extends StatelessWidget {
const myMenu({super.key});
#override
Widget build(BuildContext context) {
return Scaffold(
body: Column(
children: [
myAppBar(height: 100, title: 'Menu'),
Container(
color: Colors.teal,
child: Expanded(
child: //Stack(
//children: [
ListView(
children: [
MenuCard(
icondata: Icons.circle,
subMenu: 'my1',
onTap: () {
Navigator.push(
context,
MaterialPageRoute(
builder: (context) => const my1()),
);
}),
MenuCard(
icondata: Icons.circle,
subMenu: 'my2',
onTap: () {
Navigator.push(
context,
MaterialPageRoute(
builder: (context) => const my2()),
);
}),
MenuCard(
icondata: Icons.circle,
subMenu: 'my3',
onTap: () {
Navigator.push(
context,
MaterialPageRoute(
builder: (context) => const my3()),
);
}),
MenuCard(
icondata: Icons.circle,
subMenu: 'log out',
onTap: () {
Navigator.push(
context,
MaterialPageRoute(
builder: (context) => const my1()),
);
}),
],
),
//],
),
),
//),
],
),
);
}
}
I've tried setting the listview's shrinkwrap property to true, but that turned out to be ugly as well as not so much performant according to other threads regarding this topic.
I've also tried wrapping the listview in Expanded and Flexible, but to no avail.
You can shift the Expanded widget on top of Container.
body: Column(
children: [
myAppBar(height: 100, title: 'Menu'),
Expanded(
child: Container(
Also while you are trying to create custom AppBar, you can implements PreferredSizeWidget
class myAppBar extends StatelessWidget implements PreferredSizeWidget {
.... //get height using constructor.
#override
Widget build(BuildContext context) {
return Container(height:);
}
#override
Size get preferredSize => Size.fromHeight(height);
}
import 'package:flutter/material.dart';
import 'package:flutter_bmi_app/second_screen.dart';
import 'package:font_awesome_flutter/font_awesome_flutter.dart';
class BmiCalc extends StatefulWidget {
const BmiCalc({Key? key}) : super(key: key);
#override
State<BmiCalc> createState() => _BmiCalcState();
}
class _BmiCalcState extends State<BmiCalc> {
Color colorOfLittleBox = Color.fromARGB(255, 27, 28, 48);
Color colorOfLittleBox2 = Colors.pink;
bool isMale = true;
double _value = 150;
int weight = 60;
int age = 25;
double answer = 10;
String calc = "CALCULATE";
#override
Widget build(BuildContext context) {
return Scaffold(
backgroundColor: Color.fromARGB(255, 12, 9, 34),
body: SafeArea(
child: SingleChildScrollView(
child: Column(
children: [
Row(
children: [
FemaleBox("MALE", Icons.male),
FemaleBox("FEMALE", Icons.female),
],
),
Column(children: [
Container(
padding: EdgeInsets.all(32),
margin: EdgeInsets.all(10),
decoration: BoxDecoration(
color: Color.fromARGB(255, 27, 28, 48),
borderRadius: BorderRadius.circular(15),
),
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
const Text("HEIGHT",
style: TextStyle(color: Colors.grey, fontSize: 20)),
const SizedBox(
height: 10,
),
Row(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Text(_value.toStringAsFixed(0),
style: const TextStyle(
fontSize: 45,
color: Colors.white,
fontWeight: FontWeight.w900)),
const Text(
"cm",
style:
TextStyle(fontSize: 20, color: Colors.grey),
),
],
),
Slider(
min: 100,
max: 230,
thumbColor: Colors.pink,
value: _value,
onChanged: (value) {
setState(() {
_value = value;
});
},
),
],
))
]),
Row(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
Operation("Weight"),
Operation("Age"),
],
),
Container(
decoration: BoxDecoration(
color: Colors.pink,
borderRadius: BorderRadius.circular(15),
),
padding: EdgeInsets.only(bottom: 5),
width: MediaQuery.of(context).size.width,
child: TextButton(
child: Text(
calc,
style: const TextStyle(
fontSize: 22,
color: Colors.white,
fontWeight: FontWeight.w900),
),
onPressed: () {
Navigator.push(
context,
MaterialPageRoute(builder: (context) => SecondScreen()),
);
},
),
)
],
),
),
),
);
}
void calculate() {
answer = (weight / (_value * _value)) * 10000;
Text(answer.toString(),
style: const TextStyle(fontSize: 40, color: Colors.white));
if (calc == "CALCULATE") {
calc = answer.toStringAsFixed(1);
} else {
calc = "CALCULATE";
}
setState(() {});
}
}
I made bmi calculator, I wanna have answer on other screen. I want to send this function calculate() to the second screen, where I will
have the answer of this calculation. I gave Navigator.push(
context,
MaterialPageRoute(builder: (context) => SecondScreen()), but how to make it work? Thank you in advance.
Make the SecondScreen constructor take a parameter for the type of data that you want to send to it.
const SecondScreen(
{Key? key,required this.answer, })
: super(key: key);
final String? answer; //define value you want to pass
#override
_SecondScreenScreenState createState() => _SecondScreenState();
}
And pass data when navigate
Navigator.push(
context,
MaterialPageRoute(
builder: (context) => SecondScreen(answer: 'Hello',),
));
here is the example:
import 'package:flutter/material.dart';
class Todo {
final String title;
final String description;
const Todo(this.title, this.description);
}
void main() {
runApp(
MaterialApp(
title: 'Passing Data',
home: TodosScreen(
todos: List.generate(
20,
(i) => Todo(
'Todo $i',
'A description of what needs to be done for Todo $i',
),
),
),
),
);
}
class TodosScreen extends StatelessWidget {
const TodosScreen({Key? key, required this.todos}) : super(key: key);
final List<Todo> todos;
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: const Text('Todos'),
),
body: ListView.builder(
itemCount: todos.length,
itemBuilder: (context, index) {
return ListTile(
title: Text(todos[index].title),
// When a user taps the ListTile, navigate to the DetailScreen.
// Notice that you're not only creating a DetailScreen, you're
// also passing the current todo through to it.
onTap: () {
Navigator.push(
context,
MaterialPageRoute(
builder: (context) => DetailScreen(todo: todos[index]),
),
);
},
);
},
),
);
}
}
class DetailScreen extends StatelessWidget {
// In the constructor, require a Todo.
const DetailScreen({Key? key, required this.todo}) : super(key: key);
// Declare a field that holds the Todo.
final Todo todo;
#override
Widget build(BuildContext context) {
// Use the Todo to create the UI.
return Scaffold(
appBar: AppBar(
title: Text(todo.title),
),
body: Padding(
padding: const EdgeInsets.all(16.0),
child: Text(todo.description),
),
);
}
}
I can't get the FemaleBox and Operation in your project so I can't run that try the above example or share you full code include second screen also
add a constructor in your second screen and pass it while calling second screen
const SecondScreen(
{Key? key,required this.answer, })
: super(key: key);
final String? answer; //define value you want to pass
#override
_SecondScreenScreenState createState() => _SecondScreenState();
}
Navigator.push(
context,
MaterialPageRoute(
builder: (context) => SecondScreen(answer: 'Hello',),
));
There is another way to do that.
Create a class as given below and use static keyword to define any variable.
Now you can call this variable at your entire app via- Common.sharedData
So you can modified it according to you
Class Common{
static int sharedData=0;
//Other function
}
There are different ways to solve this
Sending parameters through constructor (Good solution).
Use a State Management package and hold the state in its class and access tit everywhere (Recommended way).
declare variable globally and use it anywhere in the app (not Recommended)
Using the following code, I am able to retrieve the username of the currently logged in user but when I try to display it, it displays as null.
import 'package:cloud_firestore/cloud_firestore.dart';
import 'package:firebase_auth/firebase_auth.dart';
import 'package:flutter/material.dart';
import 'package:localeventsapp/Screens/Login/login_screen.dart';
import 'package:localeventsapp/model/category.dart';
import 'package:localeventsapp/model/event.dart';
import 'package:localeventsapp/styleguide.dart';
import 'package:localeventsapp/ui/event_details/event_details_page.dart';
import 'package:localeventsapp/ui/homepage/form_widget.dart';
import 'package:provider/provider.dart';
import '../../app_state.dart';
import '../../authentication_service.dart';
import 'category_widget.dart';
import 'event_widget.dart';
import 'home_page_background.dart';
CollectionReference users = FirebaseFirestore.instance.collection("Users");
FirebaseAuth auth = FirebaseAuth.instance;
String uid = auth.currentUser.uid.toString();
// String uName = getUsername(uid).toString();
String getUsername(String uid) {
String username;
DocumentReference documentReference = users.doc(uid);
documentReference.get().then((snapshot) {
username = snapshot.data()['displayName'].toString();
print("Username is " + username);
});
return username;
}
class HomePage extends StatelessWidget {
#override
Widget build(BuildContext context) {
return Scaffold(
body: ChangeNotifierProvider<AppState>(
create: (_) => AppState(),
child: Stack(
children: <Widget>[
HomePageBackground(
screenHeight: MediaQuery.of(context).size.height,
),
SafeArea(
child: SingleChildScrollView(
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[
Padding(
padding: const EdgeInsets.symmetric(horizontal: 32.0),
child: Row(
children: <Widget>[
Text(
"TuLink",
style: fadedTextStyle,
),
Spacer(),
],
),
),
Padding(
padding: const EdgeInsets.symmetric(horizontal: 32.0),
child: Text(
getUsername(uid).toString(),
style: whiteHeadingTextStyle,
),
),
Padding(
padding: const EdgeInsets.symmetric(vertical: 24.0),
child: Consumer<AppState>(
builder: (context, appState, _) =>
SingleChildScrollView(
scrollDirection: Axis.horizontal,
child: Row(
children: <Widget>[
for (final category in categories)
CategoryWidget(category: category),
],
),
),
),
),
Padding(
padding: const EdgeInsets.symmetric(horizontal: 16.0),
child: Consumer<AppState>(
builder: (context, appState, _) => Column(
children: <Widget>[
for (final event in events.where((e) => e
.categoryIds
.contains(appState.selectedCategoryId)))
GestureDetector(
onTap: () {
Navigator.of(context).push(
MaterialPageRoute(
builder: (context) =>
EventDetailsPage(event: event),
),
);
},
child: EventWidget(
event: event,
),
)
],
),
),
),
FloatingActionButton.extended(
onPressed: () {
Navigator.push(context,
MaterialPageRoute(builder: (context) => FormPage()));
},
label: Text('Create'),
icon: Icon(Icons.create),
elevation: 2,
shape: RoundedRectangleBorder(borderRadius: BorderRadius.all(Radius.circular(16.0))),
backgroundColor: Color(0xFF6F35A5),
),
ElevatedButton(
child: Text('Sign Out',
style: TextStyle(
color: Colors.black,
fontSize: 16,
)),
onPressed: () {
context.read<AuthenticationService>().signOut();
Navigator.of(context).push(MaterialPageRoute(builder: (context) => LoginScreen()));
}),
],
),
),
),
],
),
),
);
}
}
class CircularButton extends StatelessWidget {
final double width;
final double height;
final Color color;
final Icon icon;
final Function onClick;
CircularButton(
{this.color, this.width, this.height, this.icon, this.onClick});
#override
Widget build(BuildContext context) {
return Container(
decoration: BoxDecoration(color: color, shape: BoxShape.circle),
width: width,
height: height,
child: IconButton(
icon: icon,
enableFeedback: true,
onPressed: onClick,
),
);
}
}
Specifically this part :
Padding(
padding: const EdgeInsets.symmetric(horizontal: 32.0),
child: Text(
getUsername(uid).toString(),
style: whiteHeadingTextStyle,
),
),
The "getUsername(uid).toString()" portion returns a null here.
This is the getUsername method:
String getUsername(String uid) {
String username;
DocumentReference documentReference = users.doc(uid);
documentReference.get().then((snapshot) {
username = snapshot.data()['displayName'].toString();
print("Username is " + username);
});
return username;
}
But print returns the name just fine. I'm kind of stumped.
Any ideas?
Just add a setState before your return statement
setState({}); /// only works in a statefulWidget
return username;
This is happening because by the time your fetch username the build method runs and the Ui is built that means username is displayed as null in the Ui, but when the username is fetched the variable has the value but its not displayed on screen because you need to redraw the widgets in order to show the updated value on the screen by calling setState thats how flutter works.I would recommend you to play around with the flutters counter app and try to add print statements and remove setState.
Although SetState might not be the best solution there are different techniques though but setState is a good place to start
And then later you could move on to using widgets like
ValueListenableBuilder, FutureBuilder etc
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),
)
],
),
),
),
),
),
),
);
}
}
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());
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.
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()),
It happens when you don't use your controller value in your widget. That's why it gives error because there is no sense in using Obx or Getx() widget
MainController controller = Get.find();
return Obx(
()
{
return Column(
children: [
Text("My pretty text")
],
);
}
);
Solution :
MainController controller = Get.find();
Obx(
()
{
return Column(
children: [
Text(controller.text)
],
);
}
);
Please note that there are two required aspects: 1) extending from a GetXController, and 2) The field/method returning a value from the controller, must be computed from a Rx type. In my case, I made a sub-class of a GetXController for a test, and the return value was hard-coded (not based on a Rx value), and the ObX error occurred.
For Current Scenario You dont need to use getx for this page
(Its not proper Implementation) . please remove the OBX() your error will gone .
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: () {}),
],
);
}),
),
}