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();
  }
}
相关推荐
早起的年轻人9 小时前
Flutter String 按 ,。分割
flutter
missmisslulu13 小时前
电容笔值得买吗?2024精选盘点推荐五大惊艳平替电容笔!
学习·ios·电脑·平板
GEEKVIP14 小时前
手机使用技巧:8 个 Android 锁屏移除工具 [解锁 Android]
android·macos·ios·智能手机·电脑·手机·iphone
GEEKVIP14 小时前
如何在 Windows 10 上恢复未保存/删除的 Word 文档
macos·ios·智能手机·电脑·word·笔记本电脑·iphone
奇客软件15 小时前
iPhone使用技巧:如何恢复变砖的 iPhone 或 iPad
数码相机·macos·ios·电脑·笔记本电脑·iphone·ipad
helloxmg19 小时前
鸿蒙harmonyos next flutter通信之MethodChannel获取设备信息
flutter
helloxmg19 小时前
鸿蒙harmonyos next flutter混合开发之开发package
flutter·华为·harmonyos
奇客软件2 天前
如何从相机的记忆棒(存储卡)中恢复丢失照片
深度学习·数码相机·ios·智能手机·电脑·笔记本电脑·iphone
GEEKVIP2 天前
如何修复变砖的手机并恢复丢失的数据
macos·ios·智能手机·word·手机·笔记本电脑·iphone
lqj_本人2 天前
flutter_鸿蒙next_Dart基础②List
flutter