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

Flutter实现类似底部导航的自定义侧边抽屉及CustomPainter学习资源咨询

Flutter自定义侧边导航抽屉实现方案及CustomPainter学习指南

现有代码问题分析

  • 路径仅实现了单处内凹效果,未适配多导航项对应的多内凹场景
  • 硬编码的尺寸比例适配性差,不同屏幕尺寸、导航项高度下容易出现视图变形
  • 未开放选中导航位的参数传递,无法实现导航切换时的视图同步更新

修正实现思路

  • 首先在CustomPainter构造函数中传入可配置参数:导航项总高度、当前选中的导航下标、内凹曲线的曲率参数,避免硬编码数值
  • 绘制路径时,先绘制抽屉主体矩形,再根据当前选中的导航下标计算对应位置的坐标,动态插入贝塞尔曲线生成对应位置的内凹效果
  • shouldRepaint方法优化为仅当选中下标、尺寸参数变化时才返回true,减少不必要的重绘开销

CustomPainter学习路径

基础阶段

  • 熟练掌握Canvas核心绘制API,包括drawPath、drawLine、drawRect、drawCircle等常用绘制方法,以及Paint类的颜色、填充样式、抗锯齿、 strokeWidth等属性配置
  • 吃透Path的核心操作:moveTo、lineTo、quadraticBezierTo(二阶贝塞尔曲线)、cubicTo(三阶贝塞尔曲线)的参数含义,可通过绘制简单图标、波浪线、圆角图形来练习
  • 理解CustomPainter的生命周期,清楚paint方法触发时机、Size参数的含义

进阶阶段

  • 学习PathMetric(路径测量)的使用,可用来获取路径上任意点的坐标、实现路径绘制动画等效果
  • 结合Animation实现绘制动效,比如本场景下导航切换时,内凹位置平滑平移的过渡效果
  • 掌握CustomPainter的性能优化方案,比如减少paint方法内的对象创建、合理控制shouldRepaint的返回值、使用RepaintBoundary隔离重绘区域等

优化后的代码示例

class MyCustomPainter extends CustomPainter {
  // 选中的导航项下标
  final int selectedIndex;
  // 每个导航项的高度
  final double itemHeight;
  // 内凹曲率系数
  final double curveFactor;
  // 顶部预留区域高度(比如用户头像信息区域)
  final double topPadding;

  MyCustomPainter({
    required this.selectedIndex,
    required this.itemHeight,
    this.curveFactor = 20,
    this.topPadding = 80,
  });

  @override
  void paint(Canvas canvas, Size size) {
    final paint = Paint()
      ..color = const Color.fromARGB(255, 33, 150, 243)
      ..style = PaintingStyle.fill
      ..isAntiAlias = true;

    final path = Path();
    // 起点:左上角
    path.moveTo(0, 0);
    // 顶部直线到右上角
    path.lineTo(size.width, 0);
    // 计算选中项对应的Y轴坐标
    final selectedCenterY = topPadding + selectedIndex * itemHeight + itemHeight / 2;
    // 右上角直线到内凹上方控制点
    path.lineTo(size.width, selectedCenterY - curveFactor);
    // 绘制二阶贝塞尔曲线实现内凹效果
    path.quadraticBezierTo(
      size.width - curveFactor,
      selectedCenterY,
      size.width,
      selectedCenterY + curveFactor,
    );
    // 内凹下方直线到右下角
    path.lineTo(size.width, size.height);
    // 右下角直线到左下角
    path.lineTo(0, size.height);
    path.close();

    canvas.drawPath(path, paint);
  }

  @override
  bool shouldRepaint(covariant MyCustomPainter oldDelegate) {
    // 仅当配置参数变化时才触发重绘
    return oldDelegate.selectedIndex != selectedIndex ||
        oldDelegate.itemHeight != itemHeight ||
        oldDelegate.curveFactor != curveFactor ||
        oldDelegate.topPadding != topPadding;
  }
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.28 07:54:07