I'm trying to create a Container with a curve on the middle top and put a Round Button inside the curve. It should look similar to the Curved Navigation Bar package from Flutter, however, just without the animation.
I've tried to work with Stack and Positioned, however, Flutter doesn't convert it how I imagine it to be.
class CurvedContainerWithButtonAtTopCenter extends StatelessWidget{
#override
Widget build(BuildContext context) {
// TODO: implement build
return Scaffold(
body: Container(
height: 200.0,
child: Stack(
children: <Widget>[
Positioned(
top: 30.0,
right: 0.0,
left: 0.0,
child: Container(
height: 170.0,
width: MediaQuery.of(context).size.width,
margin: EdgeInsets.symmetric(horizontal: 20.0, vertical:
40.0),
color: Colors.blue,
)),
Container(
height: 60.0,
width: 60.0,
decoration: BoxDecoration(
color: Colors.white,
shape: BoxShape.circle),
alignment: FractionalOffset.center,
child: Container(
margin: EdgeInsets.all(10.0),
child: FloatingActionButton(),
)
)
],
)
)
);
}
}
I would expect the Container to take the full width and be positioned a little bit lower. The Circle should be in the Center at the Top Border of the Container. The Circle should also contain a FloatingActionButton.
I hope you've found the answer by now, but just in case... bellow you can find a potential solution:
build function
Widget build(BuildContext context) {
return Scaffold(
body: Center(
child: Text('Hello'),
),
bottomNavigationBar: _navigationDrawer,
floatingActionButton: FloatingActionButton(
backgroundColor: Colors.orange,
child: Icon(Icons.add),
onPressed: () {}),
floatingActionButtonLocation:
FloatingActionButtonLocation.centerDocked);
}
getter for bottom navigation
Widget get _navigationDrawer {
return Container(
height: 80.0,
child: BottomAppBar(
shape: CircularNotchedRectangle(),
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: <Widget>[
IconButton(
icon: Icon(Icons.home),
onPressed: () {},
),
Padding(
padding: const EdgeInsets.only(right: 50),
child: IconButton(
icon: Icon(Icons.search),
onPressed: () {},
),
),
Padding(
padding: const EdgeInsets.only(left: 50),
child: IconButton(
icon: Icon(Icons.note_add),
onPressed: () {},
),
),
IconButton(
icon: Icon(Icons.portrait),
onPressed: () {},
),
],
)),
);
}
And the result
Hope this helps :) Happy coding !!!
Related
How can I create a row w/2 buttons that, together, take up the space of their parent (the row)? I want to place this row immediately above the bottom navigation bar at times and then at other times I want it to take the place of the bottom navigation bar. Can I do it just using Row? I've tried persistentFooterButtons with a child of Row and children of FractionallySizedBox but it results in an overflow error and the buttons don't take up the height of of the persistentFooterButtons. There's got to be a better, more straight-forward, approach. Just learning Flutter.
This is a rough example of what I want placed at the bottom of the screen (buttons should be of equal height), where the bottom nav bar would be... and/or immediately above.
[![horizontallyAlignedButtonsWithWidthOfRow][1]][1]
Some of the many (unsuccessful attempts) below:
Wrap Buttons in Expand Attempt:
return Row(
children: <Widget>[
Expanded(
child: ElevatedButton(
onPressed: () {},
style: TextButton.styleFrom(backgroundColor: Colors.blue),
child: Text(
"Some Text #1",
style: TextStyle(color: Colors.white),
))),
Expanded(
child: ElevatedButton(
onPressed: () {},
style: TextButton.styleFrom(backgroundColor: Colors.green),
child: Text("Some Text #2"),
),
),
],
Wrap Buttons in Expand Attempt Result:
[![Result][2]][2]
As you can see, there is white space that shouldn't be there and the buttons are evenly spaced. I have also tried using ColoredBoxes instead of buttons as I read that buttons have margins that cannot be changed?
UPDATE
Finally figured it out, with the help of #lava solutions. Just made a few tweaks to it to remove white space, etc.
return Container(
padding: EdgeInsets.all(0.0),
height: 50,
child: Row(
children: [
Container(
height: 50,
child: ElevatedButton(
style: ElevatedButton.styleFrom(
primary: Colors.blue, // background
onPrimary: Colors.white,
shape: RoundedRectangleBorder(borderRadius: BorderRadius.zero),
),
onPressed: () {},
child: Text("Button1"),
),
),
Expanded(
child: Container(
height: 100,
child: ElevatedButton(
style: ElevatedButton.styleFrom(
primary: Colors.green, // background
onPrimary: Colors.white,
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.zero)),
onPressed: () {},
child: Text("Button2"),
),
),
)
],
),
);
}
}```
[1]: https://i.stack.imgur.com/CydR4.png
[2]: https://i.stack.imgur.com/1JifM.png
Container(
padding: EdgeInsets.all(8.0),
height: 100,
child: Row(
children: [
Expanded(
child: Container(
height: 100,
child: ElevatedButton(
onPressed: () {},
child: Text("Button1"),
),
)),
Container(
padding: EdgeInsets.only(left: 8.0),
height: 100,
child:
ElevatedButton(onPressed: () {}, child: Text("Button2")))
],
),
)
Container(
padding: EdgeInsets.all(8.0),
height: 100,
child: Row(
children: [
Expanded(
child: Container(
height: 100,
child: ElevatedButton(
onPressed: () {},
child: Text("Button1"),
),
),
),
Expanded(
child: Container(
padding: EdgeInsets.only(left: 8.0),
height: 100,
child: ElevatedButton(
onPressed: () {},
child: Text("Button2"),
),
),
)
],
),
)
FullCode
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
void main() {
WidgetsFlutterBinding.ensureInitialized();
runApp(MaterialApp(home: Mainwidget()));
}
class Mainwidget extends StatefulWidget {
const Mainwidget({Key? key}) : super(key: key);
#override
_MainwidgetState createState() => _MainwidgetState();
}
class _MainwidgetState extends State<Mainwidget> {
#override
Widget build(BuildContext context) {
return Scaffold(
body: SafeArea(
child: Container(
padding: EdgeInsets.all(8.0),
height: 100,
child: Row(
children: [
Expanded(
child: Container(
height: 100,
child: ElevatedButton(
onPressed: () {},
child: Text("Button1"),
),
),
),
Expanded(
child: Container(
padding: EdgeInsets.only(left: 8.0),
height: 100,
child: ElevatedButton(
onPressed: () {},
child: Text("Button2"),
),
),
)
],
),
),
),
);
}
List<Widget> children() {
return [
Expanded(
child: Container(
height: 100,
child: ElevatedButton(
onPressed: () {},
child: Text("Button1"),
),
)),
Container(
padding: EdgeInsets.only(left: 8.0),
height: 100,
child:
ElevatedButton(onPressed: () {}, child: Text("Button2")))
];
}
}
You can either add persistentFooterButtons to the Scaffold like
Scaffold(
persistentFooterButtons: [
TextButton(),
TextButton()
]
)
Or in the view:
Column(
children: [
Expanded(child: yourContent), // To use max height space
Row(
children: [
Expanded(child: TextButton()),
Expanded(child: TextButton()),,
]
),
]
),
To give a different width you can add flex to the Expanded or use Flexible and add flex
Wrap both your buttons with Expanded so that they take same amount of width and fill the row.
Nowadays there are many devices having different types of shaps, their screen is no more rectangular shape. some devices have a camera inside the screen area like a water drop from the middle of the plain surface.
Now how we can manage our app bar widget which has a center widget. SafeArea widget can only give useful when devices have corner edges.
AppBar(
elevation: 0,
title: Padding(
padding: const EdgeInsets.all(20),
child: isbgVisible
? Image.asset(
'assets/logosmal_.png',
scale: 1.5,
)
: Container(),
),
centerTitle: true,
actions: <Widget>[
Padding(
padding: const EdgeInsets.all(8.0),
child: CircleAvatar(
child: Image.asset(
'assets/man.png',
scale: 1.5,
),
),
)
],
backgroundColor: isbgVisible ? Constants.whiteColor : Colors.transparent,
leading: Padding(
padding: const EdgeInsets.all(8.0),
child: Container(
width: 30,
height: 30,
child: IconButton(icon: Icon(Icons.menu), onPressed: () {}),
decoration:
BoxDecoration(shape: BoxShape.circle, color: Constants.darkYello),
),
),
);
SafeArea will be useful in that case:
How to use
#override
Widget build(BuildContext context) {
return Scaffold(
body: SafeArea(
child: TonsOfOtherWidgets();
),
),
}
For more information. visit here
im trying to place the inner grey Button inside the red Button, but cant find a way to align it to the left side of the red button.
Excuse my bad code, im new to flutter.
import 'package:flutter/material.dart';
void main() => runApp(MaterialApp(
home: MainApp(),
));
class MainApp extends StatelessWidget {
#override
Widget build(BuildContext context) {
return Scaffold(
body: Padding(
padding: const EdgeInsets.fromLTRB(50, 100, 50, 0),
child: SizedBox(
child: ButtonTheme(
height: 70,
child: FlatButton(
child: SizedBox(
child: Row(
mainAxisAlignment: MainAxisAlignment.start,
children: <Widget>[
ButtonTheme(
height: 70,
child: FlatButton(
child: Text(""),
shape: new RoundedRectangleBorder(
borderRadius: new BorderRadius.circular(13.0),
),
onPressed: () {},
color: Colors.grey,
),
),
],
),
),
shape: new RoundedRectangleBorder(
borderRadius: new BorderRadius.circular(13.0),
),
onPressed: () {},
color: Colors.red,
),
),
),
),
);
}
}
This is what im getting, and im trying to get rid of the red space on the left side of the innner Button.
Like others have pointed out, we are not sure of your motivation for having a button inside of a button.... however, if you actually need this for some reason, here is the solution:
SizedBox(
child: ButtonTheme(
height: 70,
child: FlatButton(
padding: EdgeInsets.zero, // ADD THIS LINE
child: SizedBox(
child: Row(
mainAxisAlignment: MainAxisAlignment.start,
children: <Widget>[
ButtonTheme(
height: 70,
child: FlatButton(
child: Text(""),
shape: new RoundedRectangleBorder(
borderRadius: new BorderRadius.circular(13.0),
),
onPressed: () {},
color: Colors.grey,
),
),
],
),
),
shape: new RoundedRectangleBorder(
borderRadius: new BorderRadius.circular(13.0),
),
onPressed: () {},
color: Colors.red,
),
),
);
Basically, FlatButton() has a padding parameter, which is used to control this spacing that you are referring to, as well as the 0-width space above and below the grey button and the equivalent space on the right side of the button. Passing in EdgeInsets.zero makes sure there is no padding on any interior side of the button.
Hope this helps
I'm trying to create a circle in the flutter. I want to add multiple buttons and bound them in a circle like this.
The marked fields are supposed to be buttons and Course 1 is just the text.
I am able to create something like this but it is only string splitted in the button.
Here is my code for this. I'm not getting any idea about how to do this task. I'm new to flutter.
import 'package:flutter/material.dart';
void main(){runApp(MyApp());}
class MyApp extends StatelessWidget {
#override
Widget build(BuildContext context) {
return MaterialApp(
home: Scaffold(
appBar: new AppBar(
title: Text("Student home"),
),
body:Center(
child: Container(
margin: EdgeInsets.all(10),
padding: EdgeInsets.all(10),
width: 200,
height: 200,
child: Center(
child: Text("Course 1 \n Course 2",
style: TextStyle(fontSize: 12.0,
fontStyle: FontStyle.italic,
),
textAlign: TextAlign.center,
),
),
decoration: BoxDecoration(
border:Border.all(width:3),
borderRadius: BorderRadius.all(
Radius.circular(50),
),
color: Colors.yellow,
),
),
)
),
);
}
}
try shape: BoxShape.circle,,
Container(
width: 100,
height: 100,
decoration: BoxDecoration(
border: Border.all(width: 2),
shape: BoxShape.circle,
// You can use like this way or like the below line
//borderRadius: new BorderRadius.circular(30.0),
color: Colors.amber,
),
child:Column(
crossAxisAlignment: CrossAxisAlignment.center,
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
Text('ABC'),
Text('XYZ'),
Text('LOL'),
],
),
),
Output
is this design that you want?
it contain two button and one text widget
body: Center(
child: Container(
margin: EdgeInsets.all(10),
padding: EdgeInsets.all(10),
width: 200,
height: 200,
child: Center(
child: Column(
crossAxisAlignment: CrossAxisAlignment.center,
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
Text(
"Course 1",
style: TextStyle(
fontSize: 12.0,
fontStyle: FontStyle.italic,
),
textAlign: TextAlign.center,
),
MaterialButton(
onPressed: () {
//do whatever you want
},
child: Text("Mark Attendance"),
),
MaterialButton(
onPressed: () {
//do whatever you want
},
child: Text("Mark Attendance"),
),
],
),
),
decoration: BoxDecoration(
border: Border.all(width: 3),
borderRadius: BorderRadius.all(
Radius.circular(200),
),
color: Colors.yellow,
),
),
),
There are multiple ways to make the border round. As of now you are using fixed height and width always use greater number for border-radius.
For eg.
when your heigh is 200X200 use 150-200 number for border-radius.
here is the code which works fine when you have fixed height and width of the container.
Note: This works only fine when your heigh and width is fixed for the container because the padding in the code is static.If you want dynamic then please use the screen calculation techniques to make if responsive
Making any widget clickable in the Flutter.
There are a couple of Widgets available to make any widget clickable
Gesture Detector
This widget has many methods including onTap() which means you can attach a callback when the user clicks on the widget. For eg (this is used in your code)
GestureDetector(
onTap: (){}, //this is call back on tap
child: Text("Mark Attendance")
)
InkWell Widget (Note: This widget will only work when it is a child of the Material widget)
Material(
child: InkWell(
onTap: (){},
child: Text("Mark Attendance"),
),
)
Here is the working code.
import 'package:flutter/material.dart';
void main(){runApp(MyApp());}
class MyApp extends StatelessWidget {
#override
Widget build(BuildContext context) {
return MaterialApp(
home: Scaffold(
appBar: new AppBar(
title: Text("Student home"),
),
body:Center(
child: Container(
margin: EdgeInsets.all(10),
padding: EdgeInsets.all(10),
width: 200,
height: 200,
child: Column(
mainAxisAlignment: MainAxisAlignment.start,
children: <Widget>[
Padding(
padding: const EdgeInsets.only(bottom:40.0,top: 20.0),
child: Text("Course 1"),
),
Column(
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
children: <Widget>[
Padding(
padding: const EdgeInsets.all(8.0),
child: GestureDetector(
onTap: (){},
child: Text("Mark Attendance")),
),
Padding(
padding: const EdgeInsets.all(8.0),
child:Material(
child: InkWell(
onTap: (){},
child: Text("Mark Attendance"),
),
)
),
],)
],
),
decoration: BoxDecoration(
border:Border.all(width:3),
borderRadius: BorderRadius.all(
Radius.circular(150),
),
color: Colors.yellow,
),
),
)
),
);
} }
Note: Material widget always set the background as white for the text
widget
Thanks, I hope is information was helpfull
Where am I supposed to place the material as the parent of the Raw material button so that it can respond to clicks and show splash color.
The widget tree looks like below.
Widget build(BuildContext context) {
return new Container(
child: new Center(
child: new Stack(
alignment: Alignment.center,
children: <Widget>[
new Container(
child: new Padding(
padding: const EdgeInsets.all(5.0),
child: new Container(
child: new AudioComponent(
updateMe: [WatchableAudioProperties.audioPlayerState],
playerBuilder: (BuildContext context, AudioPlayer
player,
Widget child) {
IconData icon = Icons.play_arrow;
return new RawMaterialButton(
shape: new CircleBorder(),
fillColor: Colors.white,
splashColor: lightAccentColor,
highlightColor: lightAccentColor.withOpacity(0.5),
elevation: 10.0,
highlightElevation: 5.0,
onPressed: (){},
child: new Padding(
padding: const EdgeInsets.all(8.0),
child: new Icon(
icon,
color: accentColor,
size: 50.0,
),
),
);
},
),
),
),
),
new Container(
height: 151.0,
width: 151.0,
child: waves,
),
],
),
),
);
}
If I add another container onto the stack and put a similar RawMaterial button, it responds as required even without adding a material widget anywhere. What I don't understand why the RawButton in the first container in the stack is not working
How do you expect to have your RawMaterialButton react when you have the following code in it's definition?
onPressed: (){},