玩转基础Widget

  • Widget
    • Stateless Widget
    • Stateful Widget
      • State生命周期
  • 基础widget
    • 文本显示
      • Text
      • RichText
      • DefaultTextStyle
    • 图片显示
      • FlutterLogo
      • Icon
      • Image
        • Iamge.asset
        • Image.file
        • Image.network
        • Image.memory
      • CircleAvatar
      • FadeInImage
    • 按钮
      • RaisedButton
      • FlatButton
      • OutlineButton
      • IconButton
    • 输入框
      • 焦点控制
      • 获取输入内容
      • TextFormField

​ 在Flutter中,几乎所有的对象都是一个 Widget,与原生开发中的 控件不同的是,Flutter中的 widget的概念更广泛,它不仅可以表示UI元素,也可以表示一些功能性的组件如:用于手势检测的 GestureDetector widget、用于应用主题数据传递的 Theme等等。由于Flutter主要就是用于构建用户界面的,所以,在大多数时候,可以认为widget就是一个控件,不必纠结于概念。

​ Widget的功能是“描述一个UI元素的配置数据”,Widget其实并不是表示最终绘制在设备屏幕上的显示元素,而只是显示元素的一个配置数据。实际上,Flutter中真正代表屏幕上显示元素的类是Element,也就是说Widget只是描述Element的一个配置。一个Widget可以对应多个Element,这是因为同一个Widget对象可以被添加到UI树的不同部分,而真正渲染时,UI树的每一个节点都会对应一个Element对象。

Widget

StatelessWidgetStatefulWidgetflutter的基础组件,日常开发中自定义Widget都是选择继承这两者之一。也是在往后的开放中,我们最多接触的Widget:

  • StatelessWidget:无状态的,展示信息,面向那些始终不变的UI控件;

  • StatefulWidget:有状态的,可以通过改变状态使得 UI 发生变化,可以包含用户交互(比如弹出一个 dialog)。

在实际使用中,Stateless与Stateful的选择需要取决于这个 Widget 是有状态还是无状态,简单来说看界面是否需要更新。

Stateless Widget

​ StatelessWidget用于不需要维护状态的场景,它通常在build方法中通过嵌套其它Widget来构建UI,在构建过程中会递归的构建其嵌套的Widget。

BuildContext表示构建widget的上下文,它是操作widget在树中位置的一个句柄,它包含了一些查找、遍历当前Widget树的一些方法。每一个widget都有一个自己的context对象。

import 'package:flutter/material.dart';void main() => runApp(StatelessApp());class StatelessApp extends StatelessWidget {///在build方法中通过嵌套其它Widget来构建UI,在构建过程中会递归的构建其嵌套的Widget@overrideWidget build(BuildContext context) {//嵌套 MaterialApp:封装了应用程序实现Material Design所需要的一些widgetreturn MaterialApp(title: "Widget演示", //标题,显示在recent时候的标题//主页面//Scaffold : Material Design布局结构的基本实现。home: Scaffold(//ToolBar/ActionBarappBar: AppBar(title: Text("Widget")),body: Text("Hello,Flutter!"),));}
}

Material Design:

一种设计语言,Material Design 于2014年的 Google I/O 首次亮相,是谷歌推出的全新的设计语言。说白了,就是一种设计风格。

Stateful Widget

​ StatefulWidget是动态的,添加了一个新的接口createState()用于创建和Stateful widget相关的状态State,它在Stateful widget的生命周期中可能会被多次调用。

​ 当State被改变时,可以手动调用其setState()方法通知Flutter framework状态发生改变,Flutter framework在收到消息后,会重新调用其build方法重新构建widget树,从而达到更新UI的目的。

class StatefulState extends State<StatefulApp> {int _i;///当Widget第一次插入到Widget树时会被调用,对于每一个State对象,Flutter framework只会调用一次该回调@overridevoid initState() {super.initState();_i = 1;}@overrideWidget build(BuildContext context) {return MaterialApp(title: "Widget演示",theme: ThemeData(),home: Scaffold(appBar: AppBar(title: Text("Widget")),body: RaisedButton(onPressed: () {//修改状态,setState会重新调用build更新uisetState(() {_i++;});},child: Text("Hello,Flutter! $_i"),),));}
}

State生命周期

​ State类除了build之外还提供了很多方法能够让我们重写,这些方法会在不同的状态下由Flutter调起执行,所以这些方法我们就称之为生命周期方法。

import 'package:flutter/material.dart';void main() => runApp(MyApp());class MyApp extends StatefulWidget {@override_MyAppState createState() => _MyAppState();
}class _MyAppState extends State<MyApp> {bool isShowChild;///当Widget第一次插入到Widget树时会被调用,对于每一个State对象,Flutter framework只会调用一次该回调@overridevoid initState() {super.initState();isShowChild = true;debugPrint("parent initState......");}///初始化时,在initState()之后立刻调用///当依赖的InheritedWidget rebuild,会触发此接口被调用@overridevoid didChangeDependencies() {super.didChangeDependencies();debugPrint("parent didChangeDependencies......");}///绘制界面,当setState触发的时候会再次被调用@overrideWidget build(BuildContext context) {debugPrint("parent build......");return MaterialApp(home: Scaffold(body: Center(child: RaisedButton(onPressed: () {setState(() {isShowChild = !isShowChild;});},child: isShowChild ? Child() : Text("演示移除Child"),)),),);}///状态改变的时候会调用该方法,比如调用了setState@overridevoid didUpdateWidget(MyApp oldWidget) {super.didUpdateWidget(oldWidget);debugPrint("parent didUpdateWidget......");}///当State对象从树中被移除时,会调用此回调@overridevoid deactivate() {super.deactivate();debugPrint('parent deactivate......');}///当State对象从树中被永久移除时调用;通常在此回调中释放资源@overridevoid dispose() {super.dispose();debugPrint('parent dispose......');}
}class Child extends StatefulWidget {@override_ChildState createState() => _ChildState();
}class _ChildState extends State<Child> {@overrideWidget build(BuildContext context) {debugPrint("child build......");return Text('lifeCycle');}@overridevoid initState() {super.initState();debugPrint("child initState......");}///初始化时,在initState()之后立刻调用///当依赖的InheritedWidget rebuild,会触发此接口被调用@overridevoid didChangeDependencies() {super.didChangeDependencies();debugPrint("child didChangeDependencies......");}///父widget状态改变的时候会调用该方法,比如父节点调用了setState@overridevoid didUpdateWidget(Child oldWidget) {super.didUpdateWidget(oldWidget);debugPrint("child didUpdateWidget......");}///当State对象从树中被移除时,会调用此回调@overridevoid deactivate() {super.deactivate();debugPrint('child deactivate......');}///当State对象从树中被永久移除时调用;通常在此回调中释放资源@overridevoid dispose() {super.dispose();debugPrint('child dispose......');}
}

执行的输出结果显示为:

  • 运行到显示
I/flutter (22218): parent initState......
I/flutter (22218): parent didChangeDependencies......
I/flutter (22218): parent build......
I/flutter (22218): child initState......
I/flutter (22218): child didChangeDependencies......
I/flutter (22218): child build......
  • 点击按钮会移除Child
I/flutter (22218): parent build......
I/flutter (22218): child deactivate......
I/flutter (22218): child dispose......
  • 将MyApp的代码由 child: isShowChild ? Child() : Text("演示移除Child"),改为 child: Child(),点击按钮时
I/flutter (22765): parent build......
I/flutter (22765): child didUpdateWidget......
I/flutter (22765): child build......

从这些实验中能够得出State的生命周期为:

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-rwh5gNCi-1652105029912)(图片/生命周期.png)]

基础widget

文本显示

Text

Text是展示单一格式的文本Widget(Android TextView)。

import 'package:flutter/material.dart';///
/// main方法 调用runApp传递Widget,这个Widget成为widget树的根
void main() => runApp(TextApp());///
/// 1、单一文本Text
///
//创建一个无状态的Widget
class TextApp extends StatelessWidget {@overrideWidget build(BuildContext context) {//封装了应用程序实现Material Design所需要的一些widgetreturn MaterialApp(title: "Text演示", //标题,显示在recent时候的标题//主页面//Scaffold : Material Design布局结构的基本实现。home: Scaffold(//ToolBar/ActionBarappBar: AppBar(title: Text("Text")),body: Text("Hello,Flutter"),),);}
}

在使用Text显示文字时候,可能需要对文字设置各种不同的样式,类似Android的 android:textColor/Size

在Flutter中也拥有类似的属性

Widget _TextBody() {return Text("Hello,Flutter",style: TextStyle(//颜色color: Colors.red,//字号 默认14fontSize: 18,//粗细fontWeight: FontWeight.w800,//斜体fontStyle: FontStyle.italic,//underline:下划线,overline:上划线,lineThrough:删除线decoration: TextDecoration.lineThrough,decorationColor: Colors.black,//solid:实线,double:双线,dotted:点虚线,dashed:横虚线,wavy:波浪线decorationStyle: TextDecorationStyle.wavy),);
}class TextApp extends StatelessWidget {@overrideWidget build(BuildContext context) {return MaterialApp(title: "Text演示", home: Scaffold(appBar: AppBar(title: Text("Text")),body: _TextBody(),),);}
}

RichText

如果需要显示更为丰富样式的文本(比如一段文本中文字不同颜色),可以使用RichText或者Text.rich

Widget _RichTextBody() {var textSpan = TextSpan(text: "Hello",style: TextStyle(color: Colors.red),children: [TextSpan(text: "Flu", style: TextStyle(color: Colors.blue)),TextSpan(text: "uter", style: TextStyle(color: Colors.yellow)),],);//Text.rich(textSpan);return RichText(text: textSpan);
}

DefaultTextStyle

​ 在widget树中,文本的样式默认是可以被继承的,因此,如果在widget树的某一个节点处设置一个默认的文本样式,那么该节点的子树中所有文本都会默认使用这个样式。相当于在Android中定义 Theme

Widget _DefaultStyle(){DefaultTextStyle(//设置文本默认样式style: TextStyle(color:Colors.red,fontSize: 20.0,),textAlign: TextAlign.start,child: Column(crossAxisAlignment: CrossAxisAlignment.start,children: <Widget>[Text("Hello Flutter!"),Text("Hello Flutter!"),Text("Hello Flutter!",style: TextStyle(inherit: false, //不继承默认样式color: Colors.grey),),],),);
}

图片显示

“图文”:有文字显示Widget,又怎么少的了图片呢。

FlutterLogo

​ 这个Widget用于显示Flutter的logo…

Widget flutterLogo() {return FlutterLogo(//大小size: 100,//logo颜色 默认为 Colors.bluecolors: Colors.red,//markOnly:只显示logo,horizontal:logo右边显示flutter文字,stacked:logo下面显示文字style: FlutterLogoStyle.stacked,//logo上文字颜色textColor: Colors.blue,);
}

Icon

主要用于显示内置图标的Widget

Widget icon() {return Icon(//使用预定义Material icons// https://docs.flutter.io/flutter/material/Icons-class.htmlIcons.add,size: 100,color: Colors.red);
}

Image

显示图片的Widget。图片常用的格式主要有bmp,jpg,png,gif,webp等,Android中并不是天生支持gif和webp动图,但是这一特性在flutter中被很好的支持了。

方式 解释
Image() 使用ImageProvider提供图片,如下方法本质上也是使用的这个方法
Image.asset 加载资源图片
Image.file 加载本地图片文件
Image.network 加载网络图片
Image.memory 加载内存图片
Iamge.asset

在工程目录下创建目录,如:assets,将图片放入此目录。打开项目根目录:pubspec.yaml

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-ilqKvFsm-1652105029913)(图片/基础Widget_AssetsImag.png)]

return MaterialApp(title: "Image演示",home: Scaffold(appBar: AppBar(title: Text("Image")),body: Image.asset("assets/banner.jpeg"),),);
Image.file

在sd卡中放入一张图片。然后利用path_provider库获取sd卡根目录(Dart库版本可以在:https://pub.dartlang.org/packages查询)。

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-NURxRVFK-1652105029914)(图片/基础Widget_FileProvider.png)]

注意权限

class ImageState extends State<ImageApp> {Image image;@overridevoid initState() {super.initState();getExternalStorageDirectory().then((path) {setState(() {image = Image.file(File("${path.path}${Platform.pathSeparator}banner.jpeg"));});});}@overrideWidget build(BuildContext context) {return MaterialApp(title: "Image演示",home: Scaffold(appBar: AppBar(title: Text("Image")),body: image,),);}
}
Image.network

直接给网络地址即可。

Flutter 1.0,加载https时候经常出现证书错误。必须断开AS打开app

Image.memory
Future<List<int>> _imageByte() async {String path = (await getExternalStorageDirectory()).path;return await File("$path${Platform.pathSeparator}banner.jpeg").readAsBytes();
}class ImageState extends State<ImageApp> {Image image;@overridevoid initState() {super.initState();_imageByte().then((bytes) {setState(() {image = Image.memory(bytes);});});}@overrideWidget build(BuildContext context) {return MaterialApp(title: "Image演示",home: Scaffold(appBar: AppBar(title: Text("Image")),body: image,),);}
}

fit属性相当于android中的scaletype,定义如下:

fit 说明 效果
BoxFit.fill 填充,忽略原有的宽高比,填满为止 [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-L6mrpsBu-1652105029915)(图片/基础Widget_Image_Fill.png)]
BoxFit.contain 包含,不改变原有比例让容器包含整个图片,容器多余部分填充背景 [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-WBcXaz3K-1652105029916)(图片/基础Widget_Image_Contain.png)]
BoxFit.cover 覆盖,不改变原有比例,让图片充满整个容器,图片多余部分裁剪 [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-aZ0c91K3-1652105029917)(图片/基础Widget_Image_Cover.png)]
BoxFit.fitWidth 横向图片填充 [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-ZyoRkEkC-1652105029917)(图片/基础Widget_Image_FitWidth.png)]
BoxFit.fitHeight 纵向图片填充 [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-RLaJsaOq-1652105029918)(图片/基础Widget_Image_FitHeight.png)]
BoxFit.none 原始大小居中 [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-uhqvKLzm-1652105029919)(图片/基础Widget_Image_none.png)]
BoxFit.scaleDown 图片大小小于容器事相当于none,图片大小大于容器时缩小图片大小实现contain [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-UI08cwJt-1652105029919)(图片/基础Widget_Image_ScaleDown.png)]

CircleAvatar

主要用来显示用户的头像,任何图片都会被剪切为圆形。

CircleAvatar(//图片提供者 ImageProviderbackgroundImage: AssetImage("assets/banner.jpeg"),//半径,控制大小radius: 50.0,);

FadeInImage

当使用默认Image widget显示图片时,您可能会注意到它们在加载完成后会直接显示到屏幕上。这可能会让用户产生视觉突兀。如果最初显示一个占位符,然后在图像加载完显示时淡入,我们可以使用FadeInImage来达到这个目的!

 image =  FadeInImage.memoryNetwork(placeholder: kTransparentImage,image: 'https://flutter.io/images/homepage/header-illustration.png',);

按钮

Material widget库中提供了多种按钮Widget如RaisedButton、FlatButton、OutlineButton等,它们都是直接或间接对RawMaterialButton的包装定制,所以他们大多数属性都和RawMaterialButton一样。所有Material 库中的按钮都有如下相同点:

  1. 按下时都会有“水波动画”。
  2. 有一个onPressed属性来设置点击回调,当按钮按下时会执行该回调,如果不提供该回调则按钮会处于禁用状态,禁用状态不响应用户点击。

RaisedButton

"漂浮"按钮,它默认带有阴影和灰色背景

RaisedButton(child: Text("normal"),onPressed: () => {},)

FlatButton

扁平按钮,默认背景透明并不带阴影

FlatButton(child: Text("normal"),onPressed: () => {},
)

OutlineButton

默认有一个边框,不带阴影且背景透明。

OutlineButton(child: Text("normal"),onPressed: () => {},
)

IconButton

可点击的Icon

IconButton(icon: Icon(Icons.thumb_up),onPressed: () => {},
)

按钮外观可以通过其属性来定义,不同按钮属性大同小异

const FlatButton({...  @required this.onPressed, //按钮点击回调this.textColor, //按钮文字颜色this.disabledTextColor, //按钮禁用时的文字颜色this.color, //按钮背景颜色this.disabledColor,//按钮禁用时的背景颜色this.highlightColor, //按钮按下时的背景颜色this.splashColor, //点击时,水波动画中水波的颜色this.colorBrightness,//按钮主题,默认是浅色主题 this.padding, //按钮的填充this.shape, //外形@required this.child, //按钮的内容
})FlatButton(onPressed: () => {},child: Text("Raised"),//蓝色color: Colors.blue,//水波splashColor: Colors.yellow,//深色主题,这样文字颜色会变成白色colorBrightness: Brightness.dark,//圆角按钮shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(50)),
)

RaisedButton,默认配置有阴影,因此在配置RaisedButton 时,拥有一系列 elevation 属性的配置

const RaisedButton({...this.elevation = 2.0, //正常状态下的阴影this.highlightElevation = 8.0,//按下时的阴影this.disabledElevation = 0.0,// 禁用时的阴影...
}

输入框

import 'package:flutter/material.dart';void main() => runApp(Demo1());class Demo1 extends StatelessWidget {@overrideWidget build(BuildContext context) {return MaterialApp(title: "Demo1",home: Scaffold(appBar: AppBar(title: Text("登录"),),//线性布局,垂直方向body: Column(children: <Widget>[TextField(//自动获得焦点autofocus: true,decoration: InputDecoration(labelText: "用户名",hintText: "用户名或邮箱",prefixIcon: Icon(Icons.person)),),TextField(//隐藏正在编辑的文本obscureText: true,decoration: InputDecoration(labelText: "密码",hintText: "您的登录密码",prefixIcon: Icon(Icons.lock)),),],),),);}
}

这个效果非常的“系统”,我们可能大多数情况下需要将下划线更换为矩形边框,这时候可能就需要组合widget来完成:

//容器 设置一个控件的尺寸、背景、margin
Container(margin: EdgeInsets.all(32),child: TextField(keyboardType: TextInputType.emailAddress,decoration: InputDecoration(labelText: "用户名",hintText: "用户名或邮箱",prefixIcon: Icon(Icons.person),border: InputBorder.none //隐藏下划线)),//装饰decoration: BoxDecoration(// 边框浅灰色,宽度1像素border: Border.all(color: Colors.red[200], width: 1.0),//圆角borderRadius: BorderRadius.circular(5.0),),)

焦点控制

​ FocusNode: 与Widget绑定,代表了这个Widget的焦点

​ FocusScope: 焦点控制范围

​ FocusScopeNode:控制焦点

class _TextFocusState extends State<TextFocusWidget> {FocusNode focusNode1 = new FocusNode();FocusNode focusNode2 = new FocusNode();void _listener() {debugPrint("用户名输入框焦点:${focusNode1.hasFocus}");}@overridevoid initState() {super.initState();//监听焦点状态改变事件focusNode1.addListener(_listener);}@overridevoid dispose() {super.dispose();focusNode1.dispose();focusNode2.dispose();}@overrideWidget build(BuildContext context) {return Column(children: <Widget>[TextField(autofocus: true,//关联焦点focusNode: focusNode1,//设置键盘动作为: 下一步textInputAction: TextInputAction.next,//点击下一步执行回调onEditingComplete: () {//获得 context对应UI树的焦点范围 的焦点控制器FocusScopeNode focusScopeNode = FocusScope.of(context);//将焦点交给focusNode2focusScopeNode.requestFocus(focusNode2);},decoration: InputDecoration(labelText: "用户名",hintText: "用户名或邮箱",prefixIcon: Icon(Icons.person)),),TextField(//隐藏正在编辑的文本obscureText: true,focusNode: focusNode2,decoration: InputDecoration(labelText: "密码",hintText: "您的登录密码",prefixIcon: Icon(Icons.lock)),),custom(),],);}
}

获取输入内容

获取输入内容有两种方式:

  1. 定义两个变量,用于保存用户名和密码,然后在onChange触发时,各自保存一下输入内容。
  2. 通过controller直接获取。

onChange获得输入内容:

TextField(onChanged: (s) => debugPrint("ssss:$s"),)

controller获取:

定义一个controller:

//定义一个controller
TextEditingController _unameController=new TextEditingController();

然后设置输入框controller:

TextField(controller: _unameController, //设置controller...
)

通过controller获取输入框内容

debugPrint(_unameController.text)

TextFormField

TextFormFieldTextField多了一些属性,其中 validator用于设置验证回调。在单独使用时与TextField没有太大的区别。当结合From,利用From可以对输入框进行分组,然后进行一些统一操作(验证)

class _TextFocusState extends State<TextFocusWidget> {//全局keyGlobalKey<FormState> _key = GlobalKey<FormState>();@overrideWidget build(BuildContext context) {return Form(//类似 idkey: _key,child: Column(children: <Widget>[TextFormField(autofocus: true,decoration: InputDecoration(labelText: "用户名",hintText: "用户名或邮箱",icon: Icon(Icons.person)),// 校验用户名validator: (v) {return v.trim().length > 0 ? null : "用户名不能为空";}),TextFormField(decoration: InputDecoration(labelText: "密码",hintText: "您的登录密码",icon: Icon(Icons.lock)),// 校验用户名validator: (v) {return v.trim().length > 0 ? null : "密码不能为空";}),RaisedButton(onPressed: () {//Form所有TextFormField成功 返回trueif (_key.currentState.validate()) {}},child: Text("提交"),)],));}
}

10天学会flutter DAY7 flutter 玩转基础Widget相关推荐

  1. 10分钟学会用Python轻松玩转Excel

    前言 当你需要每天对 Excel 做大量重复的操作,如果只靠人工来做既浪费时间,又十分枯燥,好在 Python 为我们提供了许多操作 Excel 的模块,能够让我们从繁琐的工作中腾出双手. 今天就和大 ...

  2. 10天学会kotlin DAY7 接口 泛型 协变 逆变

    kotlin 接口 泛型 协变 逆变 前言 1.接口的定义 2.抽象类 3.定义泛型类 4.泛型函数 5.泛型变换 6.泛型类型约束 7.vararg 关键字(动态参数) 8.[] 操作符 9.out ...

  3. flutter版本的玩Android客户端

    flutter学习案例 目录介绍 00.项目下载与查看 01.项目介绍 02.项目优势 03.部分功能介绍 04.部分截图展示 05.版本更新 06.flutter系列博客 07.感谢 08.如何辨别 ...

  4. Flutter 项目开发指导 从基础入门到精通使用目录

    Flutter 从入门 到精通系列文章 本文章为 Flutter 开发中的经验积累分享.教程分享.开发笔记分享目录,持续维护中. 题记 -- 执剑天涯,从你的点滴积累开始,所及之处,必精益求精. Fl ...

  5. 【Flutter】Flutter 混合开发 ( 混合开发中 Flutter 的 热重启 / 热加载 )

    文章目录 前言 一.混合开发中启用 Flutter 的 热重启 / 热加载 二.混合开发中 Flutter 的 热重启 / 热加载 命令测试 三.指定混合应用连接的设备 四.相关资源 前言 上一篇博客 ...

  6. 【Flutter】Flutter 开发环境搭建 ( 2021年08月25日 补充最新资料 | 最新安装教程 )

    文章目录 前言 一.Android Studio 环境安装 Flutter / Dart 插件 二.Flutter SDK 下载 三.设置 Flutter 环境变量 1.设置 Flutter SDK环 ...

  7. 【Flutter】Flutter 布局组件 ( Wrap 组件 | Expanded 组件 )

    文章目录 一.Wrap 组件 二.Expanded 组件 三.完整代码示例 四.相关资源 一.Wrap 组件 Wrap 组件 : 该组件是可换行的水平线性布局组件 , 与 Row 组件间类似 , 但是 ...

  8. 【Flutter】Flutter 布局组件 ( FractionallySizedBox 组件 | Stack 布局组件 | Positioned 组件 )

    文章目录 一.FractionallySizedBox 组件 二.Stack 布局组件 三.Positioned 组件 四. 完整代码示例 五. 相关资源 一.FractionallySizedBox ...

  9. 【Flutter】Flutter 布局组件 ( PhysicalModel 组件 )

    文章目录 一.PhysicalModel 组件 二. 完整代码示例 三. 相关资源 一.PhysicalModel 组件 PhysicalModel 组件 : 可以将布局显示成不同的形状 , clas ...

最新文章

  1. 使用Lucene分词
  2. ansible的安装和使用
  3. C++实现输入两个字符串,从第一字符串中删除第二个字符串中所有的字符
  4. How to Run a Stress Test in JMeter
  5. Mac下修改环境变量
  6. Leaflet中使用Leaflet.Spin插件实现地图加载等待效果
  7. django-路由-通过正则表达式来捕获路径-对应视图函数
  8. java正则表达式 后顾,正则表达式:从Copy到手写
  9. [ZT]Addison Wesley's Free Chapters and Articles
  10. java.lang.IllegalStateException: No output folder
  11. RDV需要什么服务器系统,锐起RDV的教程
  12. guice android,android – 如何使用Guice的@Singleton?
  13. 华为鸿蒙系统操作教程_鸿蒙OS Beta版怎么使用
  14. JS-underfined is not a function
  15. 【网易微专业】算法原理与实践 2
  16. 不玩手机的步步高玩大数据:一条短信让你多买一只澳洲大龙虾
  17. MATLAB之Nyquist图和Bode图
  18. oracle行转列实践
  19. Vue+ElementUI table表格分页
  20. 【项目实战】Spring Cloud Gateway入门介绍 - 网关过滤器工厂

热门文章

  1. 中望CAD的引线标注格式怎么改_首款国产中望CAD Linux登陆统一操作系统UOS
  2. delve 配合 Goland 远程调试
  3. Ueeshop:外贸网站报价,从免费到数十万是怎么回事?
  4. 速卖通php,史上最详细的速卖通选品技巧
  5. 自已动手制作Linux下拼音五笔输入法
  6. 发那科机器人六轴放大器保险丝熔断_发那科机器人R-30iB控制柜保险丝解析——发那科机器人...
  7. (C)宏定义——无参宏
  8. 22中山大学人工智能学院 上岸经验分享帖
  9. 单片机学习笔记 —— 可变调的蜂鸣器
  10. 最新行政区代码(2010-12-31) SQL语句