给Flutter PopupMenuButton添加箭头和阴影颜色

2,508 阅读1分钟

一、原始的PopupMenuButton无箭头,且无法修改阴影颜色, 阴影只能通过elevation去设置

       PopupMenuButton(
        offset: Offset(0,60),
         color: Colors.white,
        shape: RoundedRectangleBorder(
          borderRadius: BorderRadius.circular(20.sp),
        ),
        elevation: 2,
        child: Container(
          padding: EdgeInsets.all(32.sp),
          child: Image.asset(Assets.title_more,width: 56.sp,height: 56.sp,),
        ),
        itemBuilder: (BuildContext context){
          return [            PopupMenuItem(              child: Container(                child: Text("删除"),              ),            ),            PopupMenuItem(              child: Container(                child: Text("删除"),              ),            )          ];
        },
      )
      
 

image.png

二、如果需要自定义阴影颜色和增加箭头

需要修改RoundedRectangleBorder里面的代码

方法:

1、将RoundedRectangleBorder的代码copy一份放到本地,修改RoundedRectangleBorder类名为CustomRoundedRectangleBorder,然后修改paint里面的代码

  @override
  void paint(Canvas canvas, Rect rect, { TextDirection textDirection }) {
  ///假如外面的side不写,这里就不会走下面的paint代码了
    switch (side.style) {
      case BorderStyle.none:
        break;
      case BorderStyle.solid:
        final double width = side.width;
        final RRect outer = borderRadius.resolve(textDirection).toRRect(rect);
        final RRect inner = outer.deflate(width);
        final Paint paint = Paint()
          ..color = side.color;
        ///画阴影
        canvas.drawRRect(outer,
            Paint()..color = GsColors.blueShadow.withOpacity(0.3)
              ..isAntiAlias = true
              ..strokeCap = StrokeCap.round..maskFilter = MaskFilter.blur(BlurStyle.outer, 2.0));
        ///画箭头(这里箭头的位置根据自己需求定,具体图形可以自己定)
        Path path = Path();
        path
          ..moveTo(75,5)
          ..lineTo(88, -7)
          ..lineTo(90, -8)
          ..lineTo(92, -7)
          ..lineTo(105, 5)
          ..close();
        canvas.drawPath(path, paint);
    }
  }

2、将原始的PopupMenuButton里面的elevation设置为0,然后shape使用CustomRoundedRectangleBorder,并在里面设置圆角及style(因为CustomRoundedRectangleBorder里面有用style里面属性做判断,所以根据自己需求去添加)

       PopupMenuButton(
        offset: Offset(0,60),
         color: Colors.white,
        shape: CustomRoundedRectangleBorder(
          borderRadius: BorderRadius.circular(20.sp),
          ///BorderSide里面的属性在CustomRoundedRectangleBorder里面有判断,如果后者在代码里面写死,那么这里就可以不要
          side: BorderSide(
            width: 2,
            color: Colors.white,
            style: BorderStyle.solid,
          ),
        ),
        elevation: 0,
        child: Container(
          padding: EdgeInsets.all(32.sp),
          child: Image.asset(Assets.title_more,width: 56.sp,height: 56.sp,),
        ),
        itemBuilder: (BuildContext context){
          return [            PopupMenuItem(              child: Container(                child: Text("删除"),              ),            ),            PopupMenuItem(              child: Container(                child: Text("删除"),              ),            )          ];
        },
      )

最终效果图

image.png