最新公告
  • 欢迎您光临起源地模板网,本站秉承服务宗旨 履行“站长”责任,销售只是起点 服务永无止境!立即加入钻石VIP
  • Flutter仿微信的下拉弹框

    正文概述 掘金(xiangzhihong)   2021-02-28   687

    在移动开发中,下拉弹框是一种很常见的选择交互方式,效果如下图所示。 Flutter仿微信的下拉弹框 对于这种弹框,我们可以使用Dialog来实现,下面是自定义弹框的主要代码。

    Color _bgColor = Colors.white;
    double cellHeight = 34;
    double cellWidth=120;
    
    typedef ClickCallBack = void Function(int selectIndex, String selectText);
    
    class PopMenus {
      static void showPop(
          {@required BuildContext context,
          @required List<String> listData,
          @required String selText,
          ClickCallBack clickCallback}) {
        Widget _buildMenuLineCell(dataArr) {
          return ListView.separated(
            itemCount: dataArr.length,
            physics: const NeverScrollableScrollPhysics(),
            itemBuilder: (BuildContext context, int index) {
              return GestureDetector(
                  onTap: () {
                    Navigator.pop(context);
                    if (clickCallback != null) {
                      clickCallback(index, listData[index]);
                    }
                  },
                  child: Container(
                    height: cellHeight,
                    child: Column(
                      crossAxisAlignment: CrossAxisAlignment.center,
                      mainAxisAlignment: MainAxisAlignment.center,
                      children: <Widget>[
                        selText==dataArr[index]?
                        Text(dataArr[index], style: TextStyle(fontSize: 16,color:
                        Colors.blue)):Text(dataArr[index], style: TextStyle(fontSize: 16))
                      ],
                    ),
                  ));
            },
            separatorBuilder: (context, index) {
              return Divider(
                height: 0.1,
                color: Color(0xFFE6E6E6),
              );
            },
          );
        }
    
        _buildMenusView(dataArr) {
          var cellH = dataArr.length * cellHeight;
          var navH = ScreenUtils.navigationBarHeight;
          navH = navH - ScreenUtils.topSafeHeight;
          var leftP=(ScreenUtils.screenWidth-cellWidth)/2;
          return Positioned(
            left: leftP,
            top: navH-10,
            child: Column(
              crossAxisAlignment: CrossAxisAlignment.end,
              children: <Widget>[
                Container(
                  padding: EdgeInsets.only(right: 10),
                  child: TriangleUpWidget(height: 10,width: 14),
                ),
                ClipRRect(
                    borderRadius: BorderRadius.circular(2),
                    child: Container(
                        color: _bgColor,
                        width: cellWidth,
                        height: cellH,
                        child: _buildMenuLineCell(dataArr)))
              ],
            ),
          );
        }
    
        showDialog(
            context: context,
            barrierDismissible: false,
            builder: (context) {
              return BasePopMenus(child: _buildMenusView(listData));
            });
      }
    }
    
    class BasePopMenus extends Dialog {
      BasePopMenus({
        Key key,
        this.child,
      }) : super(key: key);
    
      final Widget child;
    
      @override
      Widget build(BuildContext context) {
        return Material(
          type: MaterialType.transparency,
          child: Stack(
            fit: StackFit.expand,
            children: <Widget>[
              GestureDetector(onTap: () => Navigator.pop(context)),
              child
            ],
          ),
        );
      }
    }
    

    如果需要改变弹框的位置,可以修改_buildMenusView()方法中的Positioned组件的边距代码。上面的代码中用到了一个自定义三角形,代码如下。

    class TriangleUpPainter extends CustomPainter {
    
      Color color; //填充颜色
      Paint _paint; //画笔
      Path _path; //绘制路径
      double angle; //角度
    
      TriangleUpPainter() {
        _paint = Paint()
          ..strokeWidth = 1.0 //线宽
          ..color = Colors.white
          ..isAntiAlias = true;
        _path = Path();
      }
    
      @override
      void paint(Canvas canvas, Size size) {
        final baseX = size.width;
        final baseY = size.height;
        //起点
        _path.moveTo(baseX*0.5, 0);
        _path.lineTo(baseX, baseY);
        _path.lineTo(0, baseY);
        canvas.drawPath(_path, _paint);
      }
    
      @override
      bool shouldRepaint(CustomPainter oldDelegate) {
        return false;
      }
    }
    
    class TriangleUpWidget extends StatefulWidget {
      double height;
      double width;
    
      TriangleUpWidget({Key key, this.height = 14, this.width = 16}) : super(key:
      key);
    
      @override
      CoreTriangleState createState() => CoreTriangleState();
    }
    
    class CoreTriangleState extends State<TriangleUpWidget> {
      @override
      Widget build(BuildContext context) {
        return Container(
            height: widget.height,
            width: widget.width,
            child: CustomPaint(
              painter: TriangleUpPainter(),
            ));
      }
    }
    

    最后,在需要弹框的地方,调用我们自定义的弹框组件即可,如下所示。

    PopMenus.showPop(context: context, listData: segmentLists,
          selText: selectedTab, clickCallback: (int index, String value){
                      
     });
    

    起源地下载网 » Flutter仿微信的下拉弹框

    常见问题FAQ

    免费下载或者VIP会员专享资源能否直接商用?
    本站所有资源版权均属于原作者所有,这里所提供资源均只能用于参考学习用,请勿直接商用。若由于商用引起版权纠纷,一切责任均由使用者承担。更多说明请参考 VIP介绍。
    提示下载完但解压或打开不了?
    最常见的情况是下载不完整: 可对比下载完压缩包的与网盘上的容量,若小于网盘提示的容量则是这个原因。这是浏览器下载的bug,建议用百度网盘软件或迅雷下载。若排除这种情况,可在对应资源底部留言,或 联络我们.。
    找不到素材资源介绍文章里的示例图片?
    对于PPT,KEY,Mockups,APP,网页模版等类型的素材,文章内用于介绍的图片通常并不包含在对应可供下载素材包内。这些相关商业图片需另外购买,且本站不负责(也没有办法)找到出处。 同样地一些字体文件也是这种情况,但部分素材会在素材包内有一份字体下载链接清单。
    模板不会安装或需要功能定制以及二次开发?
    请QQ联系我们

    发表评论

    还没有评论,快来抢沙发吧!

    如需帝国cms功能定制以及二次开发请联系我们

    联系作者

    请选择支付方式

    ×
    迅虎支付宝
    迅虎微信
    支付宝当面付
    余额支付
    ×
    微信扫码支付 0 元