I would like to create a UI for some screens with a nav bar and FAB in flutter below:
UI design for floating Nav bar And FAB
here is what I have currently:
floatingActionButton: InkWell(
onTap: (){
log('Action Button Tapped');
},
child: Stack(
alignment: Alignment(0,-0.2),
children:[
SvgPicture.asset('assets/svg/floating_button.svg'),
SvgPicture.asset('assets/svg/floating_button_icon.svg'),
]),
),
bottomNavigationBar: Container(
color: Colors.transparent,
padding: EdgeInsets.only(bottom: 30,left: 15, right: 15),
child: ClipRRect(
borderRadius: BorderRadius.all(Radius.circular(25)),
child: Material(
elevation: 100.0,
child: Container(
height: 55,
color: Colors.black12.withOpacity(0.15),
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceAround,
children: [
Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
SvgPicture.asset('assets/svg/colored_home_icon.svg'),
SizedBox(
height: 1.5,
),
Text('Home', style: GoogleFonts.outfit(
color: AppColors.primaryGreen,
fontSize: AppFontSize.s12
),)
],
),
Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
SvgPicture.asset('assets/svg/grey_transfer_icon.svg'),
SizedBox(
height: 1.5,
),
Text('Transactions', style: GoogleFonts.outfit(
color: AppColors.homeDullText,
fontSize: AppFontSize.s12
),)
],
),
Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
SvgPicture.asset('assets/svg/grey_more_icon.svg'),
SizedBox(
height: 1.5,
),
Text('More', style: GoogleFonts.outfit(
color: AppColors.homeDullText,
fontSize: AppFontSize.s12
),)
],
),
],
),
),
),
),
),
and here is the result:result of UI flutter code,
I need help transitioning from what I currently have to the UI requirement... Thanks.
As fast decision you can use floating_navbar lib (https://pub.dev/packages/floating_navbar, but if you want to made it by yourself, you can try this implementation (https://codenameakshay.medium.com/flutter-floating-bottom-bar-how-to-4164a9981afb).
Related
I have a chat messenger screen which looks like the given screenshot .
As you can see , bottom message is hidden behind the text input area .
The messages are listview , built using streambuilder .
I want the messages above the text input area .
https://i.stack.imgur.com/A82X2.png
return Scaffold(
appBar: AppBarMain(context),
body: Container(
child: Stack(
children: [
chatMessageList(),
Positioned(
bottom: 0,
child: Container(
color: Color(0x54ffffff),
child: Container(
padding: EdgeInsets.symmetric(horizontal: 14, vertical: 20),
width: MediaQuery.of(context).size.width,
child: Row(
children: [
Expanded(
child: TextField(
controller: messageController,
style: TextStyle(color: Colors.white),
decoration: InputDecoration(
hintText: ' Message!...',
hintStyle: TextStyle(color: Colors.white54),
border: InputBorder.none),
),
),
InkWell(
onTap: () {
sendMessage();
},
child: Container(
padding: EdgeInsets.all(9),
height: 40,
width: 40,
decoration: BoxDecoration(
gradient: LinearGradient(
colors: [
Color(0x36FFFFFF),
Color(0xFFFFFFFF)
],
),
borderRadius: BorderRadius.circular(40)),
child: Image.asset('assets/images/send.png')),
)
],
),
),
),
)
],
),
),
);
}
}
Your structure should be something like
Column(
crossAxisAlignment: CrossAxisAlignment.stretch,
children: [
Expanded(
child: chatMessageList(),
),
MessageFieldWidget(),
],
)
This will ensure that your chatMessageList will take up all of the space available in the screen and your Message Field will take up only the space that it needs. You don't need to use Positioned or Padding.
I have been trying to find a way on how I can put a navigation in "Widget CardUI" because I want it to redirect the user to another page when they click on it. However, when I try to put the usual Navigator.push(context, MaterialPageRoute(builder: (context)=>PageName()));", it tells me that the context is undefined.
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
leading: IconButton(
icon: Icon(Icons.arrow_back, color: Colors.white),
onPressed: ()
{Navigator.pop(context);
Navigator.push(context, MaterialPageRoute(builder: (context)=>homepage()));}),
title: Text("Creator's Club"),
backgroundColor: Color(0xff2657ce),
elevation: 0,),
body: Container(
padding: EdgeInsets.all(20),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[
Text('Visual Arts', style: TextStyle(
color: Color(0xff2657ce),
fontSize: 27,
),),
Text('Choose which course you want to study.', style: TextStyle(
color: Colors.black.withOpacity(0.6),
fontSize: 20
),),
SizedBox(height: 10),
Expanded(
child: SingleChildScrollView(
child: Column(
children: <Widget>[
coursesList.length == 0 ? Center(child: Text("Loading...", style: TextStyle(fontSize: 15),)): ListView.builder(
scrollDirection: Axis.vertical,
shrinkWrap: true,
physics: const NeverScrollableScrollPhysics(),
itemCount: coursesList.length,
itemBuilder: (_, index) {
return CardUI(coursesList[index].courseName, coursesList[index].teacher, coursesList[index].category);
}
)
]
),
),
),
]
)
)
);
}
}
Widget CardUI (String courseName, String teacher, String category){
return Card(
elevation: 1,
margin: EdgeInsets.all(5),
color: Color(0xffd3defa),
child: Container(
color: Colors.white,
margin: EdgeInsets.all(1),
padding: EdgeInsets.all(10),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[
Row(
children: <Widget>[
Container(
width: 50,
height: 50,
decoration: BoxDecoration(
color: Color(0xffd3defa),
borderRadius: BorderRadius.all(Radius.circular(17)),
),
child: IconButton(
icon: Icon(
Icons.star_border_rounded,
color: Color(0xff2657ce),
),
),
),
SizedBox(width: 15,),
Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[
Container(
child: InkWell(
onTap: () {},
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[
Text(courseName,
style: TextStyle(fontSize: 18)),
SizedBox(height: 5),
Text(teacher, style: TextStyle(
fontSize: 15, color: Colors.grey)),
SizedBox(height: 5),
],
),
)
)
]
)
]
)
],
)
),
);
}
Additionally, is there a way on how I can put an if else condition in the Inkwell onTap? In my code, a bunch of courses are being displayed from realtime database and I want to click on just one of it. In my current code, the Inkwell applies to all the cards being displayed but I just want it to be on one. Are there any alternatives besides using Inkwell?
Try to call
onPressed: () {
Navigator.push(context, MaterialPageRoute(builder: (context)=>homepage()));
},
without pop before.
My flutter ecommerce app is connected to Cloud Firestore backend. I have cart collection that has several documents with title as products which user adds. Each product has a field of order_status that maybe either in_cart or checked_out value. Now I want to render them on my Cart screen and Checked out screen based on the value of order_status. I am using ListView.Builder approach but as there is an itemCount I cannot render specific documents from same collection. What is correct way to do this? Should I store products on two collections?
Code:
ListView.builder(
scrollDirection: Axis.vertical,
shrinkWrap: true,
itemCount: snapshot.data.length,
itemBuilder: (_, index) {
if (snapshot.data[index]['order_status'] == 'in_cart') {
_total = _total + snapshot.data[index]['total'];
return Container(
padding: EdgeInsets.only(bottom: 12.5),
child: Column(
children: [
Container(
height: (MediaQuery.of(context).size.height) / 7,
width: MediaQuery.of(context).size.width,
child: Container(
height: 105,
width: 85,
child: DecoratedBox(
decoration: BoxDecoration(
color: Colors.black12,
),
child: Container(
padding: EdgeInsets.all(10.0),
child: Row(
mainAxisAlignment:
MainAxisAlignment.spaceBetween,
crossAxisAlignment:
CrossAxisAlignment.center,
children: [
SizedBox(
width: 12.0,
),
IconButton(
icon: Image.network(
),
iconSize: 75.0,
onPressed: () {},
),
SizedBox(
width: 30.0,
),
Column(
children: [
Text(
snapshot.data[index]['title'],
style: kHeading1.copyWith(
fontSize: 22.5),
),
SizedBox(
height: 5.0,
),
Text(
'Rs.' +
snapshot.data[index]['price']
.toString() +
'/' +
snapshot.data[index]
['product_unit'],
style: kTitle1,
),
SizedBox(
height: 5.0,
),
Text(
'Total Rs.' +
snapshot.data[index]['total']
.toString(),
style: kTitle1,
),
],
),
SizedBox(
width: 20.0,
),
Row(
children: [
IconButton(
icon: Icon(
Icons.keyboard_arrow_up,
color: Colors.black,
),
onPressed: () {
increaseCart(
snapshot.data[index]
['title'],
snapshot.data[index]
['unit'],
snapshot.data[index]
['price']);
}),
Text(
snapshot.data[index]['unit']
.toString(),
style: kHeading2,
),
IconButton(
icon: Icon(
Icons.keyboard_arrow_down,
color: Colors.black),
onPressed: () {
decreaseCart(
snapshot.data[index]
['title'],
snapshot.data[index]
['unit'],
snapshot.data[index]
['price']);
}),
],
),
],
),
),
),
),
),
],
),
);
} else {
return null;
}
}),
body: StreamBuilder(
stream: Firestore.instance.collection('students').document(_userId).snapshots(),
builder: (context,snapshot) {
return Container(
child: Column(
mainAxisAlignment: MainAxisAlignment.start,
children: <Widget>[
SizedBox(
height: 20.0,
),
Row(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
Padding(
padding: const EdgeInsets.only(left:20.0),
child: Align(
alignment: Alignment.centerRight,
child: CircleAvatar(
radius: 100,
backgroundColor: Colors.white,
child: ClipOval(
child: new SizedBox(
width: 180.0,
height: 180.0,
child: (_image!=null)?Image.file(
_image,
fit: BoxFit.fill,
):
Image.network(""),
),
),
),
),
),
Padding(
padding: EdgeInsets.only(top: 60.0),
child: IconButton(
icon: Icon(
Icons.camera,
size: 30.0,
),
onPressed: () {
getImage();
},
),
),
],
),
SizedBox(
height: 20.0,
),
Row(
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
children: <Widget>[
Padding(
padding: const EdgeInsets.only(left:40.0),
child: Align(
alignment: Alignment.center,
child: Container(
child: Column(
children: <Widget>[
Align(
alignment: Alignment.center,
child: Text('Student Name',
style: TextStyle(
color: Colors.white, fontSize: 20.0)),
),
Align(
alignment: Alignment.center,
child: Text(snapshot.data['first_name'],
style: TextStyle(
color: Colors.black,
fontSize: 18.0,
)),
),
],
),
),
),
),
i want to display student name from cloud firestore but it gives an error upon first loading but after hotreload the app works correctly.
here is my student id retrieving function
FirebaseAuth.instance.currentUser().then((user) {
_userId = user.uid;
});
i am using this id for retrieving a particular student details but it give error upon first loading the error are enter image description here
The database snap are enter image description here
Raised button taking too much width and I want to decrease according to my layout...
ButtonTheme(
minWidth: 16.0,
height: 30.0,
child: RaisedButton(
onPressed:()=>print("a"),
child: new Row(
children: <Widget>[
Padding(
padding: const EdgeInsets.only(right: 6.0),
child: Text('SORT BY',style: TextStyle(fontSize: 12.0),),
),
Icon(Icons.keyboard_arrow_down,size: 20.0,),
],
),
),
),
I got the answer
We need to add padding in Raised button for removing default padding
ButtonTheme(
minWidth: 16.0,
height: 30.0,
child: RaisedButton(
padding: const EdgeInsets.all(8.0),
onPressed: () => print("a"),
child: new Row(
children: <Widget>[
Padding(
padding: const EdgeInsets.only(right: 6.0),
child: Icon(
Icons.filter,
size: 16.0,
),
),
Text(
'FILTER',
style: TextStyle(fontSize: 12.0),
),
],
),
),
),
You are using Row widget inside your RaisedButton and it's taking the maximum width, you can fix it using the min space mainAxisSize: MainAxisSize.min like this:
ButtonTheme(
minWidth: 16.0,
height: 30.0,
child: RaisedButton(
onPressed: () => print("a"),
child: new Row(
mainAxisSize: MainAxisSize.min,
children: <Widget>[
Padding(
padding: const EdgeInsets.only(right: 6.0),
child: Text(
'SORT BY',
style: TextStyle(fontSize: 12.0),
),
),
Icon(
Icons.keyboard_arrow_down,
size: 20.0,
),
],
),
),
),