I have a button that requires the icon to be placed slightly outside the rectangle.
I can do this fine with a Stack, however the button border is overlapping the icon, as you can see here:
here is my code:
OutlinedButton(
style: scansButtonStyle,
onPressed: () {}, // TODO: add later
child: Stack(clipBehavior: Clip.none, children: [
Padding(
padding: const EdgeInsets.only(left: 50.0),
child: Text('CONNECT'),
),
Positioned(
bottom: 0,
left: -20,
child: CircleAvatar(
radius: 30,
backgroundColor: Colors.black,
child: CircleAvatar(
radius: 27,
backgroundColor: Colors.white,
child: Icon(
Icons.bluetooth_connected,
color: Colors.black,
size: 48,
),
),
),
),
]),
),
and styling:
final ButtonStyle scansButtonStyle = OutlinedButton.styleFrom(
alignment: Alignment.centerLeft,
primary: Colors.black,
backgroundColor: Color(0xfffcd722),
minimumSize: Size(242, 48),
padding: EdgeInsets.fromLTRB(20, 3, 20, 3),
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.only(
topLeft: Radius.circular(16),
topRight: Radius.zero,
bottomRight: Radius.circular(16),
bottomLeft: Radius.zero),
),
textStyle: const TextStyle(
color: Colors.black,
fontWeight: FontWeight.w600,
fontSize: 34,
fontFamily: 'HP',
),
side: BorderSide(
color: Colors.black,
width: 3.0,
style: BorderStyle.solid,
));
I've corrected the code a bit.
Main changes are:
Stack(
clipBehavior: Clip.none,
children: [
OutlinedButton(
onPressed: () {},
style: scansButtonStyle,
child: Padding(
padding: const EdgeInsets.only(left: 50.0),
child: Text(
'CONNECT',
maxLines: 1,
overflow: TextOverflow.ellipsis,
textScaleFactor: 1.0, // We do not want OS preferences (text scale option) to break our button's design
),
),
),
Positioned(
bottom: 0,
child: IgnorePointer(
//ignore touch events, so that the Outlined button triggers touch animation when pressed on the icon
child: SizedBox(
width: 60.0,
child: AspectRatio(
aspectRatio: 1.0,
child: Container(
padding: EdgeInsets.all(6.0),
decoration: BoxDecoration(
color: Colors.white,
border: Border.all(
color: Colors.black,
width: 3.0,
),
shape: BoxShape.circle,
),
child: FittedBox(
child: Icon(
Icons.bluetooth_connected,
color: Colors.black,
),
),
),
),
),
),
),
],
)
The code might need some further adjustments, but you will get the idea.
Please also note that the icon's top notch does not take any space (because of Clip.none and it's position in the Stack). You can test it by wrapping the button inside a colored Container.
If you do not like the idea of AspectRatio inside a SizedBox - change it back to width/height in the Container.