Flutter 仿Airbnb的价格区间筛选器。(二)

49 篇文章 0 订阅
47 篇文章 0 订阅

介绍

Flutter - 仿Airbnb的价格区间筛选器。(一)

Flutter - 仿Airbnb的价格区间筛选器。(二)

Flutter-CustomPaint 绘制贝塞尔曲线图表(三)

整体结构

我尽量将介绍写入到注释里,这样方便与代码关联阅读理解起来更方便。

 Stack(
              children: <Widget>[
                Container(
                  padding: EdgeInsets.symmetric(horizontal: 15),
                  width: rootWidth,
                  height: rootHeight*0.45,
                  child: Stack(
                    children: <Widget>[
                      //bottom chart 底层 背景chart
                      buildLineChart(),
                      //above chart  上层  chart
                      
                      ClipPath(
                        clipper: ChartClipPath(Size(30,20),//可以根据设计图也可以通过key传出来,这里方便起见
                            leftSlideImageOffset, rightSlideImageOffset),
                        child: buildLineChart(),
                      ),
                    ],
                  ),
                ),

                /// 价格滑块widget
                Positioned(
                  bottom: 10,
                  child: SliderPrice(list: beanList,rootWidth: rootWidth,rootHeight: rootHeight * 0.4,
                    leftSlidListener: (dragging,index,leftImageKey){
                      //debugPrint("left ------- $dragging ------- $index");
                      leftSlideImageOffset = calculateSlideBlockInfo(leftImageKey);
                      setState(() {

                      });
                    },
                    rightSlidListener: (dragging,index,rightImageKey){
                      //debugPrint("right ------- $dragging ------- $index");
                      rightSlideImageOffset = calculateSlideBlockInfo(rightImageKey);
                      setState(() {

                      });
                    },),
                ),
                ///


              ],
            )

ClipPath

可以看到这里我用了ClipPath对上层chart进行了包裹,通过传入一个Clipper(继承CustomClipper)可以对子widget进行裁剪。
另外官方还提供了ClipOval、ClipRect、ClipRRect来方便进行圆形、圆角矩形等的裁剪。

自定义Clipper 需要重写两个方法:

1,getClip(Size size),参数size是父widget给我们的最大尺寸。在这个方法里我们可以定义path并任意编辑,然后返回即可,最终会作用于子widget。

2,shouldReclip(),widget(element)刷新时是否重绘,这里要返回true。

ChartClipPath 代码:

class ChartClipPath extends CustomClipper<Path>{
    //滑块按钮大小
  Size slideBlockSize;
  //左右滑块的位置
  Offset leftBlockOffset,rightBlockOffset;


  ChartClipPath(this.slideBlockSize, this.leftBlockOffset,
      this.rightBlockOffset);
//因为一些适配原因,在这里加了个ratio方便调整,实际上如果你时间充裕,慢慢写可以完全舍弃掉这个变量...催得紧没办法
  final double ratio =0.45;

  @override
  Path getClip(Size size) {
    var path = Path();
    //避免第一针绘制时一些值是空,所以进行不裁剪操作
    if(slideBlockSize == null || leftBlockOffset == null || rightBlockOffset == null){
      path.moveTo(0, 0);
      path.lineTo(0,size.height);
      path.lineTo(size.width, size.height);
      path.lineTo(size.width, 0);
      path.close();
      return path;
    }

    //这里很简单,实际上是根据左右滑块按钮的位置,走一个矩形path,然后用于裁剪
    //这里要注意moveTo方法,例如A到B之间是没有path生成的
    // 而 lineTo方法是会生成path的。
    //path有很多子方法,贝塞尔曲线也是通过这里绘制的,实际上这里跟安卓原生非常像。
    //起始点
    path.moveTo(leftBlockOffset.dx - slideBlockSize.width * ratio, 0);
    //向下
    path.lineTo(leftBlockOffset.dx - slideBlockSize.width * ratio, leftBlockOffset.dy);
    //向右
    path.lineTo(rightBlockOffset.dx - slideBlockSize.width * ratio, rightBlockOffset.dy);
    //向上
    path.lineTo(rightBlockOffset.dx - slideBlockSize.width * ratio, 0);
    //形成从终点到起点的闭合。(这里是直线所以要确保是你想要的)
    path.close();

    return path;
  }

  @override
  bool shouldReclip(CustomClipper<Path> oldClipper) {

    return true;
  }

}

到这里整个制作就完成了。

后话

以上只是UI绘制和功能交互,实际上结合业务需求,状态处理非常复杂,我的在实际开发中是用provider进行的控制,建议有兴趣的朋友可以了解一下,非常方便。(也可以尝试inheritedwidget,provider就是基于此实现的)

##DEMO

https://github.com/bladeofgod/chart_price_slider

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值