一、Flutter架构

flutter官方文档:https://api.flutter.dev/flutter/widgets/widgets-library.html

flutter架构:

在flutter的世界里,包括views,view controllers,layouts等在内的概念都建立在Widget之上。widget是flutter功能的抽象描述。通过组合不同的 Widget,来实现我们用户交互界面。

Widget 分为两种:

1、无状态的,StatelessWidget,它只能用来展示信息,不能有动作(用户交互)

使用方法:继承 StatelessWidget,实现 build 方法

class FooWidget extends StatelessWidget {  @override  Widget build(BuildContext context) {    // ...  }}

2、有状态的,StatefulWidget,可以通过改变状态使 UI 发生变化,包含用户交互。

使用方法:稍微复杂,需要一个 State,例子如下

class BarWidget extends StatefulWidget {  @override  State createState() {    return _BarWidgetState();  }}class _BarWidgetState extends State {  @override  Widget build(BuildContext context) {    // ...  }}

二、文本Text

使用 TextStyle,可以对文本的样式进行修改

class TestWidget extends StatelessWidget {  @override  Widget build(BuildContext context) {    return Text(       "Put your text here",       textAlign: TextAlign.center,       maxLines: 1,       style: TextStyle(        color: Colors.blue,        fontSize: 16.0,        fontWeight: FontWeight.bold       ),    );  }}

三、图片Image

Flutter中的图片缩放是fit字段来控制的,缩放属性值在BoxFit枚举中。

有:fill、contain、cover,fitWidth、fitHeight、none、scaleDown

图片的来源:网络、文件、资源和内存

Image.asset(name);Image.file(file);Image.memory(bytes);Image.network(src);

例子: 

class TestWidget extends StatelessWidget {  @override  Widget build(BuildContext context) {       return Image.network(            'https://gw.alicdn.com/tfs/TB1CgtkJeuSBuNjy1XcXXcYjFXa-906-520.png',            fit: BoxFit.contain,            width: 150.0,            height: 100.0,    );  }}

四、按钮FlatButton 和 RaisedButton

两种按钮的区别在于样式不同。child 参数用于设置按钮的内容。它可以接受任意的 Widget,比方说,Text,Image;

class TestWidget extends StatelessWidget {  @override  Widget build(BuildContext context) {    var flatBtn = FlatButton(    onPressed: () => print('FlatButton pressed'),      child: Text('BUTTON'),    );    var raisedButton = RaisedButton(    onPressed: () => print('RaisedButton pressed'),      child: Text('BUTTON'),    );    return raisedButton; }}

五、文本输入框TextField

为了获取用户输入的文本,我们需要给他设置一个 controller。通过这个 controller,就可以拿到文本框里的内容

class MessageForm extends StatefulWidget {  @override  State createState() {    return _MessageFormState();  }}class _MessageFormState extends State {  var editController = TextEditingController();  @override  Widget build(BuildContext context) {    // Row、Expand 都是用于布局的控件,这里可以先忽略它们    return Row(      children: [      // 占满一行里除 RaisedButton 外的所有空间      Expanded(          child: TextField(            controller: editController,          ),        ),      RaisedButton(          child: Text("click"),          onPressed: () => print('text inputted: ${editController.text}'),        )     ],    );  }@override  void dispose() {    super.dispose();    // 手动调用 controller 的 dispose 方法以释放资源    editController.dispose();  }}

六、显示弹框

 RaisedButton(          child: Text("click"),          onPressed: () {            showDialog(                // 第一个 context 是参数名,第二个 context 是 State 的成员变量                context: context,                builder: (_) {                return AlertDialog(                    // dialog 的内容                    content: Text(editController.text),                    // actions 设置 dialog 的按钮                    actions: [                      FlatButton(                        child: Text('OK'),                        // 用户点击按钮后,关闭弹框                        onPressed: () => Navigator.pop(context),                      )                    ],                  );               }            );          })

七、Container、Padding 、Center

Flutter的设计思想就是完全的widget化!连最基本的padding,Center都是widget。Container类似于android中的ViewGroup。

class TestWidget extends StatelessWidget {  @override  Widget build(BuildContext context) {   return Padding(      padding: EdgeInsets.all(8.0),      child: Text('text'),   );  }}
class TestWidget extends StatelessWidget {  @override  Widget build(BuildContext context) {   return Container(      padding: EdgeInsets.all(8.0),      margin: EdgeInsets.all(4.0),      width: 200.0,      height: 200.0,      decoration: BoxDecoration(        // 背景色        color: Colors.grey,        // 圆角        borderRadius: BorderRadius.circular(5.0), ),      // 把文本放在 Container 的中间      child: Center(          child: Text('text'),      ),    );  }}

八、水平布局Row、竖直布局Column

class TestWidget extends StatelessWidget {  @override  Widget build(BuildContext context) {    return Row(      // 只有一个子元素的 widget,一般使用 child 参数来设置;Row 可以包含多个子控件,      // 对应的则是 children      children: [        Text('text1'),        Text('text2'),        Text('text3'),      ],    );  }}

Column 的使用和Row是一样的

九、Expand 控件

见上面TextField 的例子。通过使用 Expand,TextField 才能够占满一行里除按钮外的所有空间。当一行/列里有多个 Expand 时,我们还可以通过设置它的 flex 参数,在多个 Expand 之间按比例划分可用空间。

class TestWidget extends StatelessWidget {  @override  Widget build(BuildContext context) {    return Row(    children: [        Expanded(          // 占一行的 2/3          flex: 2,          child: RaisedButton(child: Text('btn1'),),        ),        Expanded(          // 占一行的 1/3          flex: 1,          child: RaisedButton(child: Text('btn2'),),        ),      ],    );  }}

 Expanded 只能包含一个子元素,使用的参数名是 child

十、Stack 布局

有些时候,我们可能会希望一个控件叠在另一个控件的上面。于是,Stack 应运而生:

class TestWidget extends StatelessWidget {  @override  Widget build(BuildContext context) {    return Stack(        children: [        Text('foobar'),        Text('barfoo'),      ],    );  }}

默认情况下,子控件都按 Stack 的左上角对齐,于是,上面的两个文本完全一上一下堆叠在一起。我们还可以通过设置 alignment 参数来改变这个对齐的位置:

class TestWidget extends StatelessWidget {  @override  Widget build(BuildContext context) {    return Stack(      // Aligment 的取值范围为 [-1, 1],Stack 中心为 (0, 0),      // 这里设置为 (-0.5, -0.5) 后,可以让文本对齐到 Container 的 1/4 处      alignment: const Alignment(-0.5, -0.5),      children: [        Container(          width: 200.0,          height: 200.0,          color: Colors.blue,        ),        Text('foobar'),     ],    );  }}

实际使用中Stack中的子Widgets分为两种:

  • positioned
    • 是包裹在组件Positioned中的组件
    • 可以通过Positioned属性灵活定位
  • non-positioned
    • 没有包裹在Positioned组件中
    • 需要通过父Widget Stack 的属性来控制布局
new Container(            color: Colors.yellow,            height: 150.0,            width: 500.0,            child: new Stack(children: [              new Container(                color: Colors.blueAccent,                height: 50.0,                width: 100.0,                alignment: Alignment.center,                child: Text('unPositioned'),              ),              new Positioned(                  left: 40.0,                  top: 80.0,                  child: new Container(                    color: Colors.pink,                    height: 50.0,                    width: 95.0,                    alignment: Alignment.center,                    child: Text('Positioned'),                  )),            ]))

通过组合 Row/Column 和 Stack,已经能够完成绝大部分的布局了,所以 Flutter 里没有相对布局之类的东西。

十一、Visibility

在Flutter中,组件中没有visibility属性。visibility的控制还是比较麻烦的。目前有几种方法

1、删除法:

  • 单个组件‘隐藏’自己。在build方法中返回一个空的Container.
  • 多个child,在父容器的children字段的list中,删除掉对应的cell

2、Offstage的offstage属性设置为true

@overrideWidget build(BuildContext context) {  return new Offstage(          offstage: !isVisible,          child:child);}

3、透明度

 设置widget的透明度,使之不可见。但依然会绘制,浪费计算资源,且占据的位置是存在的

十二、state 生命周期

  • initState插入渲染树时调用,只调用一次
  • didChangeDependenciesstate依赖的对象发生变化时调用
  • didUpdateWidget组件状态改变时候调用,可能会调用多次
  • build构建Widget时调用
  • deactivate当移除渲染树的时候调用
  • dispose组件即将销毁时调用

 

本篇文章大部分内容摘自:https://juejin.im/post/5bd54b7be51d456c430e35f6, https://juejin.im/post/5b8ce76f51882542c0626887  感谢!

 

 

更多相关文章

  1. 底部导航栏中间凸出效果
  2. Android控件——Checkbox复选框、RadioButton单选、ToggleButton
  3. android选择一张本机图片
  4. Android(安卓)短信模块分析(二) MMS中四大组件核心功能详解
  5. 3.addView调用之后导致子布局的android:layout_width="match_par
  6. Android(安卓)ConstraintLayout布局详解
  7. android UI小结(四)
  8. Android学习笔记01_走马观花
  9. Listview中Button抢占焦点的解决方法

随机推荐

  1. Android(安卓)- 资源(resource)
  2. Android(安卓)studio aar文件的打包过程
  3. Android原生音量控制实例详解
  4. ContentProvider 详解
  5. [Android]View响应屏幕触摸事件
  6. Android各框架的总结及选型
  7. ym——Android之常用Tools【介绍及使用】
  8. [置顶] android 深入理解AnsyncTask
  9. Android(安卓)Service两种启动启动方式
  10. Android(安卓)布局转化为View对象的两种