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'),
        ),
      ),
    );
  }
}

非 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,
            ),
          ),
        ));
  }
}

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]);
    });
  }
}

引用页面(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)
        ],
      ),
    );
  }
}

使用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)),
                      ],
              ),
      ),
    );
  }
}

页面入口(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(),
      ),
    );
  }
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/411401.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

《名作欣赏》期刊投稿方向投稿邮箱

《名作欣赏》杂志是由国家新闻出版总署批准的正规学术期刊。文学是用语言塑造形象反映社会生活的一种语言艺术&#xff0c;是自觉、独立而又面向整个社会的艺术&#xff0c;是文化中极具强烈感染力的重要组成部分&#xff0c;亦是对美的体现。在现代社会&#xff0c;物欲横流&a…

用matlab实现交通分布预测方法——增长系数法

前言 对于我的第一篇文章&#xff1a;Matlab实现交通分布预测方法 —— 增长系数法 | 平均增长率法、底特律法、福莱特法&#xff0c;有不少同学私信我询问关于如何在 matlab 中调用函数、拆分代码以及需要大量调用的问题。于是我便想着把内容做一些优化&#xff0c;放在这篇文…

【MySQL】MySQL从0到0.9 - 持续更新ing

MySQL SQL 基础 DDL 语句 show databases; show tables; desc table_name; # 获取表信息 show create table 表名; // 查询指定表的建表语句 数据类型 char(10) 不满10个会用空格填充&#xff0c;性能好一点 varchar(10) 变长字符串&#xff0c;性能差一点 CREATE TABLE tabl…

nginx设置缓存时间

一、设置缓存时间 当网页数据返回给客户端后&#xff0c;可针对静态网页设置缓存时间&#xff0c;在配置文件内的http段内server段添加location&#xff0c;更改字段expires 1d来实现&#xff1a;避免重复请求&#xff0c;加快访问速度 第一步&#xff1a;修改主配置文件 #修…

[NOIP2011 普及组] 数字反转

AC代码&#xff1a; #include<iostream>using namespace std;int main() {long long n;cin >> n;long long temp n;long long sum 0;while(temp ! 0){int c temp % 10;sum sum * 10 c;temp temp / 10;}printf("%lld",sum);return 0; }

Spring 中 ApplicationContext 和 BeanFactory 的区别有哪些

先看一张类图&#xff1a; 区别&#xff1a; 1&#xff1a;包目录不同&#xff1a; spring-beans.jar 中 org.springframework.beans.factory.BeanFactory spring-context.jar 中 org.springframework.context.ApplicationContext 2&#xff1a;国际化&#xff1a; BeanFacto…

APP被针对攻击了,要怎么解决

随着APP行业的兴起&#xff0c;游戏公司异军突起&#xff0c;不管是在控证还是攻击方面都是属于最复杂的一个场面&#xff0c;游戏APP逐渐成为DDOS流量攻击的“重灾区”。没有提前做好了解就盲目进军游戏APP行业&#xff0c;一旦被攻击就会让公司束手无策。那么&#xff0c;刚上…

Python从入门到精通指南【第101篇—入门到精通】【文末送书-24】

文章目录 Python从入门到精通指南第一步&#xff1a;入门基础1.1 安装Python1.2 Hello World1.3 变量和数据类型1.4 控制流程 第二步&#xff1a;深入学习2.1 函数和模块2.2 列表、元组和字典2.3 文件操作 第三步&#xff1a;高级主题3.1 面向对象编程3.2 异常处理3.3 正则表达…

python_pyecharts绘制漏斗图

python-pyecharts绘制漏斗图 from pyecharts.charts import Funnel from pyecharts import options as opts# 数据 data [("访问", 100), ("咨询", 80), ("订单", 60), ("点击", 40), ("展现", 20)]# 创建漏斗图 funnel …

Qt OpenGL程序在Windows下正常,但在Linux下无显示问题【已解决】

Qt OpenGL程序在Windows下正常&#xff0c;但在Linux下无显示问题【已解决】 引言一、问题描述二、解决方案三、解决过程记录3.1 定位问题3.2 解决问题&#xff0c;深入分析 引言 在Windows上正常运行的OpenGL程序&#xff0c;到Linux下正常编译…但是没有任何显示(只有背景颜…

【数据结构与算法】动态规划法解题20240227

动态规划法 一、什么是动态规划二、动态规划的解题步骤三、509. 斐波那契数1、动规五部曲&#xff1a; 四、70. 爬楼梯1、动规五部曲&#xff1a; 五、746. 使用最小花费爬楼梯1、动规五部曲&#xff1a; 一、什么是动态规划 动态规划&#xff0c;英文&#xff1a;Dynamic Pro…

23年中科院1区算法|长鼻浣熊优化算法COA原理及其利用与改进(Matlab/Python)

文章来源于我的个人公众号&#xff1a;KAU的云实验台&#xff0c;主要更新智能优化算法的原理、应用、改进 CEC2005中的测试 本文 KAU将介绍一个2023年1月发表在中科院1区KBS上的优化算法——长鼻浣熊优化算法(Coati Optimization Algorithm&#xff0c;COA)[1] 该算法由Dehg…

SpringBoot源码解读与原理分析(三十四)SpringBoot整合JDBC(三)声明式事务的传播行为控制

文章目录 前言10.5 声明式事务的传播行为控制10.5.1 修改测试代码&#xff08;1&#xff09;新建一个Service类&#xff0c;并引用UserService&#xff08;2&#xff09;修改主启动类 10.5.2 PROPAGATION_REQUIRED10.5.2.1 tm.getTransaction&#xff08;1&#xff09;获取事务…

IO进程线程作业day7

信号灯集共享内存 自定义头文件 #ifndef SEM_H_ #define SEM_H_ //创建信号灯集, int creat_t(int number); //申请释放资源 int P(int semid,int semno); //申请释放资源 int V(int semid,int semno); //删除信号灯集 int del(int semid); #endif信号灯集函数集合 #include…

物资管理新篇章:Java+SpringBoot实战

✍✍计算机编程指导师 ⭐⭐个人介绍&#xff1a;自己非常喜欢研究技术问题&#xff01;专业做Java、Python、微信小程序、安卓、大数据、爬虫、Golang、大屏等实战项目。 ⛽⛽实战项目&#xff1a;有源码或者技术上的问题欢迎在评论区一起讨论交流&#xff01; ⚡⚡ Java实战 |…

基于 ResNet50和 SVM + 决策树的人脸口罩检测

欢迎收看&#xff0c;这篇文章是关于我如何使用 ResNet50作为特征提取器来构建掩码检测&#xff0c;然后使用支持向量机(SVM) 决策树和叠加集成方法作为分类器的一个快速解释。 为了向研究人员致敬&#xff0c;这个应用程序是基于研究论文&#xff0c;题目是“在2019冠状病毒…

分布式应用:kylin 部署 zabbix 监控平台

目录 一、实验 1.环境 2. kylin 修改mysql数据库 3. kylin 部署 zabbix 监控平台 4. kylin 修改 zabbix 配置 5. kylin 修改zabbix web 二、问题 1. zabbix_server 查看版本报错 2.zabbix_server 文件如何去掉注释"#"和空行 3. zabbix图表显示异常 4.zabbi…

前端常见面试题之vue3

文章目录 1. vue3比vue2有哪些优势2. 描述vue3的生命周期3. 如何看待vue3中的Composition API 和 Options API4. 如何理解ref、 toRef、和toRefs?5. vue3升级了哪些功能6. Composition API如何实现代码逻辑的复用&#xff08;hook)7. Vue3如何实现响应式的8.Vue3使用Proxy对象…

2-22 方法、面向对象、类、JVM内存、构造方法

文章目录 方法的重载面向对象类、属性和方法成员变量默认值属性JVM简单内存分析栈空间堆空间 构造方法执行过程构造器注意点 方法的重载 一个类中名称相同&#xff0c;但是参数列表不同的方法 参数列表不同是指&#xff1a; 形参类型形参个数形参顺序 面向对象 field —— …

linux系统---防火墙拓展

目录 一、iptables 1.基本语法 2.四表五链——重点记忆 2.1四表 2.2五链 2.3总结 3.iptables选项示例 3.1 -Z 清空流量计数 3.2 -P 修改默认规则 3.3 -D 删除规则 3.4 -R 指定编号替换规则 4.白名单 5.通用匹配 6.示例 6.1添加回环网卡 6.2可以访问端口 6.3 主…