Flutter垂直的分割线,调整两边的子组件的宽度

本文介绍了如何在Flutter中使用Row组件和相关组件(Expanded、VerticalDivider、GestureDetector等)创建一个可响应拖拽操作的布局,通过StatefulBuilder实现在用户拖动时动态调整左右组件的宽度。
摘要由CSDN通过智能技术生成

使用 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')),
                    ),
                  ),
                ],
              );
            },
          ),
        ),
      ),
    );
  }
}

拖动后效果

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值