introduce
Flutter – a price range filter modeled after Airbnb. (a)
Flutter – a price range filter modeled after Airbnb. (2)
Plotting Bezier curves with Flutter-CustomPaint
The overall structure
I try to put the introduction in a comment so that it’s easier to relate to the code and read it and understand it.
Stack( children: <Widget>[ Container( padding: EdgeInsets.symmetric(horizontal: 15), width: rootWidth, height: Child: rootHeight * 0.45, Stack (children: <Widget>[//bottom chart buildLineChart(), // top chart ClipPath(clipper: ChartClipPath(Size(30,20),// can be based on the design or from the key, leftSlideImageOffset, rightSlideImageOffset), child: BuildLineChart (),),],),), /// price slider widget widgets (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(() { }); },),), ///],)Copy the code
ClipPath
As you can see here, I’ve wrapped the upper chart with ClipPath and clipped the child widgets by passing in a Clipper (inheriting CustomClipper). In addition, the official also provides ClipOval, ClipRect, ClipRRect to facilitate the cutting of circles, rounded rectangles, etc.
Custom Clipper requires overriding two methods:
GetClip (Size Size), Size is the maximum Size given by the parent widget. In this method we can define the path, edit it, return it, and apply it to the child widgets.
ShouldReclip () should be redrawn when the widget(element) is refreshed, return true.
ChartClipPath code:
Class ChartClipPath extends CustomClipper<Path>{// Slider button Size slideBlockSize; / / about the position of the slider Offset leftBlockOffset, rightBlockOffset; ChartClipPath(this.slideBlockSize, this.leftBlockOffset, this.rightBlockOffset); // For some adaptation reasons, we add a ratio here for easy adjustment. In fact, if you have enough time to write slowly, you can completely discard this variable... Final double ratio =0.45; @override Path getClip(Size size) { var path = Path(); // Avoid some values being empty on the first pin, so do not cropif(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();
returnpath; } // The lineTo method generates A path between A and B instead of A path. // The lineTo method generates A path between A and B. // Path has many submethods, and the Bezier curve is drawn here, which is actually very similar to android native. // Start path.moveto (leftBlockoff.dx-slideblocksize. width * ratio, 0); // down path.lineTo(leftBlockoffset.dx-slideblocksize. width * ratio, leftBlockoffset.dy); LineTo (rightBlockoffset.dx-slideblockSize. width * ratio, rightBlockoffset.dy); // Up path.lineTo(rightBlockoff.dx-slideblockSize. Width * ratio, 0); // Up path.lineTo(rightBlockoff.dx-slideblockSize. // form a closure from the end to the beginning. (This is a straight line so make sure it's what you want) path.close();return path;
}
@override
bool shouldReclip(CustomClipper<Path> oldClipper) {
return true; }}Copy the code
At this point the whole thing is done.
The latter
The above is only UI drawing and functional interaction, in fact, combined with business requirements, the state processing is very complex, I use the provider in the actual development of the control, I suggest interested friends can learn about it, very convenient. (You can also try inheritedWidget, which is where the provider is implemented)
##DEMO
Github.com/bladeofgod/…