Flutter TextField詳解 | 掘金技術徵文

實現TextField說簡單也簡單,說有坑,坑也不小,下面從易到難介紹一下使用git

1.最簡單的就是無參數調用構造方法:

TextField()
複製代碼

2.光有輸入框還不行,還得獲取其中的內容,因此須要傳遞controller:

import 'package:flutter/material.dart';

class TextFieldPage extends StatelessWidget {
  Widget buildTextField(TextEditingController controller) {
    return TextField(
      controller: controller,
    );
  }

  @override
  Widget build(BuildContext context) {
    final controller = TextEditingController();
    controller.addListener(() {
      print('input ${controller.text}');
    });
    return Scaffold(
      appBar: AppBar(
        title: Text('TextField'),
      ),
      body: Padding(
        padding: const EdgeInsets.all(20.0),
        child: buildTextField(controller),
      ),
    );
  }
}
複製代碼

我經過給controller添加通知來獲取TextField的值,這種使用場景不必定合適,更多的時候是在點擊按鈕的時候直接讀取controller.text的值app

3.另外TextFiled還有一下小的屬性:

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

class TextFieldPage extends StatelessWidget {
  Widget buildTextField(TextEditingController controller) {
    return TextField(
      controller: controller,
      maxLength: 30,//最大長度,設置此項會讓TextField右下角有一個輸入數量的統計字符串
      maxLines: 1,//最大行數
      autocorrect: true,//是否自動更正
      autofocus: true,//是否自動對焦
      obscureText: true,//是不是密碼
      textAlign: TextAlign.center,//文本對齊方式
      style: TextStyle(fontSize: 30.0, color: Colors.blue),//輸入文本的樣式
      inputFormatters: [WhitelistingTextInputFormatter.digitsOnly],//容許的輸入格式
      onChanged: (text) {//內容改變的回調
        print('change $text');
      },
      onSubmitted: (text) {//內容提交(按回車)的回調
        print('submit $text');
      },
      enabled: true,//是否禁用
    );
  }

  @override
  Widget build(BuildContext context) {
    final controller = TextEditingController();
    controller.addListener(() {
      print('input ${controller.text}');
    });
    return Scaffold(
      appBar: AppBar(
        title: Text('TextField'),
      ),
      body: Padding(
        padding: const EdgeInsets.all(20.0),
        child: buildTextField(controller),
      ),
    );
  }
}
複製代碼

4.接着我還能顯示placeholder

decoration能夠給TextField添加裝飾less

TextField(
      decoration:
          InputDecoration(fillColor: Colors.blue.shade100, filled: true, labelText: 'Hello'),
    );
複製代碼

fillColor設置填充顏色,labelText設置標籤文字,這個標籤在沒有輸入的時候是佔滿輸入框的,當輸入聚焦之後,就會縮小到輸入框左上角:ide

TextField(
      decoration: InputDecoration(
          fillColor: Colors.blue.shade100, filled: true, hintText: 'Hello', errorText: 'error'),
    );
複製代碼

hintText就是普通的placeholder,輸入後就不顯示了,errorText是錯誤提示post

5.還能顯示一些別的裝飾

import 'package:flutter/material.dart';

class TextFieldPage extends StatelessWidget {
  Widget buildTextField() {
    return TextField(
      decoration: InputDecoration(
          fillColor: Colors.blue.shade100,
          filled: true,
          helperText: 'help',
          prefixIcon: Icon(Icons.local_airport),
          suffixText: 'airport'),
    );
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text('TextField'),
      ),
      body: Padding(
        padding: const EdgeInsets.all(20.0),
        child: buildTextField(),
      ),
    );
  }
}

複製代碼

6.這些還不過癮,我不喜歡這個安卓風格的下面的裝飾線,我想變成圓角矩形的邊框

import 'package:flutter/material.dart';

class TextFieldPage extends StatelessWidget {
  Widget buildTextField() {
    return TextField(
      decoration: InputDecoration(
          contentPadding: EdgeInsets.all(10.0),
          border: OutlineInputBorder(
            borderRadius: BorderRadius.circular(15.0),
// borderSide: BorderSide(color: Colors.red, width: 3.0, style: BorderStyle.solid)//沒什麼卵效果
          )),
    );
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text('TextField'),
      ),
      body: Container(
        color: Colors.blue.shade100,
        child: Padding(
          padding: const EdgeInsets.all(30.0),
          child: buildTextField(),
        ),
      ),
    );
  }
}

複製代碼

7.改變裝飾線顏色

不管是下面的裝飾線,仍是矩形邊框裝飾線,對焦後顯示的顏色,都是主題顏色的primaryColor,失去焦點之後就是黑色,這顯然不能知足自定義的需求,可是經過各類努力發現,改變邊框顏色很困難,最後發現了這個答案:https://stackoverflow.com/questions/49600139/how-to-change-textfield-underline-colorui

因此正確的設置邊框顏色的方式是這樣的:spa

import 'package:flutter/material.dart';

class TextFieldPage extends StatelessWidget {
  Widget buildTextField() {
    return Theme(
      data: new ThemeData(primaryColor: Colors.red, hintColor: Colors.blue),
      child: TextField(
        decoration: InputDecoration(
            contentPadding: EdgeInsets.all(10.0),
            border: OutlineInputBorder(
              borderRadius: BorderRadius.circular(15.0),
// borderSide: BorderSide(color: Colors.red, width: 3.0, style: BorderStyle.solid)//沒什麼卵效果
            )),
      ),
    );
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text('TextField'),
      ),
      body: Padding(
        padding: const EdgeInsets.all(30.0),
        child: buildTextField(),
      ),
    );
  }
}
複製代碼

8.改變邊框的粗細

這些TextField的decoration完全不能知足要求了,須要重構成這種方式:3d

import 'package:flutter/material.dart';

class TextFieldPage extends StatelessWidget {
  Widget buildTextField() {
    return Container(
      padding: const EdgeInsets.all(8.0),
      alignment: Alignment.center,
      height: 60.0,
      decoration: new BoxDecoration(
          color: Colors.blueGrey,
          border: new Border.all(color: Colors.black54, width: 4.0),
          borderRadius: new BorderRadius.circular(12.0)),
      child: new TextFormField(
        decoration: InputDecoration.collapsed(hintText: 'hello'),
      ),
    );
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text('TextField'),
      ),
      body: Padding(
        padding: const EdgeInsets.all(30.0),
        child: buildTextField(),
      ),
    );
  }
}

複製代碼

InputDecoration.collapsed能夠禁用裝飾線,而是使用外面包圍的Container的裝飾線code

致此,全部的輸入框的坑都趟完了,歡迎你們多多交流

從 0 到 1:個人 Flutter 技術實踐 | 掘金技術徵文,徵文活動正在進行中orm

相關文章
相關標籤/搜索