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 响应式布局的核心组件之一,合理使用可以让你的界面在不同屏幕尺寸上都能良好适配。

相关推荐
叶羽西10 分钟前
Android15 EVS HAL中使用Camera HAL Provider接口
android
2501_9159184117 分钟前
除了 Perfdog,如何在 Windows 环境中完成 iOS App 的性能测试工作
android·ios·小程序·https·uni-app·iphone·webview
泓博21 分钟前
Android状态栏文字图标设置失效
android·composer
行者9626 分钟前
Flutter跨平台开发:安全检测组件适配OpenHarmony
flutter·harmonyos·鸿蒙
小雨下雨的雨1 小时前
Flutter 框架跨平台鸿蒙开发 —— GridView 控件之多维网格美学
flutter·华为·交互·harmonyos·鸿蒙系统
叶羽西1 小时前
Android15系统中(娱乐框架和车机框架)中对摄像头的朝向是怎么定义的
android
七月巫山晴1 小时前
【iOS】NSString&NSRange&NSCharacterSet
ios·cocoa·iphone
cn_mengbei1 小时前
Flutter for OpenHarmony 实战:ElevatedButton 悬浮按钮详解
flutter
h-189-53-6712071 小时前
2026(原创)Guideline 4.3(a) - Design - Spam苹果上架iOS审核被拒AppStore卡审解决办法思路
ios
Java小白中的菜鸟1 小时前
安卓studio链接夜神模拟器的一些问题
android