import 'package:flutter/material.dart';
void main() => runApp(MyApp());
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
home: SafeArea(
child: Scaffold(
body: Column(
children: [
Container(
color: Colors.orange,
child: TextField(
decoration: InputDecoration(
suffix: IconButton(
icon: Icon(Icons.check_circle),
onPressed: () {
print('222');
}),
),
),
),
],
),
),
),
);
}
}
How can I force the check_circle icon to automatically resize to match the height of the actual TextField, i.e., wrt its cursor height?
Very good question...
The basics, is to reset all the paddings in the TextField, and not using a IconButton (as all Material components have predefined and internals paddings that you can't modify).
Seems like suffix gets baseline aligned with the text, preventing the material ink interaction, while suffixIcons get properly centered in the text area, BUT propagates the Ink to the TextField. So, so far I couldn't find a way of doing it properly, maybe there's a widget/logic that I'm missing.
Check screenshot at the bottom that shows why the suffix will not be able to align with the text, as it sits within the baseline itself, and the caret generates a bigger height.....
in the first 2 textfields, the GREY boxes are suffix, and yellow, suffixIcon (which centers properly).
Solution 1: (in screenshotm is red background with 2 checkboxes) If you can (design-wise), make a row, and put the TextField and the icon:
var inputBorderDecoration = OutlineInputBorder(
borderRadius: BorderRadius.zero,
borderSide: BorderSide(width: 1, color: Colors.black));
double textHeight = 40;
// define a width if you want, or let the constrains of the parent define it.
double inputWidth = double.infinity;
return Center(
child: Container(
width: inputWidth,
height: textHeight,
color: Colors.green.withOpacity(.2),
child: Row(
crossAxisAlignment: CrossAxisAlignment.stretch,
children: <Widget>[
Flexible(
child: TextField(
controller: TextEditingController(text: 'hello world'),
style: TextStyle(fontSize: textHeight),
decoration: InputDecoration(
contentPadding: EdgeInsets.zero,
enabledBorder: inputBorderDecoration,
focusedBorder: inputBorderDecoration,
filled: true,
fillColor: Colors.red.withOpacity(.5),
),
),
),
FittedBox(
child: InkWell(
onTap: () => print("touch button"),
child: Icon(Icons.check_circle),
),
),
],
)),
);
Solution 2: (in screenshot, last textfield, green box with white icon) Wrap the icon decoration, is the better UI approach, but the TextField will .still receive touch events.
var inputBorderDecoration = OutlineInputBorder(
borderRadius: BorderRadius.zero,
borderSide: BorderSide(width: 1, color: Colors.black));
double fontSize = 24;
return GestureDetector(
onTap: () {
FocusScope.of(context).requestFocus(FocusNode());
},
child: Container(
color: Colors.green.shade50,
child: Center(
child: Column(
mainAxisSize: MainAxisSize.min,
children: [
Container(
width: 300,
height: fontSize,
color: Colors.orange,
child: TextField(
style: TextStyle(fontSize: fontSize, color: Colors.white),
decoration: InputDecoration(
fillColor: Colors.purple.withOpacity(.5),
filled: true,
border: inputBorderDecoration,
focusedBorder: inputBorderDecoration,
enabledBorder: inputBorderDecoration,
contentPadding: EdgeInsets.zero,
suffixIcon: GestureDetector(
onTap: () => print('on tap'),
child: Container(
color: Colors.green,
child: FittedBox(
alignment: Alignment.center,
fit: BoxFit.fitHeight,
child: IconTheme(
data: IconThemeData(),
child: Icon(
Icons.check_circle,
color: Colors.white,
),
),
),
),
),
),
),
),
],
),
),
),
);
Solution 3:
Build the decorations yourself using EditableText