如何调整 TextField 的 suffix/suffixIcon 高度?
How can I make TextField's suffix/suffixIcon height resize?
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');
}),
),
),
),
],
),
),
),
);
}
}
如何强制 check_circle 图标自动调整大小以匹配实际 TextField 的高度,即,根据其光标高度?
改用suffixIcon
。
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(
suffixIcon: IconButton(
icon: Icon(Icons.check_circle),
onPressed: () {
print('222');
}),
),
),
),
],
),
),
),
);
}
}
很好的问题...
基础知识是重置 TextField 中的所有填充,而不是使用 IconButton(因为所有 Material 组件都预定义了您无法修改的内部填充)。
似乎后缀与文本基线对齐,阻止了 material 墨迹交互,而 suffixIcons 在文本区域中正确居中,但将墨迹传播到 TextField。
所以,到目前为止我找不到正确的方法,也许我缺少 widget/logic。
查看底部的屏幕截图,其中显示了后缀无法与文本对齐的原因,因为它位于基线本身内,并且插入符号会产生更大的高度......
在前 2 个文本字段中,灰色框是后缀,黄色框是 suffixIcon(正确居中)。
解决方案1:(在屏幕截图中是带有2个复选框的红色背景)
可以的话(design-wise),排成一行,放TextField和图标:
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),
),
),
],
)),
);
解决方案 2:(在屏幕截图中,最后一个文本字段,带有白色图标的绿色框)
包装图标装饰,是更好的 UI 方法,但 TextField 仍将接收触摸事件。
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,
),
),
),
),
),
),
),
),
],
),
),
),
);
方案三:
自己建造装饰品
二手Stack
Stack(
children: [
TextField(),
Positioned.fill(
right: 10,
child: Align(
alignment: Alignment.centerRight,
child: InkWell(
onTap: () {
searchController.clear();
},
child: Icon(Icons.clear))))
],
),
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');
}),
),
),
),
],
),
),
),
);
}
}
如何强制 check_circle 图标自动调整大小以匹配实际 TextField 的高度,即,根据其光标高度?
改用suffixIcon
。
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(
suffixIcon: IconButton(
icon: Icon(Icons.check_circle),
onPressed: () {
print('222');
}),
),
),
),
],
),
),
),
);
}
}
很好的问题...
基础知识是重置 TextField 中的所有填充,而不是使用 IconButton(因为所有 Material 组件都预定义了您无法修改的内部填充)。
似乎后缀与文本基线对齐,阻止了 material 墨迹交互,而 suffixIcons 在文本区域中正确居中,但将墨迹传播到 TextField。 所以,到目前为止我找不到正确的方法,也许我缺少 widget/logic。
查看底部的屏幕截图,其中显示了后缀无法与文本对齐的原因,因为它位于基线本身内,并且插入符号会产生更大的高度......
在前 2 个文本字段中,灰色框是后缀,黄色框是 suffixIcon(正确居中)。
解决方案1:(在屏幕截图中是带有2个复选框的红色背景) 可以的话(design-wise),排成一行,放TextField和图标:
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),
),
),
],
)),
);
解决方案 2:(在屏幕截图中,最后一个文本字段,带有白色图标的绿色框) 包装图标装饰,是更好的 UI 方法,但 TextField 仍将接收触摸事件。
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,
),
),
),
),
),
),
),
),
],
),
),
),
);
方案三:
自己建造装饰品二手Stack
Stack(
children: [
TextField(),
Positioned.fill(
right: 10,
child: Align(
alignment: Alignment.centerRight,
child: InkWell(
onTap: () {
searchController.clear();
},
child: Icon(Icons.clear))))
],
),