how to Navigate to a new screen onclick BottomAppBar icon? - dart

i want to navigate to new screen on click icons of BottomAppBar but i get an error :
only static members can be accessed in initializers
final makeBottom = Container(
height: 45.0,
child: BottomAppBar(
color: Colors.white,
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
children: <Widget>[
IconButton(
icon: Icon(Icons.home, color: Color.fromARGB(255, 30, 110, 160)),
onPressed: navigateToPage,//only static members can be accessed in initializers
),
IconButton(
icon: Icon(Icons.search, color: Color.fromARGB(255, 30, 110, 160)),
onPressed: () {},
),
IconButton(
icon: Icon(Icons.star, color: Color.fromARGB(255, 30, 110, 160)),
onPressed: () {},
),
IconButton(
icon: Icon(Icons.favorite_border,
color: Color.fromARGB(255, 30, 110, 160)),
onPressed: () {},
),
IconButton(
icon: Icon(Icons.account_circle,
color: Color.fromARGB(255, 30, 110, 160)),
onPressed: () {},
),
],
),
),
);
the method navigateToPage
void navigateToPage() async {
Navigator.push(
context,
MaterialPageRoute(
builder: (context) => Userqst(
user: widget.user,
),
fullscreenDialog: true));
}

Try this below code..
return Scaffold{
bottomNavigationBar : bottomNav() // call the Widget
}
Widget bottomNav(){
return new Container (
height :45.0,
//Copy the bottomAppBar code
);
}

Problem can be your method can't get context
So at your Iconbutton pass context like this
IconButton(
icon: Icon(Icons.home, color: Color.fromARGB(255, 30, 110, 160)),
onPressed: (){navigateToPage(context);},//only static members can be accessed in initializers
),
And try modifying method like this
void navigateToPage(BuildContext context) async {
Navigator.push(
context,
MaterialPageRoute(
builder: (context) => Userqst(
user: widget.user,
),
fullscreenDialog: true));
}

I think you're trying to build that Widget out of the "Widget build(BuildContext context)" context, that's why you're having this problem.
I thought about 2 solutions for that.
First, you place your code into the main function "Widget build(BuildContext context)" and call the Widget wherever you want to.
#override
Widget build(BuildContext context){
//here you put your "final makeBottom" code;
return Scaffold(//and somewhere around there you place your "makeBottom" Widget);
}
Second, wrap your whole code as a Function which will return that Container() and then call it into the "build" function.
Widget makeBottom(BuildContext context){
return //your Container();
}

Below code may help you -
class Home extends StatefulWidget {
#override
State<StatefulWidget> createState() {
return _HomeState();
}
}
class _HomeState extends State<Home> {
int _currentIndex = 0;
final List<Widget> _children = [
HomeListView(),
MyGridView()
];
var _title = 'Home';
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
backgroundColor: Color.fromRGBO(41, 167, 77, 50),
title: Text(_title, textAlign: TextAlign.center),
),
body: _children[_currentIndex],
bottomNavigationBar: BottomNavigationBar(
onTap: onTabTapped,
selectedItemColor: Color.fromRGBO(33, 137, 38, 60),
type: BottomNavigationBarType.fixed,
backgroundColor: Color.fromRGBO(252, 207, 3, 60),
currentIndex: _currentIndex,
// this will be set when a new tab is tapped
items: [
BottomNavigationBarItem(
icon: new Icon(Icons.home),
title: new Text('Home'),
),
BottomNavigationBarItem(
icon: new Icon(Icons.mail),
title: new Text('My Venue'),
)
],
),
);
}
void onTabTapped(int index) {
setState(() {
_currentIndex = index;
switch (index) {
case 0:
_title = 'Home';
break;
case 1:
_title = 'My Venue';
break;
}
});
}
}

Related

Unhandled Exception: Bad state: No element

My build was working fine until I added an image to the launch screen, when I started getting a PhaseScript error. I had to completely delete the ios folder, recreate it, and then make the necessary manual changes again. Now when I run the build on a simulator through android studio, I get this error once the app starts:
[VERBOSE-2:ui_dart_state.cc(209)] Unhandled Exception: Bad state: No element
#0 List.first (dart:core-patch/growable_array.dart:339:5)
#1 main (package:globe_flutter/main.dart:19:25)
<asynchronous suspension>
Nothing shows up on the screen. I use a tabBar in the main.dart and a tabBarView to show the different screens. Here is the main.dart:
var firstCamera;
Future<void> main() async {
WidgetsFlutterBinding.ensureInitialized();
// Obtain a list of the available cameras on the device.
final cameras = await availableCameras();
// Get a specific camera from the list of available cameras.
firstCamera = cameras.first;
await Firebase.initializeApp();
runApp(MyApp());
}
// void main() async {
// WidgetsFlutterBinding.ensureInitialized();
// await Firebase.initializeApp();
// runApp(MyApp());
// }
class MyApp extends StatelessWidget {
const MyApp({Key? key}) : super(key: key);
// This widget is the root of your application.
#override
Widget build(BuildContext context) {
return MaterialApp(
title: 'GLOBE',
debugShowCheckedModeBanner: false,
home: const MyHome(),
routes: {
LoginScreen.id: (context) => LoginScreen(),
SignupScreen.id: (context) => SignupScreen(),
HomeScreen.id: (context) => HomeScreen()
},
);
}
}
class MyHome extends StatefulWidget {
const MyHome({Key? key}) : super(key: key);
#override
_MyHomeState createState() => _MyHomeState();
}
class _MyHomeState extends State<MyHome> with SingleTickerProviderStateMixin {
late TabController _tabController;
#override
void initState() {
super.initState();
_tabController = TabController(length: 5, vsync: this);
}
#override
void dispose() {
super.dispose();
_tabController.dispose();
}
#override
Widget build(BuildContext context) {
return Scaffold(
body: TabBarView(
children: [
HomeScreen(),
HomeScreen(),
TakePictureScreen(camera: firstCamera),
HomeScreen(),
ProfileScreen(username: "cjmofficial")
],
controller: _tabController
),
extendBody: true,
bottomNavigationBar: Container(
color: Colors.transparent,
padding: EdgeInsets.symmetric(vertical: 40, horizontal: 40),
child: ClipRRect(
clipBehavior: Clip.hardEdge,
borderRadius: BorderRadius.circular(50.0),
child: Container(
height: 55,
color: Colors.grey[200],
child: TabBar(
labelColor: Colors.teal[200],
unselectedLabelColor: Colors.blueGrey,
indicator: UnderlineTabIndicator(
borderSide: BorderSide(color: Colors.teal),
insets: EdgeInsets.fromLTRB(50, 0, 50, 40)
),
indicatorColor: Colors.teal,
tabs: [
Tab(icon: Icon(Icons.home_outlined)),
Tab(icon: Icon(Icons.explore_outlined)),
Tab(icon: Icon(Icons.camera_alt_outlined)),
Tab(icon: Icon(Icons.movie_outlined)),
Tab(icon: Icon(Icons.person_outline))
],
controller: _tabController),
),
),
),
);
}
}
and the first screen that is supposed to show in the TabBarView:
class HomeScreen extends StatefulWidget {
const HomeScreen({Key? key}) : super(key: key);
static const String id = "home_screen";
#override
_HomeScreenState createState() => _HomeScreenState();
}
class _HomeScreenState extends State<HomeScreen> {
Color _likeButtonColor = Colors.black;
Widget _buildPost(String username, String imageUrl, String caption, String pfpUrl) {
return Container(
color: Colors.white,
child: Column(
children: [
GestureDetector(
onTap: (){},
child: Container(
height: 50,
color: Colors.deepOrangeAccent[100],
child: Row(
children: [
SizedBox(width: 5),
CircleAvatar(
child: ClipOval(
child: Image.network(
pfpUrl,
height: 40,
width: 40,
),
),
),
SizedBox(width: 10),
Icon(Icons.more_vert, size: 20),
SizedBox(width: 10),
Text(username, style: TextStyle(fontSize: 15))
],
),
),
),
Stack(
children: [
Image.asset("images/post_background.jpg"),
Padding(
padding: const EdgeInsets.all(20.0),
child: ClipRRect(
borderRadius: BorderRadius.circular(8.0),
child: Image.network(imageUrl, fit: BoxFit.cover)),
),
],
),
Container(
height: 100,
child: Column(
children: [
const SizedBox(height: 5),
Row(
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
children: [
IconButton(
onPressed: () {
setState(() {
HapticFeedback.lightImpact();
});
},
icon: Icon(Icons.thumb_up_alt_outlined, size: 30)),
Text("l", style: TextStyle(fontSize: 30)),
IconButton(
onPressed: () {
setState(() {
HapticFeedback.lightImpact();
GallerySaver.saveImage(imageUrl);
});
},
icon: Icon(Icons.ios_share, size: 30))
],
),
Row(
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
children: [
Text(caption, style: const TextStyle(fontSize: 15))
],
)
],
),
)
],
),
);
}
List<Post> listPosts = [];
fetchPosts() async {
final userRef = FirebaseFirestore.instance.collection('users');
final QuerySnapshot result = await userRef.get();
result.docs.forEach((res) async {
print(res.id);
QuerySnapshot posts = await userRef.doc(res.id).collection("posts").get();
posts.docs.forEach((res) {
listPosts.add(Post.fromJson(res.data() as Map<String, dynamic>));
});
// Other method
// listPosts = posts.docs.map((doc) => Post.fromJson(doc.data() as Map<String, dynamic>)).toList();
setState(() {});
});
setState(() {
listPosts.sort((a, b) => a.postedDate.compareTo(b.postedDate));
});
}
pfpUrl(String username) async {
// Get pfpUrl
String downloadURL = await FirebaseStorage.instance
.ref(username + "/profile_picture.png")
.getDownloadURL();
return downloadURL;
}
#override
void initState() {
fetchPosts();
super.initState();
}
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: PreferredSize(
preferredSize: Size.fromHeight(45.0),
child: AppBar(
leading:
Icon(Icons.monetization_on_outlined, color: Colors.blueGrey),
centerTitle: true,
title: Text("GLOBE", style: TextStyle(color: Colors.blueGrey)),
actions: [
Icon(Icons.search, color: Colors.blueGrey),
SizedBox(width: 10)
],
backgroundColor: Colors.tealAccent[100]),
),
body: ListView.builder(
itemCount: listPosts.length,
itemBuilder: (BuildContext context, int index) {
// We retrieve the post at index « index »
final post = listPosts[index];
// Get name from id
var parts = post.id.split('_');
var username = parts[0].trim();
// Get pfpUrl
String pfpUrlString = "https://play-lh.googleusercontent.com/IeNJWoKYx1waOhfWF6TiuSiWBLfqLb18lmZYXSgsH1fvb8v1IYiZr5aYWe0Gxu-pVZX3";
return _buildPost(username, post.postUrlString, post.caption, pfpUrlString);
}),
);
}
}
I'm new to flutter and all I can understand about this is that something cannot load. I also ran a build with verbose but it didn't give anymore information. If someone can help me understand the issue, that would be great.
Ios simulators do not have cameras so on line 19, when firstCamera = cameras.first is called, there is no first camera.

AlertDialog setstate in Function/OnTap

new to flutter. I know how to set state the alert dialog, but with the need of tap to function like ()=> _createPlayer, It does not want to rebuild the alert dialog.
I wonder how to set state on alert dialog when you need to tap them.
File _image;
GestureDetector(
onTap: () => _createPlayer(),
After tap, it will display an alert dialog like this:
_createPlayer() {
return showDialog(
context: context,
builder: (BuildContext context) {
return AlertDialog(
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.all(Radius.circular(32.0))),
content: Container(
height: 400,
width: 300,
child: Column(
children: <Widget>[
Text('Create Player', style: Theme
.of(context)
.textTheme
.body1),
GestureDetector(
onTap: _getImageCamera,
child: CircleAvatar(
radius: 100,
backgroundColor: Colors.white,
backgroundImage: _image != null ? FileImage(_image) : AssetImage('assets/images/undercover.png'),
),
),
],
),
),
);
});
}
_getImageCamera() async{
var image = await ImagePicker.pickImage(source: ImageSource.camera);
setState(() {
_image = image;
});
}
I want to set state/change the image in alert dialog when selected. Any idea?
You can use StatefulBuilder for change inside dialog
showDialog(
context: context,
builder: (context) {
String contentText = "Content of Dialog";
// add StatefulBuilder to return value
return StatefulBuilder(
builder: (context, setState) {
return AlertDialog(
title: Text("Title of Dialog"),
content: Text(contentText),
actions: <Widget>[
FlatButton(
onPressed: () => Navigator.pop(context),
child: Text("Cancel"),
),
FlatButton(
onPressed: () {
setState(() {
contentText = "Changed Content of Dialog";
});
},
child: Text("Change"),
),
],
);
},
);
},
);
Create a separate Stateful Widget CustomDialog for the AlertDialog and move the _getImageCamera function _image variable inside it like this
_createPlayer() {
return CustomDialog();
}
class CustomDialog extends StatefulWidget {
#override
State<StatefulWidget> createState() {
return CustomDialogState();
}
}
class CustomDialogState extends State<CustomDialog> {
ImageProvider _image;
#override
void initState() {
super.initState();
}
#override
Widget build(BuildContext context) {
return AlertDialog(
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.all(Radius.circular(32.0))),
content: Container(
height: 400,
width: 300,
child: Column(
children: <Widget>[
Text('Create Player', style: Theme
.of(context)
.textTheme
.body1),
GestureDetector(
onTap: _getImageCamera,
child: CircleAvatar(
radius: 100,
backgroundColor: Colors.white,
backgroundImage: _image != null ? FileImage(_image) : AssetImage('assets/images/undercover.png'),
),
),
],
),
),
);
});
}
_getImageCamera() async{
var image = await ImagePicker.pickImage(source: ImageSource.camera);
setState(() {
_image = image;
});
}
}
In order to see UI changes on showDialog, you have to create a new StatefulWidget and then work with dialog in that class. Here is the example/sample code
The most stupidest and quickest fix is:
Navigator.of(context).pop();
Then call the showDialog() again.
There will be a micro delay but works.

Container icons changes for all on selection one

I am new to flutter this is my problem,
When I select an icon, I am selecting all the other item in the container
I am not able to change the color of container to green when selected
not only on icon but also on container function onpressed
class _AddEmpToProjectState extends State<AddEmpToProject> {
bool _isSelected = false;
Container addEmpListTile() {
return Container(
margin: EdgeInsets.fromLTRB(10.0, 0.0, 10.0, 10.0),
padding: EdgeInsets.all(5.0),
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(10.0), color: Colors.white),
child: Container(
child: ListTile(
leading: CircleAvatar(
backgroundImage: AssetImage('assets/tom.jpg'),
),
title: Text('Sam'),
subtitle: Text('Site Manager'),
trailing: InkWell(
onTap: () {
_isSelected = !_isSelected;
setState(() {});
},
child: _isSelected
? Icon(
Icons.done,
color: Colors.green,
size: 35.0,
)
: Icon(
Icons.add,
color: Colors.deepPurple,
size: 35.0,
))),
));
}
#override
Widget build(BuildContext context) {
return Scaffold(
backgroundColor: Colors.deepPurple,
appBar: AppBar(
title: Text('Add Employees'),
elevation: 0.0,
actions: <Widget>[
IconButton(
icon: Icon(
Icons.search,
color: Colors.white,
),
onPressed: () {},
),
IconButton(
icon: Icon(
Icons.done,
color: Colors.white,
),
onPressed: () {},
)
],
),
body: ListView.builder(
itemCount: 10,
itemBuilder: (BuildContext context, int index) {
return addEmpListTile();
},
),
);
}
}
when container is tapped change color to green and should move to top
if deselected must return back to the array widget index
this is what i am expected to do
Need to track in some way which item is selected (some sort of identifier), not only the fact that an item is selected (boolean).
One solution can be to use index as tracking number
class _AddEmpToProjectState extends State<AddEmpToProject> {
-bool _isSelected = false;
+Set<int> _selected = Set();
...
class _AddEmpToProjectState extends State<AddEmpToProject> {
Set<int> _selected = Set();
Container addEmpListTile(int index) {
...
onTap: () {
setState(() {
if(_selected.contains(index)) {
_selected.remove(index);
} else {
_selected.remove(index);
};
}
},
child: _selected.contains(index)
? Icon(Icons.done)
: Icon(Icons.add)
}
...
build() {
...
itemBuilder: (BuildContext context, int index) {
return addEmpListTile(index); // <-- add index here
...
}

How to use a dismissible widget inside a CustomScrollView in Flutter?

I am trying to create a list of dismissible cards inside a customscrollview. The cards are getting rendered, but when i swipe the cards to dismiss them , they don't get removed from the list. Below is the code. Please help.
CustomScrollView customScroll = new CustomScrollView(
slivers: <Widget>[
new SliverAppBar(
backgroundColor: Colors.black,
automaticallyImplyLeading: false,
expandedHeight: 90.0,
title: new Text("Test"),
),
new SliverFixedExtentList(
itemExtent: 128.0,
delegate: new SliverChildBuilderDelegate(
(BuildContext context, int index) {
return new Dismissible(key: new ObjectKey(objects[index]),
child: widget.widgetAdapter(objects[index]),
onDismissed: (DismissDirection direction) {
setState(() {
this.objects.removeAt(index);
this.reIndex();
});
direction == DismissDirection.endToStart ? print(
"favourite") : print("remove");
},
background: new Container(
color: const Color.fromRGBO(183, 28, 28, 0.8),
child: const ListTile(
leading: const Icon(
Icons.delete, color: Colors.white, size: 36.0)
)
),
secondaryBackground: new Container(
color: const Color.fromRGBO(0, 96, 100, 0.8),
child: const ListTile(
trailing: const Icon(
Icons.favorite, color: Colors.white, size: 36.0)
)
),
);
},
childCount: objects.length,
),
),
]
);
your attempt is basically correct - I have simplified list creation and replaced it in your sample code below - what you are looking for is in the dmiss function # line 35;
import 'package:flutter/material.dart';
class TestDismissCSV extends StatefulWidget {
#override
_TestDismissCSVState createState() => new _TestDismissCSVState();
}
class _TestDismissCSVState extends State<TestDismissCSV> {
#override
Widget build(BuildContext context) {
return new MaterialApp(
title: "Dismiss in Cust Scroll V",
theme: new ThemeData(brightness: Brightness.dark),
home: new Scaffold(
body: dmiss(context),
),
);
}
List<TheListClass> _theList;
Widget dmiss(context) {
return new CustomScrollView(slivers: <Widget>[
new SliverAppBar(
backgroundColor: Colors.black,
automaticallyImplyLeading: false,
expandedHeight: 90.0,
title: new Text("Test"),
),
new SliverFixedExtentList(
itemExtent: 128.0,
delegate: new SliverChildBuilderDelegate(
(BuildContext context, int index) {
return new Dismissible(
key: new ObjectKey(_theList[index]),
child: new Material(child: new Text(_theList[index].title)),
onDismissed: (DismissDirection direction) {
setState(() {
this._theList.removeAt(index);
//this.reIndex();
});
direction == DismissDirection.endToStart
? print("favourite")
: print("remove");
},
background: new Container(
color: const Color.fromRGBO(183, 28, 28, 0.8),
child: const ListTile(
leading: const Icon(Icons.delete,
color: Colors.white, size: 36.0))),
secondaryBackground: new Container(
color: const Color.fromRGBO(0, 96, 100, 0.8),
child: const ListTile(
trailing: const Icon(Icons.favorite,
color: Colors.white, size: 36.0))),
);
},
childCount: _theList.length,
),
),
]);
}
#override
void initState() {
super.initState();
_theList = new List<TheListClass>();
for (var i = 0; i < 100; i++) {
_theList.add(new TheListClass('List Item ' + i.toString()));
}
}
#override
void dispose() {
super.dispose();
}
}
class TheListClass {
String title;
TheListClass(this.title);
}
List Item dismissed
Happy coding!

Flutter floating action button with speed dial

Is there any ready made widget or where to get started floating action button with speed dial actions in Flutter.
Here's a sketch of how to implement a Speed dial using FloatingActionButton.
import 'package:flutter/material.dart';
import 'dart:math' as math;
void main() {
runApp(new MyApp());
}
class MyApp extends StatelessWidget {
#override
Widget build(BuildContext context) {
return new MaterialApp(
home: new MyHomePage(),
);
}
}
class MyHomePage extends StatefulWidget {
#override
State createState() => new MyHomePageState();
}
class MyHomePageState extends State<MyHomePage> with TickerProviderStateMixin {
AnimationController _controller;
static const List<IconData> icons = const [ Icons.sms, Icons.mail, Icons.phone ];
#override
void initState() {
_controller = new AnimationController(
vsync: this,
duration: const Duration(milliseconds: 500),
);
}
Widget build(BuildContext context) {
Color backgroundColor = Theme.of(context).cardColor;
Color foregroundColor = Theme.of(context).accentColor;
return new Scaffold(
appBar: new AppBar(title: new Text('Speed Dial Example')),
floatingActionButton: new Column(
mainAxisSize: MainAxisSize.min,
children: new List.generate(icons.length, (int index) {
Widget child = new Container(
height: 70.0,
width: 56.0,
alignment: FractionalOffset.topCenter,
child: new ScaleTransition(
scale: new CurvedAnimation(
parent: _controller,
curve: new Interval(
0.0,
1.0 - index / icons.length / 2.0,
curve: Curves.easeOut
),
),
child: new FloatingActionButton(
heroTag: null,
backgroundColor: backgroundColor,
mini: true,
child: new Icon(icons[index], color: foregroundColor),
onPressed: () {},
),
),
);
return child;
}).toList()..add(
new FloatingActionButton(
heroTag: null,
child: new AnimatedBuilder(
animation: _controller,
builder: (BuildContext context, Widget child) {
return new Transform(
transform: new Matrix4.rotationZ(_controller.value * 0.5 * math.pi),
alignment: FractionalOffset.center,
child: new Icon(_controller.isDismissed ? Icons.share : Icons.close),
);
},
),
onPressed: () {
if (_controller.isDismissed) {
_controller.forward();
} else {
_controller.reverse();
}
},
),
),
),
);
}
}
This plugin could serve you:
https://pub.dartlang.org/packages/flutter_speed_dial
You need declare the dependency in the pubspect.yaml file
dependencies:
flutter:
sdk: flutter
flutter_speed_dial: ^1.0.9
Here is an example:
Widget build(BuildContext context) {
return Scaffold(
floatingActionButton: SpeedDial(
animatedIcon: AnimatedIcons.menu_close,
animatedIconTheme: IconThemeData(size: 22.0),
// this is ignored if animatedIcon is non null
// child: Icon(Icons.add),
visible: _dialVisible,
curve: Curves.bounceIn,
overlayColor: Colors.black,
overlayOpacity: 0.5,
onOpen: () => print('OPENING DIAL'),
onClose: () => print('DIAL CLOSED'),
tooltip: 'Speed Dial',
heroTag: 'speed-dial-hero-tag',
backgroundColor: Colors.white,
foregroundColor: Colors.black,
elevation: 8.0,
shape: CircleBorder(),
children: [
SpeedDialChild(
child: Icon(Icons.accessibility),
backgroundColor: Colors.red,
label: 'First',
labelStyle: TextTheme(fontSize: 18.0),
onTap: () => print('FIRST CHILD')
),
SpeedDialChild(
child: Icon(Icons.brush),
backgroundColor: Colors.blue,
label: 'Second',
labelStyle: TextTheme(fontSize: 18.0),
onTap: () => print('SECOND CHILD'),
),
SpeedDialChild(
child: Icon(Icons.keyboard_voice),
backgroundColor: Colors.green,
label: 'Third',
labelStyle: TextTheme(fontSize: 18.0),
onTap: () => print('THIRD CHILD'),
),
],
),
);
}

Resources