Flutter - how to remove default padding (48 px as per doc) from widgets (IconButton, CheckBox, FlatButton)

FlutterFlutter LayoutPaddingFlutter Widget

Flutter 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.

enter image description here

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.

  1. Create a CustomCheckbox using the exact code from flutter/packages/flutter/lib/src/material/checkbox.dart.

  2. Add a new field to your CustomCheckbox widget

         final bool useTapTarget;
    
  3. Make sure to add the new field to your constructor with it default value set to true.

         this.useTapTarget = true
    
  4. 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);
    
  5. 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),
          )
    

Screenshot

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

enter image description here

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 :

enter image description here

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:

enter image description here


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: () {},
        ),
      ),
    ),
  );
}

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionRahul SharmaView Question on Stackoverflow
Solution 1 - FlutterAfinas EMView Answer on Stackoverflow
Solution 2 - FlutterMyorhView Answer on Stackoverflow
Solution 3 - FlutterOmid RahaView Answer on Stackoverflow
Solution 4 - FlutterGenixView Answer on Stackoverflow
Solution 5 - Fluttershahab sadeghiView Answer on Stackoverflow
Solution 6 - Fluttertipu sultanView Answer on Stackoverflow
Solution 7 - FlutterGerma VinsmokeView Answer on Stackoverflow
Solution 8 - FluttersoupjakeView Answer on Stackoverflow
Solution 9 - FlutterHarsha pulikolluView Answer on Stackoverflow
Solution 10 - FlutterAndrea RubeisView Answer on Stackoverflow
Solution 11 - FlutterCopsOnRoadView Answer on Stackoverflow