【Flutter&Dart】 拖动边界线改变列宽并且有边界高亮和鼠标效果(12 /100)

【Flutter&Dart】 拖动改变 widget 的窗口尺寸大小GestureDetector~简单实现(10 /100)
【Flutter&Dart】 拖动边界线改变列宽类似 vscode 那种拖动改变编辑框窗口大小(11 /100)

上效果

对比一下vscode的效果:

基本达到交互效果了,就是丝滑度好像差一点点。这个有可能是相关参数没有调试好。后期看看能否改进改进

上代码

dart 复制代码
import 'dart:async';

import 'package:flutter/material.dart';
import 'package:logging/logging.dart';

const String tag = 'MyDraggableViewDemo2';

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

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: Scaffold(
        appBar: AppBar(
          title: Text('MyDraggableViewDemo2'),
        ),
        body: DraggableDemo(),
      ),
    );
  }
}

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

  @override
  State<StatefulWidget> createState() {
    return _DraggableDemoState();
  }
}

class _DraggableDemoState extends State<DraggableDemo> {
  double leftWidth = 100.0;
  double height = 200.0;
  bool isResizing = false;
  Timer? _timer;
  bool _isHovered = false;
  void _startTimer() {
    Logger(tag).info('_startTimer called!');
    _timer?.cancel();
    _timer = Timer(const Duration(seconds: 1), () {
      setState(() {
        _isHovered = true;
        Logger(tag).info('Mouse hovered for 2 second!');
      });
    });
  }

  void _cancelTimer() {
    Logger(tag).info('_cancelTimer called!');
    if (isResizing) {
      return;
    }
    _timer?.cancel();
    setState(() {
      _isHovered = false;
    });
  }

  @override
  Widget build(BuildContext context) {
    return Row(children: [
      // 使用 SizedBox 组件来指定左边的组件的宽度
      SizedBox(
        width: leftWidth,
        child: Container(
          color: Colors.blue,
          child: Center(child: Text('左侧菜单')),
        ),
      ),
      // 检测鼠标进入和离开事件
      MouseRegion(
        cursor: SystemMouseCursors.resizeLeftRight, // 设置鼠标形状为剪头
        onEnter: (event) {
          Logger(tag).info('onEnter called!');
          _startTimer();
        },
        onExit: (event) {
          Logger(tag).info('onExit called!');
          _cancelTimer();
        },
        child: // 使用 GestureDetector 组件来包裹分割线
            GestureDetector(
          onHorizontalDragStart: (details) => {
            setState(() {
              isResizing = true;
            })
          },
          // 监听水平方向的拖拽操作
          onHorizontalDragUpdate: (details) {
            // 获取拖拽的距离
            double delta = details.delta.dx;
            // 更新左边的组件的宽度
            leftWidth += delta;
            // 限制左边的组件的宽度在 0 到屏幕宽度之间
            leftWidth = leftWidth.clamp(0.0, MediaQuery.of(context).size.width);
            // 重绘组件
            setState(() {});
          },
          onHorizontalDragCancel: () => {
            setState(() {
              isResizing = false;
            })
          },
          onHorizontalDragEnd: (details) => {
            Logger(tag).info('onHorizontalDragEnd called!'),
            setState(() {
              isResizing = false;
            })
          },
          child: VerticalDivider(
            width: _isHovered ? 3 : 2,
            thickness: _isHovered ? 3 : 2,
            color: Colors.grey[_isHovered ? 100 : 700],
          ),
        ),
      ),
// 使用 Expanded 组件来包裹右边的组件
      Expanded(
        child: Container(
          color: Colors.red,
          child: Center(child: Text('右侧工作区')),
        ),
      ),
    ]);
  }
}

效果已经完成,也没啥好说的了,晚安

=========END

相关推荐
孤鸿玉1 小时前
[Flutter小技巧] Row中widget高度自适应的几种方法
flutter
szhangbiao1 小时前
“开发板”类APP如果做屏幕适配
android
bawomingtian1231 小时前
FlutterView 源码解析
flutter
高林雨露2 小时前
RecyclerView中跳转到最后一条item并确保它在可视区域内显示
android
移动开发者1号4 小时前
ReLinker优化So库加载指南
android·kotlin
山野万里__4 小时前
C++与Java内存共享技术:跨平台与跨语言实现指南
android·java·c++·笔记
Huckings4 小时前
Android 性能问题
android
移动开发者1号5 小时前
剖析 Systrace:定位 UI 线程阻塞的终极指南
android·kotlin
移动开发者1号5 小时前
深入解析内存抖动:定位与修复实战(Kotlin版)
android·kotlin
whysqwhw5 小时前
OkHttp深度架构缺陷分析与革命性演进方案
android