Flutter学习(一)

之前把Dart的语法都过了一遍,并且写了一篇博客来记录了一下,接下来就是Flutter部分了

一、基本特性、代码结构理解

Flutter Widget采用现代响应式框架构建,就是跟React有些类似,中心思想是用widget构建UI,当UI状态发生变化时,刷新页面来达到显示新页面的目的,如果写过ReactNative会好理解很多

我们首先来看一下HelloWorld程序:

import 'package:flutter/material.dart';

void main() {
  runApp(
    new Center(
      child: new Text(
        'Hello, world!',
        textDirection: TextDirection.ltr,
      ),
    ),
  );
}

乍看之下这个结构有点奇怪,看起来很繁琐,但实际上,我们拆分、重组一下就可以变成很清晰的结构

void main() {
  //定义一个文字组件,并设置文字内容
  var text = Text("Hellow,World");
  //设置文字组件内容的朝向
  text.textDirection = TextDirection.ltr;
  //定义一个居中组件
  var center = Center();
  //将居中组件的内容设置为文字
  center.child = text;
  //在启动组件中将center组件穿进去显示
  runApp(
    center
  );
}

只是这个代码在实际执行时是不行的,因为Text的textDirection属性和Center的child属性都是final的,无法动态设置,那么我们可以再重组一下

void main() {
  //创建好文字组件并在构造器中设置默认的内容以及文字方向
  var text = Text("Hello,World",textDirection: TextDirection.ltr);
  //创建居中组件并在构造器中设置child的内容
  var center = Center(child: text);
  //将要现实的组件穿进去
  runApp(
    center
  );
}

这样重组之后是不是清晰多了?那么可读性方面的基本问题算是解决了

二、基础组件Widget,布局模型

Flutter有一套丰富、强大的基础widget,其中以下是很常用的:

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

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

  • Stack: 取代线性布局 (译者语:和Android中的LinearLayout相似),Stack允许子 widget 堆叠, 你可以使用 Positioned 来定位他们相对于Stack的上下左右四条边的位置。Stacks是基于Web开发中的绝度定位(absolute positioning )布局模型设计的。

  • Container: Container 可让您创建矩形视觉元素。container 可以装饰为一个BoxDecoration, 如 background、一个边框、或者一个阴影。 Container 也可以具有边距(margins)、填充(padding)和应用于其大小的约束(constraints)。另外, Container可以使用矩阵在三维空间中对其进行变换。

可以用这些基本组件来写一个demo,我就直接把中文网的demo贴出来了

import 'package:flutter/material.dart';

class MyAppBar extends StatelessWidget {
  MyAppBar({this.title});

  // Widget子类中的字段往往都会定义为"final"

  final Widget title;

  @override
  Widget build(BuildContext context) {
    return new Container(
      height: 56.0, // 单位是逻辑上的像素(并非真实的像素,类似于浏览器中的像素)
      padding: const EdgeInsets.symmetric(horizontal: 8.0),
      decoration: new BoxDecoration(color: Colors.blue[500]),
      // Row 是水平方向的线性布局(linear layout)
      child: new Row(
        //列表项的类型是 <Widget>
        children: <Widget>[
          new IconButton(
            icon: new Icon(Icons.menu),
            tooltip: 'Navigation menu',
            onPressed: null, // null 会禁用 button
          ),
          // Expanded expands its child to fill the available space.
          new Expanded(
            child: title,
          ),
          new IconButton(
            icon: new Icon(Icons.search),
            tooltip: 'Search',
            onPressed: null,
          ),
        ],
      ),
    );
  }
}

class MyScaffold extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    // Material 是UI呈现的“一张纸”
    return new Material(
      // Column is 垂直方向的线性布局.
      child: new Column(
        children: <Widget>[
          new MyAppBar(
            title: new Text(
              'Example title',
              style: Theme.of(context).primaryTextTheme.title,
            ),
          ),
          new Expanded(
            child: new Center(
              child: new Text('Hello, world!'),
            ),
          ),
        ],
      ),
    );
  }
}

void main() {
  runApp(new MaterialApp(
    title: 'My app', // used by the OS task switcher
    home: new MyScaffold(),
  ));
}

我们来整理一下:

import 'package:flutter/material.dart';

class MyAppBar extends StatelessWidget {
  MyAppBar({this.title});


  //标题栏容器的高度
  static const double appBarHeight = 56;
  //标题栏容器的形状以及颜色
  static var box = BoxDecoration(color: Colors.blue[500]);
  //容器的内边距
  static const padding = EdgeInsets.symmetric(horizontal: 8.0);

  //标题中的文字组件, Widget子类中的字段往往都会定义为"final"
  final Widget title;

  @override
  Widget build(BuildContext context) {
    //第一个按钮,菜单
    var menuIcon = IconButton(icon: Icon(Icons.menu),
                              tooltip: "Navigation menu",
                              onPressed: null,);// null 会禁用 button
    //第二个是组件,填充标题
    var expand = Expanded(child: title,);
    //第三个也是图标
    var searchIcon = IconButton(icon: Icon(Icons.search),
                                tooltip: "Search",
                                onPressed: null,);
    //然后排列好三个按钮的顺序
    var bars = <Widget>[menuIcon,expand,searchIcon];
    //设置排列方向
    var rowViews = Row(children:bars,);

    //最后设置容器
    var container = Container(height: appBarHeight,
                              padding: padding,
                              decoration: box,
                              child: rowViews,);
    return container;
  }
}

class MyScaffold extends StatelessWidget {


  @override
  Widget build(BuildContext context) {
    //标题部分
    //标题文字
//    var style1 = TextStyle(color: Colors.black,fontSize: 30);
    var appBarTitle = Text('Example title',style: Theme.of(context).primaryTextTheme.title,);
    var appBar = MyAppBar(title: appBarTitle,);

    //布局部分
    var contentText = Text("Hello, world!");
    var centerText = Center(child: contentText,);
    var expand = Expanded(child: centerText,);

    //排好顺序放进数组
    var views = <Widget>[appBar,expand];

    //标题和布局部分竖直排列
    var column = Column(children: views,);

    //最外层布局
    var material = Material(child: column,);

    // Material 是UI呈现的“一张纸”
    return material;
  }
}

void main() {
  runApp(new MaterialApp(
    title: 'My app', // used by the OS task switcher
    home: new MyScaffold(),
  ));
}

这样是不是清晰了很多,这样的话UI布局这一块其实就很明了了,其他的都是组件的熟悉方面的了

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值