Need help. I want to put the text Want to get your money? and TextButton Redeem under button 611 (screenshot below) removing all padding. I have already tried many methods, but in the end it did not work out to place the widget under the button itself. Through the Flutter Inspector, you can see that there is still a distance at the top, but I don’t understand how to put it there. I will be grateful for help.
body
Padding(
padding: const EdgeInsets.symmetric(horizontal: 24),
child: Column(
children: [
const SizedBox(height: 24),
const TotalCoinsWidget(
coins: '611',
),
const RedeemButton(
textStyle: constants.Styles.smallBookTextStyleWhite,
buttonStyle: constants.Styles.smallMediumTextStyleWhite),
Padding(
padding: EdgeInsets.only(bottom: 50),
child: Text('Hello'),
)
],
),
);
textbutton
Widget build(BuildContext context) => Row(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Text('Want to get your money?', style: textStyle),
TextButton(
style: TextButton.styleFrom(
padding: EdgeInsets.zero,
minimumSize: Size.zero,
),
onPressed: () {},
child: Text(
'Redeem',
style: buttonStyle,
),
),
],
);
TotalCoinsWidget
Widget build(BuildContext context) => Container(
alignment: Alignment.center,
width: _width,
height: _height,
decoration: BoxDecoration(
color: color,
borderRadius: BorderRadius.circular(25),
boxShadow: [
BoxShadow(
color: color.withOpacity(0.5),
blurRadius: _blurRadius,
offset: Offset(_xOffset, _yOffset)),
],
),
child: Text(
coins,
style: textStyle,
),
);
you are using TextButton widget, and if you check out the property style: TextButton.styleFrom(), you will find a property called tapTargetSize, by default tapTargetSize property uses MaterialTapTargetSize.padded, and to fix your problem you must assign tapTargetSize property to MaterialTapTargetSize.shrinkWrap to shrinks the tap target size to the minimum size.
tapTargetSize: MaterialTapTargetSize.shrinkWrap
is not sufficient. Just add
padding: EdgeInsets.zero
Related
i have a problem in my flutter project.
i have a task list screen and i want to change widget colors when task is completed, like disabled buttons(pale colors) but it can be tapped
this is my screen:
codes:
this is my widget
return Container(
margin: EdgeInsets.only(bottom: 10),
padding: EdgeInsets.only(left: 15, top: 7, bottom: 7),
height: GeneralConstants.instance.popupBoxHeight,
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(7),
color: ColorConstants.instance.mainColor),
child: InkWell(
onTap: () {
print("${baslik} Clicked");
},
child: Column(
children: [
SizedBox(
height: 25,
width: double.infinity,
child: AutoSizeText(
baslik,
style: GoogleFonts.oswald(
color: ColorConstants.instance.headerColor, fontSize: 18),
),
),
Expanded(
child: IgnorePointer(
ignoring: true,
child: ListView(
children: [
AutoSizeText(
govde,
style: GoogleFonts.openSans(
color: ColorConstants.instance.bodyColor, fontSize: 10),
),
],
),
),
)
],
),
),
);
}
I have two solutions to solve it:
You can send the row color from outside and if the task is done send a pale color. For more information please read this article.
If you return null on InkWell onTap it becomes disabled and shows a pale color. But I'm sure InkWell shows a shadow when you click it, I suggest you use GestureDetector widget for a clickable widget.
I want to provide a few buttons inside a singlechildscrollview
Column(
children: < Widget > [
SizedBox(height: constraints.maxHeight / 8.0),
AnimationConfiguration.staggeredList(
position: 1,
duration: const Duration(milliseconds: 2000),
child: SlideAnimation(
verticalOffset: constraints.maxHeight / 10,
child: FadeInAnimation(
child: Image.asset('images/mylive.png'),
),
),
),
Flexible(
child: Padding(
padding: EdgeInsets.fromLTRB(
50, 20, 50, constraints.maxHeight / 7),
child: SingleChildScrollView(
child: Padding(
padding: const EdgeInsets.all(10),
child: Wrap(
spacing: 25,
runSpacing: 25,
children: const < Widget > [
ButtonCard(
name: "My News",
imgpath: "open-email.png",
count: 0),
and this is the build method for the ButtonCard:
Widget build(BuildContext context) {
final double width = MediaQuery.of(context).size.width;
final double height = MediaQuery.of(context).size.height;
return InkWell(
onTap: () {},
child: Container( <<--->> Ink(
padding: const EdgeInsets.all(10),
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(20),
color: Colors.white,
boxShadow: const [
BoxShadow(
color: Colors.black38,
offset: Offset(0, 2),
blurRadius: 7,
),
],
),
child: Column(
children: [
Stack(
children: [
Image.asset(
"assets/images/$imgpath",
width: 60,
),
],
),
Padding(
padding: const EdgeInsets.only(top: 8.0),
child: Text(
name,
style: const TextStyle(
fontWeight: FontWeight.bold,
fontSize: 15,
),
),
),
],
),
),
);
}
When I use the container in ButtonCard, then everything is okay, but the InkWell does not show the ripple effect (because of the BoxDecation color set)
This results in the following, correct scroll view:
But when I change the Container to Ink - I get the beautiful ripple effect, which I want to have. But then the following error occurs during scolling:
As you can see, the Ink with its boxdecoration paints over the parents border. Is this a bug in Ink or does anyone know what the problem is here? Thanks!
In General cases:
Wrap the Container with Inkwell
Wrap the Inkwell with Material
Show needed color with Material
Set color to the Container as transparent
With the above settings, you can have a ripple effect with Inkwell. But very difficult to achieve when you're having gradient colors.
Ref: https://flutteragency.com/inkwell-not-showing-ripple-effect-in-flutter/
You must have Material -> Inkwell -> Ink
I am using draggableScrollableSheet. I am giving these parameters
DraggableScrollableSheet(initialChildSize: 0.4,maxChildSize: 1,minChildSize: 0.4,builder: (BuildContext context, ScrollController scrollController) {
return SingleChildScrollView(controller: scrollController,
child: Theme(
data: Theme.of(context).copyWith(canvasColor: Colors.transparent),
child: Opacity(
opacity: 1,
child: IntrinsicHeight(
child: Column(mainAxisSize: MainAxisSize.min,
mainAxisAlignment: MainAxisAlignment.start,
children: <Widget>[
SizedBox(height: 10,),
Container(
margin: EdgeInsets.only(right: 300),
decoration: BoxDecoration(
border: Border(
top: BorderSide(
color: Colors.blue,
width: 3,
style: BorderStyle.solid),
),
),
),
Card(
child: Row(
children: <Widget>[
Padding(
padding: const EdgeInsets.all(8.0),
child: Column(
crossAxisAlignment:
CrossAxisAlignment.start,
children: <Widget>[
Text(
S
.of(context)
.we_have_found_you_a_driver,
style: TextStyle(
color: Colors.black,
fontWeight: FontWeight.bold),
),
SizedBox(
height: 10,
),
Text(S
.of(context)
.driver_is_heading_towards +
' ${widget.order.foodOrders.first.food.restaurant.name}')
],
),
),
],
),
elevation: 5,
),
SizedBox(height: 10,),
Card(
elevation: 5,
child: Row(
mainAxisAlignment: MainAxisAlignment.start,
children: <Widget>[
CircleAvatar(
radius: 50.0,
backgroundColor: Colors.white,
child:
Image.asset(
'assets/img/image_not_available.jpg'),
),
Expanded(
child: Column(mainAxisAlignment: MainAxisAlignment.start,
children: <Widget>[
Row(mainAxisAlignment: MainAxisAlignment.spaceAround,
children: <Widget>[
Expanded(
child: Text('Test',
textAlign: TextAlign.start,
style: new TextStyle(
color: Colors.black,
fontSize: 16.0,
)),
),
Icon(Icons.star, color: Colors.yellow.shade700,)
],
),
SizedBox(height: 30,),
Row(mainAxisAlignment: MainAxisAlignment.spaceAround,
children: <Widget>[
Expanded(
child: Container(
child: Text('Mobile number',
textAlign: TextAlign.start,
style: new TextStyle(
color: Colors.black,
fontSize: 16.0,
)),
),
),
Icon(Icons.phone,),
SizedBox(width: 10,),
Icon(Icons.message),
],
),
],
),
)
]),
),
SizedBox(height: 10,),
Card(
child: Align( alignment: Alignment(-1,1),
child: Row(mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: <Widget>[
Padding(
padding: const EdgeInsets.all(8.0),
child: Column(
crossAxisAlignment:
CrossAxisAlignment.start,
children: <Widget>[
Text(
S
.of(context)
.you_ordered_from + ' ${widget.order.foodOrders.first.food.restaurant.name}',
style: TextStyle(
color: Colors.grey,
),
),
SizedBox(
height: 5,
),
Column(children: List.generate(widget.order.foodOrders.length,(index) {
return Text(
'${widget.order.foodOrders[index].food.name}'
);
},),),
Row(
children: <Widget>[
Column(crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[
Text('See details', style: TextStyle(fontWeight: FontWeight.bold,color: Colors.blue),),
],
),
],
),
],
),
),
Padding(
padding: const EdgeInsets.all(8.0),
child: Column(
children: <Widget>[
SizedBox(height: 40,),
Row(
children: <Widget>[
Icon(Icons.monetization_on),
Text(widget.order.foodOrders
.first.price
.toString()),
],
),
],
),
),
],
),
),
elevation: 5,
),
],
),
),
),
),
)
and I also used a single child scroll view and column so that I can show my cards in that column of draggableScrollableSheet. But I want draggableScrollableSheet to take height dynamically instead of defining size. Like now I want to show only 2 to 3 cards and that is taking full screen. But I want it to take the minimum height of the screen. How can we achieve this?
I was struggling with this for a while, and then discovered that the correct way to achieve this is to use ClampingScrollPhysics as the physics parameter of the scroll view.
https://api.flutter.dev/flutter/widgets/ClampingScrollPhysics-class.html
I'm a week into Flutter but I found a solution to this. It might be substandard so correct me if I'm wrong.
So what I've done is create a variable called bsRatio for the bottom sheet. This is will be the height of the child view/widget (or bottom sheet content) divide by the height of the parent/screen. This ratio should be set to the maxChildSize and probably even the initialChildSize of your DraggableScrollableSheet.
So in your parent widget or Widget State class add something like this.
class ParentWidget extends StatefulWidget {
ParentWidget({Key? key}) : super(key: key);
#override
State<ParentWidget> createState() => _ParentWidgetState();
}
class _ParentWidgetState extends State<ParentWidget> {
var bsRatio = 0.4; // Set an initial ratio
#override
Widget build(BuildContext context) {
// The line below is used to get status bar height. Might not be required if you are not using the SafeArea
final statusBarHeight = MediaQuery.of(context).viewPadding.top;
// If you are not using SafeArea Widget you can skip subtracting status bar height from the Window height
final windowHeight = MediaQuery.of(context).size.height - statusBarHeight;
// This below is a callback function that will be passed to the child Widget of the DraggableScrollableSheet ->
childHeightSetter(childHeight) {
// setState rebuilds the UI with the new `bsRatio` value
setState(() {
// The new bottom sheet max height ratio is the height of the Child View/Widget divide by the screen height
bsRatio = childHeight / windowHeight;
});
}
return Scaffold(
backgroundColor: Colors.black12,
body: SafeArea(
child: Stack(
children: [
const SomeBackgroundView(),
DraggableScrollableSheet(
initialChildSize: bsRatio, // here you set the newly calculated ratio as the initial height of the Bottom Sheet
minChildSize: 0.2,
maxChildSize: bsRatio, // here you set the newly calculated ratio as the initial height of the Bottom Sheet
snap: true,
builder: (_, controller) {
return LayoutBuilder(builder: (_, box) {
// Added a container here to add some curved borders and decent looking shadows via the decoration property
return Container(
child: SingleChildScrollView(
controller: controller,
// The child view/widget `MyBottomSheet` below is the actual bottom sheet view/widget
child: MyBottomSheet(childHeightSetter: childHeightSetter),
),
decoration: const BoxDecoration(
boxShadow: [
BoxShadow(
color: Colors.grey,
blurRadius: 5.0,
spreadRadius: 2.0
)
],
borderRadius: BorderRadius.all(Radius.circular(20.0))
),
);
});
},
),
],
),
),
);
}
}
And this would be your child view/widget (also your BottomSheet view/widget)
class MyBottomSheet extends StatefulWidget {
// This below is the local callback variable. The `?` is because it may not be set if not required
final ValueSetter<double>? childHeightSetter;
const MyBottomSheet({Key? key, this.childHeightSetter}) : super(key: key);
#override
_MyBottomSheetState createState() => _MyBottomSheetState();
}
class _LoginBottomSheetState extends State<LoginBottomSheet> {
// bsKey is the key used to reference the Child widget we are trying to calculate the height of. Check the `Card` container below
GlobalKey bsKey = GlobalKey();
// this method will me used to get the height of the child content and passed to the callback function so it can be triggered and the ratio can be calculated and set in the parent widget
_getSizes() {
final RenderBox? renderBoxRed =
bsKey.currentContext?.findRenderObject() as RenderBox?;
final cardHeight = renderBoxRed?.size.height;
if (cardHeight != null)
super.widget.childHeightSetter?.call(cardHeight);
}
// This is the function to be called after the Child has been drawn
_afterLayout(_) {
_getSizes();
}
#override
void initState() {
super.initState();
// On initialising state pass the _afterLayout method as a callback to trigger after the child Widget is drawn
WidgetsBinding.instance?.addPostFrameCallback(_afterLayout);
}
#override
Widget build(BuildContext context) {
return Card(
key: bsKey, // This is the key mentioned above used to calculate it's height
color: Colors.white,
shadowColor: Colors.black,
elevation: 40.0,
margin: EdgeInsets.zero,
shape: const RoundedRectangleBorder(
borderRadius: BorderRadius.only(
topLeft: Radius.circular(20.0), topRight: Radius.circular(20.0))),
child: Column(
mainAxisAlignment: MainAxisAlignment.end,
children: [
// Random children for bottom sheet content
const SizedBox(height: 10.0),
Center(
child: Container(
child: const SizedBox(width: 40.0, height: 5.0),
decoration: BoxDecoration(
color: Colors.grey[400],
borderRadius: BorderRadius.circular(5.0)
),
),
),
const SizedBox(height: 10.0),
const AnotherBottomSheetContentView()
],
),
);
}
}
the initialChildSize is the height of your ScrollView before its actually scrolled, so that means you can actually decide what it would look like.
here is an example![the draggable scrollsheet here has initialChildSize: 0.1,maxChildSize: 1,minChildSize: 0.1,
]1
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
i'm using Button theme in my project im not able to change the backgroundcolor,text color and also im not able to reduce the height of the button theme can someone please look in to it.
Here's my code:
Widget _signInButton() {
return ButtonTheme(
minWidth: 325,
child: OutlineButton(
splashColor: Colors.grey,
onPressed: () {
signInWithGoogle().whenComplete(() {
Navigator.of(context).push(
MaterialPageRoute(
builder: (context) {
return FirstScreen();
},
),
);
});
},
shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(40)),
highlightElevation: 0,
borderSide: BorderSide(color: Colors.grey),
child: Padding(
padding: const EdgeInsets.fromLTRB(0, 10, 0, 10),
child: Row(
mainAxisSize: MainAxisSize.min,
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
Flexible(
flex: 1,
child: Image(image: AssetImage("Assets/google_logo.png"), height: 35.0)),
Expanded(
flex: 1,
child: Padding(
padding: const EdgeInsets.only(left: 10),
child: Text(
'Sign in with Google',
style: TextStyle(
fontSize: 15,
color: Colors.grey,
try adding height: 8.0 or layoutBehavior:ButtonBarLayoutBehavior.constrained in ButtonTheme.
With any one of these options, you can adjust the height and padding of the button.
Note: adjust the height value as you please. I have set it to 8.0 as an example
You can use buttonColor property in ButtonTheme for changing the button's color. Or the color property in Child Button should do the work.
But since you are using an OutlineButton it won't work as it has no area to paint the color on, it just has an outline.
Note:
You should replace the OutlineButton with RaisedButton.
For Text color you can use style property of the Text widget.
A little example code would be as following:
ButtonTheme(
height: 8.0,
buttonColor: Colors.red,
child: RaisedButton(
color: Colors.blue,
child: Text(
'Button',
style: TextStyle(color: Colors.white),
),
onPressed: () {},
),
)