当前位置:   article > 正文

Flutter(二):Row、Column 布局

Flutter(二):Row、Column 布局

MaterialApp

对于 MaterialApp,组件提供了一些默认的属性,如AppBar标题背景颜色等,你可以默认使用它们

import 'package:flutter/material.dart';

void main() {
  runApp(const App());
}

class App extends StatelessWidget {
  const App({super.key});

  
  Widget build(BuildContext context) {
    /**
     * MaterialApp
     */
    return MaterialApp(
      title: 'Flutter layout demo',
      home: Scaffold(
        appBar: AppBar(
          title: const Text('标题'),
        ),
        body: const Center(
          child: Text('Hello World'),
        ),
      ),
    );
  }
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27

非 MaterialApp

默认情况下,非 MaterialApp 不包含 AppBar标题背景颜色,如希望实现这些功能,则必须手动构建它们

import 'package:flutter/material.dart';

void main() {
  runApp(const App());
}

class App extends StatelessWidget {
  const App({super.key});

  
  Widget build(BuildContext context) {
    /**
     * 非MaterialApp
     */
    return Container(
        decoration: const BoxDecoration(color: Colors.grey),
        child: const Center(
          child: Text(
            'Hello Lee!',
            textDirection: TextDirection.ltr,
            style: TextStyle(
              fontSize: 32,
              color: Colors.black87,
            ),
          ),
        ));
  }
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28

Row、Column 布局

在这里插入图片描述

实现 Select 组件

在这里插入图片描述

Select组件(lib/components/select_widget.dart)

import 'package:flutter/material.dart';

// 定义Option
class SelectOption {
  String label;
  Object value;

  SelectOption({required this.label, required this.value});
}

// Select组件
class SelectWidget extends StatefulWidget {
  final String title;
  late final List<SelectOption> options;
  final ValueChanged<SelectOption> onChange; // 监听选择

  SelectWidget({super.key, required this.title, required List<SelectOption> options, required this.onChange}) {
    this.options = options.isNotEmpty ? options : [SelectOption(label: '', value: '')];
  }

  
  State<SelectWidget> createState() => _SelectWidgetState();
}

class _SelectWidgetState extends State<SelectWidget> {
  int current = 0;

  
  Widget build(BuildContext context) {
    return Container(
      height: 50,
      padding: const EdgeInsets.only(top: 5, bottom: 5),
      decoration: BoxDecoration(color: Colors.cyan, border: Border.all(width: double.minPositive, color: Colors.black)),
      child: Column(
        mainAxisAlignment: MainAxisAlignment.center,
        children: [
          Text(widget.title, style: const TextStyle(color: Colors.white, fontSize: 12)),
          Row(
            mainAxisAlignment: MainAxisAlignment.spaceBetween,
            crossAxisAlignment: CrossAxisAlignment.center,
            children: [
              SizedBox(
                width: 24,
                height: 24,
                child: IconButton(
                  padding: const EdgeInsets.all(0),
                  color: Colors.white,
                  highlightColor: Colors.transparent,
                  splashColor: Colors.transparent,
                  icon: const Icon(Icons.arrow_left),
                  onPressed: _prev,
                ),
              ),
              Center(
                child: Text(
                  widget.options[current].label,
                  style: const TextStyle(color: Colors.yellow, fontSize: 12),
                ),
              ),
              SizedBox(
                width: 24,
                height: 24,
                child: IconButton(
                  padding: const EdgeInsets.all(0),
                  color: Colors.white,
                  highlightColor: Colors.transparent,
                  splashColor: Colors.transparent,
                  icon: const Icon(Icons.arrow_right),
                  onPressed: _next,
                ),
              ),
            ],
          ),
        ],
      ),
    );
  }

  // 上一个option
  _prev() {
    setState(() {
      if (current > 0) {
        current--;
      } else {
        current = widget.options.length - 1;
      }
      widget.onChange(widget.options[current]);
    });
  }

  // 下一个option
  _next() {
    setState(() {
      if (current < widget.options.length - 1) {
        current++;
      } else {
        current = 0;
      }
      widget.onChange(widget.options[current]);
    });
  }
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68
  • 69
  • 70
  • 71
  • 72
  • 73
  • 74
  • 75
  • 76
  • 77
  • 78
  • 79
  • 80
  • 81
  • 82
  • 83
  • 84
  • 85
  • 86
  • 87
  • 88
  • 89
  • 90
  • 91
  • 92
  • 93
  • 94
  • 95
  • 96
  • 97
  • 98
  • 99
  • 100
  • 101
  • 102

引用页面(lib/views/SelectPage.dart)

import 'package:flutter/material.dart';
import 'package:flutter_app/components/select_widget.dart';

class SelectPage extends StatefulWidget {
  const SelectPage({super.key});

  
  State<SelectPage> createState() => _SelectPage();
}

class _SelectPage extends State<SelectPage> {
  String text = '天津 - TianJin';
  List<SelectOption> addressList = [
    SelectOption(label: '天津', value: 'TianJin'),
    SelectOption(label: '北京', value: 'BeiJing'),
  ];

  
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(title: const Text('Select')),
      body: Column(
        children: [
          Container(
            margin: const EdgeInsets.all(10),
            height: 51,
            child: SelectWidget(
              title: '区域',
              options: addressList,
              onChange: (SelectOption option) {
                setState(() {
                  text = "${option.label} - ${option.value}";
                  print(text);
                });
              },
            ),
          ),
          Text(text)
        ],
      ),
    );
  }
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43

使用Select实现切换RowColumn属性

布局页面(lib/views/layout.dart)

import 'package:flutter/material.dart';

import '../components/select_widget.dart';

enum LayoutType { row, column }

enum ContentType { container, text }

class Layout extends StatefulWidget {
  const Layout({super.key});

  
  State<Layout> createState() => _Layout();
}

class _Layout extends State<Layout> {
  ContentType contentValue = ContentType.container;
  List<SelectOption> contentList = <SelectOption>[
    SelectOption(label: 'Container', value: ContentType.container),
    SelectOption(label: 'Text', value: ContentType.text),
  ];

  LayoutType layoutValue = LayoutType.row;
  List<SelectOption> layoutList = <SelectOption>[
    SelectOption(label: 'Row', value: LayoutType.row),
    SelectOption(label: 'Column', value: LayoutType.column),
  ];

  MainAxisAlignment mainAxisAlignmentValue = MainAxisAlignment.start;
  List<SelectOption> mainAxisAlignmentList = <SelectOption>[
    SelectOption(label: 'start', value: MainAxisAlignment.start),
    SelectOption(label: 'end', value: MainAxisAlignment.end),
    SelectOption(label: 'center', value: MainAxisAlignment.center),
    SelectOption(label: 'spaceBetween', value: MainAxisAlignment.spaceBetween),
    SelectOption(label: 'spaceEvenly', value: MainAxisAlignment.spaceEvenly),
    SelectOption(label: 'spaceAround', value: MainAxisAlignment.spaceAround),
  ];

  MainAxisSize mainAxisSizeValue = MainAxisSize.min;
  List<SelectOption> mainAxisSizeList = <SelectOption>[
    SelectOption(label: 'min', value: MainAxisSize.min),
    SelectOption(label: 'max', value: MainAxisSize.max),
  ];

  CrossAxisAlignment crossAxisAlignmentValue = CrossAxisAlignment.start;
  List<SelectOption> crossAxisAlignmentList = <SelectOption>[
    SelectOption(label: 'start', value: CrossAxisAlignment.start),
    SelectOption(label: 'end', value: CrossAxisAlignment.end),
    SelectOption(label: 'center', value: CrossAxisAlignment.center),
    SelectOption(label: 'stretch', value: CrossAxisAlignment.stretch),
    SelectOption(label: 'baseline', value: CrossAxisAlignment.baseline),
  ];

  TextDirection textDirectionValue = TextDirection.ltr;
  List<SelectOption> textDirectionList = <SelectOption>[
    SelectOption(label: 'ltr', value: TextDirection.ltr),
    SelectOption(label: 'rtl', value: TextDirection.rtl),
  ];

  VerticalDirection verticalDirectionValue = VerticalDirection.up;
  List<SelectOption> verticalDirectionList = <SelectOption>[
    SelectOption(label: 'up', value: VerticalDirection.up),
    SelectOption(label: 'down', value: VerticalDirection.down),
  ];

  TextBaseline textBaselineValue = TextBaseline.alphabetic;
  List<SelectOption> textBaselineList = <SelectOption>[
    SelectOption(label: 'alphabetic', value: TextBaseline.alphabetic),
    SelectOption(label: 'ideographic', value: TextBaseline.ideographic),
  ];

  
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: PreferredSize(
        preferredSize: const Size.fromHeight(150),
        child: Column(
          children: [
            // 属性
            Row(
              mainAxisAlignment: MainAxisAlignment.spaceBetween,
              children: [
                Expanded(
                  flex: 1,
                  child: SelectWidget(
                    title: 'ContentType',
                    options: contentList,
                    onChange: (SelectOption selectOption) {
                      setState(() {
                        contentValue = selectOption.value as ContentType;
                      });
                    },
                  ),
                ),
                Expanded(
                  flex: 1,
                  child: SelectWidget(
                    title: 'Layout',
                    options: layoutList,
                    onChange: (SelectOption selectOption) {
                      setState(() {
                        layoutValue = selectOption.value as LayoutType;
                      });
                    },
                  ),
                ),
              ],
            ),
            Row(
              mainAxisAlignment: MainAxisAlignment.spaceBetween,
              children: [
                Expanded(
                  flex: 1,
                  child: SelectWidget(
                    title: 'MainAxisAlignment',
                    options: mainAxisAlignmentList,
                    onChange: (SelectOption selectOption) {
                      setState(() {
                        mainAxisAlignmentValue = selectOption.value as MainAxisAlignment;
                      });
                    },
                  ),
                ),
                Expanded(
                  flex: 1,
                  child: SelectWidget(
                    title: 'MainAxisSize',
                    options: mainAxisSizeList,
                    onChange: (SelectOption selectOption) {
                      setState(() {
                        mainAxisSizeValue = selectOption.value as MainAxisSize;
                      });
                    },
                  ),
                ),
                Expanded(
                  flex: 1,
                  child: SelectWidget(
                    title: 'CrossAxisAlignment',
                    options: crossAxisAlignmentList,
                    onChange: (SelectOption selectOption) {
                      setState(() {
                        crossAxisAlignmentValue = selectOption.value as CrossAxisAlignment;
                      });
                    },
                  ),
                ),
              ],
            ),
            Row(
              mainAxisAlignment: MainAxisAlignment.spaceBetween,
              children: [
                Expanded(
                  flex: 1,
                  child: SelectWidget(
                    title: 'TextDirection',
                    options: textDirectionList,
                    onChange: (SelectOption selectOption) {
                      setState(() {
                        textDirectionValue = selectOption.value as TextDirection;
                      });
                    },
                  ),
                ),
                Expanded(
                  flex: 1,
                  child: SelectWidget(
                    title: 'VerticalDirection',
                    options: verticalDirectionList,
                    onChange: (SelectOption selectOption) {
                      setState(() {
                        verticalDirectionValue = selectOption.value as VerticalDirection;
                      });
                    },
                  ),
                ),
                Expanded(
                  flex: 1,
                  child: SelectWidget(
                    title: 'TextBaseline',
                    options: textBaselineList,
                    onChange: (SelectOption selectOption) {
                      setState(() {
                        textBaselineValue = selectOption.value as TextBaseline;
                      });
                    },
                  ),
                ),
              ],
            ),
          ],
        ),
      ),
      body: Container(
        margin: const EdgeInsets.all(20),
        decoration: BoxDecoration(color: Colors.black12, border: Border.all(width: 1, color: Colors.grey)),
        child: layoutValue == LayoutType.row
            ? Row(
                mainAxisAlignment: mainAxisAlignmentValue,
                mainAxisSize: mainAxisSizeValue,
                crossAxisAlignment: crossAxisAlignmentValue,
                textDirection: textDirectionValue,
                verticalDirection: verticalDirectionValue,
                textBaseline: textBaselineValue,
                children: contentValue == ContentType.container
                    ? [
                        Container(color: Colors.red, width: 100, height: 70),
                        Container(color: Colors.green, width: 60, height: 90),
                        Container(color: Colors.blue, width: 80, height: 50),
                      ]
                    : [
                        const Text('Red', style: TextStyle(fontSize: 20, backgroundColor: Colors.red)),
                        const Text('Green', style: TextStyle(fontSize: 50, backgroundColor: Colors.green)),
                        const Text('Blue', style: TextStyle(fontSize: 30, backgroundColor: Colors.blue)),
                      ],
              )
            : Column(
                mainAxisAlignment: mainAxisAlignmentValue,
                mainAxisSize: mainAxisSizeValue,
                crossAxisAlignment: crossAxisAlignmentValue,
                textDirection: textDirectionValue,
                verticalDirection: verticalDirectionValue,
                textBaseline: textBaselineValue,
                children: contentValue == ContentType.container
                    ? [
                        Container(color: Colors.red, width: 100, height: 70),
                        Container(color: Colors.green, width: 60, height: 90),
                        Container(color: Colors.blue, width: 80, height: 50),
                      ]
                    : [
                        const Text('Red', style: TextStyle(fontSize: 20, backgroundColor: Colors.red)),
                        const Text('Green', style: TextStyle(fontSize: 50, backgroundColor: Colors.green)),
                        const Text('Blue', style: TextStyle(fontSize: 30, backgroundColor: Colors.blue)),
                      ],
              ),
      ),
    );
  }
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68
  • 69
  • 70
  • 71
  • 72
  • 73
  • 74
  • 75
  • 76
  • 77
  • 78
  • 79
  • 80
  • 81
  • 82
  • 83
  • 84
  • 85
  • 86
  • 87
  • 88
  • 89
  • 90
  • 91
  • 92
  • 93
  • 94
  • 95
  • 96
  • 97
  • 98
  • 99
  • 100
  • 101
  • 102
  • 103
  • 104
  • 105
  • 106
  • 107
  • 108
  • 109
  • 110
  • 111
  • 112
  • 113
  • 114
  • 115
  • 116
  • 117
  • 118
  • 119
  • 120
  • 121
  • 122
  • 123
  • 124
  • 125
  • 126
  • 127
  • 128
  • 129
  • 130
  • 131
  • 132
  • 133
  • 134
  • 135
  • 136
  • 137
  • 138
  • 139
  • 140
  • 141
  • 142
  • 143
  • 144
  • 145
  • 146
  • 147
  • 148
  • 149
  • 150
  • 151
  • 152
  • 153
  • 154
  • 155
  • 156
  • 157
  • 158
  • 159
  • 160
  • 161
  • 162
  • 163
  • 164
  • 165
  • 166
  • 167
  • 168
  • 169
  • 170
  • 171
  • 172
  • 173
  • 174
  • 175
  • 176
  • 177
  • 178
  • 179
  • 180
  • 181
  • 182
  • 183
  • 184
  • 185
  • 186
  • 187
  • 188
  • 189
  • 190
  • 191
  • 192
  • 193
  • 194
  • 195
  • 196
  • 197
  • 198
  • 199
  • 200
  • 201
  • 202
  • 203
  • 204
  • 205
  • 206
  • 207
  • 208
  • 209
  • 210
  • 211
  • 212
  • 213
  • 214
  • 215
  • 216
  • 217
  • 218
  • 219
  • 220
  • 221
  • 222
  • 223
  • 224
  • 225
  • 226
  • 227
  • 228
  • 229
  • 230
  • 231
  • 232
  • 233
  • 234
  • 235
  • 236
  • 237
  • 238
  • 239

页面入口(lib/main.dart)

import 'package:flutter/material.dart';
import 'package:flutter_app/views/layout.dart';

void main() {
  runApp(const App());
}

class App extends StatefulWidget {
  const App({super.key});

  
  State<App> createState() => _AppState();
}

class _AppState extends State<App> {
  
  Widget build(BuildContext context) {
    return MaterialApp(
      home: Scaffold(
        appBar: AppBar(title: const Text('Row、Column 布局')),
        body: const Layout(),
      ),
    );
  }
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/你好赵伟/article/detail/143546
推荐阅读
相关标签
  

闽ICP备14008679号