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");
   }
}


目录
相关文章
|
25天前
深入理解Flutter鸿蒙next版本 中的Widget继承:使用extends获取数据与父类约束
本文详细介绍了Flutter中如何通过继承其他Widget来创建自定义组件。首先解释了Widget继承的基本概念,包括StatelessWidget和StatefulWidget的区别。接着通过具体示例展示了如何继承StatelessWidget和StatefulWidget,并在子类中访问父类的build方法和状态。最后,结合多个自定义Widget展示了如何在实际应用中灵活使用继承和组合来构建复杂的UI。
72 8
|
23天前
|
容器
flutter&鸿蒙next 使用 InheritedWidget 实现跨 Widget 传递状态
在 Flutter 中,状态管理至关重要。本文详细介绍了如何使用 InheritedWidget 实现跨 Widget 的状态传递。InheritedWidget 允许数据在 Widget 树中向下传递,适用于多层嵌套的场景。通过一个简单的计数器示例,展示了如何创建和使用 InheritedWidget,包括其基础概念、工作原理及代码实现。虽然 InheritedWidget 较底层,但它是许多高级状态管理解决方案的基础。
94 2
|
1月前
|
容器
flutter:第一个flutter&Widget的使用 (二)
本文介绍了Flutter框架下的基本组件及其用法,包括简单的 Stateless Widget 如文本和按钮,以及更复杂的 StatefulWidget 示例。详细解释了如何使用 `context` 获取祖先小部件的信息,并展示了 `MaterialApp` 的属性及用途。此外,还探讨了 `StatefulWidget` 与 `StatelessWidget` 的区别,以及 `AppBar` 的常见属性配置方法。适合Flutter初学者参考学习。
|
23天前
|
Dart JavaScript 前端开发
Flutter 的 Widget 概述与常用 Widgets 与鸿蒙 Next 的对比
Flutter 是 Google 开发的开源 UI 框架,用于快速构建高性能的移动、Web 和桌面应用。Flutter 通过 Widget 构建 UI,每个 UI 元素都是 Widget,包括文本、按钮、图片等。Widget 不仅描述外观,还描述行为,是不可变的。常见的 Widget 包括结构型(Container、Column、Row)、呈现型(Text、Image)、交互型(ElevatedButton)和状态管理型(StatefulWidget)。Flutter 与鸿蒙 Next 在组件化架构、开发语言、布局系统、性能和跨平台支持方面各有优势
68 0
|
4月前
Flutter-底部弹出框(Widget层级)
文章描述了如何在Flutter中使用DraggableScrollableSheet创建一个底部弹出框,同时保持其可手势滑动关闭。作者遇到问题并提出对原控件进行扩展,以支持头部和列表布局的滑动关闭功能。
189 0
|
5月前
Flutter StreamBuilder 实现局部刷新 Widget
Flutter StreamBuilder 实现局部刷新 Widget
47 0
|
6月前
|
Android开发
Flutter完整开发实战详解(六、 深入Widget原理),2024百度Android岗面试真题收录解析
Flutter完整开发实战详解(六、 深入Widget原理),2024百度Android岗面试真题收录解析
|
6月前
|
开发框架 前端开发 搜索推荐
【Flutter前端技术开发专栏】Flutter中的自定义Widget与渲染流程
【4月更文挑战第30天】探索Flutter的自定义Widget与渲染流程。自定义Widget是实现复杂UI设计的关键,优点在于个性化设计、功能扩展和代码复用,但也面临性能优化和复杂性管理的挑战。创建步骤包括设计结构、定义Widget类、实现构建逻辑和处理交互。Flutter渲染流程涉及渲染对象树、布局、绘制和合成阶段。实践案例展示如何创建带渐变背景和阴影的自定义按钮。了解这些知识能提升应用体验并应对开发挑战。查阅官方文档以深入学习。
80 0
【Flutter前端技术开发专栏】Flutter中的自定义Widget与渲染流程
|
6月前
|
JavaScript 前端开发 开发者
【Flutter前端技术开发专栏】Flutter中的Widget与状态管理
【4月更文挑战第30天】本文探讨了Flutter的Widget和状态管理。Widget是Flutter构建UI的基础,分为有状态和无状态两种。状态管理确保UI随应用状态变化更新,影响应用性能和可维护性。文章介绍了`setState`、`Provider`、`Riverpod`、`Bloc`和`Redux`等状态管理方法,并通过计数器应用展示了其实现。选择合适的状态管理策略对高效开发至关重要。
94 0
【Flutter前端技术开发专栏】Flutter中的Widget与状态管理
|
6月前
|
Dart 前端开发 开发者
【Flutter前端技术开发专栏】Flutter Dart语言基础语法解析
【4月更文挑战第30天】Dart是Google为Flutter框架打造的高效编程语言,具有易学性、接口、混入、抽象类等特性。本文概述了Dart的基础语法,包括静态类型(如int、String)、控制流程(条件、循环)、函数、面向对象(类与对象)和异常处理。此外,还介绍了库导入与模块使用,帮助开发者快速入门Flutter开发。通过学习Dart,开发者能创建高性能的应用。
73 0
【Flutter前端技术开发专栏】Flutter Dart语言基础语法解析
下一篇
无影云桌面