Flutter - how to remove default padding (48 px as per doc) from widgets (IconButton, CheckBox, FlatButton)
FlutterFlutter LayoutPaddingFlutter WidgetFlutter Problem Overview
I am facing a problem with the default padding of the widgets (IconButton, CheckBox, FlatButton). I have searched a lot for this concern but with no success.
In the above image, the outer blue rect is the actual size of these widgets and I have to remove that space.
Checkbox(
onChanged: (value) {
setState(() {
_rememberMeFlag = !_rememberMeFlag;
});
},
value: _rememberMeFlag,
activeColor: const Color(0xff00bbff),
materialTapTargetSize: MaterialTapTargetSize.shrinkWrap,
)
and below is the widget code for hide/show widget icon:
new Container(
child: TextFormField(
decoration: InputDecoration(
labelText: "Password",
suffixIcon: Padding(
padding: EdgeInsetsDirectional.zero,
child: GestureDetector(
child: Icon(
hidePassword ? Icons.visibility : Icons.visibility_off,
size: 20.0,
color: Colors.black,
),
),
),
contentPadding: const EdgeInsets.only(
left: 0.0, top: 6.0, bottom: 6.0, right: 0.0),
),
obscureText: !hidePassword,
maxLength: 20,
),
)
I have tried to set the container size too but no luck. Also tried the padding properties of the widgets but with no success.
Is there any way to remove this extra spacing from these widgets?
Flutter Solutions
Solution 1 - Flutter
wrap your CheckBox
inside SizedBox
will resize the padding of the check box
SizedBox(
height: 24.0,
width: 24.0,
child: Checkbox(...),
)
Solution 2 - Flutter
EDIT
Set the value of materialTapTargetSize to MaterialTapTargetSize.shrinkWrap
Checkbox(
materialTapTargetSize: MaterialTapTargetSize.shrinkWrap,
...
)
Alternatively, you can achieve this by customising the Checkbox widget.
-
Create a CustomCheckbox using the exact code from flutter/packages/flutter/lib/src/material/checkbox.dart.
-
Add a new field to your CustomCheckbox widget
final bool useTapTarget;
-
Make sure to add the new field to your constructor with it default value set to true.
this.useTapTarget = true
-
Modify the build method in the _CheckboxState method. Add this block of code above the return call.
Size noTapTargetSize = Size(CustomCheckbox.width, CustomCheckbox.width); final BoxConstraints additionalConstraints = BoxConstraints.tight(widget .useTapTarget? size : noTapTargetSize);
-
Finally, use your CustomCheckbox widget in your code, and set your custom field to false to remove material padding. example
Container( margin: EdgeInsets.only(right: 15), child:CustomCheckbox( value: _checked, onChanged: _onCheckBoxChange, useTapTarget: false, activeColor: Colors.teal), )
Solution 3 - Flutter
There are three options:
// or Checkbox()
Radio(
materialTapTargetSize: MaterialTapTargetSize.shrinkWrap,
)
// or Checkbox()
Radio(
visualDensity: VisualDensity(horizontal: -4, vertical: -4),
)
SizedBox(
height: 20,
width: 20,
// or Checkbox()
child: Radio()
)
Solution 4 - Flutter
For those looking for copy and paste ;), here is what I use
import 'package:flutter/material.dart';
class NoPaddingCheckbox extends StatelessWidget {
final bool isMarked;
final Function(bool newValue) onChange;
final double size;
NoPaddingCheckbox({
@required this.isMarked,
@required this.onChange,
this.size = 24,
});
@override
Widget build(BuildContext context) {
return ConstrainedBox(
constraints: BoxConstraints(maxHeight: size, maxWidth: size),
child: RawMaterialButton(
shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(4)),
child: Icon(_getIconData(), size: size),
onPressed: () => onChange(!isMarked),
),
);
}
IconData _getIconData() {
if (isMarked) {
return Icons.check_box;
}
return Icons.check_box_outline_blank;
}
}
Solution 5 - Flutter
Wrap(
children: <Widget>[
Text('radio'),
Radio(
groupValue: _character,
onChanged: (value){},
materialTapTargetSize: MaterialTapTargetSize.shrinkWrap,
)
],
crossAxisAlignment: WrapCrossAlignment.center,
),
this removes lots of spaces
Solution 6 - Flutter
Wrap your CheckBox inside SizedBox Widget and give them height or width as per your need.
SizedBox(
height: 20.0,
width: 20.0,
child: Checkbox(
value: _checkBoxValue, onChanged: (value){
setState(() {
_checkBoxValue = value;
});
}),
),
Solution 7 - Flutter
The default dimensions of Checkbox
widget is 48x48. So, as per the above answer, if we wrap Checkbox
inside SizedBox
then the white spacing reduces. I tried with 24x24 and all the spacing was gone.
SizedBox(
width: 24.0,
height: 24.0,
child: Checkbox(),
After this, I wrapped SizedBox
inside the Padding
widget to give any side of spacing I want.
Padding(
padding: const EdgeInsets.only(right: 8.0),
child: SizedBox(
width: 24.0,
height: 24.0,
child: Checkbox(),
),
)
Solution 8 - Flutter
The simplest method I found is to create your version of the widget usually by combining GestureDetector
Widget with something. For example, here's a version of the IconButton
which doesn't have the default Material Design padding:
GestureDetector(
onTap: () {
//do stuff here
},
child: Icon(
Icons.icon_choice
),
)
Solution 9 - Flutter
You can try changing things by opening IconButton
class by clicking on IconButton
while pressing ctrl
in windows. Then you will find a variable Padding = EdgeConsts.all(8.0)
. Keep changing it and play with it according to your needs.
Solution 10 - Flutter
You can achieve this by customising the Checkbox widget's _outerRectAt method:
RRect _outerRectAt(Offset origin, double t) {
final double inset = 1.0 - (t - 0.5).abs() * 2.0;
final double size = _kEdgeSize - inset * _kStrokeWidth;
//final Rect rect = Rect.fromLTWH(origin.dx + inset, origin.dy + inset, size, size); //ORIGINAL
final Rect rect = Rect.fromLTWH(0, origin.dy + inset, size, size); //CUSTOM
return RRect.fromRectAndRadius(rect, _kEdgeRadius);
}
With this modification the result is :
Last, but not least, you need to change the _drawCheck method like this :
void _drawCheck(Canvas canvas, Offset origin, double t, Paint paint) {
assert(t >= 0.0 && t <= 1.0);
// As t goes from 0.0 to 1.0, animate the two check mark strokes from the
// short side to the long side.
final Path path = Path();
const Offset start = Offset(_kEdgeSize * 0.15, _kEdgeSize * 0.45);
const Offset mid = Offset(_kEdgeSize * 0.4, _kEdgeSize * 0.7);
const Offset end = Offset(_kEdgeSize * 0.85, _kEdgeSize * 0.25);
if (t < 0.5) {
final double strokeT = t * 2.0;
final Offset drawMid = Offset.lerp(start, mid, strokeT);
//NEW
path.moveTo(0 + start.dx, origin.dy + start.dy);
path.lineTo(0 + drawMid.dx, origin.dy + drawMid.dy);
//OLD
/*path.moveTo(origin.dx + start.dx, origin.dy + start.dy);
path.lineTo(origin.dx + drawMid.dx, origin.dy + drawMid.dy);*/
} else {
final double strokeT = (t - 0.5) * 2.0;
final Offset drawEnd = Offset.lerp(mid, end, strokeT);
//NEW
path.moveTo(0 + start.dx, origin.dy + start.dy);
path.lineTo(0 + mid.dx, origin.dy + mid.dy);
path.lineTo(0 + drawEnd.dx, origin.dy + drawEnd.dy);
//OLD
/*path.moveTo(origin.dx + start.dx, origin.dy + start.dy);
path.lineTo(origin.dx + mid.dx, origin.dy + mid.dy);
path.lineTo(origin.dx + drawEnd.dx, origin.dy + drawEnd.dy);*/
}
canvas.drawPath(path, paint);
}
Solution 11 - Flutter
Screenshot:
Code (Also solves circular tap effect's size):
@override
Widget build(BuildContext context) {
var size = 20.0; // Your desired size.
return Scaffold(
body: Center(
child: SizedBox.fromSize(
size: Size.fromRadius(size / 2),
child: IconButton(
padding: EdgeInsets.zero,
splashRadius: size,
iconSize: size,
icon: Icon(Icons.mail),
onPressed: () {},
),
),
),
);
}