How to use itemBuilder to select the last tapped ListTile widget? - flutter

I am trying to change the selected property of the last tapped ListTile widget to true inside a Drawer (and then obviously the selected property of other ListTiles to false), but I do not understand how can I use itemBuilder (which is mentioned in the official flutter docs) for this.
I tried putting my ListTiles into an AnimatedListItemBuilder widget, but that was not working for me.
Widget _buildDrawer() {
return ListView(
// Important: Remove any padding from the ListView.
padding: EdgeInsets.zero,
children: <Widget>[
DrawerHeader(
child:
Wrap(
alignment: WrapAlignment.center,
direction: Axis.vertical,
children: <Widget>[
Text(
_currentUser.displayName,
style: TextStyle(
fontSize: 20,
color: Colors.white
),
),
Wrap(
direction: Axis.vertical,
children: <Widget>[
Text(
"Iskolai kategória: A",
style: TextStyle(
fontSize: 18,
color: Colors.white70
),
),
Text(
"Kollégiumi kategória: A",
style: TextStyle(
fontSize: 18,
color: Colors.white70
),
),
],
)
],
),
decoration: BoxDecoration(
color: Colors.blue,
),
),
ListTile(
selected: true,
leading: Icon(Icons.date_range_rounded),
title: Text('Stúdium jelentkezés'),
onTap: () {
// Update the state of the app.
// ...
// Then close the drawer.
Navigator.pop(context);
},
),
ListTile(
leading: Icon(Icons.article_rounded),
title: Text('Koleszhírek'),
onTap: () {
// Update the state of the app.
// ...
Navigator.pop(context);
},
),
ListTile(
leading: Icon(Icons.account_box_rounded),
title: Text('Profil'),
onTap: () {
// Update the state of the app.
// ...
Navigator.pop(context);
},
),
ListTile(
leading: Icon(Icons.logout),
title: Text('Kijelentkezés'),
onTap: () => {
_googleSignIn.disconnect(),
Navigator.pop(context)
},
),
],
);
}

You have to save the 'selected index' in a variable and check if the current index equals selected index to highlight the ListView. I've updated your code to make it work.
import 'package:flutter/material.dart';
void main() {
runApp(MyApp());
}
class MyApp extends StatelessWidget {
// This widget is the root of your application.
#override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter Demo',
theme: ThemeData(
primarySwatch: Colors.blue,
visualDensity: VisualDensity.adaptivePlatformDensity,
),
home: MyHomePage(title: 'Flutter Demo Home Page'),
);
}
}
class MyHomePage extends StatefulWidget {
MyHomePage({Key key, this.title}) : super(key: key);
final String title;
#override
_MyHomePageState createState() => _MyHomePageState();
}
class _MyHomePageState extends State<MyHomePage> {
int _selectedIndex = 0;
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text(widget.title),
),
drawer: _buildDrawer(context),
body: Center(
child: Text("DrawerHeader Demo"),
),
);
}
Widget _buildDrawer(BuildContext context) {
List<Widget> leading = [
Icon(Icons.date_range_rounded),
Icon(Icons.article_rounded),
Icon(Icons.account_box_rounded),
Icon(Icons.logout),
];
List<Widget> title = [
Text('Stúdium jelentkezés'),
Text('Koleszhírek'),
Text('Profil'),
Text('Kijelentkezés'),
];
return Container(
color: Colors.white,
child: ListView(
padding: EdgeInsets.zero,
children: <Widget>[
DrawerHeader(
child: Wrap(
alignment: WrapAlignment.center,
direction: Axis.vertical,
children: <Widget>[
Text(
"A",
style: TextStyle(fontSize: 20, color: Colors.white),
),
Wrap(
direction: Axis.vertical,
children: <Widget>[
Text(
"Iskolai kategória: A",
style: TextStyle(fontSize: 18, color: Colors.white70),
),
Text(
"Kollégiumi kategória: A",
style: TextStyle(fontSize: 18, color: Colors.white70),
),
],
)
],
),
decoration: BoxDecoration(
color: Colors.blue,
),
),
ListView.builder(
itemCount: 4,
shrinkWrap: true,
itemBuilder: (BuildContext context, int index) {
return ListTile(
title: title[index],
leading: leading[index],
selected: index == _selectedIndex,
onTap: () {
setState(() {
_selectedIndex = index;
Navigator.pop(context);
});
},
);
},
),
],
),
);
}
}

Related

Having an issue using TextFeild in flutter, Text box not showing up

I'm creating a flutter app that requires a user to complete certain tasks in order to stop an alarm clock. It's a more immersive alarm clock app that could help stimulate the brain in order to aid in the process of waking up.
The tasks are simple questions the user has to answer. I'm utilizing TextFeild() to allow the user to input their answer. However, when I go to debug my code is redirected to a file called box.dart this is where the error is stated.
Here is the box.dart file error:
throw FlutterError.fromParts(<DiagnosticsNode>[
ErrorSummary('Cannot hit test a render box with no size.'),
describeForError('The hitTest() method was called on this RenderBox'),
ErrorDescription(
'Although this node is not marked as needing layout, '
'its size is not set.',
),
ErrorHint(
'A RenderBox object must have an '
'explicit size before it can be hit-tested. Make sure '
'that the RenderBox in question sets its size during layout.',
),
]);
}
Here is my full code:
import 'package:flutter/material.dart';
import 'package:audioplayers/audioplayers.dart';
//import 'package:audioplayers/audio_cache.dart';
void main() {
runApp(const MyApp());
}
class MyApp extends StatelessWidget {
const MyApp({super.key});
#override
Widget build(BuildContext context) {
return MaterialApp(
debugShowCheckedModeBanner: false,
title: 'Time Attack',
theme: ThemeData(
primarySwatch: Colors.red,
),
home: const MyHomePage(),
);
}
}
class MyHomePage extends StatefulWidget {
const MyHomePage({super.key});
#override
State<MyHomePage> createState() => _MyHomePageState();
}
class _MyHomePageState extends State<MyHomePage> {
#override
Widget build(BuildContext context) {
return MaterialApp(
home: Scaffold(
backgroundColor: Colors.black,
appBar: AppBar(
backgroundColor: Colors.red,
title: const Text('Time Attack'),
centerTitle: true,
),
floatingActionButton: FloatingActionButton(
onPressed: () async {
// ignore: avoid_print
print("alarm is playing");
final player = AudioCache();
//bool isPLaying = false;
await player.load('musicForapp.mp3');
AudioPlayer p = AudioPlayer();
p.audioCache = player;
await p.play(AssetSource('musicForapp.mp3'));
},
backgroundColor: Colors.red,
child: const Icon(Icons.punch_clock),
),
body: Padding(
padding: const EdgeInsets.all(170),
child: Column(
children: [
const Text(
"Click the Icon in the bottem right to simulate alarm",
style: TextStyle(
color: Colors.white,
fontSize: 30.0,
),
),
ElevatedButton(
style: ElevatedButton.styleFrom(backgroundColor: Colors.red),
onPressed: () {
Navigator.push(
context,
MaterialPageRoute(
builder: (_) => const TasksPage(),
),
);
}, //on pressed
child: const Text(
"Tasks page",
style: TextStyle(color: Colors.white),
),
)
],
),
),
),
);
} //widget build
}
class TasksPage extends StatefulWidget {
const TasksPage({super.key});
#override
State<TasksPage> createState() => _TasksPageState();
}
class _TasksPageState extends State<TasksPage> {
final _textcontroller = TextEditingController();
#override
Widget build(BuildContext context) {
return MaterialApp(
home: Scaffold(
backgroundColor: Colors.black,
appBar: AppBar(
backgroundColor: Colors.red,
title: const Text('Tasks'),
centerTitle: true,
),
floatingActionButton: FloatingActionButton(
onPressed: () {
Navigator.push(
context,
MaterialPageRoute(
builder: (_) => const SecondTask(),
),
);
},
backgroundColor: Colors.red,
child: const Text("Next"),
),
body: Padding(
padding: const EdgeInsets.all(8.0),
child: Center(
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
children: [
const Text(
"How many states are there in the United States of America?",
style: TextStyle(
backgroundColor: Colors.white,
color: Colors.black,
fontSize: 30.0,
),
),
Expanded(
child: TextField(
controller: _textcontroller,
decoration: InputDecoration(
hintText: "Type your answer here!",
border: const OutlineInputBorder(),
suffixIcon: IconButton(
onPressed: () {
_textcontroller.clear();
},
icon: const Icon(Icons.clear),
),
),
),
),
],
),
),
),
),
);
} //widget build
}
class SecondTask extends StatefulWidget {
const SecondTask({super.key});
#override
State<SecondTask> createState() => _SecondTask();
}
class _SecondTask extends State<SecondTask> {
final _textcontroller2 = TextEditingController();
#override
Widget build(BuildContext context) {
return MaterialApp(
home: Scaffold(
backgroundColor: Colors.black,
appBar: AppBar(
backgroundColor: Colors.red,
title: const Text('Tasks'),
centerTitle: true,
),
floatingActionButton: FloatingActionButton(
onPressed: () {
Navigator.push(
context,
MaterialPageRoute(
builder: (_) => const Thirdtask(),
),
);
},
backgroundColor: Colors.red,
child: const Text("Next"),
),
body: Padding(
padding: const EdgeInsets.all(8.0),
child: Center(
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
children: [
const Text(
"how many oceans are there?",
style: TextStyle(
backgroundColor: Colors.white,
color: Colors.black,
fontSize: 30.0,
),
),
Expanded(
child: TextField(
controller: _textcontroller2,
decoration: InputDecoration(
hintText: "Type your answer here!",
border: const OutlineInputBorder(),
suffixIcon: IconButton(
onPressed: () {
_textcontroller2.clear();
},
icon: const Icon(Icons.clear),
),
),
),
),
],
),
),
),
),
);
} //widget build
}
class Thirdtask extends StatefulWidget {
const Thirdtask({super.key});
#override
State<Thirdtask> createState() => _Thirdtask();
}
class _Thirdtask extends State<Thirdtask> {
final _textcontroller3 = TextEditingController();
#override
Widget build(BuildContext context) {
return MaterialApp(
home: Scaffold(
backgroundColor: Colors.black,
appBar: AppBar(
backgroundColor: Colors.red,
title: const Text('Tasks'),
centerTitle: true,
),
floatingActionButton: FloatingActionButton(
onPressed: () {
Navigator.push(
context,
MaterialPageRoute(
builder: (_) => const Finaltask(),
),
);
},
backgroundColor: Colors.red,
child: const Text("Next"),
),
body: Padding(
padding: const EdgeInsets.all(8.0),
child: Center(
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
children: [
const Text(
"What is 8 x 7?",
style: TextStyle(
backgroundColor: Colors.white,
color: Colors.black,
fontSize: 30.0,
),
),
Expanded(
child: TextField(
controller: _textcontroller3,
decoration: InputDecoration(
hintText: "Type your answer here!",
border: const OutlineInputBorder(),
suffixIcon: IconButton(
onPressed: () {
_textcontroller3.clear();
},
icon: const Icon(Icons.clear),
),
),
),
),
],
),
),
),
),
);
} //widget build
}
class Finaltask extends StatefulWidget {
const Finaltask({super.key});
#override
State<Finaltask> createState() => _Finaltask();
}
class _Finaltask extends State<Finaltask> {
final _textcontroller4 = TextEditingController();
#override
Widget build(BuildContext context) {
return MaterialApp(
home: Scaffold(
backgroundColor: Colors.black,
appBar: AppBar(
backgroundColor: Colors.red,
title: const Text('Tasks'),
centerTitle: true,
),
floatingActionButton: FloatingActionButton(
onPressed: () {
Navigator.push(
context,
MaterialPageRoute(
builder: (_) => const Congrats(),
),
);
},
backgroundColor: Colors.red,
child: const Text("Submit"),
),
body: Padding(
padding: const EdgeInsets.all(8.0),
child: Center(
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
children: [
const Text(
"Riddle: What goes up but never comes back down?",
style: TextStyle(
backgroundColor: Colors.white,
color: Colors.black,
fontSize: 30.0,
),
),
Expanded(
child: TextField(
controller: _textcontroller4,
decoration: InputDecoration(
hintText: "Type your answer here!",
border: const OutlineInputBorder(),
suffixIcon: IconButton(
onPressed: () {
_textcontroller4.clear();
},
icon: const Icon(Icons.clear),
),
),
),
),
],
),
),
),
),
);
} //widget build
}
class Congrats extends StatefulWidget {
const Congrats({super.key});
#override
State<Congrats> createState() => _Congrats();
}
class _Congrats extends State<Congrats> {
#override
Widget build(BuildContext context) {
return MaterialApp(
home: Scaffold(
backgroundColor: Colors.black,
appBar: AppBar(
backgroundColor: Colors.red,
title: const Text('Good Job!'),
centerTitle: true,
),
floatingActionButton: FloatingActionButton(
onPressed: () {
Navigator.push(
context,
MaterialPageRoute(
builder: (_) => const MyHomePage(),
),
);
//player.clear('explosion.mp3'); (to stop alarm)
// ignore: avoid_print
print("Alarm has stoped");
},
backgroundColor: Colors.red,
child: const Text("Home"),
),
body: Padding(
padding: const EdgeInsets.all(8.0),
child: Center(
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
children: const [
Expanded(
child: Text(
"Congratulations you completed your tasks, Click the home button to return home and stop the timer!",
style: TextStyle(
backgroundColor: Colors.white,
color: Colors.black,
fontSize: 30.0,
),
),
),
],
),
),
),
),
);
} //widget build
}
Firstly, please delete all MaterialApp (except the first on the top). Because in Flutter app there must be only one MaterialApp throughout the code.
Secondly, juste change your padding 170 to 17 for exemple. 170 is extremely big.
Use single MaterialApp on top widget as #Antonin Liehn said. Now for the TextFormField border. You need to use enabledBorder, also try others border property , Find more about OutlineInputBorder.
decoration: InputDecoration(
hintText: "Type your answer here!",
enabledBorder: OutlineInputBorder(
borderSide: BorderSide(
color: Colors.white,
width: 22,
),
),
errorBorder: ,
focusedBorder: ,
disabledBorder: ,
focusedErrorBorder: ,
border: OutlineInputBorder(
borderSide: BorderSide(
color: Colors.white,
width: 22,
),
),
Also wrap text with Flexible/Expanded widget. You cal follow this widget
class TasksPage extends StatefulWidget {
const TasksPage({super.key});
#override
State<TasksPage> createState() => _TasksPageState();
}
class _TasksPageState extends State<TasksPage> {
final _textcontroller = TextEditingController();
final border = const OutlineInputBorder(
borderSide: BorderSide(
color: Colors.white,
width: 22,
));
#override
Widget build(BuildContext context) {
return Scaffold(
backgroundColor: Colors.black,
appBar: AppBar(
backgroundColor: Colors.red,
title: const Text('Taskssssssss'),
centerTitle: true,
),
floatingActionButton: FloatingActionButton(
onPressed: () {
Navigator.push(
context,
MaterialPageRoute(
builder: (_) => const SecondTask(),
),
);
},
backgroundColor: Colors.red,
child: const Text("Next"),
),
body: Padding(
padding: const EdgeInsets.all(8.0),
child: Center(
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
children: [
Flexible(
child: const Text(
"How many states are there in the United States of America?",
style: TextStyle(
backgroundColor: Colors.white,
color: Colors.black,
fontSize: 30.0,
),
),
),
Expanded(
child: TextFormField(
controller: _textcontroller,
decoration: InputDecoration(
hintText: "Type your answer here!",
enabledBorder: OutlineInputBorder(
borderSide: BorderSide(
color: Colors.white,
),
),
errorBorder: border,
focusedBorder: border,
disabledBorder: border,
focusedErrorBorder: border,
border: border,
suffixIcon: IconButton(
onPressed: () {
_textcontroller.clear();
},
icon: const Icon(Icons.clear),
),
),
),
),
],
),
),
),
);
} //widget build
}

Flutter:How can i change the color of selected menu item from drawer

I am creating an app in flutter, I have got some issue in drawer. I want to change the color of the selected drawer item.Here is my full code it looks fine to me but its not working for me... please help me find out what i am doing wrong
class _DrawerClassState extends State<DrawerClass> {
Here is my full code it looks fine to me but its not working for me... please help me find out what i am doing wrong
List<String> menuStrings = [
'HOME',
'NOTIFICATIONS',
'PARTNERS',
'LOCATIONS',
'FEEDBACK',
'CONTACT US',
'AWARDS'
];
Here is my full code it looks fine to me but its not working for me... please help me find out what i am doing wrong
List menuScreens = [
HomeScreen(),
Notifications(),
Partners(),
Locations(),
FeedbackScreen(),
const ContactUs(),
Awards()
];
Here is my full code it looks fine to me but its not working for me... please help me find out what i am doing wrong
List<bool> isHighlighted = [false, false, false, false, true, false, false];
#override
Widget build(BuildContext context) {
return Theme(
data: Theme.of(context).copyWith(
canvasColor: Colors.black,
),
child: Drawer(
child: Column(
mainAxisAlignment: MainAxisAlignment.start,
crossAxisAlignment: CrossAxisAlignment.start,
children: [
drawerTop("HI USER"),
ListView.builder(
shrinkWrap: true,
itemCount: menuScreens.length,
itemBuilder: (context, index) {
return GestureDetector(
onTap: () {
for (int i = 0; i < isHighlighted.length; i++) {
setState(() {
if (index == i) {
isHighlighted[index] = true;
} else {
//the condition to change the highlighted item
isHighlighted[i] = false;
}
});
}
},
child: drawerItems(
context,
menuStrings[index],
menuScreens[index],
isHighlighted[index] ? Colors.amber : Colors.white,
),
);
},
),
],
),
),
);
}
}
Here is the method drawerItems() to build drawer items
drawerItems(BuildContext context, String title, path, Color color) {
return Padding(
padding: EdgeInsets.only(
top: 0.0, left: MediaQuery.of(context).size.width * 0.1),
child: Column(crossAxisAlignment: CrossAxisAlignment.start, children: [
GestureDetector(
onTap: () {
Navigator.of(context)
.push(MaterialPageRoute(builder: ((context) => path)));
},
child: Padding(
padding: const EdgeInsets.symmetric(vertical: 8.0),
child: Text(
title,
style: TextStyle(
color: color,
fontFamily: "Raleway Reg",
fontSize: 23,
letterSpacing: 2),
),
),
),
SizedBox(
width: MediaQuery.of(context).size.width * 0.5,
child: const Divider(
thickness: 1,
color: Colors.white,
height: 3,
),
),
]));
}
Update your drawerItems
drawerItems(BuildContext context, String title, path, Color color) {
return Container(
color: color,
padding: EdgeInsets.only(
top: 0.0, left: MediaQuery.of(context).size.width * 0.1),
child: Column(crossAxisAlignment: CrossAxisAlignment.start, children: [
GestureDetector(
onTap: () {
Navigator.of(context)
.push(MaterialPageRoute(builder: ((context) => path)));
},
child: Padding(
padding: const EdgeInsets.symmetric(vertical: 8.0),
child: Text(
title,
style: TextStyle(
color: color,
fontFamily: "Raleway Reg",
fontSize: 23,
letterSpacing: 2),
),
),
),
SizedBox(
width: MediaQuery.of(context).size.width * 0.5,
child: const Divider(
thickness: 1,
color: Colors.white,
height: 3,
),
),
]));
}
the root widget that is returned from the method, change it from Padding to Container and give it a color
I think it's a very complex solution to solve this simple task in Flutter.
I suggest my solution:
Publish it on my git:
https://github.com/igdmitrov/flutter-drawer
Create a new Abstract Page State:
abstract class MyPageState<T extends StatefulWidget> extends State {
List<Widget> drawerItems(BuildContext context) {
return menuItems
.map(
(item) => ListTile(
leading: const Icon(Icons.my_library_books),
title: Text(
item['menuName'] as String,
style: TextStyle(
color: isHighlighted[menuItems.toList().indexOf(item)]
? Colors.amber
: Colors.grey),
),
onTap: () {
isHighlighted = isHighlighted.map((mark) => false).toList();
isHighlighted[menuItems.toList().indexOf(item)] = true;
Navigator.of(context).push(MaterialPageRoute(
builder: ((context) => item['route'] as Widget)));
},
),
)
.toList();
}
}
Create drawer.dart file with code:
final menuItems = {
{'menuName': 'HOME', 'route': const HomeScreen()},
{'menuName': 'NOTIFICATIONS', 'route': const Notifications()},
};
List<bool> isHighlighted = [false, false];
And create pages:
class MyHomePage extends StatefulWidget {
const MyHomePage({Key? key, required this.title}) : super(key: key);
final String title;
#override
MyPageState<MyHomePage> createState() => _MyHomePageState();
}
class _MyHomePageState extends MyPageState<MyHomePage> {
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: const Text('Main page'),
),
drawer: Drawer(
child: ListView(
children: [
const Text("HI USER"),
...drawerItems(context),
],
),
),
body: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: const [
Text(
'New app',
),
],
),
),
);
}
}
And Notifications page:
class Notifications extends StatefulWidget {
static String routeName = '/notifications';
const Notifications({Key? key}) : super(key: key);
#override
MyPageState<Notifications> createState() => _NotificationsState();
}
class _NotificationsState extends MyPageState<Notifications> {
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: const Text('Notifications'),
),
drawer: Drawer(
child: ListView(
children: [
const Text("HI USER"),
...drawerItems(context),
],
),
),
body: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: const [
Text(
'Notifications page',
),
],
),
),
);
}
}

The instance member 'posts' can't be accessed in an initializer

I would like to load other REST CALL which callS other data from DB.
I would like to use bottom navigation bar.
When I coded without bottom navigation bar, the app worked.
But When I inserted bottom navigation bar, "posts" function(related to REST CALL) has an error.
itemCount: posts == null ? 0 : posts.length,
itemBuilder: (context, index) {
Post post = posts[index];
import 'package:flutter/material.dart';
import 'package:http/http.dart' as http;
import 'Services.dart';
import 'Post.dart';
void main() {
runApp(MyApp());
}
class MyApp extends StatelessWidget {
const MyApp({Key? key}) : super(key: key);
#override
Widget build(BuildContext context) {
return MaterialApp(
debugShowCheckedModeBanner: false,
title: 'Flutter Demo',
theme: ThemeData(
primarySwatch: Colors.blue,
visualDensity: VisualDensity.adaptivePlatformDensity,
),
home: MyHomePage(title: 'Flutter ListView'),
);
}
}
class MyHomePage extends StatefulWidget {
MyHomePage({Key? key, required this.title}) : super(key: key);
final String title;
#override
_MyHomePageState createState() => _MyHomePageState();
}
class _MyHomePageState extends State<MyHomePage> {
late List<Post> posts;
late bool loading;
#override
void initState() {
super.initState();
loading = true;
Services.getPosts().then((list) {
super.setState(() {
posts = list;
loading = false;
});
});
}
#override
int _selectedIndex = 0;
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text(loading ? 'Loading...' : 'Posts'),
),
bottomNavigationBar: BottomNavigationBar(
type: BottomNavigationBarType.fixed,
backgroundColor: Colors.grey,
selectedItemColor: Colors.white,
unselectedItemColor: Colors.white.withOpacity(.60),
selectedFontSize: 14,
unselectedFontSize: 14,
currentIndex: _selectedIndex,
//현재 선택된 Index
onTap: (int index) {
setState(() {
_selectedIndex = index;
});
},
items: [
BottomNavigationBarItem(
title: Text('Favorites'),
icon: Icon(Icons.favorite),
),
BottomNavigationBarItem(
title: Text('Music'),
icon: Icon(Icons.music_note),
),
BottomNavigationBarItem(
title: Text('Places'),
icon: Icon(Icons.location_on),
),
BottomNavigationBarItem(
title: Text('News'),
icon: Icon(Icons.library_books),
),
],
),
body: Center(
child: _widgetOptions.elementAt(_selectedIndex),
),
);
}
List _widgetOptions = [
Column(
// mainAxisAlignment: MainAxisAlignment.spaceBetween,
// crossAxisAlignment:CrossAxisAlignment.center,
children: [
Container(
color: Colors.amber,
child: Row(
children: const [
Expanded(
child: Center(
child: Text('Date',
style: TextStyle(
height: 2.5,
fontSize: 18,
fontWeight: FontWeight.bold,
leadingDistribution: TextLeadingDistribution.even,
)))),
Expanded(
child: Center(
child: Text('Koreanwon/us\$',
style: TextStyle(
height: 2.5,
fontSize: 18,
fontWeight: FontWeight.bold,
leadingDistribution: TextLeadingDistribution.even,
)))),
Expanded(
child: Center(
child: Text('Koreanwon',
style: TextStyle(
height: 2.5,
fontSize: 18,
fontWeight: FontWeight.bold,
leadingDistribution: TextLeadingDistribution.even,
)))),
Expanded(
child: Center(
child: Text('US \$',
style: TextStyle(
height: 2.5,
fontSize: 18,
fontWeight: FontWeight.bold,
leadingDistribution: TextLeadingDistribution.even,
)))),
],
),
),
Expanded(
child: Center(
child: Container(
child: ListView.builder(
itemCount: posts == null ? 0 : posts.length,
itemBuilder: (context, index) {
Post post = posts[index];
return Container(
decoration: const BoxDecoration(
border: Border(
bottom: BorderSide(color: Colors.blueAccent)),
),
child: ListTile(
title: Row(
// mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: <Widget>[
Expanded(child: Center(child: Text(post.date))),
Expanded(child: Center(child: Text(post.rate))),
Expanded(
child: Center(child: Text(post.koreanwon))),
Expanded(child: Center(child: Text(post.dollar))),
],
),
),
// ),
);
}),
),
),
),
],
),
];
}
You're trying to access an instance variable (posts), in another instance variable(_widgetOptions). This is disallowed as you're trying to access something that isn't. Move the initialization into the initState.
import 'package:flutter/material.dart';
import 'package:http/http.dart' as http;
import 'Services.dart';
import 'Post.dart';
void main() {
runApp(MyApp());
}
class MyApp extends StatelessWidget {
const MyApp({Key? key}) : super(key: key);
#override
Widget build(BuildContext context) {
return MaterialApp(
debugShowCheckedModeBanner: false,
title: 'Flutter Demo',
theme: ThemeData(
primarySwatch: Colors.blue,
visualDensity: VisualDensity.adaptivePlatformDensity,
),
home: MyHomePage(title: 'Flutter ListView'),
);
}
}
class MyHomePage extends StatefulWidget {
MyHomePage({Key? key, required this.title}) : super(key: key);
final String title;
#override
_MyHomePageState createState() => _MyHomePageState();
}
class _MyHomePageState extends State<MyHomePage> {
late List<Post> posts;
late bool loading;
late List _widgetOptions;
#override
void initState() {
super.initState();
loading = true;
Services.getPosts().then((list) {
super.setState(() {
posts = list;
loading = false;
});
});
//You have to initialize _widgetOptions into the `initState` method.
_widgetOptions = [
Column(
// mainAxisAlignment: MainAxisAlignment.spaceBetween,
// crossAxisAlignment:CrossAxisAlignment.center,
children: [
Container(
color: Colors.amber,
child: Row(
children: const [
Expanded(
child: Center(
child: Text('Date',
style: TextStyle(
height: 2.5,
fontSize: 18,
fontWeight: FontWeight.bold,
leadingDistribution: TextLeadingDistribution.even,
)))),
Expanded(
child: Center(
child: Text('Koreanwon/us\$',
style: TextStyle(
height: 2.5,
fontSize: 18,
fontWeight: FontWeight.bold,
leadingDistribution: TextLeadingDistribution.even,
)))),
Expanded(
child: Center(
child: Text('Koreanwon',
style: TextStyle(
height: 2.5,
fontSize: 18,
fontWeight: FontWeight.bold,
leadingDistribution: TextLeadingDistribution.even,
)))),
Expanded(
child: Center(
child: Text('US \$',
style: TextStyle(
height: 2.5,
fontSize: 18,
fontWeight: FontWeight.bold,
leadingDistribution: TextLeadingDistribution.even,
)))),
],
),
),
Expanded(
child: Center(
child: Container(
child: ListView.builder(
itemCount: posts == null ? 0 : posts.length,
itemBuilder: (context, index) {
Post post = posts[index];
return Container(
decoration: const BoxDecoration(
border: Border(
bottom: BorderSide(color: Colors.blueAccent)),
),
child: ListTile(
title: Row(
// mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: <Widget>[
Expanded(child: Center(child: Text(post.date))),
Expanded(child: Center(child: Text(post.rate))),
Expanded(
child: Center(child: Text(post.koreanwon))),
Expanded(child: Center(child: Text(post.dollar))),
],
),
),
// ),
);
}),
),
),
),
],
),
];
}
#override
int _selectedIndex = 0;
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text(loading ? 'Loading...' : 'Posts'),
),
bottomNavigationBar: BottomNavigationBar(
type: BottomNavigationBarType.fixed,
backgroundColor: Colors.grey,
selectedItemColor: Colors.white,
unselectedItemColor: Colors.white.withOpacity(.60),
selectedFontSize: 14,
unselectedFontSize: 14,
currentIndex: _selectedIndex,
//현재 선택된 Index
onTap: (int index) {
setState(() {
_selectedIndex = index;
});
},
items: [
BottomNavigationBarItem(
title: Text('Favorites'),
icon: Icon(Icons.favorite),
),
BottomNavigationBarItem(
title: Text('Music'),
icon: Icon(Icons.music_note),
),
BottomNavigationBarItem(
title: Text('Places'),
icon: Icon(Icons.location_on),
),
BottomNavigationBarItem(
title: Text('News'),
icon: Icon(Icons.library_books),
),
],
),
body: Center(
child: _widgetOptions.elementAt(_selectedIndex),
),
);
}
}

I am getting two appBar in flutter app. I am trying to add Drawer widget and TabBar widget in flutter app

main.dart
import 'package:flutter/material.dart';
import 'package:stray_animal_emergencyrescue/signUpPage.dart';
import './commons/commonWidgets.dart';
import 'package:stray_animal_emergencyrescue/loggedIn.dart';
void main() {
runApp(MyApp());
}
class MyApp extends StatelessWidget {
// This widget is the root of your application.
#override
Widget build(BuildContext context) {
return MaterialApp(
//title: 'Flutter login UI',
theme: ThemeData(
primarySwatch: Colors.blue,
),
home: MyHomePage(),
);
}
}
class MyHomePage extends StatefulWidget {
MyHomePage({Key key, this.title}) : super(key: key);
final String title;
#override
_MyHomePageState createState() => _MyHomePageState();
}
class _MyHomePageState extends State<MyHomePage> {
//String showPasswordText = "Show Password";
bool obscurePasswordText = true;
#override
Widget build(BuildContext context) {
final passwordField = TextField(
obscureText: obscurePasswordText,
decoration: InputDecoration(
//contentPadding: EdgeInsets.fromLTRB(20.0, 15.0, 20.0, 15.0),
hintText: "Password",
//border: OutlineInputBorder(borderRadius: BorderRadius.circular(32.0)),
suffixIcon: IconButton(
icon: new Icon(Icons.remove_red_eye),
onPressed: () {
setState(() {
this.obscurePasswordText = !obscurePasswordText;
});
},
)),
);
final loginButon = Material(
//elevation: 5.0,
//borderRadius: BorderRadius.circular(30.0),
color: Colors.blue,
child: MaterialButton(
//minWidth: MediaQuery.of(context).size.width,
//padding: EdgeInsets.fromLTRB(20.0, 15.0, 20.0, 15.0),
onPressed: () {
//print(MediaQuery.of(context).size.width);
Navigator.pushReplacement(
context,
MaterialPageRoute(builder: (context) => LogIn()),
);
},
child: Text('Login', textAlign: TextAlign.center),
),
);
final facebookContinueButton = Material(
//borderRadius: BorderRadius.circular(30.0),
color: Colors.blue,
child: MaterialButton(
//minWidth: MediaQuery.of(context).size.width,
//padding: EdgeInsets.fromLTRB(20.0, 15.0, 20.0, 15.0),
onPressed: () {
//print(MediaQuery.of(context).size.width);
},
child: Text('Facebook', textAlign: TextAlign.center),
),
);
final googleContinueButton = Material(
//borderRadius: BorderRadius.circular(30.0),
color: Colors.blue,
child: MaterialButton(
//minWidth: MediaQuery.of(context).size.width,
//padding: EdgeInsets.fromLTRB(20.0, 15.0, 20.0, 15.0),
onPressed: () {
//print(MediaQuery.of(context).size.width);
},
child: Text('Google ', textAlign: TextAlign.center),
),
);
final signUpButton = Material(
//borderRadius: BorderRadius.circular(30.0),
color: Colors.blue,
child: MaterialButton(
//minWidth: MediaQuery.of(context).size.width,
//padding: EdgeInsets.fromLTRB(20.0, 15.0, 20.0, 15.0),
onPressed: () {
Navigator.push(
context,
MaterialPageRoute(builder: (context) => FormScreen()),
);
//print(MediaQuery.of(context).size.width);
},
child: Text('Sign Up ', textAlign: TextAlign.center),
),
);
return Scaffold(
appBar: AppBar(
title: Text("Animal Emergency App"),
),
body: Center(
child: Container(
//color: Colors.white,
child: Padding(
padding: const EdgeInsets.all(36.0),
child: Column(
crossAxisAlignment: CrossAxisAlignment.center,
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
//SizedBox(height: 45.0),
getTextFieldWidget(),
SizedBox(height: 15.0),
passwordField,
sizedBoxWidget,
Row(
mainAxisAlignment: MainAxisAlignment.center,
children: [
facebookContinueButton,
SizedBox(width: 5),
googleContinueButton,
SizedBox(width: 5),
loginButon
],
),
/*loginButon,
signUpButton,*/
sizedBoxWidget,
const Divider(
color: Colors.black,
height: 20,
thickness: 1,
indent: 20,
endIndent: 0,
),
Row(
mainAxisAlignment: MainAxisAlignment.center,
//crossAxisAlignment: CrossAxisAlignment.stretch,
children: [
signUpButton
],
),
],
),
),
),
),
);
}
}
loggedIn.dart
import 'package:flutter/material.dart';
import './tabbarviews/emergencyresue/EmergencyHome.dart';
import './tabbarviews/animalcruelty/animalCrueltyHome.dart';
import './tabbarviews/bloodbank/bloodBankHome.dart';
class LogIn extends StatefulWidget {
#override
_LogInState createState() => _LogInState();
}
class _LogInState extends State<LogIn> {
int _selectedIndex = 0;
static const TextStyle optionStyle =
TextStyle(fontSize: 30, fontWeight: FontWeight.bold);
static List<Widget> _widgetOptions = <Widget>[
EmergencyHome(),
AnimalCrueltyHome(),
BloodBankHome()
];
void _onItemTapped(int index) {
setState(() {
_selectedIndex = index;
});
}
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('First app bar appearing'),
actions: <Widget>[
GestureDetector(
onTap: () {},
child: CircleAvatar(
//child: Text("SC"),
backgroundImage: AssetImage('assets/images/760279.jpg'),
//backgroundImage: ,
),
),
IconButton(
icon: Icon(Icons.more_vert),
color: Colors.white,
onPressed: () {},
),
],
),
drawer: Drawer(
child: ListView(
children: <Widget>[
new ListTile(title: Text("Primary")),
MyListTile(
"Home",
false,
"Your customized News Feed about people you follow, ongoing rescues, nearby activities, adoptions etc.",
3,
Icons.home,
true,
() {}),
MyListTile(
"News & Media Coverage",
false,
"News about incidents which need immediate action, changing Laws",
3,
Icons.home,
false,
() {}),
MyListTile(
"Report",
true,
"Report cases with evidences anonymously",
3,
Icons.announcement,
false,
() {}),
MyListTile(
"Blood Bank",
true,
"Details to donate blood ",
3,
Icons.medical_services,
false,
() {}),
],
),
),
body: _widgetOptions[_selectedIndex],
bottomNavigationBar: BottomNavigationBar(
currentIndex: _selectedIndex,
selectedItemColor: Colors.blue,
items: const <BottomNavigationBarItem>[
BottomNavigationBarItem(
icon: Icon(Icons.pets),
label: 'Emergency Rescue',
),
BottomNavigationBarItem(
icon: Icon(Icons.add_alert),
label: 'Report Cruelty',
),
BottomNavigationBarItem(
icon: Icon(Icons.medical_services),
label: 'Blood Bank',
),
/*BottomNavigationBarItem(
icon: Icon(Icons.school),
label: 'Safe Hands',
backgroundColor: Colors.blue),*/
],
onTap: _onItemTapped,
),
);
}
}
//Safe Hands
class MyListTile extends StatelessWidget {
final String title;
final bool isThreeLine;
final String subtitle;
final int maxLines;
final IconData icon;
final bool selected;
final Function onTap;
MyListTile(this.title, this.isThreeLine, this.subtitle, this.maxLines,
this.icon, this.selected, this.onTap);
#override
Widget build(BuildContext context) {
return ListTile(
title: Text(title),
isThreeLine: isThreeLine,
subtitle:
Text(subtitle, maxLines: maxLines, style: TextStyle(fontSize: 12)),
leading: Icon(icon),
selected: selected,
onTap: onTap);
}
}
EmergencyHome.dart
import 'package:flutter/material.dart';
import './finishedAnimalEmergencies.dart';
import './reportAnimalEmergency.dart';
import './ongoingAnimalEmergencies.dart';
class EmergencyHome extends StatefulWidget {
#override
_EmergencyHomeState createState() => _EmergencyHomeState();
}
class _EmergencyHomeState extends State<EmergencyHome> {
#override
Widget build(BuildContext context) {
return DefaultTabController(
length: 3,
child: Scaffold(
appBar: AppBar(
title: Text("Second appBar appearing"),
bottom: TabBar(
tabs: [
Tab(
//icon: Icon(Icons.more_vert),
text: "Report",
),
Tab(
text: "Ongoing",
),
Tab(
text: "Finished",
)
],
),
),
body: TabBarView(
children: [
ReportAnimalEmergency(),
OngoingAnimalEmergencies(),
FinishedAnimalEmergencies(),
],
),
)
);
}
}
The issue I am facing is two appBar, I tried removing appBar from loggedIn.dart but Drawer hamburger icon is not showing, and I cannot remove appBar from emergencyHome.dart as I wont be able to add Tab bar. What is viable solution for this? Please help how to Structure by app and routes to easily manage navigation within app
Remove the appbar from EmergencyHome.dart
this will remove the second app title. But there will be that shadow from the first app bar so put elvation:0
so, this will look like one appbar now your drawer will also work.
you can use flexibleSpace in EmergencyHome.dart
DefaultTabController(
length: 3,
child: Scaffold(
appBar: AppBar(
flexibleSpace: Column(
mainAxisAlignment: MainAxisAlignment.end,
children: <Widget>[
TabBar(
tabs: [
Tab(
//icon: Icon(Icons.more_vert),
text: "Report",
),
Tab(
text: "Ongoing",
),
Tab(
text: "Finished",
)
],
)
],
),
),
body: TabBarView(
children: [
ReportAnimalEmergency(),
OngoingAnimalEmergencies(),
FinishedAnimalEmergencies(),
],
),
)
);
You don't want to make two appbar to get the drawer property. Use DefaultTabController then inside that you can use scaffold.so, you can have drawer: Drawer() inside that you can also get a appbar with it with TabBar as it's bottom.
This is most suitable for you according to your use case.
i will put the full code below so you can copy it.
void main() {
runApp(const TabBarDemo());
}
class TabBarDemo extends StatelessWidget {
const TabBarDemo({Key? key}) : super(key: key);
#override
Widget build(BuildContext context) {
return MaterialApp(
home: DefaultTabController(
length: 3,
child: Scaffold(
drawer: Drawer(),
appBar: AppBar(
bottom: const TabBar(
tabs: [
Tab(
text: "report",
),
Tab(text: "ongoing"),
Tab(text: "completed"),
],
),
title: const Text('Tabs Demo'),
),
body: const TabBarView(
children: [
Icon(Icons.directions_car),
Icon(Icons.directions_transit),
Icon(Icons.directions_bike),
],
),
),
),
);
}
}
OUTPUT

Adding an Icon to a List using a button and actively updating UI using Provider state management

I want to add an Icon to a List following UI update using flutter Provider state Management.
I was successful to add an Icon using the floating button and confirm the result by printing the new List length. This ensures the addition of an Icon to a List but it does not update the UI for the new added Icon. Snippets are below
#override
_MedicalCosmeticsDetailsPageState createState() =>
_MedicalCosmeticsDetailsPageState();
}
class _MedicalCosmeticsDetailsPageState
extends State<MedicalCosmeticsDetailsPage> {
#override
Widget build(BuildContext context) {
Size size = MediaQuery.of(context).size;
return ChangeNotifierProvider<GridIcons>(
create: (context) => GridIcons(),
child: SafeArea(
child: Scaffold(
appBar: AppBar(
automaticallyImplyLeading: true,
iconTheme: IconThemeData(color: Colors.purple),
title: Text(
'xyz',
style: TextStyle(color: Colors.purple),
),
backgroundColor: Colors.transparent,
elevation: size.width * 0.05,
actions: [
Padding(
padding: EdgeInsets.only(right: size.width * 0.01),
child: IconButton(
icon: Icon(
Icons.search,
),
onPressed: () {},
),
),
],
),
body: GridViewPage(),
floatingActionButton: Consumer<GridIcons>(
builder: (context, myIcons, _) {
return FloatingActionButton(
child: Icon(Icons.add),
onPressed: () {
print(myIcons.iconList.length);
myIcons.addIcon();
},
);
},
),
),
),
);
}
}
```//floating button for adding an ICON
```class GridIcons with ChangeNotifier {
List<IconData> iconList = [
Icons.ac_unit,
Icons.search,
Icons.arrow_back,
Icons.hdr_on_sharp,
];
addIcon<IconData>() {
iconList.add(Icons.sentiment_dissatisfied);
notifyListeners();
}
getIconList<IconData>() {
return iconList;
}
}
```//Function for icon addition
class GridViewPage extends StatelessWidget {
#override
Widget build(BuildContext context) {
List _iconList = GridIcons().getIconList();
return ChangeNotifierProvider<GridIcons>(
create: (context) => GridIcons(),
child: Consumer<GridIcons>(
builder: (context, myIcon, child) {
return GridView.builder(
itemCount: _iconList.length,
padding: EdgeInsets.all(8.0),
gridDelegate: SliverGridDelegateWithMaxCrossAxisExtent(
maxCrossAxisExtent: 250.0),
itemBuilder: (BuildContext context, int index) {
print('_buildGridViewBuilder $index');
return Card(
color: Colors.purple.shade300,
margin: EdgeInsets.all(8.0),
child: InkWell(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
Icon(
_iconList[index],
size: 48.0,
color: Colors.purple.shade100,
),
Divider(),
Text(
'Index $index',
textAlign: TextAlign.center,
style: GoogleFonts.dmSans(
fontSize: 16,
color: Colors.white,
),
),
],
),
onTap: () {
print('Row: $index');
},
),
);
},
);
},
),
);
}
}
The icon doesn't appear in the UI although an icon is added to the Icon List.
You can copy paste run full code below
Step 1: In GridViewPage, you do not need ChangeNotifierProvider
Step 2: remove List _iconList = GridIcons().getIconList();
Step 3: use myIcon.iconList.length and myIcon.iconList[index]
code snippet
class GridViewPage extends StatelessWidget {
#override
Widget build(BuildContext context) {
//List _iconList = GridIcons().getIconList();
return Consumer<GridIcons>(
builder: (context, myIcon, child) {
return GridView.builder(
itemCount: myIcon.iconList.length,
...
Icon(
myIcon.iconList[index],
size: 48.0,
working demo
full code
import 'package:flutter/material.dart';
import 'package:google_fonts/google_fonts.dart';
import 'package:provider/provider.dart';
class MedicalCosmeticsDetailsPage extends StatefulWidget {
#override
_MedicalCosmeticsDetailsPageState createState() =>
_MedicalCosmeticsDetailsPageState();
}
class _MedicalCosmeticsDetailsPageState
extends State<MedicalCosmeticsDetailsPage> {
#override
Widget build(BuildContext context) {
Size size = MediaQuery.of(context).size;
return ChangeNotifierProvider<GridIcons>(
create: (context) => GridIcons(),
child: SafeArea(
child: Scaffold(
appBar: AppBar(
automaticallyImplyLeading: true,
iconTheme: IconThemeData(color: Colors.purple),
title: Text(
'xyz',
style: TextStyle(color: Colors.purple),
),
backgroundColor: Colors.transparent,
elevation: size.width * 0.05,
actions: [
Padding(
padding: EdgeInsets.only(right: size.width * 0.01),
child: IconButton(
icon: Icon(
Icons.search,
),
onPressed: () {},
),
),
],
),
body: GridViewPage(),
floatingActionButton: Consumer<GridIcons>(
builder: (context, myIcons, _) {
return FloatingActionButton(
child: Icon(Icons.add),
onPressed: () {
print(myIcons.iconList.length);
myIcons.addIcon();
},
);
},
),
),
),
);
}
}
class GridIcons with ChangeNotifier {
List<IconData> iconList = [
Icons.ac_unit,
Icons.search,
Icons.arrow_back,
Icons.hdr_on_sharp,
];
addIcon<IconData>() {
iconList.add(Icons.sentiment_dissatisfied);
notifyListeners();
}
getIconList<IconData>() {
return iconList;
}
}
class GridViewPage extends StatelessWidget {
#override
Widget build(BuildContext context) {
//List _iconList = GridIcons().getIconList();
return Consumer<GridIcons>(
builder: (context, myIcon, child) {
return GridView.builder(
itemCount: myIcon.iconList.length,
padding: EdgeInsets.all(8.0),
gridDelegate: SliverGridDelegateWithMaxCrossAxisExtent(
maxCrossAxisExtent: 250.0),
itemBuilder: (BuildContext context, int index) {
print('_buildGridViewBuilder $index');
return Card(
color: Colors.purple.shade300,
margin: EdgeInsets.all(8.0),
child: InkWell(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
Icon(
myIcon.iconList[index],
size: 48.0,
color: Colors.purple.shade100,
),
Divider(),
Text(
'Index $index',
textAlign: TextAlign.center,
style: GoogleFonts.dmSans(
fontSize: 16,
color: Colors.white,
),
),
],
),
onTap: () {
print('Row: $index');
},
),
);
},
);
},
);
}
}
void main() {
runApp(MyApp());
}
class MyApp extends StatelessWidget {
#override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter Demo',
theme: ThemeData(
primarySwatch: Colors.blue,
visualDensity: VisualDensity.adaptivePlatformDensity,
),
home: MedicalCosmeticsDetailsPage());
}
}