关于flutter中的布局

124 阅读3分钟

Flutter 布局系统由一系列的 Widget 组成,每个 Widget 代表界面中的一个小部件,通过组合这些 Widget 可以构建复杂的用户界面。以下是 Flutter 布局中常用的内容和关键点:

1. 基本布局组件

1.1 Container

Container 是一个多功能的容器组件,可以用来装饰、定位和调整子组件的大小。

  • 使用关键点

    • 设置宽度和高度。
    • 设置颜色或装饰。
    • 设置内边距和外边距。
dart
复制代码
Container(
  width: 200,
  height: 100,
  color: Colors.blue,
  child: Text('Hello, Flutter!'),
)

1.2 Row 和 Column

RowColumn 分别用于水平和垂直方向布局子组件。

  • 使用关键点

    • RowmainAxisAlignmentcrossAxisAlignment 属性控制主轴和交叉轴对齐方式。
    • ColumnmainAxisAlignmentcrossAxisAlignment 属性控制主轴和交叉轴对齐方式。
dart
复制代码
// 水平布局
Row(
  mainAxisAlignment: MainAxisAlignment.spaceEvenly,
  children: <Widget>[
    Icon(Icons.star),
    Icon(Icons.star),
    Icon(Icons.star),
  ],
)

// 垂直布局
Column(
  mainAxisAlignment: MainAxisAlignment.center,
  crossAxisAlignment: CrossAxisAlignment.start,
  children: <Widget>[
    Text('Line 1'),
    Text('Line 2'),
    Text('Line 3'),
  ],
)

2. 布局约束和对齐

2.1 Expanded 和 Flexible

ExpandedFlexible 用于在 RowColumn 中按比例分配可用空间。

  • 使用关键点

    • Expanded 会占据主轴上所有剩余空间。
    • Flexible 可以和 flex 属性一起使用来按比例分配空间。
dart
复制代码
Row(
  children: <Widget>[
    Expanded(
      child: Container(color: Colors.red),
      flex: 2,
    ),
    Expanded(
      child: Container(color: Colors.green),
      flex: 1,
    ),
    Expanded(
      child: Container(color: Colors.blue),
      flex: 1,
    ),
  ],
)

2.2 Align 和 Center

AlignCenter 用于对齐子组件。

  • 使用关键点

    • Alignalignment 属性用于设置对齐方式。
    • Center 组件默认将子组件居中对齐。
dart
复制代码
// Center 对齐
Center(
  child: Text('Centered Text'),
)

// Align 对齐
Align(
  alignment: Alignment.bottomRight,
  child: Text('Bottom Right'),
)

3. 高级布局组件

3.1 Stack

Stack 用于叠放子组件,可以通过 Positioned 调整子组件的位置。

  • 使用关键点

    • Stack 的子组件按照添加顺序从底部到顶部叠放。
    • Positioned 组件用于指定子组件的位置。
dart
复制代码
Stack(
  children: <Widget>[
    Container(color: Colors.blue, width: 200, height: 200),
    Positioned(
      top: 50,
      left: 50,
      child: Container(color: Colors.red, width: 100, height: 100),
    ),
  ],
)

3.2 ListView 和 GridView

ListViewGridView 用于实现滚动列表和网格布局。

  • 使用关键点

    • ListViewchildren 属性用于添加列表项。
    • GridViewcrossAxisCount 属性用于设置每行的列数。
dart
复制代码
// ListView
ListView(
  children: <Widget>[
    ListTile(title: Text('Item 1')),
    ListTile(title: Text('Item 2')),
    ListTile(title: Text('Item 3')),
  ],
)

// GridView
GridView.count(
  crossAxisCount: 2,
  children: <Widget>[
    Container(color: Colors.red, height: 100),
    Container(color: Colors.green, height: 100),
    Container(color: Colors.blue, height: 100),
    Container(color: Colors.yellow, height: 100),
  ],
)

4. 复杂布局和自定义布局

4.1 CustomScrollView 和 Slivers

CustomScrollViewSlivers 用于实现复杂的滚动效果。

  • 使用关键点

    • CustomScrollView 结合 SliverListSliverGrid 等实现复杂的滚动布局。
    • SliverAppBar 可以实现动态效果。
dart
复制代码
CustomScrollView(
  slivers: <Widget>[
    SliverAppBar(
      title: Text('SliverAppBar'),
      floating: true,
      expandedHeight: 200.0,
    ),
    SliverList(
      delegate: SliverChildBuilderDelegate(
        (BuildContext context, int index) {
          return ListTile(
            title: Text('Item #$index'),
          );
        },
        childCount: 20,
      ),
    ),
  ],
)

4.2 CustomMultiChildLayout 和 CustomSingleChildLayout

CustomMultiChildLayoutCustomSingleChildLayout 用于实现自定义布局。

  • 使用关键点

    • CustomSingleChildLayout 通过实现 SingleChildLayoutDelegate 进行布局。
    • CustomMultiChildLayout 通过实现 MultiChildLayoutDelegate 进行布局。
dart
复制代码
class MyCustomLayout extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return CustomSingleChildLayout(
      delegate: MySingleChildLayoutDelegate(),
      child: Container(color: Colors.blue),
    );
  }
}

class MySingleChildLayoutDelegate extends SingleChildLayoutDelegate {
  @override
  BoxConstraints getConstraintsForChild(BoxConstraints constraints) {
    return BoxConstraints(
      maxWidth: constraints.maxWidth / 2,
      maxHeight: constraints.maxHeight / 2,
    );
  }

  @override
  Offset getPositionForChild(Size size, Size childSize) {
    return Offset(size.width / 4, size.height / 4);
  }

  @override
  bool shouldRelayout(SingleChildLayoutDelegate oldDelegate) {
    return false;
  }
}

5. 响应式布局

响应式布局是为了适应不同屏幕尺寸和方向的变化。

5.1 MediaQuery

MediaQuery 用于获取屏幕尺寸和方向等信息。

  • 使用关键点

    • 使用 MediaQuery.of(context).size 获取屏幕宽度和高度。
dart
复制代码
MediaQuery.of(context).size.width

5.2 LayoutBuilder

LayoutBuilder 用于根据父组件的约束动态调整子组件的布局。

  • 使用关键点

    • LayoutBuilderbuilder 属性提供 BoxConstraints 进行布局判断。
dart
复制代码
LayoutBuilder(
  builder: (BuildContext context, BoxConstraints constraints) {
    if (constraints.maxWidth > 600) {
      return Text('Large Screen');
    } else {
      return Text('Small Screen');
    }
  },
)

结论