在Flutter里面构建布局

https://flutter.io/tutorials/layout/

finished lakes app that you'll build in 'Building a Layout'

可以学到:

Flutter的布局机制

如何水平与垂直布局控件

如何构建一个Flutter布局

布局的效果图:https://flutter.io/tutorials/layout/images/lakes.jpg

这篇指南,分步介绍了Flutter的布局方式,展示了如何在屏幕放一个控件.在介绍如何布局前,先来看一看包含的范围:

构建一个布局

如果想了解Flutter的布局机制,可以查看https://flutter.io/tutorials/layout/#approach

第0步:

设置环境,创建一个基础的Flutter应用.这一步不再赘述

添加一个图片到项目的顶层叫images.添加lage.jpg到这个目录中https://github.com/flutter/website/blob/master/_includes/code/layout/lakes/images/lake.jpg

更新pubspec.yaml文件,包含进assets

assets:

- images/lake.jpg

步骤1:

这步,分为以下几步:

确定行与列

布局是否包含网格

有没有遮罩的元素

ui是否需要tab

通知区域需要垂直定位,补白边框等

首先,确定最大元素.示例中,四个元素在一列,图片,两行,一个文本.

效果图:https://flutter.io/tutorials/layout/images/lakes-diagram.png

diagramming the rows in the lakes screenshot

两行内容的效果图:https://flutter.io/tutorials/layout/images/lakes-diagram.png

diagramming the widgets in the Title section

第一行,是标题,有三个子元素.一列文本,一个star图标,一个数字.第一列,包含两个文本,第一个文本有较大空间,需要折叠的.

第二行效果图:https://flutter.io/tutorials/layout/images/button-section-diagram.png

diagramming the widgets in the button section

按钮段,有三个元素,每一个子元素是一列,包含一个图标与文本.

一旦布局图形化,就很容易地自下而上的去实现它.

步骤2:实现标题行

先构建左侧的标题.将这一列放到可展开的控件中.让它充满这个剩下的空间.设置crossAxisAlignment属性到crossAxisAlignment.start行的开始位置.

将文本第一行放到一个容器中,添加padding.第二个子元素,也是文本,显示颜色是grey.

剩下的两个项是图标.为红色,文本为"41",将事先 行放到容器中,边的补白是32像素.

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    Widget titleSection = Container(
      padding: const EdgeInsets.all(32.0),
      child: Row(
        children: [
          Expanded(
            child: Column(
              crossAxisAlignment: CrossAxisAlignment.start,
              children: [
                Container(
                  padding: const EdgeInsets.only(bottom: 8.0),
                  child: Text(
                    'Oeschinen Lake Campground',
                    style: TextStyle(
                      fontWeight: FontWeight.bold,
                    ),
                  ),
                ),
                Text(
                  'Kandersteg, Switzerland',
                  style: TextStyle(
                    color: Colors.grey[500],
                  ),
                ),
              ],
            ),
          ),
          Icon(
            Icons.star,
            color: Colors.red[500],
          ),
          Text('41'),
        ],
      ),
    );
  //...
}

步骤3,实现按钮行

按钮行包含三个按钮,使用同样的布局.一个图标在文本上.

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

    return MaterialApp(
      title: 'Flutter Demo',
      theme: ThemeData(
        primarySwatch: Colors.blue,
      ),

    //...
}

每一行几乎是确定的,可以很高效地创建内部方法.如buildButtonColumn(),它包含文本与图标.文字是主色

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

    Column buildButtonColumn(IconData icon, String label) {
      Color color = Theme.of(context).primaryColor;

      return Column(
        mainAxisSize: MainAxisSize.min,
        mainAxisAlignment: MainAxisAlignment.center,
        children: [
          Icon(icon, color: color),
          Container(
            margin: const EdgeInsets.only(top: 8.0),
            child: Text(
              label,
              style: TextStyle(
                fontSize: 12.0,
                fontWeight: FontWeight.w400,
                color: color,
              ),
            ),
          ),
        ],
      );
    }
  //...
}

build方法,添加一个图标到列中,放一个文本到容器里,添加补白与图标分开.

行包含三个列.所以作为参数传入图标与文本.列在主轴方向,使用MainAxisAlignment.spaceEvenly来使它充满剩下的空间.

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

    Widget buttonSection = Container(
      child: Row(
        mainAxisAlignment: MainAxisAlignment.spaceEvenly,
        children: [
          buildButtonColumn(Icons.call, 'CALL'),
          buildButtonColumn(Icons.near_me, 'ROUTE'),
          buildButtonColumn(Icons.share, 'SHARE'),
        ],
      ),
    );
  //...
}

步骤4,实现文本段

定义文本段,将一个长文本定义一个变量.将它放入容器中,32像素的补白边.softwrap属性表明可折叠.

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    //...
    Widget textSection = Container(
      padding: const EdgeInsets.all(32.0),
      child: Text(
        '''
Lake Oeschinen lies at the foot of the Blüemlisalp in the Bernese Alps. Situated 1,578 meters above sea level, it is one of the larger Alpine Lakes. A gondola ride from Kandersteg, followed by a half-hour walk through pastures and pine forest, leads you to the lake, which warms to 20 degrees Celsius in the summer. Activities enjoyed here include rowing, and riding the summer toboggan run.
        ''',
        softWrap: true,
      ),
    );
  //...
}

步骤5:实现图标段

四列元素的三个已经完成了.剩下图片.图片获取比较慢,虽然它是通用的协议.步骤0已经添加了图片了.现在引用它.

在build最后

return MaterialApp(
//...
body: ListView(
  children: [
    Image.asset(
      'images/lake.jpg',
      height: 240.0,
      fit: BoxFit.cover,
    ),
    // ...
  ],
),
//...
);

步骤6,所有放一起

这些控件放到一个ListView,而不是一列中,因为ListView可以实现自己的滚动,特别是小屏上.

return MaterialApp(
      title: 'Flutter Demo',
      theme: ThemeData(
        primarySwatch: Colors.blue,
      ),
      home: Scaffold(
        appBar: AppBar(
          title: Text('Top Lakes'),
        ),
        body: ListView(
          children: [
            Image.asset(
              'images/lake.jpg',
              width: 600.0,
              height: 240.0,
              fit: BoxFit.cover,
            ),
            titleSection,
            buttonSection,
            textSection,
          ],
        ),
      ),
    );
//...

代码地址:https://raw.githubusercontent.com/flutter/website/master/_includes/code/layout/lakes/main.dart

https://raw.githubusercontent.com/flutter/website/master/_includes/code/layout/lakes/pubspec.yaml

当热加载或编译运行时,就可以看到效果了.

 

Flutter的布局方式:

控件类用于构建ui

控件用于ui元素与布局.

组合简单的控件来构建复杂的控件.

Flutter的核心布局机制是控件.在Flutter,几乎所有的东西都是一个控件.甚至布局模型也是控件.图片,图标,文本是最常用的控件.你看不到的也是,像行,列,网格,约束等.

组合一个复杂的控件,像屏幕中展示的,左边三个图标,一个文本在下面的控件.https://flutter.io/tutorials/layout/images/lakes-icons.png

sample layout

https://flutter.io/tutorials/layout/images/lakes-icons-visual.png展示了可视化的布局,显示了各控件.

sample sample layout with visual debugging turned on

看一下控件树的图形:

https://flutter.io/tutorials/layout/images/sample-flutter-layout.png

node tree representing the sample layout

看到你效果,你可能会想容器.容器是一个控件,允许你自定义子控件.使用容器Container,要添加padding,margins,borders,或背景色.

示例中,文本控件放在容器中,有margins.整个行也有padding.

剩下的示例中 的ui,通过属性控制,使用color设置按钮的颜色.使用style属性来设置文本的字体,颜色,权重等.行列也有属性.可以设置垂直与水平方向的定位占比.

布局一个控件.

app本身也是一个控件

很容易创建控件与添加到布局中.

添加到布局中,显示在设备上

很容易使用Scaffold,它是Material组件库中的控件,提供默认的banner,背景色,有添加drawer,snackbar ,bottom sheets的api.

如果你喜欢,可以构建一个app,使用默认的库中的控件.

在Flutter如何布局一个单一的控件.这音展示如何创建一个简单的控件,然后展示在屏幕中.

就像hello world中一样,没太多需要介绍的

import 'package:flutter/material.dart';

void main() {
  runApp(MyApp());
}

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Container(
      decoration: BoxDecoration(color: Colors.white),
      child: Center(
        child: Text('Hello World',
            textDirection: TextDirection.ltr,
            style: TextStyle(fontSize: 40.0, color: Colors.black87)),
      ),
    );
  }
}

效果图:https://flutter.io/tutorials/layout/images/hello-world.png

非Material的app没有appbar,标题,背景等.如果需要这些.可以自己加.

Material风格的:https://raw.githubusercontent.com/flutter/website/master/_includes/code/layout/hello-world/main.dart

只包含控件的:https://raw.githubusercontent.com/flutter/website/master/_includes/code/layout/widgets-only/main.dart

 

水平或垂直布局多个控件:

最常用的布局模式是将控件水平或垂直地排放.可以使用Row控件水平排放,使用Column控件垂直排放.

Row与Column是最常用的布局模式

Row与Column都有一个子控件列表.

子控件可以自己是一个Row或Column或其它复杂的控件.

可以同时指定子元素的垂直与水平位置

可以拉伸或约束子控件.

可以分配子元素如何使用空间.

内容:

在Flutter里面创建行或列,然后添加子元素列表到行或列控件中.下面展示如何嵌套

这个布局组织为一行,行包含两个子元素,一列在左,一个图标在右.https://flutter.io/tutorials/layout/images/pavlova-diagram.png

screenshot with callouts showing the row containing two children: a column and an image.

左侧是一个嵌套的控件.https://flutter.io/tutorials/layout/images/pavlova-left-column-diagram.png

diagram showing a left column broken down to its sub-rows and sub-columns

实现代码https://flutter.io/tutorials/layout/#nesting.

行列是基本的元素,这些低阶控件,允许你最大化地自定义.Flutter也提供了一些高阶的控件,来满足你的需求.如,可以使用ListTile来替代行,它是很容易使用的控件,有图标,三行文本.而取代列的有ListView,它自适应滚动.

排列控件

你使用mainAxisAlignment与crossAxisAlignment属性来控制着如何安排子元素.对于行,主轴是水平的.纵轴是垂直的.对于列则相反.

https://flutter.io/tutorials/layout/images/row-diagram.png,https://flutter.io/tutorials/layout/images/column-diagram.png

diagram showing the main axis and cross axis for a row diagram showing the main axis and cross axis for a column

接下来的示例中,三个图像是100像素宽,渲染框是大于300像素.所以设置主轴的排列是spaceEvenly,平分分割水平方向的空间.

appBar: AppBar(
  title: Text(widget.title),
),
body: Center(
  child: Row(
    mainAxisAlignment: MainAxisAlignment.spaceEvenly,
    children: [
      Image.asset('images/pic1.jpg'),

https://flutter.io/tutorials/layout/images/row-spaceevenly-visual.png

列与行是一样的.

appBar: AppBar(
  title: Text(widget.title),
),
body: Center(
  child: Column(
    mainAxisAlignment: MainAxisAlignment.spaceEvenly,
    children: [
      Image.asset('images/pic1.jpg'),

https://flutter.io/tutorials/layout/images/column-visual.png

代码:https://raw.githubusercontent.com/flutter/website/master/_includes/code/layout/column/main.dart

https://github.com/flutter/website/tree/master/_includes/code/layout/column/images

当一个布局太大了,会出现红色的条在边上.https://flutter.io/tutorials/layout/images/layout-too-large.png

a row that is too wide, showing a red string along the right edge

控件可以缩放来适应,这时要使用Expanded控件.

对控件缩放大小

如果你的控件是两倍于兄弟控件的大小.可以放到Expanded控件中,控件着它的主轴方向的大小.它有flex属性,是整型值,测量flex因子.默认是1.这就像weight一样.

appBar: AppBar(
  title: Text(widget.title),
),
body: Center(
  child: Row(
    crossAxisAlignment: CrossAxisAlignment.center,
    children: [
      Expanded(
        child: Image.asset('images/pic1.jpg'),
      ),
      Expanded(
        flex: 2,
        child: Image.asset('images/pic2.jpg'),
      ),
      Expanded(

效果:https://flutter.io/tutorials/layout/images/row-expanded-visual.png

三个元素,中间是旁边的两倍大小,所以flex:2

当空间太大,会有红色的边框,https://flutter.io/tutorials/layout/images/row-expanded-2-visual.png,放到Expanded就可以了

打包控件

默认的行与列会尽量占用主轴的空间.如果你要打包起来,就设置mainAxisSize到最小MainAxisSize.min.

class _MyHomePageState extends State<MyHomePage> {
  @override
  Widget build(BuildContext context) {
    var packedRow = Row(
      mainAxisSize: MainAxisSize.min,
      children: [
        Icon(Icons.star, color: Colors.green[500]),
        Icon(Icons.star, color: Colors.green[500]),
        Icon(Icons.star, color: Colors.green[500]),
        Icon(Icons.star, color: Colors.black),
        Icon(Icons.star, color: Colors.black),
      ],
    );

  // ...
}

https://flutter.io/tutorials/layout/images/packed.png 这种就是居中显示,所有控件向中间靠拢.它不像android里的居中定位,所以是通过设置轴上的属性来实现的

a row of 3 images with the middle image twice as wide as the others

嵌套的列与行

布局框架,允许你嵌套行与列,只要你喜欢.https://flutter.io/tutorials/layout/images/pavlova-large-annotated.png

a screenshot of the pavlova app, with the ratings and icon rows outlined in red

概述章节为两行实现的.rating行由五个星图标实现.图标行,包含三列图与文本.

rating行的控件树:https://flutter.io/tutorials/layout/images/widget-tree-pavlova-rating-row.png

a node tree showing the widgets in the ratings row

rating变量,创建一个行,包含五个星图标.与文本

class _MyHomePageState extends State<MyHomePage> {
  @override
  Widget build(BuildContext context) {
    //...

    var ratings = Container(
      padding: EdgeInsets.all(20.0),
      child: Row(
        mainAxisAlignment: MainAxisAlignment.spaceEvenly,
        children: [
          Row(
            mainAxisSize: MainAxisSize.min,
            children: [
              Icon(Icons.star, color: Colors.black),
              Icon(Icons.star, color: Colors.black),
              Icon(Icons.star, color: Colors.black),
              Icon(Icons.star, color: Colors.black),
              Icon(Icons.star, color: Colors.black),
            ],
          ),
          Text(
            '170 Reviews',
            style: TextStyle(
              color: Colors.black,
              fontWeight: FontWeight.w800,
              fontFamily: 'Roboto',
              letterSpacing: 0.5,
              fontSize: 20.0,
            ),
          ),
        ],
      ),
    );
    //...
  }
}

它的下面,包含三列.每一列包含一个图标与两行文本.控件树:https://flutter.io/tutorials/layout/images/widget-tree-pavlova-icon-row.png

a node tree for the widets in the icons row

iconList变量定义在icons行中

class _MyHomePageState extends State<MyHomePage> {
  @override
  Widget build(BuildContext context) {
    // ...

    var descTextStyle = TextStyle(
      color: Colors.black,
      fontWeight: FontWeight.w800,
      fontFamily: 'Roboto',
      letterSpacing: 0.5,
      fontSize: 18.0,
      height: 2.0,
    );

    // DefaultTextStyle.merge allows you to create a default text
    // style that is inherited by its child and all subsequent children.
    var iconList = DefaultTextStyle.merge(
      style: descTextStyle,
      child: Container(
        padding: EdgeInsets.all(20.0),
        child: Row(
          mainAxisAlignment: MainAxisAlignment.spaceEvenly,
          children: [
            Column(
              children: [
                Icon(Icons.kitchen, color: Colors.green[500]),
                Text('PREP:'),
                Text('25 min'),
              ],
            ),
            Column(
              children: [
                Icon(Icons.timer, color: Colors.green[500]),
                Text('COOK:'),
                Text('1 hr'),
              ],
            ),
            Column(
              children: [
                Icon(Icons.restaurant, color: Colors.green[500]),
                Text('FEEDS:'),
                Text('4-6'),
              ],
            ),
          ],
        ),
      ),
    );
    // ...
  }
}

leftColumn变量,包含rating图标.

class _MyHomePageState extends State<MyHomePage> {
  @override
  Widget build(BuildContext context) {
    //...

    var leftColumn = Container(
      padding: EdgeInsets.fromLTRB(20.0, 30.0, 20.0, 20.0),
      child: Column(
        children: [
          titleText,
          subTitle,
          ratings,
          iconList,
        ],
      ),
    );
    //...
  }
}

leftColumn放在容器中,宽受约束,整个ui放在一个卡片里.

使用Image.network来内嵌图片,但这个示例图片是放在images目录中的.并添加到pubspec文件里.

body: Center(
  child: Container(
    margin: EdgeInsets.fromLTRB(0.0, 40.0, 0.0, 30.0),
    height: 600.0,
    child: Card(
      child: Row(
        crossAxisAlignment: CrossAxisAlignment.start,
        children: [
          Container(
            width: 440.0,
            child: leftColumn,
          ),
          mainImage,
        ],
      ),
    ),
  ),
),

代码:https://raw.githubusercontent.com/flutter/website/master/_includes/code/layout/pavlova/main.dart

图片:https://github.com/flutter/website/tree/master/_includes/code/layout/pavlova/images

配置:https://raw.githubusercontent.com/flutter/website/master/_includes/code/layout/pavlova/pubspec.yaml

通用布局控件:

Flutter有丰富的布局控件,有一些比较常用.https://docs.flutter.io/文档可以查到更多关于控件的使用.这些控件主要是让用户可以容易地实现需求.

控件,分为两类,普通的控件与Material设计库.但只有Material的app可以使用Material库.

Standard widgets

  • Container

    Adds padding, margins, borders, background color, or other decorations to a widget.

  • GridView

    Lays widgets out as a scrollable grid.

  • ListView

    Lays widgets out as a scrollable list.

  • Stack

    Overlaps a widget on top of another.

Material Components

  • Card

    Organizes related info into a box with rounded corners and a drop shadow.

  • ListTile

    Organizes up to 3 lines of text, and optional leading and trailing icons, into a row.

容器:

很多布局,大量使用容器来分割控件,这些容器带有边框,空白等.通过将整个布局放在容器中,可以修改设备的背景色.

容器总结:

添加padding,margin,border

改变背景色

包含单一的控件,可以是行,列或根

a diagram showing that margins, borders, and padding, that surround content in a container

容器示例

可以在https://github.com/flutter/flutter/tree/master/examples/flutter_gallery中查找到使用的示例.

a screenshot showing 2 rows, each containing 2 images; the images have grey rounded borders, and the background is a lighter grey

这个布局包含一个列,每列两行,有两个图片,每个图片,包含灰边与间距,列使用容器来设置背景色.

代码:https://raw.githubusercontent.com/flutter/website/master/_includes/code/layout/container/main.dart

图片:https://github.com/flutter/website/tree/master/_includes/code/layout/container/images

配置:https://raw.githubusercontent.com/flutter/website/master/_includes/code/layout/container/pubspec.yaml

class _MyHomePageState extends State<MyHomePage> {
  @override
  Widget build(BuildContext context) {

    var container = Container(
      decoration: BoxDecoration(
        color: Colors.black26,
      ),
      child: Column(
        children: [
          Row(
            children: [
              Expanded(
                child: Container(
                  decoration: BoxDecoration(
                    border: Border.all(width: 10.0, color: Colors.black38),
                    borderRadius:
                        const BorderRadius.all(const Radius.circular(8.0)),
                  ),
                  margin: const EdgeInsets.all(4.0),
                  child: Image.asset('images/pic1.jpg'),
                ),
              ),
              Expanded(
                child: Container(
                  decoration: BoxDecoration(
                    border: Border.all(width: 10.0, color: Colors.black38),
                    borderRadius:
                        const BorderRadius.all(const Radius.circular(8.0)),
                  ),
                  margin: const EdgeInsets.all(4.0),
                  child: Image.asset('images/pic2.jpg'),
                ),
              ),
            ],
          ),
          // ...
          // See the definition for the second row on GitHub:
          // https://raw.githubusercontent.com/flutter/website/master/_includes/code/layout/container/main.dart
        ],
      ),
    );
    //...
  }
}

网格:

GridView是二维的列表.当它太大时,会自己滚动.可以使用预设也可以自定义.

总结:

网格外放控件

检测到列超过渲染框时提供滚动.

有两个构建方式.GridView.count允许几列.GridView.extent允许最大宽像素.

a 3-column grid of photosa 2 column grid with footers containing titles on a partially translucent background

代码:https://raw.githubusercontent.com/flutter/website/master/_includes/code/layout/grid/main.dart

代码:https://github.com/flutter/flutter/blob/master/examples/flutter_gallery/lib/demo/material/grid_list_demo.dart

// The images are saved with names pic1.jpg, pic2.jpg...pic30.jpg.
// The List.generate constructor allows an easy way to create
// a list when objects have a predictable naming pattern.
List<Container> _buildGridTileList(int count) {

  return List<Container>.generate(
      count,
      (int index) =>
          Container(child: Image.asset('images/pic${index+1}.jpg')));
}

Widget buildGrid() {
  return GridView.extent(
      maxCrossAxisExtent: 150.0,
      padding: const EdgeInsets.all(4.0),
      mainAxisSpacing: 4.0,
      crossAxisSpacing: 4.0,
      children: _buildGridTileList(30));
}

class _MyHomePageState extends State<MyHomePage> {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text(widget.title),
      ),
      body: Center(
        child: buildGrid(),
      ),
    );
  }
}

列表:列表是一个列的控件,当内容超过渲染框时自动滚动

总结:一个特定box的列表

可以水平或垂直布局

超过渲染框范围会自动滚动.

比Column更容易实现滚动.配置更少.

列表示例:

a ListView containing movie theaters and restaurants

代码:https://raw.githubusercontent.com/flutter/website/master/_includes/code/layout/listview/main.dart

gallery代码示例:https://github.com/flutter/flutter/blob/master/examples/flutter_gallery/lib/demo/colors_demo.dart

List<Widget> list = <Widget>[
  ListTile(
    title: Text('CineArts at the Empire',
        style: TextStyle(fontWeight: FontWeight.w500, fontSize: 20.0)),
    subtitle: Text('85 W Portal Ave'),
    leading: Icon(
      Icons.theaters,
      color: Colors.blue[500],
    ),
  ),
  ListTile(
    title: Text('The Castro Theater',
        style: TextStyle(fontWeight: FontWeight.w500, fontSize: 20.0)),
    subtitle: Text('429 Castro St'),
    leading: Icon(
      Icons.theaters,
      color: Colors.blue[500],
    ),
  ),
  // ...
  // See the rest of the column defined on GitHub:
  // https://raw.githubusercontent.com/flutter/website/master/_includes/code/layout/listview/main.dart
];

class _MyHomePageState extends State<MyHomePage> {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      // ...
      body: Center(
        child: ListView(
          children: list,
        ),
      ),
    );
  }
}

栈:

使用栈来排列控件.通常是在顶部的 图片上使用.这个控件可以部分或全部浮在基础控件上.

在悬浮另一个控件上使用.

列表中的第一个元素,是一个基础擦伤,然后第二个在上面.

栈的内容不可滚动.

可以选择是否切割来显示超过部分.

a circular avatar containing the label 'Mia B' in the lower right portion of the circle

代码:https://raw.githubusercontent.com/flutter/website/master/_includes/code/layout/stack/main.dart

class _MyHomePageState extends State<MyHomePage> {
  @override
  Widget build(BuildContext context) {
    var stack = Stack(
      alignment: const Alignment(0.6, 0.6),
      children: [
        CircleAvatar(
          backgroundImage: AssetImage('images/pic.jpg'),
          radius: 100.0,
        ),
        Container(
          decoration: BoxDecoration(
            color: Colors.black45,
          ),
          child: Text(
            'Mia B',
            style: TextStyle(
              fontSize: 20.0,
              fontWeight: FontWeight.bold,
              color: Colors.white,
            ),
          ),
        ),
      ],
    );
    // ...
  }
}

卡片:

卡片是Material组件库中的,可以组合几乎所有控件.但它经常与ListTile一起使用.卡片是有单一的子元素.这个子元素可 以是行,或,列表,网格.默认的卡片是0*0像素,可以使用SizedBox来约束大小.

在Flutter,卡片特性有圆角与阴影,像3d效果.改变卡片的elevation属性,允许你控制阴影效果.这点像Android里面的一样.查看https://material.io/guidelines/material-design/elevation-shadows.html可以知道支持的属性.

总结:

来自于Material设计.实现了Material卡片

像砖块的形式展现

接受单一的子元素,子元素可以包含各种控件.

带有圆角与阴影边

不可滚动.

示例:

a Card containing 3 ListTiles

代码:https://raw.githubusercontent.com/flutter/website/master/_includes/code/layout/card/main.dart

class _MyHomePageState extends State<MyHomePage> {
  @override
  Widget build(BuildContext context) {
    var card = SizedBox(
      height: 210.0,
      child: Card(
        child: Column(
          children: [
            ListTile(
              title: Text('1625 Main Street',
                  style: TextStyle(fontWeight: FontWeight.w500)),
              subtitle: Text('My City, CA 99984'),
              leading: Icon(
                Icons.restaurant_menu,
                color: Colors.blue[500],
              ),
            ),
            Divider(),
            ListTile(
              title: Text('(408) 555-1212',
                  style: TextStyle(fontWeight: FontWeight.w500)),
              leading: Icon(
                Icons.contact_phone,
                color: Colors.blue[500],
              ),
            ),
            ListTile(
              title: Text('costa@example.com'),
              leading: Icon(
                Icons.contact_mail,
                color: Colors.blue[500],
              ),
            ),
          ],
        ),
      ),
    );
  //...
}

ListTile

使用ListTile作为一个定制化的行控件,来自Material库,可以容易地创建一三行文本,一个可选的首尾图标.它经常与卡片与ListView共用.

示例:a Card containing 3 ListTiles

代码:https://flutter.io/tutorials/layout/#card-examples

资源:

下面的资源帮助你编写布局:

 

翻译的不太好.像其它框架一个,react,weex,一切都是控件,然后用这些控件去拼接起来,整体上会比单独在Android或ios上要复杂一点.布局中,使用的是轴的概念,因为允许垂直与水平方向的.基于目前的ide与插件,开发比较耗事,无法预览是个问题, 但ios开发人员可能比较容易适应它.Android习惯了xml布局会有些迷茫,整体思路都类似的.控件就是上下左右摆放,然后设置一些间距等.

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值