Flutter - Form簡單封裝 - 單行、多行、選擇樣式

demo 地址: https://github.com/iotjin/jh_flutter_demo

效果圖

FormTest.png
FormTest2.png

單行輸入調(diào)用

            JhFormTool.inputText(
                title: "聯(lián)系電話",
                inputInfo: _phone,
                hintText: "請輸入電話號碼",
                focusNode: _node2,
//                    space: 100,
                keyboardType: TextInputType.number,
                inputCallBack: (value) {
                  _phone = value;
                  print("callback" + value);
                }
            ),

多行輸入調(diào)用

            JhFormTool.textView(
                inputInfo: "這是默認值",
                hintText: "這是提示文字",
                focusNode: _node3,
                showRedStar: true,
                inputCallBack: (value) {
                  print("textView" + value);
                }
            ),

選擇調(diào)用

            JhFormTool.selectText(
                title: "選擇樣式",
                selectInfo: selectTextStr,
//                  hintText: "請選擇0",
                clickCallBack: () {
//                  JhPickerTool.showStringPicker(context,
//                      data: ["1", "2", "3"],
//                      clickCallBack: (index, str) {
//                        setState(() {
//                          selectTextStr = str;
//                        });
//                      }
//                  );
                }
            ),

主界面代碼

import 'package:flutter/material.dart';
import 'package:flutter_app/JhTools/jhPickerTool.dart';
import 'package:flutter_app/JhTools/jhFormTool.dart';
import 'package:keyboard_actions/keyboard_actions.dart';


class FormTest extends StatefulWidget {
  @override
  _FormTestState createState() => _FormTestState();
}

class _FormTestState extends State<FormTest> {

  var _phone ="123456";
  var selectTextStr="";

  final FocusNode _node1 = FocusNode();
  final FocusNode _node2 = FocusNode();
  final FocusNode _node3 = FocusNode();
  final FocusNode _node4 = FocusNode();

  @override
  void initState() {
    // TODO: implement initState
    super.initState();

  }

  @override
  Widget build(BuildContext context) {
    return

      GestureDetector(
          behavior: HitTestBehavior.translucent,
          onTap: () {// 點擊空白收起鍵盤
            FocusScope.of(context).requestFocus(FocusNode());
          },
          child:
          Scaffold(
//              resizeToAvoidBottomPadding: true, //輸入框抵住鍵盤
              appBar: AppBar(
                  title: Text('FormTest')
              ),
              body:
              KeyboardActions(
                config: JhFormTool.getKeyboardConfig(context, [_node1,_node2,_node3,_node4]),
                child: _mainBody(),
              )
          )

      );


     }






    _mainBody(){

    double _space = 5;
     return   Scrollbar(
        child:
        SingleChildScrollView(child:
        Column(
          children: <Widget>[
            SizedBox(height: _space),
            JhFormTool.inputText(
                title: "聯(lián)系人", hintText: "這是提示文字",focusNode: _node1, space: 100),
            SizedBox(height: _space),
            JhFormTool.inputText(
                title: "聯(lián)系電話",
                inputInfo: _phone,
                hintText: "請輸入電話號碼",
                focusNode: _node2,
//                    space: 100,
                keyboardType: TextInputType.number,
                inputCallBack: (value) {
                  _phone = value;
                  print("callback" + value);
                }
            ),

            SizedBox(height: _space,),
            JhFormTool.textView(
                inputInfo: "這是默認值",
                hintText: "這是提示文字",
                focusNode: _node3,
                showRedStar: true,
                inputCallBack: (value) {
                  print("textView" + value);
                }
            ),
            SizedBox(height: _space,),
            JhFormTool.textView(
                focusNode: _node4,
                inputCallBack: (value) {
                  print("textView2" + value);
                }
            ),
            SizedBox(height: _space,),
            JhFormTool.selectText(
                title: "選擇樣式",
                selectInfo: selectTextStr,
//                  hintText: "請選擇0",
                clickCallBack: () {
//                  JhPickerTool.showStringPicker(context,
//                      data: ["1", "2", "3"],
//                      clickCallBack: (index, str) {
//                        setState(() {
//                          selectTextStr = str;
//                        });
//                      }
//                  );
                }
            ),


            SizedBox(height: _space,),
            RaisedButton(
                child: Text("確認"),
                onPressed: () {
                  print("確認" + _phone);
                  print("確認" + selectTextStr);
                }
            ),
          ],
        ),
        )
    );
  }


}



jhFormTool 代碼

import 'package:flutter/material.dart';
import 'package:keyboard_actions/keyboard_actions.dart';
//import 'package:keyboard_actions/keyboard_actions_config.dart';

const double _titleFontSize = 16.0; //左側(cè)字體大小
const double _infoFontSize = 15.0;  //右側(cè)字體大小
const Color  _textColor = Colors.black87;
const Color  _inputBoderColor = Colors.grey; //邊框默認顏色
const double _titleSpace = 80.0; //左側(cè)title默認寬
const double _cellHeight = 50.0; //輸入、選擇樣式一行的高度
const double _inputCellHeight = 40.0; //輸入框、選擇框高度
//const Color  _bgColor = Colors.transparent;
//const Color  _inputColor = Colors.transparent;

const Color  _bgColor = Colors.orange;
const Color  _inputColor = Colors.yellow;


typedef _InputCallBack = void Function(String value);
typedef _ClickCallBack = void Function();


class JhFormTool{

  /** 一行輸入樣式 */
  static Widget inputText({
    @required String title,
    String inputInfo,
    String hintText ='請輸入',
    FocusNode focusNode,
    TextInputType keyboardType = TextInputType.text,
    double space = _titleSpace,
    _InputCallBack inputCallBack,
  }){
    return
      CreateInputCell(
        title:title,
        inputInfo:inputInfo,
        hintText: hintText,
        focusNode: focusNode,
        keyboardType: keyboardType,
        space: space,
        inputCallBack: inputCallBack,
      );

  }


  /** 多行輸入樣式 */
  static Widget textView({
    String inputInfo,
    String hintText ='請輸入',
    FocusNode focusNode,
    bool showRedStar =false,
    _InputCallBack inputCallBack,
  }){
    return
      CreateTextViewCell(
        inputInfo:inputInfo,
        hintText: hintText,
        focusNode: focusNode,
        showRedStar: showRedStar,
        inputCallBack: inputCallBack,
      );

  }


  /** 選擇樣式 */
  static Widget selectText({
    @required String title,
    String selectInfo,
    String hintText ='請選擇',
    double space = _titleSpace,
    _ClickCallBack clickCallBack,
  }){
    return

      CreateSelectTextCell(
        title: title,
        selectInfo: selectInfo,
        hintText: hintText,
        space: space,
        clickCallBack: clickCallBack,
      );

  }

  //三方鍵盤配置
  static KeyboardActionsConfig getKeyboardConfig(BuildContext context, List<FocusNode> list) {
    return KeyboardActionsConfig(
      keyboardBarColor: Colors.grey[200],
      nextFocus: true,
      actions: List.generate(list.length, (i) => KeyboardAction(
        focusNode: list[i],
        toolbarButtons: [
              (node) {
            return GestureDetector(
                onTap: () => node.unfocus(),
                child:
                Stack(
                    alignment:Alignment.centerRight ,
                    children: <Widget>[
                      Container(color: Colors.transparent, width: 100,),
                      Positioned(right: 15,child: Text("關閉"),),
                    ]
                )

            );
          },
        ],
      )),
    );
  }



}


class CreateInputCell extends StatefulWidget {

  final String title;
  final String inputInfo;
  final String hintText;
  final FocusNode focusNode;
  final TextInputType keyboardType;
  final double space;
  final _InputCallBack inputCallBack;

  CreateInputCell({
    @required this.title,
    this.inputInfo,
    this.hintText,
    this.focusNode,
    this.keyboardType,
    this.space,
    this.inputCallBack,
  });

  @override
  _CreateInputCellState createState() => _CreateInputCellState();
}

class _CreateInputCellState extends State<CreateInputCell> {

  var inputController = TextEditingController();

  @override
  void initState() {
    // TODO: implement initState
    super.initState();
    inputController.text = widget.inputInfo;
  }

  @override
  Widget build(BuildContext context) {
    return Container(
      color: _bgColor,
      height: _cellHeight,
      padding: EdgeInsets.fromLTRB(15, 5, 15, 5),
      child: Row(
        mainAxisAlignment: MainAxisAlignment.spaceBetween,
        children: <Widget>[
          Container(
            width: widget.space,
            child: Text(widget.title, style: TextStyle(fontSize: _titleFontSize,color: _textColor)),
          ),
          Expanded(
              child:
              Container(
                color: _inputColor,
                height: _inputCellHeight,
                child: TextField(
                  controller: inputController,
                  focusNode: widget.focusNode,
                  keyboardType: widget.keyboardType,  //鍵盤類型
                  maxLines: 1,
                  style: TextStyle(fontSize: _infoFontSize,color: _textColor),
                  decoration: InputDecoration(
                    hintText: widget.hintText,
                    contentPadding: EdgeInsets.all(5),
                    border: OutlineInputBorder(),
                    enabledBorder: OutlineInputBorder(
                      borderSide: BorderSide(color: _inputBoderColor),
                    ),
                  ),
                  onChanged: (value){
                    if(widget.inputCallBack!=null){
                      widget.inputCallBack(inputController.text);
                    }
                  },
                ),
              )
          ),
        ],
      ),
    );
  }
}


class CreateTextViewCell extends StatefulWidget {

  final String inputInfo;
  final String hintText;
  final FocusNode focusNode;
  final bool showRedStar;
  final _InputCallBack inputCallBack;

  CreateTextViewCell({
    this.inputInfo,
    this.hintText,
    this.focusNode,
    this.showRedStar,
    this.inputCallBack,
  });

  @override
  _CreateTextViewCellState createState() => _CreateTextViewCellState();
}

class _CreateTextViewCellState extends State<CreateTextViewCell> {

  var inputController = TextEditingController();

  @override
  void initState() {
    // TODO: implement initState
    super.initState();
    inputController.text = widget.inputInfo;
  }

  @override
  Widget build(BuildContext context) {
    return  Container(
      color: _bgColor,
      padding: EdgeInsets.fromLTRB(15, 5, 15, 5),
      child: Row(
        crossAxisAlignment: CrossAxisAlignment.start,
        children: <Widget>[
          Text(widget.showRedStar ? "*":"", style: TextStyle(fontSize: 18.0,color: Colors.red)),
          SizedBox(width: widget.showRedStar ? 5:0,),
          Expanded(
              child:
              Container(
                color: _inputColor,
                child: TextField(
                  controller: inputController,
                  focusNode: widget.focusNode,
                  keyboardType: TextInputType.text,  //鍵盤類型
                  maxLines: 5,
                  style: TextStyle(fontSize: _infoFontSize,color: _textColor),
                  decoration: InputDecoration(
                    hintText: widget.hintText,
                    contentPadding: EdgeInsets.all(5),
                    border: OutlineInputBorder(),
                    enabledBorder: OutlineInputBorder(
                      borderSide: BorderSide(color: _inputBoderColor),
                    ),
                  ),
                  onChanged: (val) {
                    if(widget.inputCallBack!=null){
                      widget.inputCallBack(inputController.text);
                    }
                  },
                ),
              )
          ),
        ],
      ),
    );
  }
}



class CreateSelectTextCell extends StatefulWidget {

  final String title;
  final String selectInfo;
  final String hintText;
  final double space;
  final _ClickCallBack clickCallBack;

  CreateSelectTextCell({
    @required this.title,
    this.selectInfo,
    this.hintText,
    this.space,
    this.clickCallBack,
  });


  @override
  _CreateSelectTextCellState createState() => _CreateSelectTextCellState();
}

class _CreateSelectTextCellState extends State<CreateSelectTextCell> {

  var selectController = TextEditingController();

  @override
  Widget build(BuildContext context) {

    selectController.text = widget.selectInfo;

    return Container(
      color: _bgColor,
      height: _cellHeight,
      padding: EdgeInsets.fromLTRB(15, 5, 15, 5),
      child: Row(
        mainAxisAlignment: MainAxisAlignment.spaceBetween,
        children: <Widget>[
          Container(
            width: widget.space,
            child: Text(widget.title, style: TextStyle(fontSize: _titleFontSize,color: _textColor)),
          ),
          Expanded(
              child:
              GestureDetector(
                child:
                Container(
                  color: Colors.transparent,
                  height: _inputCellHeight,
//                        decoration: BoxDecoration(
//                          border: Border.all(width: 0.7, color: Colors.grey),
//                          color: Colors.transparent,
//                          borderRadius: BorderRadius.all(new Radius.circular(4.0)),
//                        ),
                  child:
                  TextField(
                    controller: selectController,
                    textAlign : TextAlign.center,
                    maxLines: 1,
                    enabled: false,
                    style: TextStyle(fontSize: _infoFontSize,color: _textColor),
                    decoration: InputDecoration(
                      hintText: widget.hintText,
                      contentPadding: EdgeInsets.all(5),
                      border: OutlineInputBorder(),
//                              border: InputBorder.none,
                      disabledBorder: OutlineInputBorder(
                        borderSide: BorderSide(color: _inputBoderColor),
                      ),
                    ),
                  ),
                ),
                onTap: (){

                  if(widget.clickCallBack!=null){
                    widget.clickCallBack();
                  }
                },
              )

          ),
        ],
      ),
    );
  }
}



最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務。

相關閱讀更多精彩內(nèi)容

  • 一、簡歷準備 1、個人技能 (1)自定義控件、UI設計、常用動畫特效 自定義控件 ①為什么要自定義控件? Andr...
    lucas777閱讀 5,388評論 2 54
  • 《春天里的福田》(二首) 文:東海風 站滿了風和濕漉漉的眼睛 在眾多星群里我看見大海朝東 隨后...
    東海風_7eb6閱讀 303評論 2 3
  • HTTP協(xié)議概念 超文本傳輸協(xié)議 基于TCP連接的傳輸協(xié)議 默認端口是80 基于 請求-響應 模式的協(xié)議 HTTP...
    老茂在北京閱讀 486評論 0 0
  • 故事的開始有些冷漠又灰暗,這部電影反應了社會題材上面的現(xiàn)實事件年幼的時候兩個女生的感情,或許從幼年的時候福南就...
    照舊_c6b3閱讀 1,977評論 0 0
  • 原作者是個歐美人,在韓國和日本姑娘之間,他選擇了日本。雖然他坦誠韓國姑娘擁有最好的身材,但現(xiàn)實中和她們約會實在令人...
    點強閱讀 1,695評論 0 0

友情鏈接更多精彩內(nèi)容