Day06 - Flutter 常用的基础 Widget(下)

简介: Day06 - Flutter 常用的基础 Widget(下)
  • 3.6、实现圆角图片
  • 方式一:ClipRRect
    ClipRRect用于实现圆角效果,可以设置圆角的大小。
    实现代码如下,非常简单:


Center(
   child: ClipRRect(
       borderRadius: BorderRadius.circular(10),
       child: Image.network(
          "https://tva1.sinaimg.cn/large/006y8mN6gy1g7aa03bmfpj3069069mx8.jpg",
          width: 200,
          height: 200,
       ),
    ),
);
  • 方式二:Container+BoxDecoration


class HomeContent extends StatelessWidget {
   @override
   Widget build(BuildContext context) {
       return Center(
          child: Container(
             width: 200,
             height: 200,
             decoration: BoxDecoration(
                borderRadius: BorderRadius.circular(20),
                image: DecorationImage(
                    image: NetworkImage("https://tva1.sinaimg.cn/large/006y8mN6gy1g7aa03bmfpj3069069mx8.jpg"),
                )
             ),
          ),
      );
   }
}


四、TextField


  • 4.1、TextField的介绍TextField用于接收用户的文本输入,它提供了非常多的属性,我们来看一下源码:但是我们没必要一个个去学习,很多时候用到某个功能时去查看是否包含某个属性即可


const TextField({
   Key key,
   this.controller,
   this.focusNode,
   this.decoration = const InputDecoration(),
   TextInputType keyboardType,
   this.textInputAction,
   this.textCapitalization = TextCapitalization.none,
   this.style,
   this.strutStyle,
   this.textAlign = TextAlign.start,
   this.textAlignVertical,
   this.textDirection,
   this.readOnly = false,
   ToolbarOptions toolbarOptions,
   this.showCursor,
   this.autofocus = false,
   this.obscureText = false,
   this.autocorrect = true,
   this.maxLines = 1,
   this.minLines,
   this.expands = false,
   this.maxLength,
   this.maxLengthEnforced = true,
   this.onChanged,
   this.onEditingComplete,
   this.onSubmitted,
   this.inputFormatters,
   this.enabled,
   this.cursorWidth = 2.0,
   this.cursorRadius,
   this.cursorColor,
   this.keyboardAppearance,
   this.scrollPadding = const EdgeInsets.all(20.0),
   this.dragStartBehavior = DragStartBehavior.start,
   this.enableInteractiveSelection = true,
   this.onTap,
   this.buildCounter,
   this.scrollController,
   this.scrollPhysics,
})
  • 几个比较常见的属性:一些属性比较简单:keyboardType键盘的类型,style设置样式,textAlign文本对齐方式,maxLength最大显示行数等等;
  • decoration:用于设置输入框相关的样式
  • icon:设置左边显示的图标
  • labelText:在输入框上面显示一个提示的文本
  • hintText:显示提示的占位文字
  • border:输入框的边框,默认底部有一个边框,可以通过InputBorder.none删除掉
  • filled:是否填充输入框,默认为false
  • fillColor:输入框填充的颜色
  • controller:TextEditingController()
  • onChanged:监听输入框内容的改变,传入一个回调函数
  • onSubmitted:点击键盘中右下角的down时,会回调的一个函数
  • 4.2、TextField 的样式以及监听


TextField(
   decoration: InputDecoration(
      labelText: "username",
      icon: Icon(Icons.favorite),
      hintText: "请输入用户名",
      // OutlineInputBorder()
      // InputBorder.none
      border: OutlineInputBorder()
   ),
   onChanged: (value) {
       print("输入的内容:$value");
   },
   onSubmitted: (value) {
       print("提交的值:$value");
   },
   // 输入不可见
   obscureText: true,
)
  • 4.3、TextField的controller
    我们可以给TextField添加一个控制器(Controller),可以使用它设置文本的初始值,也可以使用它来监听文本的改变;
    事实上,如果我们没有为TextField提供一个Controller,那么会Flutter会默认创建一个TextEditingController的,这个结论可以通过阅读源码得到:


@override
void initState() {
    super.initState();
    // ...其他代码
    if (widget.controller == null)
    _controller = TextEditingController();
}
  • 我们也可以自己来创建一个Controller控制一些内容:


class _TextFieldDemoState extends State<TextFieldDemo> {
    final textEditingController = TextEditingController();
    @override
    void initState() {
        super.initState();
        // 1.设置默认值
        textEditingController.text = "Hello World";
        // 2.监听文本框
        textEditingController.addListener(() {
            print("textEditingController:${textEditingController.text}");
        });
    }
    // ...省略build方法
}


五. Form表单的使用


在我们开发注册、登录页面时,通常会有多个表单需要同时获取内容或者进行一些验证,如果对每一个TextField都分别进行验证,是一件比较麻烦的事情。

做过前端的开发知道,我们可以将多个input标签放在一个form里面,Flutter也借鉴了这样的思想:我们可以通过Form对输入框进行分组,统一进行一些操作。


  • 5.1、Form 表单的基本使用
    Form表单也是一个Widget,可以在里面放入我们的输入框。
    但是Form表单中输入框必须是FormField类型的
    我们查看刚刚学过的TextField是继承自StatefulWidget,并不是一个FormField类型;
    我们可以使用TextFormField,它的使用类似于TextField,并且是继承自FormField的;
    我们通过Form的包裹,来实现一个注册的页面:


class JKHomeContent extends StatefulWidget {
  @override
  _JKHomeContentState createState() => _JKHomeContentState();
}
class _JKHomeContentState extends State<JKHomeContent> {
  @override
  Widget build(BuildContext context) {
      return Form(
         child: Column(
            mainAxisAlignment: MainAxisAlignment.center,
            children: <Widget>[
               TextFormField(
                  decoration: InputDecoration(
                     icon: Icon(Icons.people),
                     labelText: '用户名或者手机号'
                  ),
               ),
               TextFormField(
                  obscureText: true,
                   decoration: InputDecoration(
                       icon: Icon(Icons.lock),
                       labelText: "密码"
                   ),
               ),
               SizedBox(
                  height: 20,
               ),
               Container(
                  // double.infinit
                  width: 200,
                  height: 44,
                  child: RaisedButton(
                     color: Colors.green,
                     child: Text("注 册", style: TextStyle(fontSize: 20, color: Colors.white),),
                  onPressed: () {
                       print('点击了 注册');
                  },
               ),
            )
         ],
       )
    );
  }
}
  • 5.2、保存和获取表单数据有了表单后,我们需要在点击注册时,可以同时获取和保存表单中的数据,怎么可以做到呢?
  • 1、需要监听注册按钮的点击,在之前我们已经监听的onPressed传入的回调中来做即可。(当然,如果嵌套太多,我们待会儿可以将它抽取到一个单独的方法中)
  • 2、监听到按钮点击时,同时获取用户名和密码的表单信息。


  • 如何同时获取 用户名密码 的表单信息?
  • 如果我们调用 Form的State对象 的save方法,就会调用Form中放入的TextFormField的onSave回调:


TextFormField(
   decoration: InputDecoration(
      icon: Icon(Icons.people),
      labelText: "用户名或手机号"
   ),
   onSaved: (value) {
      print("用户名:$value");
   },
),
  • 但是,我们有没有办法可以在点击按钮时,拿到 Form对象 来调用它的save方法呢?


知识点:在Flutter如何可以获取一个通过一个引用获取一个StatefulWidget的State对象:通过绑定一个GlobalKey即可


image.png


image.png


class JKHomeContent extends StatefulWidget {
   @override
   _JKHomeContentState createState() => _JKHomeContentState();
}
class _JKHomeContentState extends State<JKHomeContent> {
     final registerFormKey = GlobalKey<FormState>();
     String username, password;
     void registerForm() {
        registerFormKey.currentState.save();
        print("username:$username password:$password");
     }
     @override
     Widget build(BuildContext context) {
        return Form(
            key: registerFormKey,
           child: Column(
              mainAxisAlignment: MainAxisAlignment.center,
              children: <Widget>[
                   TextFormField(
                      decoration: InputDecoration(
                         icon: Icon(Icons.people),
                         labelText: '用户名或者手机号'
                      ),
                      onSaved: (value) {
                         username = value;
                      },
                   ),
                   TextFormField(
                      obscureText: true,
                      decoration: InputDecoration(
                         icon: Icon(Icons.lock),
                         labelText: "密码"
                      ),
                      onSaved: (value) {
                         password = value;
                      },
                   ),
                   SizedBox(
                      height: 20,
                   ),
                   Container(
                      // double.infinit
                      width: 200,
                      height: 44,
                      child: RaisedButton(
                          color: Colors.green,
                          child: Text("注 册", style: TextStyle(fontSize: 20, color: Colors.white),),
                      onPressed: () {
                        print('点击了 注册');
                        registerForm();
                      },
                   ),
               )
           ],
        )
      );
    }
}
  • 5.3、验证填写的表单数据在表单中,我们可以添加 验证器,如果不符合某些特定的规则,那么给用户一定的提示信息比如我们需要账号和密码有这样的规则:账号和密码都不能为空。按照如下步骤就可以完成整个验证过程:
  • 1、为TextFormField添加validator的回调函数;


validator: (value) {
   return value.length < 6 ? "密码长度不够6位" : null;
},
  • 2、调用Form的State对象的validate方法,就会回调validator传入的函数;
    也可以为TextFormField添加一个属性:autovalidate
    不需要调用validate方法,会自动验证是否符合要求;



image.pngimage.png


void registerForm() {
   // 读取当前 From 的状态
   var registerFrom = registerFormKey.currentState;
   // 验证From表单
   if (registerFrom.validate()) {
      // 符合要求进行存储
      registerFrom.save();
      print("username:$username password:$password");
   }
}


目录
相关文章
|
5天前
|
前端开发 开发者 UED
Flutter的自定义Painter:深入探索自定义绘制Widget的技术实现
【4月更文挑战第26天】Flutter的自定义Painter允许开发者根据需求绘制独特UI,通过继承`CustomPaint`类和重写`paint`方法实现。在`paint`中使用`Canvas`绘制图形、路径等。创建自定义Painter类后,将其作为`CustomPaint` Widget的`painter`属性使用。此技术可实现自定义形状、渐变、动画等复杂效果,提升应用视觉体验。随着Flutter的进化,自定义Painter将提供更丰富的功能。
|
5天前
|
编解码 算法 开发者
Flutter的布局系统:深入探索布局Widget与布局原则
【4月更文挑战第26天】Flutter布局系统详解,涵盖布局Widget(Row/Column、Stack、GridView/ListView、CustomSingleChildLayout)和布局原则(弹性布局、约束优先、流式布局、简洁明了)。文章旨在帮助开发者理解并运用Flutter的布局系统,创建适应性强、用户体验佳的界面。通过选择合适的布局Widget和遵循原则,可实现复杂且高效的UI设计。
|
5天前
|
开发框架 搜索推荐 Android开发
Flutter的Widget基础:概念、分类与深入探索
【4月更文挑战第26天】Flutter Widget详解:基础、分类与工作原理。Widget是Flutter UI的核心,描述界面外观而非直接渲染。分为基础、布局、可滚动及状态管理四大类。基于响应式编程,状态变化时自动更新UI。了解其概念、分类和原理,能助开发者高效构建精美应用。随着Flutter生态发展,Widget系统潜力无限。
|
8月前
|
Dart 前端开发 开发工具
谷歌移动UI框架Flutter教程之Widget
谷歌移动UI框架Flutter教程之Widget
|
9月前
Flutter源码分析笔记:Widget类源码分析
本文记录阅读与分析Flutter源码 - Widget类源码分析。
62 0
Flutter源码分析笔记:Widget类源码分析
|
10月前
|
API Android开发 容器
Flutter控件之基类Widget封装
基类的Widget主要确定以下几个方面,第一就是,自定义一个抽象类还是非抽象类,第二、继承方式,采取有状态还是无状态,第三、关于组件的点击方式,如何进行实现。
105 0
Flutter万物皆为Widget
Flutter 中的 Widget 是描述界面元素的基本单元,可以包含视觉和交互元素。Widget 可以嵌套、组合和扩展,从而构建出复杂的 UI 界面。在 Flutter 中,Widget 可以分为两种类型:StatelessWidget 和 StatefulWidget。
Flutter万物皆为Widget
|
JavaScript 前端开发 开发工具
Flutter | 基础 Widget
Flutter | 基础 Widget
【布局 widget】 Flutter GridView
GridView 独有的参数其实只有一个 gridDelegate,gridDelegate 的作用是为 GridView 布局,制定每行几个 child,空白多少等。
111 0
【布局 widget】 Flutter GridView
|
缓存 前端开发 Java
手写一个Flutter State Widget,来让你彻底理解State的来龙去脉
手写一个Flutter State Widget,来让你彻底理解State的来龙去脉
177 0
手写一个Flutter State Widget,来让你彻底理解State的来龙去脉