Flutter

Flutter - Weight 入门

2019-08-17  本文已影响0人  前行的乌龟
来张野性的_回归原始

从 C 开始,我们进步到 java,再到 kotlin,现在又迎来了 Dart、Flutter,还要去学学 python。时代在进步,我们也得跟着进步,新的思想、新的工具、新的语言,速度越来越快,东西越来越多,不停学习真是 coder 这行不变的准则啊

阅读完本文推荐大家唉再去看看这篇,毕竟孤木难支,取长补短嘛~,下面这篇也是极好的:


Flutter 没有 Activity 概念

稍稍了解 Flutter 的同学都应该知道 Flutter 构建的 android 项目整个 app 只剩下 MainActivity 这一个 Activity 了,其内部使用一个 FlutterView 来承载所有的Flutter 页面,看下图:

所以 Flutter 天然的就没有页面这个概念了,Flutter 遵循 RN、前端的页面搭建思路,在 UI 这块和 android 有天壤之别,android 那种独特的写 xml 布局的方式从此是路人,历史又回归了主流

先尝个味,不要以为 Flutter 跑在 android 上就还是 android 那套,Flutter 绝逼是另一个全新的东西了。不是之前想的简简单单学学就能搞定的了,是要狠下心来耗费一番功夫的。这里我们先从 Flutter 页面搭建开始一步步深入理解 Flutter 的魅力,或者说熟悉下主流前端开发


吐槽 Flutter 的 Weight

就像 JAVA 那样一切皆对象有个口号,Flutter 也有自己的口号:一切皆 Weight,怎么理解呢,直接去看 Flutter 社区的朋友中绝对有这种表情的:

我在哪_我是谁_我来干什么

官方中文文档绝逼退治效果一流,至少我这样的就有些懵逼的感觉,其实这是大家思路停留在 android 的问题,抱着 android 的期待来学习 Flutter 绝对懵逼。要是我们当做新的语言来学习的话,静下新来仔细找找规律、思路的话反到是学起来轻松很多

android 里
<android.support.constraint.ConstraintLayout
    <Button
        android:id="@+id/btn_toast"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginTop="20dp"
        android:text="toast 组件"
        app:layout_constraintLeft_toLeftOf="parent"
        app:layout_constraintRight_toRightOf="parent"
        app:layout_constraintTop_toTopOf="parent"/>
</android.support.constraint.ConstraintLayout>

android 的 UI 层,命名规范:布局容器都用layout结尾、内容部件都用view结尾、属性设置位置统一

Flutter 里

一切都变了:

当我看完 Flutter 的 Weight 之后,心里是哇凉哇凉的啊...


android 的经验一点用都没了,宝宝心里苦啊...


Flutter weight 特性

在学习 Flutter weight 之前一定要了解 Flutter weight 特性...

1. Flutter 是声明式编程

这点是和 android 有决定性差别的,Android 我们是写 xml 文件,activity 里面拿到 view 的引用,Flutter 不是的,Flutter 直接 A 代码画 UI,没了那烦人的 xml 文件。优点是:书写简便,代码少,随意性强,像怎么写怎么写。缺点是:没有预览,时间长了再看很麻烦,需要借助第三方工具查看UI 结构

  @override
  Widget build(BuildContext context) {
  
    return Scaffold(
      appBar: AppBar(
        title: Text(widget.title),
      ),
      body: Center(
        child: Column(
          mainAxisAlignment: MainAxisAlignment.center,
          children: <Widget>[
            Text(
              wordPair.asPascalCase,
            ),
            RandomWord(),
            Text(
              '$_counter',
              style: Theme.of(context).textTheme.display1,
            ),
            RaisedButton(
              onPressed: _other,
              child: Text("减一"),
            )
          ],
        ),
      ),
      floatingActionButton: FloatingActionButton(
        onPressed: _incrementCounter,
        tooltip: 'Increment',
        child: Icon(Icons.add),
      ), 
    );
  }
2. Flutter weight 天然实现了数据绑定

其实这个特性也是声明式编程的一部分,拿出来说效果好一些。在 android 里面我们只能拿到 view 引用 setXXXValue 才能修改该 view 的值,想要实现响应式 UI(UI 和数据绑定)还需要接触其他组件,还要学一些额外的代码

Flutter 就没这么麻烦,Weight UI 直接就是和数据是绑定的,只要在 setValue({...}) 里面修改值就能更新 UI,看下面的例子(删除了无关代码):

class _MyHomePageState extends State<MyHomePage> {

  int _counter = 0;

  void _incrementCounter() {
    setState(() {
    _counter++;
    });
  }

  void _other() {
    setState(() {
    _counter--;
    });
  }

  @override
  Widget build(BuildContext context) {
   
      body: Center(
        child: Column(
          mainAxisAlignment: MainAxisAlignment.center,
          children: <Widget>[
            Text(
              '$_counter',
              style: Theme.of(context).textTheme.display1,
            ),
            RaisedButton(
              onPressed: _other,
              child: Text("减一"),
            )
          ],
        ),
      ),
      floatingActionButton: FloatingActionButton(
        onPressed: _incrementCounter,
        tooltip: 'Increment',
        child: Icon(Icons.add),
      ), 
    );
  }
}

一个 text 用来显示文本(count 的值),RaisedButton 按钮点一下 -1,floatingActionButton 点一下 +1,onPressed 属性配置点击方法,只要 text 组件里面引用了 count 的值就行,然后我们只要使用系统 API setState 修改值就 OK 啦

setState(() {
    _counter--;
});

Flutter 放弃 xml 结合 UI 响应式编程的思路比传统 android 方便多了,android 计就算是上了 DataBinding 在 xml 里写 UI 赋值逻辑,那也远远没 Flutter 直观啊,Flutter 又不是打开其他文件,直接就看了,多省事...程序员都是懒人,只要能偷懒,就是进步,就是优秀的

3. Flutter 对属性的拆分

这里 Flutter 是学习前端的,android 里我们可以在 xml 下对 view 配置任何属性,按照分类可以分成:宽高大小类的位置定位类的各种边距,边框,背景view 自身的属性

Flutter 把除了view 自身的属性之外的其他属性逗提升为 layout 容器级别,比如说你在 Flutter 里给一个 text 添加 padding,那么就得在这个 text 外面套上这么一层 padding 的容器

            Padding(
              padding: EdgeInsets.all(10),
              child: (Text(
                '$_counter',
                style: Theme.of(context).textTheme.display1,
              )),
            ),

就是这个样子,属性提升成了容器了,Flutter 的容器绝对了里面 view 的外观(外在属性),具体的绘制则交给了该容器内部的 weight,这看着感觉好像模板设计模式啊,外面是模板,里面是可变部分

OK,有这些打底,下面 Flutter 的 weight 就好理解了


Flutter Weight 层级划分

在 Flutter 里一切揭 Weight,Weight 像 view 一样在 Flutter 也是所有 view 的父类

Weight 按照功能划分,可以这么看:

结合 android 来看的话:

布局 Weight

Flutter 的 布局 Weight 比较典型的有:row、Column。row 是一行,Column 是一列

class oneRow extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    // TODO: implement build
    return Row(
      mainAxisSize: MainAxisSize.max,
      mainAxisAlignment: MainAxisAlignment.spaceEvenly,
      children: <Widget>[
        Text("AAAAAA"),
        Text("BBBBBB"),
        Text("CCCCCC"),
      ],
    );
  }
}
class oneColume extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    // TODO: implement build
    return Column(
      mainAxisSize: MainAxisSize.min,
      mainAxisAlignment: MainAxisAlignment.spaceEvenly,
      children: <Widget>[
        Text("AAAAAA"),
        Text("BBBBBB"),
        Text("CCCCCC"),
      ],
    );
  }
}
修饰 Weight

修饰 Weight最经典的就是 Container 了,这里我们设置一个背景色

class oneContainer extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    // TODO: implement build
    return Container(
      color: Colors.lightBlueAccent,
      child: oneRow(),
    );
  }
}

具体的 weight 这里就不写了,那是下一节的学习内容,通过这几个小例子让大家熟悉下 Flutter 的 Weight 结构,后面就好学多了,就算是去官方文档也会顺利很多


Flutter 如何组织页面

Flutter 虽然没有 Activity 这样的页面概念,但是 UI 出图可都是一个页面一个页面的,既然设计环节依然存在页面,那么 Flutter 也必须有页面或者相近的概念才能让我们的 UI设计图落地啊

在 Flutter 中和页面概念最接近的就是 Flutter 中唯二名字里带 Weight 的组件了:StatelessWidgetStatefulWidget

Flutter 所有的 UI、页面都是在一个 FlutterView 上显示的,大家把StatelessWidgetStatefulWidget理解为 ViewTree + viewGroup,或者直接理解成 layout 就 OK了

好比 android xml 里一层套一层的 layout,大 layout 里套小的 layout,上面 Container 的例子里,oneContainer 里面不就是套了一个 row 嘛,上面例子里我们把 layout 写成一个 class,这就是 Flutter 的自定义 viewGroup 了,大家看着简单不,省代码不

StatelessWidgetStatefulWidget的区别就是能不能在自己 layout 内部修改自己的 UI,能该的就是 StatefulWidget,不能该的必须依赖父层级修改 UI的就是 StatelessWidget

在代码上的区别就是之前提到过的 setValue 修改 UI了,StatefulWidget 里可以跑 setValue 方法,setValue 方法实际就是多次调用了 StatefulWidget 的 build 方法,StatelessWidget 反之

然后 Flutter 有专门切换 StatelessWidgetStatefulWidget显示不同页面的 API,后面讲


最后

本文其实并不是直接去学习如何使用 Flutter Weight,而是尝试梳理下 Flutter 中 Weight 的分类,相互关系,提供给看了 Flutter 有些懵或者还没有开始 Flutter 学习的朋友一些便利,希望能带给大家帮助

上一篇下一篇

猜你喜欢

热点阅读