I want to make a Button that looks like the picture above with Flutter.
But I have no idea how to make it... help me, please!
Widget _startButton(BuildContext context) {
return Container(
margin: const EdgeInsets.only(top: 250.0),
child: Stack(
children: <Widget>[
Center(
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
children: <Widget>[
_buildSideButtons(context, Icons.settings, palette.limeYellow,
const EdgeInsets.only(right: 30.0)),
_buildSideButtons(context, Icons.lightbulb_outline,
palette.limeGreen, const EdgeInsets.only(left: 30.0)),
],
),
),
Center(
child: Container(
width: MediaQuery.of(context).size.width * 0.35,
height: MediaQuery.of(context).size.height,
child: DecoratedBox(
decoration: BoxDecoration(
shape: BoxShape.circle,
gradient: LinearGradient(
begin: Alignment.centerLeft,
end: Alignment.centerRight,
colors: [palette.limeYellow, palette.limeGreen])),
))),
Center(
child: Container(
width: MediaQuery.of(context).size.width * 0.275,
height: MediaQuery.of(context).size.height,
child: new RaisedButton(
elevation: 0.0,
color: Colors.white,
child: new Text(
"START",
style: TextStyle(
fontFamily: "Bebas Neue",
fontSize: 25.0,
fontWeight: FontWeight.bold),
),
onPressed: () => Navigator.push(
context,
MaterialPageRoute(
builder: (BuildContext context) => CountDown())),
shape: CircleBorder())))
],
),
);
}
Widget _buildSideButtons(
BuildContext context, IconData icon, Color coverColor, EdgeInsets pad,
{VoidCallback navigate}) {
return Container(
height: MediaQuery.of(context).size.height * 0.07,
child: RaisedButton(
elevation: 5.0,
onPressed: () {},
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.all(Radius.circular(50.0))),
child: Container(
child: Padding(
padding: pad,
child: Icon(icon, color: Colors.black),
),
),
color: coverColor,
textColor: Colors.white,
),
);
}
I used Stack and Raised Buttons and finally made it! Thank you for the advice. I simply need to add boxShadow to make it close to the example picture I uploaded above.
To make a similar compound Button you should use a stack widget, you can see that both the side buttons are same so they are identical buttons in a row with a BorderRadius. they design of the middle button can be done by clipping button border by half of its width and then lay it out at the middle of the row.
You can make use of an IconButton with an asset image which contain a transparent background.
IconButton(
icon: Image.asset('assets/your/transperantBG/icon.png'),
onPressed: (){},
)
Related
How do I retrieve a specific URL from the real-time database?
final database = FirebaseDatabase(
databaseURL:
"https://trackkit-a5cf3-default-rtdb.asia-southeast1.firebasedatabase.app")
.reference()
.child('NTU')
.child(widget.referenceName);
.
.
.
Widget _buildItem(String imgPath, String labName, int quantity, String expiry,
Function onAdd, Function onSubtract, Function onDelete) {
void _minusNum() {
onSubtract();
}
void _onAdd() {
onAdd();
}
void _onDelete() {
onDelete();
}
return Padding(
padding: const EdgeInsets.only(left: 0.0, right: 10, top: 0.0),
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: <Widget>[
GestureDetector(
onLongPress: _onDelete,
child: Row(children: [
Hero(
tag: imgPath,
child: const Image(
image: NetworkImage(''), <---THIS IS THE LINE
fit: BoxFit.cover,
height: 120.0,
width: 130.0)),
const SizedBox(width: 10.0),
Column(crossAxisAlignment: CrossAxisAlignment.start, children: [
Text(
labName,
style: const TextStyle(
fontFamily: 'Montserrat',
fontSize: 12.0,
fontWeight: FontWeight.bold,
),
),
Text(
expiry,
style: const TextStyle(
fontFamily: 'Montserrat',
fontSize: 12.0,
fontWeight: FontWeight.bold,
),
),
Container(
width: 100.0,
height: 30.0,
margin: const EdgeInsets.only(left: 0.0, top: 5.0),
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(17.0),
color: const Color(0xFF7A9BEE)),
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
children: <Widget>[
InkWell(
onTap: _minusNum,
child: Container(
height: 25.0,
width: 25.0,
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(7.0),
color: const Color(0xFF7A9BEE)),
child: const Center(
child: Icon(
Icons.remove,
color: Colors.white,
size: 20.0,
),
),
),
),
Text(quantity.toString(),
style: const TextStyle(
color: Colors.white,
fontFamily: 'Montserrat',
fontSize: 15.0)),
InkWell(
onTap: _onAdd,
child: Container(
height: 25.0,
width: 25.0,
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(7.0),
color: Colors.white),
child: const Center(
child: Icon(
Icons.add,
color: Color(0xFF7A9BEE),
size: 20.0,
),
),
),
),
],
),
)
]),
]),
),
],
));
}
.
.
.
tag: imgPath,
child: const Image(
image: NetworkImage(''),
fit: BoxFit.cover,
height: 120.0,
width: 130.0)
I am able to retrieve the rest of the item in the firebase, but I am unable to retrieve the Image.
The error appears:
======== Exception caught by image resource service ================================================
The following ArgumentError was thrown resolving an image codec:
Invalid argument(s): No host specified in URI file:///lists%5Bindex%5D%5B%22Image%22%5D
The question is not really clear, but This error is definitely happening because you're assigning an invalid image link '' to your NetworkImage.
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.
Hi so I was doing an app like uber but I got an error of this. I'm new in using flutter. Before this, I can run app this normally but suddenly I got this error this morning.
This is my code. Can someone help me?
this is the error
A build function returned null.
The offending widget is: StreamBuilder
To return an empty space that causes the building widget to fill available room, return "Container()". To return an empty space that takes as little room as possible, return "Container(width: 0.0, height: 0.0)".
import 'package:ezbin3/Aboutus.dart';
import 'package:ezbin3/SCREENS/home/map.dart';
import 'package:ezbin3/SCREENS/home/map2.dart';
import 'package:ezbin3/SERVICES/auth.dart';
import 'package:ezbin3/activity.dart';
import 'package:ezbin3/models/user.dart';
import 'package:ezbin3/profile.dart';
import 'package:ezbin3/settings.dart';
import 'package:flutter/material.dart';
import 'package:ezbin3/SERVICES/database.dart';
import 'package:provider/provider.dart';
import 'package:ezbin3/models/ezuser.dart';
class Home extends StatelessWidget {
final AuthService _auth = AuthService();
#override
Widget build(BuildContext context) {
final user = Provider.of<User>(context);
return StreamBuilder<EzuserData>(
stream: DatabaseService(uid: user.uid).userData,
builder: (context, snapshot) {
if (snapshot.hasData) {
EzuserData userData = snapshot.data;
return StreamProvider<List<Ezuser>>.value(
value: DatabaseService().userz,
child: Scaffold(
drawer: Drawer(
child: ListView(
children: <Widget>[
DrawerHeader(
decoration: BoxDecoration(
gradient: LinearGradient(colors: <Color>[
Colors.lightGreen,
Colors.green
])),
child: Container(
child: Column(
children: <Widget>[
Material(
borderRadius:
BorderRadius.all(Radius.circular(50.0)),
elevation: 10,
child: Padding(
padding: EdgeInsets.all(8.0),
child: Image.asset(
'image/ezbin2.png',
width: 80,
height: 80,
),
),
),
SizedBox(height: 10),
Text(
userData.name,
style: TextStyle(
color: Colors.white, fontSize: 20.0),
),
],
)),
),
//PROFILE PAGE
Padding(
padding: const EdgeInsets.fromLTRB(8.0, 0, 8.0, 0),
child: Container(
decoration: BoxDecoration(
border: Border(
bottom: BorderSide(
color: Colors.grey.shade400))),
child: InkWell(
splashColor: Colors.lightGreenAccent,
onTap: () => Navigator.push(
context,
MaterialPageRoute(
builder: (context) => ProfilePage())),
child: Container(
height: 50,
child: Row(
mainAxisAlignment:
MainAxisAlignment.spaceBetween,
children: <Widget>[
Row(
children: <Widget>[
Icon(Icons.person),
Padding(
padding:
const EdgeInsets.all(8.0),
child: Text('Profile',
style: TextStyle(
fontSize: 16.0))),
],
),
Icon(Icons.arrow_right)
],
),
)),
)),
//ACTIVITY PAGE
Padding(
padding: const EdgeInsets.fromLTRB(8.0, 0, 8.0, 0),
child: Container(
decoration: BoxDecoration(
border: Border(
bottom: BorderSide(
color: Colors.grey.shade400))),
child: InkWell(
splashColor: Colors.lightGreenAccent,
onTap: () => Navigator.push(
context,
MaterialPageRoute(
builder: (context) => ActivityPage())),
child: Container(
height: 50,
child: Row(
mainAxisAlignment:
MainAxisAlignment.spaceBetween,
children: <Widget>[
Row(
children: <Widget>[
Icon(Icons.description),
Padding(
padding:
const EdgeInsets.all(8.0),
child: Text('Activity',
style: TextStyle(
fontSize: 16.0))),
],
),
Icon(Icons.arrow_right)
],
),
)),
)),
//SETTING PAGE
Padding(
padding: const EdgeInsets.fromLTRB(8.0, 0, 8.0, 0),
child: Container(
decoration: BoxDecoration(
border: Border(
bottom: BorderSide(
color: Colors.grey.shade400))),
child: InkWell(
splashColor: Colors.lightGreenAccent,
onTap: () => Navigator.push(
context,
MaterialPageRoute(
builder: (context) => SettingPage())),
child: Container(
height: 50,
child: Row(
mainAxisAlignment:
MainAxisAlignment.spaceBetween,
children: <Widget>[
Row(
children: <Widget>[
Icon(Icons.settings),
Padding(
padding:
const EdgeInsets.all(8.0),
child: Text('Settings',
style: TextStyle(
fontSize: 16.0))),
],
),
Icon(Icons.arrow_right)
],
),
)),
)),
//ABOUT US PAGE
Padding(
padding: const EdgeInsets.fromLTRB(8.0, 0, 8.0, 0),
child: Container(
decoration: BoxDecoration(
border: Border(
bottom: BorderSide(
color: Colors.grey.shade400))),
child: InkWell(
splashColor: Colors.lightGreenAccent,
onTap: () => Navigator.push(
context,
MaterialPageRoute(
builder: (context) => AboutusPage())),
child: Container(
height: 50,
child: Row(
mainAxisAlignment:
MainAxisAlignment.spaceBetween,
children: <Widget>[
Row(
children: <Widget>[
Icon(Icons.info_outline),
Padding(
padding:
const EdgeInsets.all(8.0),
child: Text('About Us',
style: TextStyle(
fontSize: 16.0))),
],
),
Icon(Icons.arrow_right)
],
),
)),
)),
//LOG OUT
Padding(
padding: const EdgeInsets.fromLTRB(8.0, 0, 8.0, 0),
child: Container(
decoration: BoxDecoration(
border: Border(
bottom: BorderSide(
color: Colors.grey.shade400))),
child: InkWell(
splashColor: Colors.lightGreenAccent,
onTap: () async {
await _auth.signOut();
print('logout');
},
child: Container(
height: 50,
child: Row(
mainAxisAlignment:
MainAxisAlignment.spaceBetween,
children: <Widget>[
Row(
children: <Widget>[
Icon(Icons.lock),
Padding(
padding:
const EdgeInsets.all(8.0),
child: Text('Log Out',
style: TextStyle(
fontSize: 16.0))),
],
),
Icon(Icons.arrow_right)
],
),
)),
))
],
),
),
backgroundColor: Colors.green[50],
appBar: AppBar(
title: Text('EZBIN'),
backgroundColor: Colors.green[400],
elevation: 0.0,
actions: <Widget>[],
),
body: //HomeGoogle(),
MapSample(),
),
);
}
});
}
}
If anything happens please let me know. Thank you
Let's take a look at the error message
A build function returned null. The offending widget is: StreamBuilder
That means, that somewhere in your program a StreamBuilder (or its build method) is not returning a Widget, but null.
Now let's take a look at your code.
return StreamBuilder<EzuserData>(
stream: DatabaseService(uid: user.uid).userData,
builder: (context, snapshot) {
if (snapshot.hasData) {
EzuserData userData = snapshot.data;
return StreamProvider<List<Ezuser>>.value(
...
);
}
});
}
With the error and the simplified code in mind, where could you not return a Widget, but instead no value at all? Hint: What happens, if snapshot.hasData is not true?
I am just creating a form in Flutter. I am not able to set the top margin for the button.
class _MyHomePageState extends State<MyHomePage> {
String firstname;
String lastname;
final scaffoldKey = new GlobalKey<ScaffoldState>();
final formKey = new GlobalKey<FormState>();
#override
Widget build(BuildContext context) {
return new Scaffold(
key: scaffoldKey,
appBar: new AppBar(
title: new Text('Validating forms'),
),
body: new Padding(
padding: const EdgeInsets.all(16.0),
child: new Form(
key: formKey,
child: new Column(
children: [
new TextFormField(
decoration: new InputDecoration(labelText: 'First Name'),
validator: (val) =>
val.length == 0 ?"Enter FirstName" : null,
onSaved: (val) => firstname = val,
),
new TextFormField(
decoration: new InputDecoration(labelText: 'Password'),
validator: (val) =>
val.length ==0 ? 'Enter LastName' : null,
onSaved: (val) => lastname = val,
obscureText: true,
),
new RaisedButton(
onPressed: _submit,
child: new Text('Login'),
),
],
),
),
),
);
}
Put your button inside a Container and then set the margin
Container(
margin: const EdgeInsets.only(top: 10.0),
child : RaisedButton(
onPressed: _submit,
child: Text('Login'),
),
Alternatively you can wrap your button with Padding. (That is what Container does internally.)
Padding(
padding: const EdgeInsets.all(20),
child: ElevatedButton(
onPressed: _submit,
child: Text('Login'),
),
);
See this answer more more on adding margin to a widget.
Note: RaisedButton is deprecated as of Flutter 2.0. ElevatedButton is the replacement.
In Flutter 2.0, RaisedButton was deprecated, The ElevatedButton is replacement.
So you can use ElevatedButton and set style as bellow to remove margin:
ElevatedButton.icon(
onPressed: () {},
icon: Icon(Icons.add),
label: Text(
'Add Place',
),
style: ButtonStyle(tapTargetSize: MaterialTapTargetSize.shrinkWrap),
),
image marging top:
Scaffold(
backgroundColor: Color.fromARGB(255, 238, 237, 237),
body: Center(
child: Container(
margin: const EdgeInsets.only(top: 25),
child: Column(
children: <Widget>[
Column(children: <Widget>[
Image.asset(
'images/logo.png',
fit: BoxFit.contain,
width: 130,
)
]),
],
),
),
),
)
I found the EdgeInsets.symmetric:
child : new RaisedButton(
onPressed: _submit,
child: new Text('Login'),
padding: EdgeInsets.symmetric(horizontal: 50, vertical: 10),
),
Screenshot:
Use the recommended ElevatedButton.style property to provide padding.
ElevatedButton(
onPressed: () {},
child: Text('Button'),
style: ElevatedButton.styleFrom(
padding: EdgeInsets.all(20), // Set padding
),
)
This is how I set the size, padding, and margin of widgets in general. here is an example for Button:
Container(
margin: EdgeInsets.only(top: 10), // Top Margin
child:
ElevatedButton(
style: TextButton.styleFrom(
// Inside Padding
padding: EdgeInsets.symmetric(horizontal: 0, vertical: 20),
// Width,Height
minimumSize: Size(300, 30),
),
child: Text('Upload Data'),
onPressed: () {submitForm();},
),
),
Other Options are
Container(
margin: EdgeInsets.only(top:20),
child:
ElevatedButton(
set horizontal & vertical margins
Container(
margin: EdgeInsets.symmetric(horizontal: 0, vertical: 20),
child:
Container(
margin: EdgeInsets.all(20),
child:
ElevatedButton(
Container(
margin: EdgeInsets.fromLTRB(5,10,5,10),
child:
ElevatedButton(
This is worked for me!
ElevatedButton(
style: ElevatedButton.styleFrom(
primary: Global.deepOrange,
padding: const EdgeInsets.all(20), // at this line you can add margin.
),
onPressed: () {},
child: const Text('Add New Poll Item')),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[
Text(data.dataList[index].codeName, style: TextStyle(fontSize: 14, fontWeight: FontWeight.w500, color: UtilColors.darkGrey)),
Row(
//TODO to edit employee details
crossAxisAlignment: CrossAxisAlignment.end,
children: <Widget>[
Expanded(child: Text(BasicAction.formatDate(data.dataList[index].payDate), style: TextStyle(fontSize: 16, fontWeight: FontWeight.w500, color: UtilColors.darkGrey))),
Padding(
padding: EdgeInsets.all(4),
child: Text('Edit', style: TextStyle(fontSize: 14, fontWeight: FontWeight.w500, color: UtilColors.blueColor)),
),
],
),
],
),
in this on edit text how to set clicklistenr
You can use margin and padding on Card like this:-
#override
Widget build(BuildContext context) {
return Scaffold(
body: ListView.builder(
itemCount: _newsArticles.length,
padding: EdgeInsets.symmetric(horizontal: 2,vertical: 2),
itemBuilder: (context, index) {
return Card( // <-- Card widget
shadowColor: Colors.grey,
elevation: 3,
margin: EdgeInsets.all(5.0),
child: ListTile(
title: _newsArticles[index].urlToImage == null ?
Image.asset(Constants.NEWS_PLACEHOLDER_IMAGE_ASSET_URL) :
Image.network(_newsArticles[index].urlToImage),
subtitle: Text(_newsArticles[index].title, style: TextStyle(fontSize: 14)),
),
);
},
)
);
}
Margin and Padding are not the same thing and I feel like they are being used interchangeably in some of the comments.
Margin controls the spacing from outside of the widget border to its edge.
Padding controls the spacing from its edge, to its child.
For the ElevatedButton widget, trung's answer is correct, change the tapTargetSize in the button style.