You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Flutter:实现嵌套容器内子容器点击右侧展开的方法

Flutter 实现点击容器右侧展开效果

实现思路

  1. 用StatefulWidget维护当前选中的容器索引,初始设为-1(无选中状态)
  2. 给每个绿色容器绑定点击事件,点击时更新选中索引
  3. 构建容器时,根据是否为当前选中项,动态调整容器宽度(或切换展开/收起的布局结构)

完整代码示例

import 'package:flutter/material.dart';

void main() => runApp(const MyApp());

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

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: Scaffold(
        appBar: AppBar(title: const Text('点击展开容器')),
        body: const ExpandableContainerList(),
      ),
    );
  }
}

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

  @override
  State<ExpandableContainerList> createState() => _ExpandableContainerListState();
}

class _ExpandableContainerListState extends State<ExpandableContainerList> {
  // 记录当前选中的容器索引,-1表示未选中任何容器
  int _selectedIndex = -1;

  // 模拟5个容器的数据源
  final List<String> _items = List.generate(5, (index) => '容器 ${index + 1}');

  @override
  Widget build(BuildContext context) {
    return Container(
      color: const Color(0xFFE0E5EC), // 灰蓝色背景
      padding: const EdgeInsets.symmetric(vertical: 16, horizontal: 8),
      child: ListView.builder(
        itemCount: _items.length,
        itemBuilder: (context, index) {
          return GestureDetector(
            onTap: () {
              setState(() {
                // 点击切换选中状态:若当前是选中项则取消,否则设置为当前索引
                _selectedIndex = _selectedIndex == index ? -1 : index;
              });
            },
            child: AnimatedContainer(
              duration: const Duration(milliseconds: 300),
              margin: const EdgeInsets.only(bottom: 12),
              height: 80,
              // 根据选中状态动态设置宽度
              width: _selectedIndex == index 
                  ? MediaQuery.of(context).size.width * 0.9 // 展开宽度
                  : MediaQuery.of(context).size.width * 0.7, // 收起宽度
              decoration: BoxDecoration(
                color: Colors.green,
                borderRadius: BorderRadius.circular(8),
                boxShadow: const [
                  BoxShadow(
                    color: Colors.black12,
                    blurRadius: 4,
                    offset: Offset(2, 2),
                  )
                ],
              ),
              alignment: Alignment.center,
              child: Row(
                mainAxisAlignment: MainAxisAlignment.spaceBetween,
                children: [
                  Padding(
                    padding: const EdgeInsets.only(left: 16),
                    child: Text(
                      _items[index],
                      style: const TextStyle(color: Colors.white, fontSize: 18),
                    ),
                  ),
                  // 展开时显示额外元素(示例用箭头图标)
                  if (_selectedIndex == index)
                    const Padding(
                      padding: EdgeInsets.only(right: 16),
                      child: Icon(Icons.arrow_forward, color: Colors.white),
                    ),
                ],
              ),
            ),
          );
        },
      ),
    );
  }
}

关键细节说明

  • 状态管理:通过_selectedIndex控制容器的展开状态,点击时调用setState触发UI更新
  • 平滑过渡:使用AnimatedContainer替代普通Container,让宽度变化带有动画效果,提升交互体验
  • 动态布局:利用MediaQuery获取屏幕宽度,根据选中状态设置不同的容器宽度,实现右侧展开的视觉效果
  • 扩展能力:如果需要展开后显示更多内容,可将容器的子组件替换为包含展开内容的布局,配合AnimatedSwitcher实现内容切换动画

内容的提问来源于stack exchange,提问作者Vaishnav k

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.25 01:05:10