求助:Flutter实现两个Container拖拽中间区域自动调整大小的方法
Flutter实现拖拽调整两个Row容器的宽度
你可以通过StatefulWidget配合GestureDetector实现拖拽调整宽度的功能,核心是维护两个容器的宽度状态,拖拽时实时更新并保证总宽度不变。以下是完整实现代码:
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( body: const ResizableRow(), ), ); } } class ResizableRow extends StatefulWidget { const ResizableRow({super.key}); @override State<ResizableRow> createState() => _ResizableRowState(); } class _ResizableRowState extends State<ResizableRow> { late double _leftWidth; late double _screenWidth; // 限制最小宽度,防止容器被拖到消失 final double _minWidth = 50; @override void initState() { super.initState(); _screenWidth = WidgetsBinding.instance.window.physicalSize.width / WidgetsBinding.instance.window.devicePixelRatio; _leftWidth = _screenWidth * 0.5; } @override Widget build(BuildContext context) { return Row( children: [ // 左侧容器 Container( color: Colors.red, width: _leftWidth, height: double.infinity, ), // 拖拽手柄 GestureDetector( onPanUpdate: (details) { setState(() { // 计算新的左侧宽度,叠加拖拽水平偏移量 double newLeftWidth = _leftWidth + details.delta.dx; // 限制宽度范围,避免容器消失 _leftWidth = newLeftWidth.clamp(_minWidth, _screenWidth - _minWidth); }); }, child: Container( width: 5, height: double.infinity, color: Colors.grey[700], child: const Center( child: Icon(Icons.drag_indicator, color: Colors.white), ), ), ), // 右侧容器,自动占满剩余空间 Expanded( child: Container( color: Colors.blue, height: double.infinity, ), ) ], ); } }
关键实现说明:
- 状态维护:用
_leftWidth保存左侧容器宽度,右侧容器通过Expanded自动填充剩余空间 - 拖拽逻辑:通过
GestureDetector的onPanUpdate监听拖拽动作,利用details.delta.dx获取水平偏移量,实时更新左侧宽度 - 边界控制:用
clamp方法限制宽度范围,确保容器不会被拖到完全消失 - 交互优化:中间添加带图标的灰色窄容器作为拖拽手柄,明确提示可交互区域
效果示意图:
内容的提问来源于stack exchange,提问作者cheetahbyte
相关产品推荐
相关产品推荐

