So I have a flatButton widget with an asset image as the child. I would like to append a label to the bottom of it, but I don't know how.
Expanded(
child: FlatButton(
child: Image.asset('images/boy.png'),
onPressed: () {
Navigator.push(context, _PageTwo());
},
),
)
You could make the child property a Column. How does this work for you?
Column class docs: https://docs.flutter.io/flutter/widgets/Column-class.html
Expanded(
child: FlatButton(
child: Column(
children: <Widget>[
Image.asset('images/boy.png'),
Text('I am a label')
]
)
onPressed: () {
Navigator.push(context, _PageTwo());
},
),
)
Related
How to make two buttons expand equally over the entire width of the Navigation Drawer?
The main thing will be
ListTile(
title: Row(
children: <Widget>[
Expanded(child: RaisedButton(onPressed: () {},child: Text("Clear"),color: Colors.black,textColor: Colors.white,)),
Expanded(child: RaisedButton(onPressed: () {},child: Text("Filter"),color: Colors.black,textColor: Colors.white,)),
],
),
)
Complete Code
class SO extends StatelessWidget {
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(),
drawer: Drawer(
child: ListView(
padding: EdgeInsets.zero,
children: <Widget>[
DrawerHeader(
child: Text('Drawer Header'),
decoration: BoxDecoration(
color: Colors.blue,
),
),
ListTile(
title: Text('Item 1'),
onTap: () {
// Update the state of the app
// ...
},
),
ListTile(
//contentPadding: EdgeInsets.all(<some value here>),//change for side padding
title: Row(
children: <Widget>[
Expanded(child: RaisedButton(onPressed: () {},child: Text("Clear"),color: Colors.black,textColor: Colors.white,)),
Expanded(child: RaisedButton(onPressed: () {},child: Text("Filter"),color: Colors.black,textColor: Colors.white,)),
],
),
)
],
),
),
);
}
}
This worked for me
Row(
children: <Widget>[
RaisedButton(
onPressed: () {
Route route =
MaterialPageRoute(builder: (context) => MinionFlare());
Navigator.push(context, route);
},
child: SizedBox(
width: MediaQuery.of(context).size.width * 0.4,
child: Text("Minion"),
),
),
RaisedButton(
onPressed: () {
Route route = MaterialPageRoute(
builder: (context) => EmojiRatingBar());
Navigator.push(context, route);
},
child: SizedBox(
width: MediaQuery.of(context).size.width * 0.4,
child: Text("Emoji")),
),
],
),
You can wrap each button with Expanded.
Row(
children : <Widget>[
Expanded(
child: Button(
child: Text("Clear")
)
),
Expanded(
child: Button(
child: Text("Filter")
)
),
])
Container(
height: 100,
child: Row(
children : <Widget>[
Expanded(
child: RaisedButton(
onPressed: () {},
color: Color(0xff0000ff),
child: Text("Left Button", style: TextStyle(color: Colors.white),)
)
),
Expanded(
child: RaisedButton(
onPressed: () {},
color: Color(0xffd4d4d4),
child: Text("Right Button")
)
),
])
)
I have 4 images in 2 columns, when I clicked on one image its style should change like color, shadow should change or that image should be replaced by other image. Once click on that image, other images should remain same. It should work like radio buttons. How to do that? Please help me, thanks in advance.
final img_rowi= Center(child:
new Container(
color: Colors.transparent,
padding: const EdgeInsets.all(5.0),
child: Row(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
Padding(padding: const EdgeInsets.all(3.0),child: Stack(
alignment: Alignment.center,
children: <Widget>[
svgIcon,new GestureDetector(
onTap: (){
setState(() {
pressed = !pressed;
});
},
child:
Container(
child: new Column(
children: <Widget>[
new Container(
child: new Image.asset(
'images/sheep_female.png',
height: 50.0,
fit: BoxFit.cover,
),
),
new Container(
child: new Text('Sheep',style: pressed
? TextStyle(color: const Color(0xFFCDCDCD),fontFamily: 'Montserrat',
)
: TextStyle(color:Colors.black,fontFamily: 'Montserrat',
),),
),
],
),
),
),
],
),),
Padding(padding: const EdgeInsets.all(3.0),child:
Stack(
alignment: Alignment.center,
children: <Widget>[
svgIcon,new GestureDetector(
onTap: (){
setState(() {
pressed1 = !pressed1;
});
},
child:
Container(
child: new Column(
children: <Widget>[
new Container(
child: new Image.asset(
'images/biily_doe.png',
height: 50.0,
fit: BoxFit.cover,
),
),
new Container(
child: new Text('Billy Doe',style: pressed1
? TextStyle(color: const Color(0xFFCDCDCD),fontFamily: 'Montserrat',
)
: TextStyle(color:Colors.black,fontFamily: 'Montserrat',
),),
),
],
),
),
),
],
),),
],
),
),
);
Store initial properties of Image in variables. For example if I want to set initial color of FlutterLogo widget to Colors.blue then declare a state in the class. Then wrap your Image with GestureDetector widget and set onTap property. Now call setState method and change all the variables (properties of Image) inside it.
Below is an example where there is one FlutterLogo widget where I've set initial color of that widget to be Colors.blue and when I tap on it, color of FlutterLogo widget is changed to Colors.green. If I again tap on it and if color is Colors.green then it changes color to Colors.yellow and so on. You can do similar thing with your Image and change it's size, visibility and other properties.
There is also imagePath variable which stores path of initial asset and when user taps on second widget (Image.asset) in Column, value of variable imagePath is changed and build method get called again and image is replaced.
import 'package:flutter/material.dart';
void main() => runApp(MaterialApp(home: MyApp()));
class MyApp extends StatefulWidget {
#override
_MyAppState createState() => _MyAppState();
}
class _MyAppState extends State<MyApp> {
bool visibility;
Color colorOfFlutterLogo = Colors.blue;
String imagePath1 = "assets/initial-path-of-image-1";
String imagePath2 = "assets/initial-path-of-image-2";
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
backgroundColor: Colors.black,
),
body: Column(
children: <Widget>[
GestureDetector(
onTap: () => setState(() {
if (colorOfFlutterLogo == Colors.blue)
colorOfFlutterLogo = Colors.green;
else if (colorOfFlutterLogo == Colors.green)
colorOfFlutterLogo = Colors.yellow;
else if (colorOfFlutterLogo == Colors.yellow)
colorOfFlutterLogo = Colors.blue;
}),
child: FlutterLogo(
size: double.infinity,
colors: colorOfFlutterLogo,
),
),
// Image 1
GestureDetector(
onTap: () => setState(() {
imagePath2 = "assets/new-path-for-image-2";
}),
child: Image.asset(imagePath1),
),
// Image 2
GestureDetector(
onTap: () => setState(() {
imagePath1 = "assets/new-path-for-image-1";
}),
child: Image.asset(imagePath2),
)
],
));
}
}
I am trying to create a custom widget that is a rounded rectangle containing 3 iconButtons, used for navigation. but, as far as I have seen, iconButtons cannot be used outside of material widgets, and i don't know how to wrap them in a widget that doesn't mess up my UI.
just a container with iconButtons throws "no material widget found, iconButton widgets require material widget"
trying to wrap with a material widget, i get positional arguments, messing up my UI
i have tried wrapping my container in other widgets to no avail.
here is a piece of my code, just one of the icons in the container. the code repeats twice with different icon and onPressed before closing the widget.
i really would like my UI to look how i planned, and for these buttons to work.
#override
Widget build(BuildContext context) {
return Container(
height: 50.0,
width: 200.0,
// color: Colors.grey[800],
decoration: new BoxDecoration(
color: Colors.grey[800],
borderRadius: new BorderRadius.all( Radius.circular(50.0)),
),
child: Stack(
children: <Widget>[
Center(
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
children: <Widget>[
new Container(
child: Column(
mainAxisSize: MainAxisSize.max,
children: <Widget>[
IconButton(
icon: Icon(Icons.menu),
color: Colors.white,
onPressed: () {
print('test');
},
) // IconButton
], // <Widget>[]
) //Column
), // Container
Wrap your code in Scaffold and it will work.
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(),
body: Container(
height: 50.0,
width: 200.0,
decoration: BoxDecoration(
color: Colors.grey[800],
borderRadius: new BorderRadius.all(Radius.circular(50.0)),
),
child: Stack(
children: [
Center(
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
children: [
Container(
child: Column(
mainAxisSize: MainAxisSize.max,
children: [
IconButton(
icon: Icon(Icons.menu),
color: Colors.white,
onPressed: () {
print('test');
},
)
],
),
)
],
),
)
],
),
),
); // IconButton ], // [] ) //Column ), // Container
}
I've the below code working fine, and showing the FlatButton under the TextField:
import 'package:flutter/material.dart';
class LocationCapture extends StatelessWidget {
LocationCapture(this.clickCallback, this.tc);
final TextEditingController tc;
final VoidCallback clickCallback;
#override
Widget build(BuildContext context) {
return Column(
mainAxisSize: MainAxisSize.min,
children: <Widget>[
// Row(
// children: <Widget>[
TextField(controller: tc,),
FlatButton(
child: const Icon(Icons.my_location),
onPressed: () => clickCallback(),
)
// ])
]);
}
}
I tried adding Row to make them in single line, but it is not working, and showing blank screen!!
** UPDATE**
I was able to put them in line, by wrapping each element into a container, but still not happy for this as it require me to assign the container width, I need this to be done automatically:
Row(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
Container(
width: 180,
child: TextField(
controller: tc,
enabled: false,
textAlign: TextAlign.center,
decoration: InputDecoration.collapsed(hintText: "")
)
),
Container(
child: FlatButton(
child: const Icon(Icons.my_location),
onPressed: () => clickCallback(),
)
),
]
);
This is how you can do it.
textDirection property of Row() widget will allow you to start the positioning of the children widget from the mentioned directions.
NOTE :- **You can remove or comment out the 'textDirection' if your are using MaterialApp() widget in your project. It takes care of the textDirection.
Expanded() widget is used to occupy the remaining whole space.
child: Row(
textDirection: TextDirection.rtl,
children: <Widget>[
FlatButton(onPressed: () {}, child: Text("Demo Button")),
Expanded(child: TextFormField())
],
)
While working on an application, we have an instance where we want a card to have an inkwell as well as a button on the card (also with an inkwell). However, I have been unable to determine a way to separate the gestures such that only the inkwell directly under the user's tap is invoked. As it is today, it appears that the tap 'bleeds through' to the next inkwell such that both splash effects are invoked. This is undesirable behavior, the application appears to be selecting the card not the invokable item on the card (note: actual application is much different but the same issue is present). I have reproduced this in a simple application to demonstrate the bleed through when the user pressed the button in the bottom right of the card. Is there something I am missing which can prevent this behavior? Thanks
class _MyHomePageState extends State<MyHomePage> {
#override
Widget build(BuildContext context) {
return new Scaffold(
body: Card(
color: Colors.blue,
child: InkWell(
onTap: () { },
child: Container(
height: 150.0,
child: Align(
alignment: Alignment.bottomRight,
child: RaisedButton(
color: Colors.red,
onPressed: () { },
),
),
),
),
),
);
}
}
This is the normal expected InkWell behavior as most of the time you want to use it's tap feature for every widget in it's tree. So what you can do is to define a Stack and set the button in the z-axis absolute over the InkWell:
Widget build(BuildContext context) {
return new Scaffold(
body: Center(
child: Card(
color: Colors.blue,
child: Stack(
children: <Widget>[
InkWell(
onTap: () {
print("inkwell");
},
child: Container(
height: 150.0,
),
),
RaisedButton(
color: Colors.red,
onPressed: () {
print("button");
},
),
],
),
),
),
);
}
If you would want to set the button in the bottom right corner again you can set a Row and Colum around it and assign it's alignment:
#override
Widget build(BuildContext context) {
return new Scaffold(
body: Center(
child: Container(
height: 150.0,
child: Card(
color: Colors.blue,
child: Stack(
children: <Widget>[
InkWell(
onTap: () {
print("inkwell");
},
child: Container(
height: 150.0,
),
),
Row(
mainAxisAlignment: MainAxisAlignment.end,
children: <Widget>[
Column(
mainAxisAlignment: MainAxisAlignment.end,
children: <Widget>[
RaisedButton(
color: Colors.red,
onPressed: () {
print("button");
},
),
],
),
],
),
],
),
),
),
),
);
}
Upper code would result in seperated widgets: