按路径切割组件
ClipPath(
clipper:继承了CustomClipper<Path>的类且重写了两个方法 , 裁切路径
child: 待切割组件
)
切割类
class BottomClipper extends CustomClipper<Path>{
Path getClip(Size size){
var path=Path();
(1)根据坐标点绘制,size包含了子组件宽高
(2)若不是被贝塞尔曲线,依次直线相连lineTo设置的坐标路径剪裁
(3)若使用了贝塞尔曲线,则贝塞尔曲线的首尾点的前后的点先连也是贝塞尔曲线
贝塞尔绘制弧线
path.lineTo(0, 0);
path.lineTo(0,size.height-30);
贝塞尔曲线的两个坐标,根据高低通过弧线相连
var firstPoint=Offset(size.width/2,size.height);
var endPoint=Offset(size.width,size.height-30);
绘制贝塞尔曲线
path.quadraticBezierTo(firstPoint.dx, firstPoint.dy, endPoint.dx, endPoint.dy);
path.lineTo(size.width, 0);
贝塞尔绘制波浪线
path.lineTo(0,0);
path.lineTo(0,size.height-40);
波浪线需要四个贝塞尔坐标,分别在1/4、1/2.25,3/4,1处设置,会根据高低弧线相连
var firstPoint=Offset(size.width/4,size.height);
var secondPoint=Offset(size.width/2.25,size.height-30);
path.quadraticBezierTo(firstPoint.dx, firstPoint.dy, secondPoint.dx, secondPoint.dy);
var thirdPoint=Offset(size.width/4*3,size.height-90);
var fourthPoint=Offset(size.width,size.height-40);
path.quadraticBezierTo(thirdPoint.dx, thirdPoint.dy, fourthPoint.dx, fourthPoint.dy);
path.lineTo(size.width, 0);
return path;
}
@override
bool shouldReclip(CustomClipper<Path> oldClipper) {
// TODO: implement shouldReclip
return false;
}
}
效果图:
代码示例:
import 'package:flutter/gestures.dart';
import "package:flutter/material.dart";
import 'package:flutter/rendering.dart';
import "drag.dart";
import 'dart:ui';
import 'page/1.dart';
import 'page/2.dart';
import 'page/3.dart';
import 'xuan.dart';
void main()
{
runApp(App());
}
class App extends StatelessWidget {
const App({Key key}) : super(key: key);
@override
Widget build(BuildContext context) {
return App2();
}
}
class App2 extends StatefulWidget {
App2({Key key}) : super(key: key);
@override
_AppState createState() => _AppState();
}
class _AppState extends State<App2> with SingleTickerProviderStateMixin {
// List _page=[Home3(),Home2(),Home4()];
// int index=0;
TabController con;
@override
void initState() {
// TODO: implement initState
super.initState();
con=new TabController(length: 3, vsync: this);
}
@override
void dispose() {
// TODO: implement dispose
super.dispose();
con.dispose();
}
@override
Widget build(BuildContext context) {
return MaterialApp(
home:Scaffold(
appBar:AppBar(
title: Text('小案例'),
),
body:Home(),
//去掉右上角的debug贴纸
debugShowCheckedModeBanner: false,
theme: ThemeData(
primarySwatch: Colors.blue
),
);
}
}
class Home extends StatefulWidget {
@override
_HomeState createState() => _HomeState();
}
class _HomeState extends State<Home> {
@override
Widget build(BuildContext context) {
return Container(
// width: double.infinity,
child:Center(
child:Column(
children: <Widget>[
ClipPath(
clipper:BottomClipper() , //裁切路径
child: Container(
height: 200,
width: double.infinity,
color:Colors.indigoAccent
),
)
],
),
)
);
}
}
class BottomClipper extends CustomClipper<Path>{
Path getClip(Size size){
var path=Path();
// path.lineTo(0, 0);
// path.lineTo(0,size.height-30);
// var firstPoint=Offset(size.width/2,size.height);
// var endPoint=Offset(size.width,size.height-30);
// path.quadraticBezierTo(firstPoint.dx, firstPoint.dy, endPoint.dx, endPoint.dy);
// path.lineTo(size.width, 0);
path.lineTo(0,0);
path.lineTo(0,size.height-40);
var firstPoint=Offset(size.width/4,size.height);
var secondPoint=Offset(size.width/2.25,size.height-30);
path.quadraticBezierTo(firstPoint.dx, firstPoint.dy, secondPoint.dx, secondPoint.dy);
var thirdPoint=Offset(size.width/4*3,size.height-90);
var fourthPoint=Offset(size.width,size.height-40);
path.quadraticBezierTo(thirdPoint.dx, thirdPoint.dy, fourthPoint.dx, fourthPoint.dy);
path.lineTo(size.width, 0);
return path;
}
@override
bool shouldReclip(CustomClipper<Path> oldClipper) {
// TODO: implement shouldReclip
return false;
}
}