Flutter入门进阶之旅(四)文本输入Widget TextField

上一篇文章中我们一起学习了什么是Text跟如何给Text设置字体样式以及Text Widget的一些常用属性Flutter入门进阶之旅(三) Text Widgets,通过对Text的学习我们了解到Text是用于显示文本的,如果对显示的文本有一些特殊的要求,比如字体样式,文字颜色我们可以通过TextStyle去给Text指定style来做个性化定制,这一点跟原生Android的TextView非常类似,有了文字显示就肯定会有文字输入,今天我们就一起来学习一下Flutter中的文字输入Widget TextField。

先来看下TextField的构造方法
const TextField({
    Key key,
    this.controller,           ////控制器,控制TextField文字
    this.focusNode,
    this.decoration = const InputDecoration(),    //输入器装饰
    TextInputType keyboardType,   ////输入的类型
    this.textInputAction,
    this.textCapitalization = TextCapitalization.none,
    this.style,
    this.textAlign = TextAlign.start,   //文字显示位置
    this.autofocus = false,
    this.obscureText = false,
    this.autocorrect = true,
    this.maxLines = 1,
    this.maxLength,
    this.maxLengthEnforced = true,
    this.onChanged,                //文字改变触发
    this.onEditingComplete,   //当用户提交可编辑内容时调用
    this.onSubmitted,   ////文字提交触发(键盘按键)
    this.inputFormatters,
    this.enabled,
    this.cursorWidth = 2.0,
    this.cursorRadius,
    this.cursorColor,
    this.keyboardAppearance,
    this.scrollPadding = const EdgeInsets.all(20.0),
  })
image

通过上面的构造方法跟预览效果图,熟悉android开发的小伙伴们是不是有种似曾相识的感觉,Flutter的TextField跟原生Android中的EditText用法包括部分属性名几乎都是一样的,比如我们可以通过keyboardType来指定唤起软件盘时的输入方式,例如上图的两个输入框属性设置:


import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
 
void main() {
  runApp(new MaterialApp(home: new PullToRefreshDemo()));
}
 
class PullToRefreshDemo extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: new AppBar(
        title: new Text("文本输入"),
      ),
      body: new Center(
          child: new Column(
        children: <Widget>[
          new Text("简单文本输入框",style: new TextStyle(fontSize: 20.0)),
          new TextField(keyboardType: TextInputType.text,),  //指定输入方式为文本输入
          new TextField(keyboardType: TextInputType.number,),//指定唤起软键盘时默认显示数字键盘
 
        ],
      )),
    );
  }
}

通过上面的构造方法我们留意到TextField给我提供了onChanged、onSubmitted、OnEditingComplete回调方法帮助我们监听输入框的内容变化、编辑提交、编辑完成等事件,我们给输入框绑定上述监听方法做下测试:

new TextField(
            onSubmitted: (value){
              print("------------文字提交触发(键盘按键)--");
            },
            onEditingComplete: (){
              print("----------------编辑完成---");
            },
            onChanged: (value){
              print("----------------输入框中内容为:$value--");
            },
            keyboardType: TextInputType.text,
          ),

唤起软键盘后在输入框中输入123456,log控制台打印出:


image

到此对输入框的基本使用你已经完全get到了,但是现实开发过程中,可能我们会需要给输入框指定一些辅助性的说明内容,比如输入框未输入内容时添加hint提示,或者在输入框的旁边添加Icon指示,或者输入框内部文字的显示样式、背景色等等,这些辅助性的设置在Flutter中统一有一个叫做InputDecoration的装饰器来完成操作,我们先来看下InputDecoration的构造方法,然后来简单尝试下几个日常开发中常用的操作。

const InputDecoration({
    this.icon, //输入框左侧添加个图标
    this.labelText,//输入框获取焦点/有内容 会移动到左上角,否则在输入框内labelTex的位置
    this.labelStyle,
    this.helperText,
    this.helperStyle,
    this.hintText, //未输入文字时,输入框中的提示文字
    this.hintStyle,
    this.errorText,
    this.errorStyle,
    this.errorMaxLines,
    this.isDense,
    this.contentPadding,
    this.prefixIcon, //输入框内侧左面的控件
    this.prefix,
    this.prefixText,
    this.prefixStyle,
    this.suffixIcon,//输入框内侧右面的图标
    this.suffix,
    this.suffixText,
    this.suffixStyle,
    this.counterText,
    this.counterStyle,
    this.filled,
    this.fillColor,
    this.errorBorder,
    this.focusedBorder,
    this.focusedErrorBorder,
    this.disabledBorder,
    this.enabledBorder,
    this.border,  //增加一个边框
    this.enabled = true,
    this.semanticCounterText,
  })

给输入框添加输入辅助性输入说明:


 body: new Center(
          child: new TextField(
            decoration: new InputDecoration(
                labelText: "请输入内容",//输入框内无文字时提示内容,有内容时会自动浮在内容上方
                helperText: "随便输入文字或数字", //输入框底部辅助性说明文字
                prefixIcon: new Icon(Icons.print), //输入框左边图标
                suffixIcon: new Icon(Icons.picture_as_pdf), //输入框右边图片
                contentPadding: const EdgeInsets.only(bottom:15.0)),
            keyboardType: TextInputType.number,
          ),
        ));
image

通过给InputDecoration设置border给输入框添加边框:

body: new Center(
          child: new TextField(
            decoration: new InputDecoration(
                border: new OutlineInputBorder(  //添加边框
                  gapPadding: 10.0,
                  borderRadius: BorderRadius.circular(20.0),
                ),
                prefixIcon: new Icon(Icons.print),
                contentPadding: const EdgeInsets.all(15.0)),
            keyboardType: TextInputType.number,
          ),

image

其他样式跟属性读者可自行运行体验,我就不逐一列举说明了,总之参考文档再结合原生开发的经验去使用TextField还是比较简单的。下面我分享一个完整的登录UI的例子供大家参考:

image

完整代码:

import 'package:flutter/material.dart';
 
void main() {
  runApp(new MaterialApp(home: new MyApp()));
}
 
class MyApp extends StatefulWidget {
  @override
  State<StatefulWidget> createState() {
    return new MyAppState();
  }
}
 
class MyAppState extends State<MyApp> {
  @override
  Widget build(BuildContext context) {
    TextEditingController _userPhoneController = new TextEditingController();
    TextEditingController _userPasswordController = new TextEditingController();
 
    /**
     * 清空输入框内容
     */
    void onTextClear() {
      setState(() {
        _userPhoneController.text = "";
        _userPasswordController.text = "";
      });
    }
 
    return new Scaffold(
        appBar: new AppBar(
          title: new Text("登录"),
        ),
        body: new Column(
          children: <Widget>[
            new TextField(
              controller: _userPhoneController,
              keyboardType: TextInputType.number,
              decoration: new InputDecoration(
                  contentPadding: const EdgeInsets.all(10.0),
                  icon: new Icon(Icons.phone),
                  labelText: "请输入手机号",
                  helperText: "注册时填写的手机号"),
              onChanged: (String str) {
                //onChanged是每次输入框内每次文字变更触发的回调
                print('手机号为:$str----------');
              },
              onSubmitted: (String str) {
                //onSubmitted是用户提交而触发的回调{当用户点击提交按钮(输入法回车键)}
                print('最终手机号为:$str---------------');
              },
            ),
            new TextField(
              controller: _userPasswordController,
              keyboardType: TextInputType.text,
              decoration: new InputDecoration(
                  contentPadding: const EdgeInsets.all(10.0),
                  icon: new Icon(Icons.nature_people),
                  labelText: "请输入名字",
//                  hintText: "fdsfdss",
                  helperText: "注册名字"),
            ),
            new Builder(builder: (BuildContext context) {
              return new RaisedButton(
                onPressed: () {
                  if (_userPasswordController.text.toString() == "10086" &&
                      _userPhoneController.text.toString() == "10086") {
                    Scaffold.of(context)
                        .showSnackBar(new SnackBar(content: new Text("校验通过")));
                  } else {
                    Scaffold.of(context)
                        .showSnackBar(new SnackBar(content: new Text("校验有问题,请重新输入")));
                    onTextClear(); //情况输入内容,让用户重新输入
                  }
                },
                color: Colors.blue,
                highlightColor: Colors.deepPurple,
                disabledColor: Colors.cyan,
                child: new Text(
                  "登录",
                  style: new TextStyle(color: Colors.white),
                ),
              );
            })
          ],
        ));
  }
}

下一篇:Flutter入门进阶之旅(五)Image Widget

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