Flutter Flexible

在 Flutter 中,Flexible 是一个重要的布局组件,用于在 RowColumnFlex 中创建灵活的布局。让我详细解释它的用法:

基本概念

Flexible 可以让子组件在主轴方向上灵活伸缩 ,与其他 FlexibleExpanded 组件共享可用空间。

主要属性

1. flex(弹性系数)

dart

复制代码
Flexible(
  flex: 2,  // 权重,默认值为1
  child: Container(color: Colors.red),
)

2. fit(填充方式)

dart

复制代码
Flexible(
  fit: FlexFit.tight,  // 强制填满分配的空间
  child: Container(color: Colors.blue),
)

Flexible(
  fit: FlexFit.loose,  // 可以小于分配的空间(默认值)
  child: Container(width: 50), // 只占用50宽度
)

与 Expanded 的区别

dart

复制代码
// Expanded 实际上是 Flexible 的快捷方式:
Expanded = Flexible(fit: FlexFit.tight)

// 区别:
// - Expanded: 必须填满分配的空间
// - Flexible: 可以填满,也可以不填满(取决于 fit 参数)

实用示例

示例1:基本使用

dart

复制代码
Row(
  children: [
    Flexible(
      flex: 1,
      child: Container(color: Colors.red, height: 100),
    ),
    Flexible(
      flex: 2,
      child: Container(color: Colors.green, height: 100),
    ),
    Flexible(
      flex: 1,
      child: Container(color: Colors.blue, height: 100),
    ),
  ],
)
// 比例:红:绿:蓝 = 1:2:1

示例2:响应式布局

dart

复制代码
Row(
  children: [
    // 固定宽度部分
    Container(
      width: 80,
      color: Colors.grey,
      child: Icon(Icons.menu),
    ),
    
    // 自适应部分
    Flexible(
      child: Container(
        color: Colors.blue,
        child: TextField(
          decoration: InputDecoration(hintText: '搜索...'),
        ),
      ),
    ),
    
    // 另一个固定部分
    Container(
      width: 60,
      color: Colors.grey,
      child: Icon(Icons.search),
    ),
  ],
)

示例3:Column 中的使用

dart

复制代码
Column(
  children: [
    Container(
      height: 100,
      color: Colors.red,
      child: Center(child: Text('固定高度')),
    ),
    
    Flexible(  // 占据剩余空间
      child: Container(
        color: Colors.green,
        child: ListView(
          children: [
            ListTile(title: Text('项目1')),
            ListTile(title: Text('项目2')),
            // ...更多列表项
          ],
        ),
      ),
    ),
    
    Container(
      height: 60,
      color: Colors.blue,
      child: Center(child: Text('底部栏')),
    ),
  ],
)

示例4:嵌套 Flexible

dart

复制代码
Column(
  children: [
    Flexible(
      flex: 2,
      child: Row(
        children: [
          Flexible(
            flex: 1,
            child: Container(color: Colors.red),
          ),
          Flexible(
            flex: 3,
            child: Container(color: Colors.green),
          ),
        ],
      ),
    ),
    Flexible(
      flex: 1,
      child: Container(color: Colors.blue),
    ),
  ],
)

常见使用场景

场景1:三栏布局

dart

复制代码
Row(
  children: [
    Flexible(flex: 1, child: Sidebar()),
    Flexible(flex: 3, child: MainContent()),
    Flexible(flex: 1, child: RightPanel()),
  ],
)

场景2:带图标的输入框

dart

复制代码
Container(
  padding: EdgeInsets.symmetric(horizontal: 16),
  child: Row(
    children: [
      Icon(Icons.search),
      SizedBox(width: 8),
      Flexible(  // 输入框自适应
        child: TextField(
          decoration: InputDecoration(
            hintText: '请输入内容',
            border: InputBorder.none,
          ),
        ),
      ),
      Icon(Icons.mic),
    ],
  ),
)

场景3:聊天界面

dart

复制代码
Column(
  children: [
    Flexible(  // 消息列表自适应
      child: ListView.builder(
        itemCount: messages.length,
        itemBuilder: (context, index) => MessageItem(messages[index]),
      ),
    ),
    Container(  // 固定高度的输入框
      padding: EdgeInsets.all(8),
      child: Row(
        children: [
          Flexible(
            child: TextField(
              decoration: InputDecoration(
                hintText: '输入消息...',
                border: OutlineInputBorder(),
              ),
            ),
          ),
          IconButton(
            icon: Icon(Icons.send),
            onPressed: () {},
          ),
        ],
      ),
    ),
  ],
)

注意事项

  1. 父容器需要有限制Flexible 的父组件(Row/Column/Flex)必须有有限的主轴尺寸

  2. 正确使用 fit

    dart

    复制代码
    // ❌ 可能不会按预期工作
    Flexible(
      fit: FlexFit.loose,
      child: Container(), // 空容器,可能不显示
    )
    
    // ✅ 明确指定尺寸或使用 tight
    Flexible(
      fit: FlexFit.tight,
      child: Container(color: Colors.red),
    )
  3. 与 SizedBox.expand 结合

    dart

    复制代码
    Flexible(
      child: SizedBox.expand(  // 强制填满父容器
        child: Container(color: Colors.red),
      ),
    )
  4. 性能考虑 :过度使用 Flexible 可能影响性能,特别是在列表中使用时

最佳实践

dart

复制代码
// 推荐:使用 Expanded 当需要填满空间时
Row(
  children: [
    Expanded(child: Content()),  // 更简洁
  ],
)

// 推荐:使用 Flexible 当需要 loose 模式时
Row(
  children: [
    Flexible(
      fit: FlexFit.loose,
      child: Container(width: 100), // 保持原有宽度
    ),
  ],
)

Flexible 是 Flutter 响应式布局的核心组件之一,合理使用可以让你的界面在不同屏幕尺寸上都能良好适配。

相关推荐
2501_915106321 小时前
iOS App 测试方法,通过 Xcode、Instruments、Safari Inspector、克魔(KeyMob)等工具
android·ios·小程序·uni-app·iphone·xcode·safari
游戏开发爱好者81 小时前
对 iOS IPA 文件进行深度混淆的一种实现路径
android·ios·小程序·https·uni-app·iphone·webview
坚果派·白晓明1 小时前
Windows 11 OpenHarmony 版 Flutter 开发环境搭建完整指南
windows·flutter·开源鸿蒙·鸿蒙跨平台应用
成都大菠萝1 小时前
2-2-5 快速掌握Kotlin-语言的泛型函数
android
成都大菠萝1 小时前
2-2-4 快速掌握Kotlin-定义泛型类
android
掘我的金1 小时前
加载状态优化实践:如何让用户始终知道当前状态
android
JZXStudio1 小时前
Swift 6 + MLX + SwiftUI:三位一体本地AI架构蓝图
前端·ios
成都大菠萝1 小时前
2-2-6 快速掌握Kotlin-语言的多泛型参数学习
android
音浪豆豆_Rachel1 小时前
Flutter跨平台通信的实战演练:复杂数据结构与单元测试在鸿蒙生态中的完美实现
数据结构·flutter·单元测试·harmonyos
掘我的金1 小时前
空状态优化实践:如何让"白屏"变成友好的提示
android