Flutter Input控件封装

324 阅读1分钟

1. 概述

虽然Flutter控件库提供了许多方便且易于使用的基础控件,但是针对不同的业务往往需要封装适用于业务本身的控件库,方便后续的开发工作。因此,我准备开启一个flutter的控件库专栏,封装一些我平时学习和工作中使用到的控件库,方便今后直接取用。今天是第一个控件的封装,封装了一个简单Input控件,代码和效果如下。

2. 效果

image.png

3. 代码

3.1 LoginInput控件


import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:hello_world/utils/color.dart';

class LoginInput extends StatefulWidget {
  final String title;
  final String hint;
  final ValueChanged<String>? onChanged;
  final ValueChanged<bool>? focusChanged;
  final bool lineStretch;
  final bool obscureText;
  final TextInputType? keyBoardType;

  LoginInput(
      this.title,
      this.hint,
      {this.onChanged, this.focusChanged,
      this.lineStretch=false, this.obscureText=false, this.keyBoardType});

  @override
  State<LoginInput> createState() => _LoginInputState();
}

class _LoginInputState extends State<LoginInput> {
  final _focusNode = FocusNode();
  @override
  void initState() {
    super.initState();
    //是否获取光标监听
    _focusNode.addListener(() {
      print("Has focus: ${_focusNode.hasFocus}");
      if(widget.focusChanged!=null){
        widget.focusChanged!(_focusNode.hasFocus);
      }
    });
  }

  @override
  void dispose() {
    _focusNode.dispose();
    super.dispose();
  }

  @override
  Widget build(BuildContext context) {
    return Column(
      children: [
        Row(
          children: [
            Container(
              padding: EdgeInsets.only(left: 15),
              width: 100,
              child: Text(
                widget.title,
                style: TextStyle(fontSize: 16),
              ),
            ),
            _input()
          ],
        ),
        Padding(padding: EdgeInsets.only(left: !widget.lineStretch?15:0),child:
          const Divider(
            height: 1,
            thickness: 0.5
          ))
      ],
    );
  }

  _input() {
    return Expanded(
        child: TextField(
          focusNode: _focusNode,
          onChanged: widget.onChanged,
          obscureText: widget.obscureText,
          keyboardType: widget.keyBoardType,
          autofocus: !widget.obscureText,
          cursorColor: primary,
          style: TextStyle(fontSize: 16,color: Colors.black,fontWeight: FontWeight.w300),
          decoration: InputDecoration(
            contentPadding: EdgeInsets.only(left: 20,right: 20),
            border: InputBorder.none,
            hintText: widget.hint,
            hintStyle: TextStyle(fontSize: 15,color: Colors.grey)
          ),
        )
    );
  }
}

3.2 使用

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

import '../widgets/login_input.dart';

class RegistrationPage extends StatefulWidget {
  const RegistrationPage({Key? key}) : super(key: key);

  @override
  State<RegistrationPage> createState() => _RegistrationPageState();
}

class _RegistrationPageState extends State<RegistrationPage> {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: Container(
        child: ListView(
          children: [
            LoginInput(
                "用户名",
                "请输入用户名",
                onChanged:(text){
                  print(text);
                }),
            LoginInput(
                "密码",
                "请输入密码",
                lineStretch: true,
                obscureText: true,
                onChanged:(text){
                  print(text);
                })
          ],
        ),
      ),
    );
  }
}