Flutter 日记APP-添加笔记本-常用组件封装

前言

先上效果图: 功能很简单:

  1. 输入标题
  2. 是否开启闹钟
  3. 选择闹钟循环样式
  4. 选择提醒时间
  5. 输入描述
  6. 保存

实现方式

首先实现输入标题,考虑到这个样式在开发中会经常用到,决定将这个封装下,方便后面开发使用。

封装 SSLInputRow.dart

分析:组件需要传入标题、显示样式、可选的输入内容。需要返回点击事件、输入改变事件、输入完成事件。颜色啥的由于是项目中统一定义的颜色管理,这里就没添加可传入参数,可根据需要添加。

定义如下:

kotlin 复制代码
enum SSLInputStyle{
  text,//输入文本
  num,//输入数字
  arrow;//不可输入,可点击选择
}
class SSLInputRow extends StatefulWidget{
  final SSLInputStyle style;//样式
  final String title;//标题
  final String? inputText;//输入信息或子标题
  final ValueChanged<String>? onTextChange;//输入改变
  final ValueChanged<String>? onEditComplete;//输入完成事件
  final int tag;
  final GestureTapCallback? onTap;//arrow 类型点击事件
  const SSLInputRow({
    Key? key,
    this.style = SSLInputStyle.text,
    required this.title,
    this.onTextChange,
    this.callback,
    this.tag = 0,
    this.inputText,
    this.onTap,
    this.onEditComplete,
  }):super(key: key);
}

具体实现:

php 复制代码
class SSLInputRowState extends State <SSLInputRow>{
  TextEditingController? textControl;//输入控制器
  @override
  void initState() {
    // TODO: implement initState
    //根据类型判断是否初始化输入控制器并将数据赋值
    if (widget.style != SSLInputStyle.arrow){
      textControl = TextEditingController();
      if (widget.inputText != null){
        var str = widget.inputText!;
        debugPrint("set default text $str");
        textControl!.text = str;//如果有已输入文本则显示已输入文本
      }
    }
    super.initState();
  }
  @override
  Widget build(BuildContext context) {
    // TODO: implement build
    return Padding(
      padding: const EdgeInsets.only(top: 1),
      child: GestureDetector(//点击手势
        child: Container(
          color: sslUI.cellBackColor,
          child: Flex(
            direction: Axis.horizontal,
            children: [
              Expanded(
                  flex: 1,//标题和输入区占比1:1
                  child: Container(
                    alignment: Alignment.centerLeft,
                    padding: const EdgeInsets.only(left: 15),
                    height: 50,
                    child: Text(widget.title, style: TextStyle(color: sslUI.mainText),),
                  )
              ),
              Expanded(
                  flex: widget.style == SSLInputStyle.num ? 1 : 1,
                  child: Container(
                    alignment: Alignment.centerRight,
                    padding: const EdgeInsets.only(right: 0,top: 5,bottom: 5),
                    height: 50,
                    child: showText()
                  )
              ),
              styleChange(),
            ],
          ),
        ),
        //手势点击回调
        onTap: (){
          if (widget.onTap != null){
            widget.onTap!();
          }
        },
      )
    );
  }
  //判断显示类型,区分显示的组件
  Widget showText(){
    if (widget.style == SSLInputStyle.arrow){
      if (widget.inputText != null){
        return Text(widget.inputText!, style: TextStyle(color: sslUI.subText),);
      }else{
        return const Padding(padding: EdgeInsets.zero);
      <img src="}" alt="" width="30%" />
    }else{
      return TextField(
        controller: textControl,
        readOnly: widget.style == SSLInputStyle.arrow ? true : false,
        textAlign: TextAlign.right,
        style: TextStyle(color: sslUI.subText),
        keyboardType: widget.style == SSLInputStyle.num ? const TextInputType.numberWithOptions(signed: false, decimal: true) : TextInputType.text,
        decoration: InputDecoration(
          // labelText: widget.inputText,
          hintText: SSLLocales.l_input_placeholder.tr + widget.title,
          fillColor: sslUI.cellBackColor,
          border: InputBorder.none,
          // border: OutlineInputBorder(
          //   borderSide: BorderSide(color: sslUI.priColor, width: 1),
          // ),
        ),
        //输入变化回调
        onChanged: (v){
          if (widget.onTextChange != null){
            widget.onTextChange!(v);
          }
        },
        //输入完成回调
        onEditingComplete: (){
          if (widget.onEditComplete != null){
            widget.onEditComplete!(textControl!.text);
          }
        },
      );
    }
  }
  根据不同风格决定返回widget
  Widget styleChange(){
    if (widget.style == SSLInputStyle.arrow){
      return Padding(
        padding: const EdgeInsets.only(right: 15),
        child: Icon(Icons.arrow_forward_ios, color: sslUI.iconColor,),
      );
    }else{
      return const Padding(padding: EdgeInsets.only(left: 15),);
    }
  }
  @override
  void dispose() {
  //销毁文本输入控制器
    // TODO: implement dispose
    if (textControl != null){
      textControl!.dispose();
    }
    super.dispose();
  }
}
相关推荐
Mr.NickJJ2 小时前
Swift系列02-Swift 数据类型系统与内存模型
开发语言·ios·swift
二流小码农2 小时前
鸿蒙开发:wrapBuilder传递参数
android·ios·harmonyos
火柴就是我4 小时前
flutter rust bridge 编译成so 文件 或者 .a文件 依赖到主项目
flutter·ios·rust
YungFan5 小时前
iOS开发之网络代码进化史
ios·swift
pengyu5 小时前
系统化掌握Flutter组件之Transform:空间魔法师
android·flutter·dart
坚果的博客6 小时前
鸿蒙版Flutter快递查询助手
flutter·华为·harmonyos
晴天学长7 小时前
一个多功能的GetX 项目代码生成工具
前端·flutter
蜡笔小新..8 小时前
Windows下配置Flutter移动开发环境以及AndroidStudio安装和模拟机配置
windows·flutter
顾林海10 小时前
深入理解 Dart 函数:从基础到高阶应用
android·前端·flutter
SunshineBrother11 小时前
shell脚本,怎么查找项目中的重复图片
ios