flutter笔记(十)-----输入框TextField

flutter笔记汇总

这个组件属性很多。。。
先看一下吧

const TextField({
  Key key,
  TextEditingController controller,            //输入框的控制器
  FocusNode focusNode,           //控制输入框是否获得焦点
  InputDecoration decoration: const InputDecoration(),    //设置输入框的外观
  TextInputType keyboardType,          //键盘类型
  TextInputAction textInputAction,         //回车按钮的类型
  TextCapitalization textCapitalization: TextCapitalization.none,    // 键盘大小写
  TextStyle style,             //文本样式
  StrutStyle strutStyle,
  TextAlign textAlign: TextAlign.start,     //水平方向对齐方式
  TextAlignVertical textAlignVertical,      //垂直方向对齐方式
  TextDirection textDirection,           //文本书写顺序
  bool readOnly: false,          //是否只读
  bool showCursor,        //是否显示光标
  bool autofocus: false,         //是否自动获得焦点
  bool obscureText: false,     //是否隐藏正在输入的文本,内容显示为圆点
  bool autocorrect: true,    //是否自动修正
  int maxLines: 1,        //输入框的最大行数
  int minLines,            //最小行数
  bool expands: false,    //是否填充父级
  int maxLength,             //文本最大长度
  bool maxLengthEnforced: true,          //超过文本最大长度是否限制输入
  ValueChanged<String> onChanged,      //输入文本时的回调
  VoidCallback onEditingComplete,          //完成输入时触发(按回车)
  ValueChanged<String> onSubmitted,        //完成输入时触发,接收当前输入文本为参数
  List<TextInputFormatter> inputFormatters,      //指定输入格式
  bool enabled,             //是否可用
  double cursorWidth: 2.0,            //光标宽度
  Radius cursorRadius,                //光标圆角
  Color cursorColor,                      //光标颜色
  Brightness keyboardAppearance,        //键盘色调,只在ios上有效
  EdgeInsets scrollPadding: const EdgeInsets.all(20.0),   //当输入框获得焦点并且有一部分被滚动出屏外时,将自动滚动。
  DragStartBehavior dragStartBehavior: DragStartBehavior.start,
  bool enableInteractiveSelection,      //是否允许选中
  GestureTapCallback onTap,            //点击回调
  InputCounterWidgetBuilder buildCounter,
  ScrollController scrollController,
  ScrollPhysics scrollPhysics
})

先来一个最简单的demo

import 'package:flutter/material.dart';

void main() => runApp(MyApp());

class MyApp extends StatelessWidget {
  // This widget is the root of your application.
  @override
  Widget build(BuildContext context) {
    return new MaterialApp(
        home: Scaffold(
            body: Center(
              child: TextField(

              )
            )
        )
    );
  }
}

屏幕中间一条线...点击获得焦点。


image.png

接下来挨个属性看一下

1、controller

输入框文本发生改变时触发,但不限于这个功能。
先看demo

import 'package:flutter/material.dart';

void main() => runApp(MyApp());

class MyApp extends StatelessWidget {
  // This widget is the root of your application.
  @override
  Widget build(BuildContext context) {
    return new MaterialApp(
        home: Scaffold(
            body: TextFieldDemo()
        )
    );
  }
}

class TextFieldDemo extends StatefulWidget {
  @override
  _TextFieldState createState() => new _TextFieldState();
}

class _TextFieldState extends State<TextFieldDemo> {
  TextEditingController _controller = TextEditingController();

  @override
  void initState() {
    _controller.addListener(() {
      print(_controller.text);
    });
    super.initState();
  }

  @override
  Widget build(BuildContext context) {
    return Center(
      child: TextField(
        controller: _controller
      )
    );
  }
}

和前几个组件类似,但不相同,不只是一个状态值,而是有一个controller,并且在initState里监听文本变化。
是不是感觉和onChange重复了,继续往下看,除了监听文本变化,还有一些其他的功能。

设置默认值

initState方法修改如下

@override
void initState() {
  _controller.text = 'default value';      //输入框的默认值
  _controller.addListener(() {
    print(_controller.text);
  });
  super.initState();
}
清空输入框

initState方法修改如下

@override
void initState() {
  _controller.text = 'default value';
  _controller.addListener(() {
    print(_controller.text);
    _controller.clear();
  });
  super.initState();
}

当输入框获得焦点时,会触发_controller这个时候调用clear方法会清空输入框。

selection

将initState方法修改如下:

void initState() {
  _controller.text = 'default value';
  _controller.selection = TextSelection(
    baseOffset: 3,
    extentOffset: 5,
    affinity: TextAffinity.upstream,
    isDirectional: true
  );
  _controller.addListener(() {
    print(_controller.text);
  });
  super.initState();
}

baseOffsetextentOffset配对使用,demo中的写法为从文本中第四个和第五个字符为选中状态。
另外的两个我不知道是干啥的。。。

2、focusNode

焦点控制

import 'package:flutter/material.dart';

void main() => runApp(MyApp());

/// This Widget is the main application widget.
class MyApp extends StatelessWidget {
  static const String _title = 'Flutter Code Sample';

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: _title,
      home: Scaffold(
        appBar: AppBar(title: const Text(_title)),
        body: FocusNodeDemo(),
      ),
    );
  }
}

class FocusNodeDemo extends StatefulWidget {
  @override
  _FocusNodeState createState() => new _FocusNodeState();
}

class _FocusNodeState extends State<FocusNodeDemo> {
  FocusNode focusNode1 = new FocusNode();
  FocusNode focusNode2 = new FocusNode();
  FocusScopeNode focusScopeNode;

  @override
  Widget build(BuildContext context) {
    return Container (
      child: Column(
        children: <Widget>[
          TextField(
            //关联focusNode1
            focusNode: focusNode1,     
          ),
          TextField(
             //关联focusNode2
            focusNode: focusNode2,             
          ),
          RaisedButton(
            child: Text('移动焦点到1'),
            onPressed: () {
              //没有输入框获得焦点时初始值为null
              if (focusScopeNode == null) {
                focusScopeNode = FocusScope.of(context);
              }
              //focusNode1获得焦点
              focusScopeNode.requestFocus(focusNode1);
              //focusNode1和focusNode2焦点状态
              print(focusNode1.hasFocus);
              print(focusNode2.hasFocus);
            }
          ),
          RaisedButton(
            child: Text('移动焦点到2'),
            onPressed: () {
               //没有输入框获得焦点时初始值为null
              if (focusScopeNode == null) {
                focusScopeNode = FocusScope.of(context);
              }
              //focusNode2获得焦点
              focusScopeNode.requestFocus(focusNode2);
              //focusNode1和focusNode2焦点状态
              print(focusNode1.hasFocus);
              print(focusNode2.hasFocus);
            }
          ),
          RaisedButton(
            child: Text('隐藏键盘'),
            onPressed: () {
              //focusNode1和focusNode2失去焦点
              focusNode1.unfocus();
              focusNode2.unfocus();
            }
          ),
          RaisedButton(
            child: Text('焦点状态'),
            onPressed: () {
              //focusNode1和focusNode2焦点状态
              print(focusNode1.hasFocus);
              print(focusNode2.hasFocus);
            },
          )
        ]
      )
    );
  }
}
image.png

输入框的焦点通过FocusNodefocusScopeNode控制,focusScopeNode可以通过focusScope.of方法来获取初始值,这个方法不会让元素获得焦点,focusScopeNode.requestFocus方法可以让元素获得焦点。focusNode还有一个unFocus方法,可以让输入框失去焦点,另外focusNode还有一个hasFocus属性,输入框获得焦点时为true,失去焦点时为false

3、decoration

先看一下constructor

const InputDecoration({
  Widget icon,         //输入框前的图标
  String labelText,    //与placeholder类似,当输入框获得焦点时会缩小到左上角
  TextStyle labelStyle,   //labelText的字体样式
  String helperText,    //帮助类型文字提示在输入框下方,默认为灰色
  TextStyle helperStyle,    //helperText的文字样式
  String hintText,      //相当于html里的placeholder,当设置了labelText时输入框未获得焦点时不显示,获得焦点之后labelText缩小后会显示
  TextStyle hintStyle,    //hintText文字样式
  int hintMaxLines,      //hintText最大行数,如果文本超出这个最大行数后边会显示为...
  String errorText,      //错误提示,和helperText位置相同,默认为红色
  TextStyle errorStyle,  //helperText的文字样式
  int errorMaxLines,    //errorText的最大行数,超出部分显示为...
  bool hasFloatingPlaceholder: true,  //为false时,当输入框获得焦点labelText不会缩小到左上角,而是消失
  bool isDense,
  EdgeInsetsGeometry contentPadding,    //输入框内边距
  Widget prefixIcon,        //输入框前缀图标
  Widget prefix,              //输入框前缀
  String prefixText,          //输入框前缀文本
  TextString prefixStyle,    //前缀样式
  Widget suffixIcon,        //后缀图标
  Widget suffix,              //后缀文本
  String suffixText,        //后缀
  TextStyle suffixStyle,    //后缀样式
  Widget counter,            //输入框右下方组件
  String counterText,        //输入框右下方文本
  TextStyle counterStyle,      //右下方文本样式
  bool filled,                  //是否填充
  Color fillColor,          //填充色(相当于背景色)
  Color focusColor,    //
  Color hoverColor,      //鼠标移入的填充色
  InputBorder errorBorder,      //错误时的边框
  InputBorder focusedBorder,    //获得焦点时边框
  InputBorder focusedErrorBorder,    //错误并获得焦点时的边框
  InputBorder disabledBorder,        //禁用时的边框
  InputBorder enabledBorder,        //可用时的边框
  InputBorder border,                //边框
  bool enabled: true,              //是否可用  
  String semanticCounterText,
  bool alignLabelWithHint
})

这里的属性都很简单,没啥细说的而且有很多都是重复的,只不过是在不同状态下和不同位置。没注释的暂时还没整明白是干啥的。

4、keyboardType

输入框获得焦点时弹出键盘的类型。
numberphoneurldatetimemultilineemailAddressnumberWithOptions()visiblePasswordtext
看着挺多,其实有好几个都是重复的,可能是为了语义化。

import 'package:flutter/material.dart';

void main() => runApp(MyApp());

class MyApp extends StatelessWidget {
  // This widget is the root of your application.
  @override
  Widget build(BuildContext context) {
    return new MaterialApp(
      home: Scaffold(
        body: Center(
          child: TextField(
            keyboardType: TextInputType.number,
          )
        )
      )
    );
  }
}
image.png

5、textInputAction

回车按钮的类型
continueActiondoneemergencyCallgojoinnewlinenextroutesearchsendunspecifiednoneprevious
unspecifiednewline是回车,noneprevious不知道干啥,android和ios都报错不支持,其他的值是什么按钮就显示什么

import 'package:flutter/material.dart';

void main() => runApp(MyApp());

class MyApp extends StatelessWidget {
  // This widget is the root of your application.
  @override
  Widget build(BuildContext context) {
    return new MaterialApp(
      home: Scaffold(
        body: Center(
          child: TextField(
            textInputAction: TextInputAction.send,
          )
        )
      )
    );
  }
}
image.png

6、textCapitalization

配置平台键盘如何选择大写或小写键盘,只有文本键盘有效。
none:默认键盘
characters:大写键盘
sentences:第一个字母大写
words:单词首字母大写

import 'package:flutter/material.dart';

void main() => runApp(MyApp());

class MyApp extends StatelessWidget {
  // This widget is the root of your application.
  @override
  Widget build(BuildContext context) {
    return new MaterialApp(
      home: Scaffold(
        body: Center(
          child: TextField(
            textCapitalization: TextCapitalization.words
          )
        )
      )
    );
  }
}
image.png

7、style

文本样式,这里不说了,之前的笔记有介绍。

8、strutStyle

这个也不说了,看之前的笔记flutter笔记(二)-----hello world和文本组件Text、TextSpan

9、textAlign

对齐方式flutter笔记(二)-----hello world和文本组件Text、TextSpan

10、TextAlignVertical

垂直方向的对齐方式,有三个值
topcenterbottom
和css的vertical-align一个作用

11、textDirection

文本的书写顺序,不详细介绍了看之前的笔记flutter笔记(二)-----hello world和文本组件Text、TextSpan

12、readOnly

是否只读,值为boolean类型,为true时只读,但是输入框可获得焦点。

13、showCursor

是否显示光标,值为boolean类型。

14、autofocus

是否自动获得焦点。

15、obscureText

是否密文,一般用于密码输入。

16、autocorrect

是否自动修正输入的文本,默认为true

17、maxLines

输入框的最当行数,默认为1,为null时不做限制。

18、minLines

输入框最小行数,和maxLines同时使用,并且不能大于maxLines

19、expands

是否调整输入框高度,以填充父级,maxLinesminLines必须为null。

20、maxLength

文本最大长度,输入框右下角有长度显示。

import 'package:flutter/material.dart';

void main() => runApp(MyApp());

class MyApp extends StatelessWidget {
  // This widget is the root of your application.
  @override
  Widget build(BuildContext context) {
    return new MaterialApp(
      home: Scaffold(
        body: Center(
          child: TextField(
            maxLength: 20
          )
        )
      )
    );
  }
}
image.png

21、maxLengthEnforced

文本长度超过最大长度是否限制输入,为false时不禁止输入,但是输入框会变红。

import 'package:flutter/material.dart';

void main() => runApp(MyApp());

class MyApp extends StatelessWidget {
  // This widget is the root of your application.
  @override
  Widget build(BuildContext context) {
    return new MaterialApp(
      home: Scaffold(
        body: Center(
          child: TextField(
            maxLength: 5,
            maxLengthEnforced: false
          )
        )
      )
    );
  }
}
image.png

22、onChanged

文本输入回调

23、onEditingComplete

文本输入完成时的回调,即按回车时的回调。

24、onSubmitted

文本输入完成的回调,当前输入的文本为参数。

25、inputFormatters

指定输入文本的格式,需要引入package:flutter/services.dart,值是List类型,可以有多个配置。
BlacklistingTextInputFormatter:黑名单
WhitelistingTextInputFormatter:白名单

import 'package:flutter/material.dart';
import 'package:flutter/services.dart';

void main() => runApp(MyApp());

class MyApp extends StatelessWidget {
  // This widget is the root of your application.
  @override
  Widget build(BuildContext context) {
    return new MaterialApp(
      home: Scaffold(
        body: Center(
          child: TextField(
            inputFormatters: [
              BlacklistingTextInputFormatter(RegExp("[abc]"))
            ],
          )
        )
      )
    );
  }
}

abc添加黑名单,禁止输入。

26、enabled

是否可用,为false时不可用,输入框不能获得焦点。

27、cursorWidth

光标宽度,默认是2.0。

28、cursorRadius

光标圆角。

29、cursorColor

光标颜色

30、keyboardAppearance

键盘色调,Brightness.light为亮色,Brightness.dark为暗,只在ios上有效。

31、scrollPadding

当输入框获得焦点,并有一部分滚动到可视区之外时,自动将输入框滚动到可视区之内。

32、dragStartBehavior

好像和拖动有关,还没整明白怎么用。

33、enableInteractiveSelection

输入的文本属否允许选中,默认为true,为false时不能选中。

34、onTap

点击的回调。

35、buildCounter

没看明白怎么用。

36、scrollController & scrollPhysics

这两个放一起是因为不知道怎么用,看文档scrollController是创建一个滚动控制器,scrollPhysics是对滚动的物理特性做处理,应该是可以控制滚动惯性、滚动回弹的东西。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 159,219评论 4 362
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 67,363评论 1 293
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 108,933评论 0 243
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 44,020评论 0 206
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 52,400评论 3 287
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 40,640评论 1 219
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 31,896评论 2 313
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 30,597评论 0 199
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 34,327评论 1 244
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 30,581评论 2 246
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 32,072评论 1 261
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 28,399评论 2 253
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 33,054评论 3 236
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 26,083评论 0 8
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 26,849评论 0 195
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 35,672评论 2 274
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 35,585评论 2 270

推荐阅读更多精彩内容