Flutter Widget之初体验 for iOSer

Widget(小部件)定义:

在 iOS 中,构建 UI 的过程中将大量使用 view 对象。这些对象都是 UIView 的实例。它们可以用作容器来承载其他的 UIView,最> 终构成你的界面布局。

在 Flutter 中,你可以粗略地认为 Widget 相当于 UIView 。Widget 和 iOS 中的控件并不完全等价,但当你试图去理解 Flutter 是> 如何工作的时候,你可以认为它们是“声明和构建 UI 的方法”。
然而,Widget 和 UIView 还是有些区别的。首先,widgets 拥有不同的生存时间:它们一直存在且保持不变,直到当它们需要被>改变。当 widgets 和它们的状态被改变时,Flutter 会构建一颗新的 widgets 树。作为对比,iOS 中的 views 在改变时并不会被重>新创建。但是与其说 views 是可变的实例,不如说它们被绘制了一次,并且直到使用 setNeedsDisplay() 之后才会被重新绘制。
为了更系统的了解Flutter的结构我们从 0 开始创建一个App

首先打开我们之前创建的项目打开main.dart ,为了熟悉一下代码结构,我们删除 main.dart 中所有代码。我们来自己写一个。

在iOS中我们编写页面首先需要import UIKit, Flutter 也一样有个类似的操作我们需要导入 material.dart

import 'package:flutter/material.dart';

image

入口函数:

iOS 中有个入口函数main,Flutter也一样有个main函数作为入口函数:

/// 入口函数 相当于 main 函数
void main() {
  //  runApp 相当于 UIApplicationMain(argc, argv, nil, appDelegateClassName)
 //  runApp 里面的参数 相当于 设置 Appdelegate 但又不完全相像 这个参数相当于设置根
  //  widget 更像直接设置 rootViewController
  runApp(
/// Center 就是系统提供的一个 Widget (这里写Center 就相当于UIApplicationMain设置 Appdelegate 的操作 )
      Center(
// 这里的child: 有的说可以理解为addSubview ,但因为他只能设置一个,所以我理解为 手动设置 Center Widget 的layer,
// 注意 textDirection: TextDirection.ltr,为必填
    child: Text("Home ",textDirection: TextDirection.ltr,), 

  ));

}

效果

widget 的两种分类

/// statelessWidget (相当于不可变组件)、statefulwidget (相当于可变组件)
/// ps:有状态只是有一个状态类保存了他的状态 ( 因为 UI 本身就是没有状态的)

所以我们可以这样理解,一个widget就是一个类,就是一个继承自 statelessWidget或statefulwidget的类,类似于我们iOS中继承UIView自定义一个View。

在iOS中我们自定义一个 UIView 我们需要 把子view 一个个 addSubview 。Flutter 这没有这用语法,它是通过利用:Build 方法来添加的

class ssssss  extends StatelessWidget {
// 其实这就是 图层数 不需要我们手动 addSubview
/// build 方法会将 build 方法所包含的视图 渲染
  @override
  Widget build(BuildContext context) {
    return Container(
      child:Text('My Text', TextDirection.rtl),
    );
  }
}

这里把 main 函数中 runapp 里面 Center.child 后面的 Text 小部件 修改为 ssssss() 这个我们刚刚创建的小部件。


运行效果

到此我们自定义了一个小部件。
下面我们看看一些预置的小部件。

Text

Text
该 widget 可让创建一个带格式的文本。

    Text(
            'titlewwwView',
            textDirection: TextDirection.ltr,
          )

Row Column

RowColumn
childrens 相当于 addSubviews
return Column(
children: [
Text(datas[index].name),
Image.network(datas[index].imgUrl)
],
);


这些具有弹性空间的布局类Widget可让您在水平(Row)和垂直(Column)方向上创建灵活的布局。其设计是基于web开发中的Flexbox布局模型。

Stack
Stack 是叠加布局
Stack

*   [`Stack`](https://docs.flutter.io/flutter/widgets/Stack-class.html): 取代线性布局 (译者语:和Android中的LinearLayout相似),[`Stack`](https://docs.flutter.io/flutter/widgets/Stack-class.html)允许子 widget 堆叠, 你可以使用 [`Positioned`](https://docs.flutter.io/flutter/widgets/Positioned-class.html) 来定位他们相对于`Stack`的上下左右四条边的位置。Stacks是基于Web开发中的绝度定位(absolute positioning )布局模型设计的。
iOS 也有 UIStackView 这很容易对应起来

Container
Container
这个我觉得 更贴近于 UIView , 这个是一个纯粹的 视图容器
他就跟 UIView 十分相似 需要 frame 也就是 坐标 宽高
不设置高度就是 autoLayout
另有区别 就是 他的子小控件 用 child 来添加

  • ContainerContainer 可让您创建矩形视觉元素。container 可以装饰为一个BoxDecoration, 如 background、一个边框、或者一个阴影。 Container 也可以具有边距(margins)、填充(padding)和应用于其大小的约束(constraints)。另外, Container可以使用矩阵在三维空间中对其进行变换。
class BaseWidgetDemo extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Row(
      children: [
        Container(
          /// 内间距
          padding: EdgeInsets.only(left: 10, top: 20, bottom: 20, right: 10),
          /// 外间距
          margin: EdgeInsets.only(top: 10, left: 20, bottom: 10, right: 20),
          child: Text("AAAAA"),
        ),
        Container(
          child: Text("ddddd"),
        ),
      ],
    );
  }
}

MaterialApp

MaterialApp 是一个 根widget ,对于 iOS 我们需要设根导航控制器MaterialApp是Flutter提供给我们的一个根小部件。它有以下属性

title : 在任务管理窗口中所显示的应用名字
theme : 应用各种 UI 所使用的主题颜色
color : 应用的主要颜色值(primary color),也就是安卓任务管理窗口中所显示的应用颜色
home : 应用默认所显示的界面 Widget
routes : 应用的顶级导航表格,这个是多页面应用用来控制页面跳转的,类似于网页的网址
initialRoute :第一个显示的路由名字,默认值为 Window.defaultRouteName
onGenerateRoute : 生成路由的回调函数,当导航的命名路由的时候,会使用这个来生成界面
onLocaleChanged : 当系统修改语言的时候,会触发这个回调
navigatorObservers : 应用 Navigator 的监听器
debugShowMaterialGrid : 是否显示 Material design 基础布局网格,用来调试 UI 的工具
showPerformanceOverlay : 显示性能标签
checkerboardRasterCacheImages 、showSemanticsDebugger、debugShowCheckedModeBanner 各种调试开关

Scaffold

iOS 开发中我们肯定会写 UINavigationController, Scaffold 就相当于 UINavigationController,
他有一个title属性,这个属性就相当于navigation的titleView。所以它的参数是一个 Widget类型。
另外他有一个 Body 属性,这个属性就是相当于 给 navigationcontroller设置rootViewController,只不过这里是试着Widget

Scaffold(
        appBar: AppBar(
          title: Text(
            'titlewwwView',
            textDirection: TextDirection.ltr,
          ),
        ),
        body: ssssss(),
      ),

ListView

这个很容易理解 就相当于 UITableView

final List<Car> datas = [
  Car('名字', 'https://t7.baidu.com/it/u=4288073668,192091314&fm=193&f=GIF'),
  Car('名字', 'https://t7.baidu.com/it/u=4288073668,192091314&fm=193&f=GIF'),
  Car('名字', 'https://t7.baidu.com/it/u=4288073668,192091314&fm=193&f=GIF'),
  Car('名字', 'https://t7.baidu.com/it/u=4288073668,192091314&fm=193&f=GIF'),
  Car('名字', 'https://t7.baidu.com/it/u=4288073668,192091314&fm=193&f=GIF'),
  Car('名字', 'https://t7.baidu.com/it/u=4288073668,192091314&fm=193&f=GIF'),
];

class ListViewDemo extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return ListView.builder(
      itemCount: datas.length, // 相当于 numberOfRowsInSection
      itemBuilder: (context, index) { // 相当于 CellForRowAtIndexPath
        return Column(
          children: [
            Text(datas[index].name),
            Image.network(datas[index].imgUrl)
          ],
        );
      },
    );
  }
}

class Car {
  const Car(
    this.name,
    this.imgUrl,
  );

  final String name;
  final String imgUrl;
}

以上代码效果图:


ListView

RichText 富文本

这里的富文本比 iOS 差不多,其实都是拼接,但不如iOS那个灵活舒服我感觉。Flutter 的 RichText 其实就是套娃的感觉

class RichTextDemo extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return RichText(
      text: TextSpan(
        text: '这里是富文本这里是富文本呼呼哈哈',
        style: TextStyle(fontSize: 18, color: Colors.red),
        children: [
/// 这里一直铺下去即可
          TextSpan(text: 'hhhh', style: TextStyle(color: Colors.blue)),
          TextSpan(text: 'hhhh', style: TextStyle(color: Colors.red)),
          TextSpan(text: 'hhhh', style: TextStyle(color: Colors.yellow)),
        ],
      ),
    );
  }
}

下一篇:Flutter 布局、state、Dart语法简单入门

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 223,207评论 6 521
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 95,455评论 3 400
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 170,031评论 0 366
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 60,334评论 1 300
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 69,322评论 6 398
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 52,895评论 1 314
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 41,300评论 3 424
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 40,264评论 0 277
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 46,784评论 1 321
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 38,870评论 3 343
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 40,989评论 1 354
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 36,649评论 5 351
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 42,331评论 3 336
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 32,814评论 0 25
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 33,940评论 1 275
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 49,452评论 3 379
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 45,995评论 2 361

推荐阅读更多精彩内容