hust
  • 简介
  • 效率
    • on-my-zsh git alias
    • Markdown写ppt
    • 开发者的Mac工具集合
  • 语言
    • Java
    • Dart
      • 基本语法
      • 基本库
      • 异步编程之Future
      • 异步编程之Stream
    • Kotlin
      • Kotlin中的可空类型
  • Android
    • Native
      • 自定义Material点击效果的View
      • 开源视频播放器JiaoZiVideoPlayer学习
      • ConstraintLayout使用说明
      • 布局文件中的tools命名空间
      • TabLayout使用指南
      • AppBarLayout学习
      • EditText在RecyclerView中的解决方案
      • Jetpack
        • 动画和转换
          • 具有动画效果的图片资源
          • 使用动画隐藏或显示View
          • 使用动画移动View
          • 使用动画缩放图片
          • ViewGroup内容改变时的动画效果—LayoutTransition
          • 在布局切换之间实现Transition动画
          • 在Activity切换之间实现Transition动画
      • Flutter
        • APP的基础——组件
      • 开源库
        • EventBus
          • EventBus简介及初步使用
          • EventBus线程分发
          • EventBus配置、粘性事件、优先级和取消事件分发
          • EventBus源码分析之发布订阅模型
          • EventBus源码分析之线程分发
Powered by GitBook
On this page
  • Basics
  • Row
  • Column
  • Text
  • Image
  • Icon
  • Container
  • AppBar
  • Scaffold
  • Text
  • Text
  • RichText
  • DefaultTextStyle
  • Input
  • Form
  • FormField
  • Material组件
  • App结构和导航
  • Buttons
  • Input和Selections
  • 对话框
  • 信息展示
  • Layout
  1. Android
  2. Native
  3. Flutter

APP的基础——组件

一个APP除了逻辑外,最主要的就是UI,Flutter提供了很多已有的View(在Flutter中叫Widgets)。本文将主要介绍这些Widgets,这是创建APP的基础。

Widgets分为几类,下面分别介绍。

Basics

基础组件是创建APP前必须要了解的,非常重要。

Row

横向布局一系列子Widgets。(和LinearLayout的水平方向大致)。Row组件不支持滚动,因此如果子Widgets超过了Row的空间,那么将会报错。如果想使用一个可以滚动的组件,可以使用ListView。

如果需要子Widgets进行填充,那么可以使用Expand组件进行包装。

void main() {
  runApp(new MaterialApp(
    home: new RowDemo(),
  ));
}

class RowDemo extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return new Row(
      children: <Widget>[
       const Text(
          'Flutter\'s hot reload helps you quickly and easily experiment, build UIs, add features, and fix bug faster. Experience sub-second reload times, without losing state, on emulators, simulators, and hardware for iOS and Android.',
          textAlign: TextAlign.start,
        ),
        const Text(
          'Hello World',
          textAlign: TextAlign.start,
        ),
      ],
    );
  }
}

在Row中摆放两个Text,其中第一个Text内容很多,超过了屏幕显示范围,导致第二个Text没有显示,下面是结果:

可以看到Flutter将会提示右边超过了多少像素,那么如果需要将两个Text同时显示,可以使用Expand对第一个Text进行包装,如下:

class RowDemo extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return new Row(
      children: <Widget>[
        const Expanded(
          child: const Text(
            'Flutter\'s hot reload helps you quickly and easily experiment, build UIs, add features, and fix bug faster. Experience sub-second reload times, without losing state, on emulators, simulators, and hardware for iOS and Android.',
            textAlign: TextAlign.start,
          ),
        ),

        const Text(
          'Hello World',
          textAlign: TextAlign.start,
        ),
      ],
    );
  }
}

这个时候的显示结果如下:

可以看到,第一个Text在垂直方向进行了扩展,给第二个Text腾了个位子。

如果需要像LinearLayout一样设置Weight,可以将二个Text也用Expand进行包装,结果如下图:

布局算法

Row的布局分为六步:

  1. 使用不受限制的水平约束和受限制的垂直约束布局非Expanded组件

  2. 在剩下的水平空间中按照flex参数将设下的组件进行分割

  3. 使用不受限制的水平和垂直约束,布局剩下的组件

  4. 在满足传入高度约束的前提下,Row的height是最大子组件的height

  5. Row的高度决定于mainAxisSize属性。

  6. 按照mainAxisAlignment和crossAxisAlignment属性进行摆放组件位置。

Column

Column与Row相对,垂直方向的LinearLayout,因此不过多介绍。

Text

Text组件和TextView相似,使用单一style显示文本。

Image

Image组件和ImageView相似,显示一张图片。Image提供了不少构造方法,用于从不同源加载图片。

  1. new Image,从ImageProvider中获取图片

  2. new Image.asset,从AssetBundle中获取图片

  3. new Image.network,从网络获取图片

  4. new Image.file,从File获取图片

  5. new Image.memory,从Unit8List中获取图片

Icon

Icon代表着不能交互的图标,如果需要交互,那么需要使用IconButton。Icons工具类提供了很多常用的Icon,不得不说,Flutter这一点太nice了。

Container

Container是一个可以放置一个子Widget的容器,可以设置padding、margin这些参数。

在绘制过程中,Container首先应用传入的transform,然后用decoration绘制padded区域,然后绘制子组件,最后绘制foregroundDecoration。

AppBar

AppBar中的参数说明如上图。

Scaffold

这个组件实现了material design基本的布局。提供了显示drawers、snack bars和bottom sheets。

参数有如下:

this.appBar,
    this.body,
    this.floatingActionButton,
    this.floatingActionButtonLocation,
    this.floatingActionButtonAnimator,
    this.persistentFooterButtons,
    this.drawer,
    this.endDrawer,
    this.bottomNavigationBar,
    this.backgroundColor,
    this.resizeToAvoidBottomPadding: true,
    this.primary: true,

Text

显示和格式化文本。

Text

单一style的文本。

RichText

一段富文本。

使用多种style显示文本。

new RichText(
  text: new TextSpan(
    text: 'Hello ',
    style: DefaultTextStyle.of(context).style,
    children: <TextSpan>[
      new TextSpan(text: 'bold', style: new TextStyle(fontWeight: FontWeight.bold)),
      new TextSpan(text: ' world!'),
    ],
  ),
)

DefaultTextStyle

Input

除了Material和Cupertino中的输入组件。

Form

将多个组件组合蕲艾的容器,比如说TextField组件。

每一个单独的form字段必须使用FormField组件进行包装,调用FormState来保存、充值或更新状态。

可以使用Form.of获取一个FormState。

FormField

一个单独的form字段。

这个组件管理当前form的状态。当在Form中使用时,你可以使用FormState上的方法来查询和操作form数据。

Material组件

App结构和导航

  • Scaffod

  • Appbar

  • BottomNavigatonBar

  • TabBar

  • TabBarView

  • MaterialApp

  • WidgetsApp

  • Drawer

Buttons

  • RaisedButton

  • FloatingActionButton

  • FlatButton

  • IconButton

  • PopupMenuButton

  • BUttonBar

Input和Selections

  • TextField

  • CheckBox

  • Radio

  • Switch

  • Slider

  • Date&Time Pickers

对话框

  • SimpleDialog

  • AlertDialog

  • ButtonSheet

  • ExpansionPanel

  • SnackBar

信息展示

  • Image

  • Icon

  • Chip

  • Tooltip

  • DataTable

  • Card

  • LinearProgresssIndicator

  • Gridview

Layout

  • ListTile

  • Stepper

  • Diveider

根据上面的控件,写了一个例子,如下图:

PreviousFlutterNext开源库

Last updated 6 years ago

RowDemo_超过Row范围
RowDemo_Expand
RowDemo_Weight属性

代码地址