Flutter 学习笔记6 - 常用 Widgets

下面的 widget 分为两类:widgets library中的标准 widget 和 Material Components library 中的专用 widget。任何应用程序都可以使用 widgets library 中的 widget,但只有 Material 应用程序可以使用 Material Components library。

标准 Widgets

Container

添加 padding,margins,borders,background color,或添加其它装饰。

15462446744089.png

return Scaffold (
  backgroundColor: Colors.blue, // 背景色
  appBar: AppBar(
    title: Text('Startup Name Generator'),
  ),
  body: Container(
    decoration: BoxDecoration( // 边框
      border: Border.all(width: 10.0, color: Colors.red), // 红色 10px
      borderRadius: const BorderRadius.all(const Radius.circular(8.0)), // 圆角
    ),
    margin: const EdgeInsets.all(14.0), // 外边距
    padding: const EdgeInsets.all(16.0), // 内边距
    child: Image.asset('images/lake.jpg'),
  ),
);

屏幕快照 2018-12-31 下午4.32.48.png

GridView

可滚动网格布局。它提供了两种 Grid:

GridView.extent 可指定项的最大像素宽度

class WidgetScaffold extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Scaffold (
      backgroundColor: Colors.blue, // 背景色
      appBar: AppBar(
        title: Text('Startup Name Generator'),
      ),
      body: Center(child: buildGrid(),)
    );
  }
}

Widget buildGrid() {
  // GridView.extent
  return GridView.extent(
    maxCrossAxisExtent: 150, // 指定最大宽度
    padding: const EdgeInsets.all(4.0),
    mainAxisSpacing: 4.0,
    crossAxisSpacing: 4.0,
    children: _buildGridTileList(30)); // 通过 children 提供子项
}

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

屏幕快照 2019-01-01 上午11.07.58.png

改变最大宽度为 maxCrossAxisExtent: 350 变成

屏幕快照 2019-01-01 上午11.08.57.png

可见是根据这个最大宽度值自动计算来确定列数。

GridView.count 可指定列数

Widget buildGrid(BuildContext context) {
  // 判断屏幕方向
  final Orientation orientation = MediaQuery.of(context).orientation;
  return GridView.count(
    // 竖屏为 2 列,横屏为 3 列
    crossAxisCount: (orientation == Orientation.portrait) ? 2 : 3,
    mainAxisSpacing: 4.0,
    crossAxisSpacing: 4.0,
    padding: const EdgeInsets.all(4.0),
    childAspectRatio: (orientation == Orientation.portrait) ? 1.0 : 1.3,
    children: _buildGridTileList(30));
}

竖向两列:

屏幕快照 2019-01-01 上午11.16.11.png

旋转屏幕横向三列:

屏幕快照 2019-01-01 上午11.16.40.png

ListView

自动滚动的列表

class WidgetScaffold extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Scaffold (
      appBar: AppBar(
        title: Text('Startup Name Generator'),
      ),
      // ListView 参数是一个 List
      body: ListView(
        children: _buildGridTileList(30),
      )
    );
  }
}

List<ListTile> _buildGridTileList(int count) {
  return List<ListTile>.generate(
    count,
    (int index) {
      return ListTile(
        title: Text('A $index',
        style: TextStyle(fontWeight: FontWeight.w500, fontSize: 20.0)),
        subtitle: Text('sub $index'),
      );
    }
  );
}

device-2019-01-01-113629.png

Stack

将 widget 重叠在另一个 widget 之上。

class WidgetScaffold extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Scaffold (
      appBar: AppBar(
        title: Text('Startup Name Generator'),
      ),
      body: stack
    );
  }
}

var stack = Stack(
  alignment: const Alignment(0.6, 0.6),
  children: [ // children 中的内容堆叠在一起
    CircleAvatar( // 一个圆形图片
      backgroundImage: AssetImage('images/lake.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,
        ),
      ),
    ),
  ],
);

屏幕快照 2019-01-01 上午11.51.02.png

图片没显示出来。

Material Components

Card

具有圆角和阴影的 3D 效果,和 Android 的 CardView 有点相似。更改 elevation 属性控制投影效果。

只允许有一个 child,但这个 child 可以是其它复杂的 widget

ListTile

是一个行级 widget。将最多三行文字,可选的行前和行尾的图标排成一行。在 Card 和 ListView 中最常用。

class WidgetScaffold extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Scaffold (
      appBar: AppBar(
        title: Text('Startup Name Generator'),
      ),
      body: card
    );
  }
}

var card = SizedBox(
  height: 140.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('title'),
          subtitle: Text('subtitle'),
          leading: Icon( // 前面的 icon
            Icons.contact_mail,
            color: Colors.blue[500],
          ),
          trailing:new Icon( // 后面的 icon
            Icons.contact_phone,
            color: Colors.blue[500],
          ),
        ),
      ],
    ),
  ),
);

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

扫码关注云+社区

领取腾讯云代金券