使用 Row 组件,它可以让你在水平方向上排列多个子组件。
给 Row 组件传入三个子组件,分别是左边的组件,中间的分割线,和右边的组件。
使用 Expanded 组件来包裹左右两边的组件,让它们可以占据剩余的空间。使用 VerticalDivider 组件来作为分割线,它可以显示一个垂直的线条。如下:
import 'package:flutter/material.dart';
void main() {
runApp(MyApp());
}
class MyApp extends StatelessWidget {
// 定义一个变量来存储左边的组件的宽度
double leftWidth = 100;
@override
Widget build(BuildContext context) {
return MaterialApp(
home: Scaffold(
body: Row(
children: [
Expanded(
child: Container(
color: Colors.blue,
child: Center(child: Text('Left')),
),
),
VerticalDivider(
width: 16,
thickness: 4,
color: Colors.black,
),
Expanded(
child: Container(
color: Colors.red,
child: Center(child: Text('Right')),
),
),
],
),
),
);
}
}
效果如图:
这样的布局还不能实现拖拽的功能,需要给分割线添加一个手势识别器,让它可以响应用户的拖拽操作,并且改变左右两边的组件的宽度。
我们需要做一下改变
- 使用 GestureDetector 组件,它可以让你监听用户的各种手势操作。
- 给 GestureDetector 组件传入一个 onHorizontalDragUpdate 属性,它是一个函数,接受一个 DragUpdateDetails 参数,返回一个 void。
- 通过 DragUpdateDetails 参数来获取用户的拖拽的距离和速度,然后根据这些值来调整左右两边的组件的宽度。
- 为了调整宽度,你需要使用一个 StatefulBuilder 组件,它可以让你在一个无状态的组件中更新状态。
- 使用一个变量来存储左边的组件的宽度,然后在拖拽时更新这个变量,并且调用 setState 方法来重绘组件。
修改后代码如下:
import 'package:flutter/material.dart';
void main() {
runApp(MyApp());
}
class MyApp extends StatelessWidget {
// 定义一个变量来存储左边的组件的宽度
double leftWidth = 100;
@override
Widget build(BuildContext context) {
return MaterialApp(
home: Scaffold(
body: Center(
child: StatefulBuilder(
builder: (context, setState) {
return Row(
children: [
// 使用 SizedBox 组件来指定左边的组件的宽度
SizedBox(
width: leftWidth,
child: Container(
color: Colors.blue,
child: Center(child: Text('Left')),
),
),
// 使用 GestureDetector 组件来包裹分割线
GestureDetector(
// 监听水平方向的拖拽操作
onHorizontalDragUpdate: (details) {
// 获取拖拽的距离
double delta = details.delta.dx;
// 更新左边的组件的宽度
leftWidth += delta;
// 限制左边的组件的宽度在 0 到屏幕宽度之间
leftWidth = leftWidth.clamp(0.0, MediaQuery.of(context).size.width);
// 重绘组件
setState(() {});
},
child: VerticalDivider(
width: 16,
thickness: 4,
color: Colors.black,
),
),
// 使用 Expanded 组件来包裹右边的组件
Expanded(
child: Container(
color: Colors.red,
child: Center(child: Text('Right')),
),
),
],
);
},
),
),
),
);
}
}
拖动后效果