How to remove background color for the sized box in flutter - flutter

The background color is coming for the elevated button in flutter. I have added a background image for the elevated button, but the background color( blue and grey color ) is coming for it. I do not know where it is coming from. So how to remove it?
child:SingleChildScrollView(
child: Wrap(
alignment: WrapAlignment.center,
runSpacing: 20.0, // Or more
spacing: 20, // Or more
children: [
const SizedBox(
height: 520,
),
SizedBox(
width: double.infinity, // <-- Your width
height: 50, // <-- Your height
),
SizedBox(
height: 80, // <-- Your height
width: 80,
child: ElevatedButton(
onPressed: () {
onGoogleSignIn(context);
},
child: Image.asset('images/gm.png')
),
),
SizedBox(
height: 80, // <-- Your height
width: 80,
child: ElevatedButton(
onPressed: () {
//validateForm();
Navigator.push(context,
MaterialPageRoute(builder: (c) => const PhoneLoginScreen()));
},
style: ElevatedButton.styleFrom(
primary: Colors.red.withOpacity(0),
),
child: Image.asset('images/mn.png')
),// Button
),
],
),
),

The Solution is :
Make Elevation - 0
style: ButtonStyle(
color: MaterialStateProperty.all(Colors.transparent),
elevation: MaterialStateProperty.all(0), //Defines Elevation
),

It seems to be the elevation causing the issue. Use Ink with InkWell to make an image button. Given your image is circular, you can use the border-radius to limit the splash.
class ImageButton extends StatelessWidget {
#override
Widget build(BuildContext context) {
const double size = 80;
const String imageUrl = "https://picsum.photos/512";
return SizedBox(
width: size,
height: size,
child: Ink(
decoration: BoxDecoration(
image: const DecorationImage(image: NetworkImage(imageUrl)),
borderRadius: BorderRadius.circular(size / 2),
),
child: InkWell(
onTap: () {},
borderRadius: BorderRadius.circular(size / 2),
),
),
);
}
}
Check the example in Dartpad

you can try another option to make similar
InkWell(
onTap:(){},
splashColor: .... // this will add ripple effect
child: Padding(padding:EdgeInsets.all(20),
child: Image.asset('images/mn.png')
)

Related

How can I align the children of a IndexedStack widget to the bottom of its inclosing widget?

The code below has 3 buttons and a container, Inside the container are two positioned widgets,
The bottom positioned widget contains a IndexedStack with 3 containers, When I click on the buttons I want the containers to show as per the code, all fine but the containers are aligned to the top of its parent widget, I want them to align to the bottom center.
I did use the Align widget to align to bottom center but couldn't get it to work,
I want the last three containers with red, blue and green align to the bottom of the yellow container, Right now it will align towards the mid/ mid top, Only the green aligns to the bottom center.
How can I achieve this ?
DART PAD
import 'package:flutter/material.dart';
class Istack extends StatefulWidget {
#override
_IstackState createState() => _IstackState();
}
class _IstackState extends State<Istack> {
int _selectedIndex = 0;
void _showContainer(int index) {
setState(() {
_selectedIndex = index;
});
}
#override
Widget build(BuildContext context) {
return Scaffold(
body: Container(
height: 600,
// color: Colors.purpleAccent,
child: Column(
children: [
const SizedBox(
height: 50,
),
ElevatedButton(
onPressed: () => _showContainer(0),
child: const Text('Show Container 1'),
),
ElevatedButton(
onPressed: () => _showContainer(1),
child: const Text('Show Container 2'),
),
ElevatedButton(
onPressed: () => _showContainer(2),
child: const Text('Show Container 3'),
),
Container(
color: Colors.yellow,
height: 400,
child: Stack(
children: [
Positioned(
top: 0,
child: Container(
color: Color.fromARGB(255, 222, 136, 136),
height: 200,
),
),
Positioned(
bottom: 0,
left: 0,
right: 0,
child: IndexedStack(
index: _selectedIndex,
children: <Widget>[
Container(
height: 50,
color: Colors.red,
),
Container(
height: 100,
color: Colors.blue,
),
Container(
height: 300,
color: Colors.green,
),
],
),
),
],
),
),
],
),
),
);
}
}
You need to remove the fixed height on top and add Spacer() widget just before yellow widget, Spacer widget will push other.
And use alignment: Alignment.bottomCenter on IndexedStack
#override
Widget build(BuildContext context) {
return Scaffold(
body: Container(
// color: Colors.purpleAccent,
child: Column(
children: [
const SizedBox(
height: 50,
),
ElevatedButton(
onPressed: () => _showContainer(0),
child: const Text('Show Container 1'),
),
ElevatedButton(
onPressed: () => _showContainer(1),
child: const Text('Show Container 2'),
),
ElevatedButton(
onPressed: () => _showContainer(2),
child: const Text('Show Container 3'),
),
Spacer(),
Container(
color: Colors.yellow,
height: 400,
alignment: Alignment.bottomCenter,
child: Stack(
children: [
Positioned(
top: 0,
child: Container(
color: Color.fromARGB(255, 222, 136, 136),
height: 200,
),
),
Positioned(
bottom: 0,
left: 0,
right: 0,
child: IndexedStack(
alignment: Alignment.bottomCenter
index: _selectedIndex,
children: <Widget>[
Container(
height: 50,
color: Colors.red,
),
Container(
height: 100,
color: Colors.blue,
),
Container(
height: 300,
color: Colors.green,
),
],
),
),
],
),
),
],
),
),
);
}

button shadow when clicked is covered by other widget

Button's shadow is happened when click the button.
But, the shadow is covered by other widget.
How can I resolve this?
#override
Widget build(BuildContext context) {
int total = 0;
for (int i = 1; i <= count; i++) {
total += i;
}
return Stack(
clipBehavior: Clip.none,
children: [
Container(
width: 343.43,
height: 150.62,
decoration: RadiusAndShadow().getDecoration(),
child: Column(
children: <Widget>[
Header(text: name),
EcRow(t1: '칼로리', t2: '1회당 ${calorie}kcal'),
EcRow(t1: '카드개수', t2: '$count 개'),
EcRow(t1: '반복횟수', t2: '$total회'),
],
),
),
Positioned(
width: 343.43,
height: 150.62,
top: 17,
child: Align(
alignment: Alignment.bottomCenter,
child: Container(
height: 40,
width: 40,
decoration: const BoxDecoration(
shape: BoxShape.circle,
color: Colors.black,
),
child: IconButton(
padding: const EdgeInsets.all(0),
onPressed: () {
Navigator.push(context, MaterialPageRoute(builder: (context) {
return ExEdit();
}));
},
icon: const Icon(
Icons.edit_outlined,
color: Colors.white,
size: 30,
),
),
),
),
),
],
);
}
I used Stack widget.
In Stack, there are Container and Positioned.
In Container, there are Header and Text.
In Positioned, there is an IconButton.
I didn't understand exactly what happens since you did not provide any code, but I think when you click on the IconButton a splash effect happens and not exactly a shadow so inside the IconButton add:
splashRadius: 20,
you can also disable this effect:
return Theme(
data: ThemeData.light().copyWith(
textTheme: GoogleFonts.poppinsTextTheme(),
splashColor: Colors.transparent,
highlightColor: Colors.transparent,
),
child: const WelcomeScreen(),
);
Wrap your IconButton with widget Material
in Material
color: Colors.transparent,
in IconButton
splashRadius: 20,

how to make different layout for tablet in flutter

I'm thinking about making different layout for Tablet/iPad version but I'm new to Flutter so I'm not really sure how to make it. I'll be really appreciated if I can get any suggestion on how to do it.
Right now If I run on Tablet, my cards are stretch out and I'm trying to fix it right now. Also I'm trying to add a divider and column on the right side (attached pic of the design below) so that I can add more text.
This is my cards
Widget build(BuildContext context) {
return Container(
height: 180,
child: SingleChildScrollView(
child: Card(
elevation: 8.0,
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(10.0),
),
child: Column(children: [
Padding(
padding: const EdgeInsets.fromLTRB(10, 10, 10,0),
child: Row(children: [
Text(
title,
style: TextStyle(fontSize: 18, fontWeight: FontWeight.bold),
),
Spacer(),
Container(
child: IconButton(
icon: Icon(Icons.favorite),
onPressed: () {
Navigator.of(context).push(MaterialPageRoute(builder: (context)=> DetailsPage("Favorite")));
},
))
]),
),
Divider(color: Colors.black),
Row(children: [
//Legend
tileWidget(TileItem(
topText: "Top",
middleText: "Middle",
bottomText: "Bottom")),
Container(
color: Colors.red,
height: 60, width: 2),
(tileItems.length < 1) ? null : tileWidget(tileItems[0]),
Container(
color: Colors.green,
height: 60, width: 2),
(tileItems.length < 2) ? null : tileWidget(tileItems[1]),
Container(
color: Colors.black26, height: 60, width: 2),
(tileItems.length < 3) ? null : tileWidget(tileItems[2])
]),
]),
),
),
);
}
To get the screen width, use MediaQuery.of(context).size.width
Make a widget for any width under 600dp (ie. the phone) and another for any width above (ie. the tablet).
Then your code will look something like this:
body: OrientationBuilder(builder: (context, orientation) {
if (MediaQuery.of(context).size.width > 600) {
isTablet= true;
} else {
isTablet= false;
} etc...
}
Here is a helpful resource: https://medium.com/flutter-community/developing-for-multiple-screen-sizes-and-orientations-in-flutter-fragments-in-flutter-a4c51b849434

How do deal with nested InkWell with Flutter?

Suppose you have a few nested InkResponse, if you tap on the inner one, all of the parent will actually trigger the splash effect even though they will loose in the tap arena for the right tapped widget. The effect will be something like this:
How to prevent such behavior? How to display the splash only for the tapped widget? In this example image it's being used a Container > Row (with InkReponse) > Icon (also with InkResponse). This will also happen if you use material buttons.
You might want to try IgnorePointer
I encourage you to use Stack widget because you can be able to put together multiple widgets. Here there is an example of a container with inner container and they are both clickable independently,
Stack(
children: [
InkWell(
onTap: (){},
child: Container(
width: 400,
height: 400,
color: Colors.green,
),
),
Positioned(
top: 30,
left: 20,
child: InkWell(
onTap: (){},
child: Container(
width: 100,
height: 100,
color: Colors.red,
),
))
],
)
This worked for me
Center(
child:Container(
width: 100,
height: 100,
child: Card(
child: InkWell(
splashColor: color3,
onTap: () {
},
child: Column(
children: [
SizedBox(
height: 10,
),
IconButton(
splashRadius: 7,
splashColor: Colors.pink,
onPressed: () {},
icon: SvgPicture.asset(
ImageConst.bellIcon,
width: 20,
height: 20,
color: Colors.black,
),
),
SizedBox(
height: 10,
),
Text("text"),
],
),
),
),
),
)
Try to wrap the icon into GestureDetector with the empty handler + Padding.

How to set the width and height of a button in Flutter?

I have seen that I can't set the width of a ElevatedButton in Flutter. If I have well understood, I should put the ElevatedButton into a SizedBox. I will then be able to set the width or height of the box. Is it correct? Is there another way to do it?
This is a bit tedious to create a SizedBox around every buttons so I'm wondering why they have chosen to do it this way. I'm pretty sure that they have a good reason to do so but I don't see it.
The scaffolding is pretty difficult to read and to build for a beginner.
new SizedBox(
width: 200.0,
height: 100.0,
child: ElevatedButton(
child: Text('Blabla blablablablablablabla bla bla bla'),
onPressed: _onButtonPressed,
),
),
As said in documentation here
Raised buttons have a minimum size of 88.0 by 36.0 which can be
overidden with ButtonTheme.
You can do it like that
ButtonTheme(
minWidth: 200.0,
height: 100.0,
child: RaisedButton(
onPressed: () {},
child: Text("test"),
),
);
match_parent (Full width):
SizedBox(
width: double.infinity, // <-- match_parent
height: double.infinity, // <-- match-parent
child: ElevatedButton(...)
)
or
SizedBox.expand(
child: ElevatedButton(...)
)
Specific width:
SizedBox(
width: 100, // <-- Your width
height: 50, // <-- Your height
child: ElevatedButton(...)
)
With Flutter 2.0 RaisedButton is deprecated and replaced by ElevatedButton.
With that in mind, much more cleaner approach to give custom size to ElevatedButton is minimumSize property of ElevatedButton widget.
Output
Full Code
ElevatedButton(
style: ElevatedButton.styleFrom(
primary: Colors.green,
onPrimary: Colors.white,
shadowColor: Colors.greenAccent,
elevation: 3,
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(32.0)),
minimumSize: Size(100, 40), //////// HERE
),
onPressed: () {},
child: Text('Hey bro'),
)
Note: Also keep in mind that same approach can be used in new widgets like TextButton and OutlinedButton using TextButton.styleFrom(minimumSize: Size(100, 40)) and OutlinedButton.styleFrom(minimumSize: Size(100, 40)) respectively.
That's because flutter is not about size. It's about constraints.
Usually we have 2 use cases :
The child of a widget defines a constraint. The parent size itself is based on that information. ex: Padding, which takes the child constraint and increases it.
The parent enforce a constraint to its child. ex: SizedBox, but also Column in strech mode, ...
RaisedButton is the first case. Which means it's the button which defines its own height/width. And, according to material rules, the raised button size is fixed.
You don't want that behavior, therefore you can use a widget of the second type to override the button constraints.
Anyway, if you need this a lot, consider either creating a new widget which does the job for you. Or use MaterialButton, which possesses a height property.
I would recommend using a MaterialButton, than you can do it like this:
MaterialButton(
height: 40.0,
minWidth: 70.0,
color: Theme.of(context).primaryColor,
textColor: Colors.white,
child: new Text("push"),
onPressed: () => {},
splashColor: Colors.redAccent,
)
You need to use an Expanded Widget. But, if your button is on a column, the Expanded Widget fills the rest of the column. So, you need to enclose the Expanded Widget within a row.
Row(children: <Widget>[
Expanded(
flex: 1,
child: RaisedButton(
child: Text("Your Text"),
onPressed: _submitForm,
),
),),])
The new buttons TextButton, ElevatedButton, OutlinedButton etc. are to be changed in a different way.
One method I found is from this article: you need to "tighten" a constrained box around the button.
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('Kindacode.com'),
),
body: Center(
child: ConstrainedBox(
constraints: BoxConstraints.tightFor(width: 300, height: 200),
child: ElevatedButton(
child: Text('300 x 200'),
onPressed: () {},
),
),
));
}
Use Media Query to use width wisely for your solution which will run the same for small and large screen
Container(
width: MediaQuery.of(context).size.width * 0.5, // Will take 50% of screen space
child: RaisedButton(
child: Text('Go to screen two'),
onPressed: () => null
),
)
You can apply a similar solution to SizeBox also.
My preferred way to make Raise button with match parent is that wrap it with Container.
below is sample code.
Container(
width: double.infinity,
child: RaisedButton(
onPressed: () {},
color: Colors.deepPurpleAccent[100],
child: Text(
"Continue",
style: TextStyle(color: Colors.white),
),
),
)
This piece of code will help you better solve your problem, as we cannot specify width directly to the RaisedButton, we can specify the width to it's child
double width = MediaQuery.of(context).size.width;
var maxWidthChild = SizedBox(
width: width,
child: Text(
StringConfig.acceptButton,
textAlign: TextAlign.center,
));
RaisedButton(
child: maxWidthChild,
onPressed: (){},
color: Colors.white,
);
Simply use FractionallySizedBox, where widthFactor & heightFactor define the percentage of app/parent size.
FractionallySizedBox(
widthFactor: 0.8, //means 80% of app width
child: RaisedButton(
onPressed: () {},
child: Text(
"Your Text",
style: TextStyle(color: Colors.white),
),
color: Colors.red,
)),
You can create global method like for button being used all over the app. It will resize according to the text length inside container. FittedBox widget is used to make widget fit according to the child inside it.
Widget primaryButton(String btnName, {#required Function action}) {
return FittedBox(
child: RawMaterialButton(
fillColor: accentColor,
splashColor: Colors.black12,
elevation: 8.0,
shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(5.0)),
child: Container(
padding: EdgeInsets.symmetric(horizontal: 20.0, vertical: 13.0),
child: Center(child: Text(btnName, style: TextStyle(fontSize: 18.0))),
),
onPressed: () {
action();
},
),
);
}
If you want button of specific width and height you can use constraint property of RawMaterialButton for giving min max width and height of button
constraints: BoxConstraints(minHeight: 45.0,maxHeight:60.0,minWidth:20.0,maxWidth:150.0),
If you want globally change the height and the minWidth of all your RaisedButtons, then you can override ThemeData inside your MaterialApp:
#override
Widget build(BuildContext context) {
return MaterialApp(
...
theme: ThemeData(
...
buttonTheme: ButtonThemeData(
height: 46,
minWidth: 100,
),
));
}
Wrap RaisedButton inside Container and give width to Container Widget.
e.g
Container(
width : 200,
child : RaisedButton(
child :YourWidget ,
onPressed(){}
),
)
We can also use ElevatedButton Widget, it have fixedSize property. latest Flutter version
ElevatedButton(
onPressed: () {},
style: ElevatedButton.styleFrom(
fixedSize: Size(120, 34), // specify width, height
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(
20,
))),
child: Text("Search"),
)
Preview
This worked for me. The Container provides the height and FractionallySizedBox provides the width for the RaisedButton.
Container(
height: 50.0, //Provides height for the RaisedButton
child: FractionallySizedBox(
widthFactor: 0.7, ////Provides 70% width for the RaisedButton
child: RaisedButton(
onPressed: () {},
),
),
),
Try with Container, I think we will have more control.
ElevatedButton(
style: ElevatedButton.styleFrom(textStyle: const TextStyle(fontSize: 20)),
onPressed: () {
buttonClick();
},
child: Container(
height: 70,
width: 200,
alignment: Alignment.center,
child: Text("This is test button"),
),
),
you can do as they say in the comments or you can save the effort and work with RawMaterialButton . which have everything and you can change the border to be circular
and alot of other attributes. ex shape(increase the radius to have more circular shape)
shape: new RoundedRectangleBorder(borderRadius: BorderRadius.circular(25)),//ex add 1000 instead of 25
and you can use whatever shape you want as a button by using GestureDetector which is a widget and accepts another widget under child attribute.
like in the other example here
GestureDetector(
onTap: () {//handle the press action here }
child:Container(
height: 80,
width: 80,
child:new Card(
color: Colors.blue,
shape: new RoundedRectangleBorder(borderRadius: BorderRadius.circular(25)),
elevation: 0.0,
child: Icon(Icons.add,color: Colors.white,),
),
)
)
If the button is placed in a Flex widget (including Row & Column), you can wrap it using an Expanded Widget to fill the available space.
we use Row or Column, Expanded, Container and the element to use example RaisedButton
body: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.start,
children: <Widget>[
Padding(
padding: const EdgeInsets.symmetric(vertical: 10.0),
),
Row(
children: <Widget>[
Expanded(
flex: 2, // we define the width of the button
child: Container(
// height: 50, we define the height of the button
child: Padding(
padding: const EdgeInsets.symmetric(horizontal: 10.0),
child: RaisedButton(
materialTapTargetSize: MaterialTapTargetSize.shrinkWrap,
textColor: Colors.white,
color: Colors.blue,
onPressed: () {
// Method to execute
},
child: Text('Copy'),
),
),
),
),
Expanded(
flex: 2, // we define the width of the button
child: Container(
// height: 50, we define the height of the button
child: Padding(
padding: const EdgeInsets.symmetric(horizontal: 10.0),
child: RaisedButton(
materialTapTargetSize: MaterialTapTargetSize.shrinkWrap,
textColor: Colors.white,
color: Colors.green,
onPressed: () {
// Method to execute
},
child: Text('Paste'),
),
),
),
),
],
),
],
),
),
SizedBox(
width: double.infinity,
child: ElevatedButton(
child: Text("FULL WIDTH"),
onPressed: () {},
),
),
Use ElevatedButton since RaisedButton is deprecated
In my case(the Button is a child of a horizontal ListView), I had to wrap the button with a padding widget and set right/left padding.
Padding(
padding: const EdgeInsets.only(right: 50, left: 50),
child: ElevatedButton(onPressed: () {}, child: Text("LOGOUT")),
)
In my case I used margin to be able to change the size:
Container(
margin: EdgeInsets.all(10),
// or margin: EdgeInsets.only(left:10, right:10),
child: RaisedButton(
padding: EdgeInsets.all(10),
shape: RoundedRectangleBorder(borderRadius:
BorderRadius.circular(20)),
onPressed: () {},
child: Text("Button"),
),
),
If you don't want to remove all the button theme set up.
ButtonTheme.fromButtonThemeData(
data: Theme.of(context).buttonTheme.copyWith(
minWidth: 200.0,
height: 100.0,,
)
child: RaisedButton(
onPressed: () {},
child: Text("test"),
),
);
If you have a button inside a Column() and want the button to take maximum width, set:
crossAxisAlignment: CrossAxisAlignment.stretch
in your Column widget. Now everything under this Column() will have maximum available width
I struggled with this problem and found what my problem was: I defined all my buttons inside a ListView. Does not matter what I did, the width of the button was always the width of the screen. I replaces ListView by Column and voila - suddenly I could control the button width.
Use SizeBox with width and height parameters
SizedBox(
width: double.infinity,
height: 55.0,
child: ElevatedButton(
.....
),
);
You don't need to use other widget to set the size. You can use minimumSize for ElevatedButton
ElevatedButton(
style: ElevatedButton.styleFrom(
minimumSize: const Size(200, 50),
elevation: 0,
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(50), // <-- Radius
),
),
onPressed: (){},
child: const Text("Text", style: TextStyle(fontSize: 20, fontWeight: FontWeight.w500),),
),
To set the height and width of Any Button Just Wrap it with SizedBox. you set easily the height and width of any button by Wrape with SizedBox .
And if you want to give Space between Two Any Kind of Widgets then you can Used SizedBox and inside the SizedBox you use height .As much as you want to give..
wrap your ElevatedButton with a Column PLUS add padding for the button for the style:
Column(
children: [
ElevatedButton(
style: TextButton.styleFrom(
backgroundColor: Colors.green,
padding: const EdgeInsets.symmetric(
horizontal: 20 * 1.5, vertical: 20),
),
onPressed: () {},
child: const Text('text')),],),