前言:
各位同學(xué)大家好,有段時(shí)間沒有給大家更新文章了,趁著今天有時(shí)間我們就給大家分享一個(gè)flutter的貝塞爾曲線的繪制的案例,希望能幫助到各位同學(xué)的學(xué)習(xí)和工作,那么廢話不多說我們正式開始 。
準(zhǔn)備工作 :
需要安裝flutter的開發(fā)環(huán)境:大家可以去看看之前的教程:
1 win系統(tǒng)flutter開發(fā)環(huán)境安裝教程: http://www.itdecent.cn/p/152447bc8718
2 mac系統(tǒng)flutter開發(fā)環(huán)境安裝教程:http://www.itdecent.cn/p/bad2c35b41e3
效果圖:


具體實(shí)現(xiàn):
普通貝塞爾曲線

@override
Widget build(BuildContext context) {
// TODO: implement build
return Scaffold(
body: Column(
children: [
ClipPath(
clipper: BottomClippertest(),
child: Container(
color: Colors.deepOrangeAccent,
height: 200,
),
)
],
),
);
}
我們這邊寫了ClipPath 來處理我們貝塞爾曲線的繪制 ClipPath 里面我們嵌套了一個(gè) Container 盒子組件設(shè)置高度200 寬度撐滿屏幕 然后我們來處理ClipPath 組件里面的 clipper 熟悉
class BottomClippertest extends CustomClipper<Path>{
@override
Path getClip(Size size) {
var path=Path();
path.lineTo(0, 0); //第一個(gè)點(diǎn)
path.lineTo(0, size.height-60);//第二個(gè)點(diǎn)
var firstControlPoint=Offset(size.width/2, size.height); //曲線開始點(diǎn)
var firstendPoint=Offset(size.width, size.height-60); // 曲線結(jié)束點(diǎn)
path.quadraticBezierTo(firstControlPoint.dx, firstControlPoint.dy,
firstendPoint.dx, firstendPoint.dy);
path.lineTo(size.width, size.height-60); //第四個(gè)點(diǎn)
path.lineTo(size.width,0); // 第五個(gè)點(diǎn)
return path;
}
@override
bool shouldReclip(covariant CustomClipper<Path> oldClipper) {
return false;
}
}
我們這邊寫了一個(gè) BottomClippertest 類繼承與 CustomClipper 然后重寫了getClip 和 shouldReclip 方法 ,shouldReclip 方法我們返回 false 在 getClip 方法中我們創(chuàng)建 path對(duì)象
var path=Path();
然后繪制貝塞爾曲線需要的 一些節(jié)點(diǎn) 如上圖話的5個(gè)點(diǎn)和 貝塞爾曲線的需要的開始點(diǎn)和結(jié)束點(diǎn) 最后我們返回一個(gè) path對(duì)象即可
完整代碼:
import 'package:flutter/material.dart';
/**
*
* 創(chuàng)建人:xuqing
* 創(chuàng)建時(shí)間:2020年11月14日16:28:54
* 類說明: 普通貝塞爾曲線
*
*
*/
class MyHomePage extends StatefulWidget {
MyHomePage({Key key}) : super(key: key);
@override
_MyHomePageState createState() {
return _MyHomePageState();
}
}
class _MyHomePageState extends State<MyHomePage> {
@override
void initState() {
super.initState();
}
@override
void dispose() {
super.dispose();
}
@override
Widget build(BuildContext context) {
// TODO: implement build
return Scaffold(
body: Column(
children: [
ClipPath(
clipper: BottomClippertest(),
child: Container(
color: Colors.deepOrangeAccent,
height: 200,
),
)
],
),
);
}
}
class BottomClippertest extends CustomClipper<Path>{
@override
Path getClip(Size size) {
var path=Path();
path.lineTo(0, 0); //第一個(gè)點(diǎn)
path.lineTo(0, size.height-60);//第二個(gè)點(diǎn)
var firstControlPoint=Offset(size.width/2, size.height); //曲線開始點(diǎn)
var firstendPoint=Offset(size.width, size.height-60); // 曲線結(jié)束點(diǎn)
path.quadraticBezierTo(firstControlPoint.dx, firstControlPoint.dy,
firstendPoint.dx, firstendPoint.dy);
path.lineTo(size.width, size.height-60); //第四個(gè)點(diǎn)
path.lineTo(size.width,0); // 第五個(gè)點(diǎn)
return path;
}
@override
bool shouldReclip(covariant CustomClipper<Path> oldClipper) {
return false;
}
}
波浪形貝塞爾曲線實(shí)現(xiàn):

@override
Widget build(BuildContext context) {
// TODO: implement build
return Scaffold(
body: Column(
children: [
ClipPath(
clipper: BottomClipper(),
child: Container(
color: Colors.blue,
height: 200,
),
)
],
),
);
}
}
我們很上面的普通的貝塞爾曲線一樣 我寫了一個(gè) `ClipPath 組件 里面嵌套一個(gè) Container 組件高度200 寬度撐滿屏幕 我們重點(diǎn)看一下 clipper 屬性的實(shí)現(xiàn):
class BottomClipper extends CustomClipper<Path>{
@override
Path getClip(Size size) {
var path=Path();
path.lineTo(0, 0);
path.lineTo(0, size.height-40);
var firstControlPoint=Offset(size.width/4, size.height);
var firstendPoint=Offset(size.width/2.25, size.height-30);
path.quadraticBezierTo(firstControlPoint.dx, firstControlPoint.dy,
firstendPoint.dx, firstendPoint.dy);
var secondConttorPoint=Offset(size.width/4*3, size.height-90);
var secondendPoint=Offset(size.width, size.height-40);
path.quadraticBezierTo(secondConttorPoint.dx, secondConttorPoint.dy,
secondendPoint.dx, secondendPoint.dy);
path.lineTo(size.width, size.height-40);
path.lineTo(size.width,0);
return path;
}
@override
bool shouldReclip(covariant CustomClipper<Path> oldClipper) {
return false;
}
}
同上我們寫了一個(gè)BottomClipper 類繼承 CustomClipper 類 重寫getClip 方法和 shouldReclip ,shouldReclip 返回 false 重點(diǎn)是getClip 方法里面 我們創(chuàng)建 path對(duì)象
var path=Path();
這個(gè)波浪形的貝塞爾曲線我們有2個(gè)控制點(diǎn) 分別是在屏幕寬度1/4和屏幕寬度按3/4 處
var firstControlPoint=Offset(size.width/4, size.height); //第一個(gè)控制點(diǎn)起始點(diǎn)
var firstendPoint=Offset(size.width/2.25, size.height-30);//第一個(gè)控制結(jié)束點(diǎn)
path.quadraticBezierTo(firstControlPoint.dx, firstControlPoint.dy,
firstendPoint.dx, firstendPoint.dy);
var secondConttorPoint=Offset(size.width/4*3, size.height-90); // 第二個(gè)控制點(diǎn)起始點(diǎn)
var secondendPoint=Offset(size.width, size.height-40); // 第二個(gè)控制點(diǎn)結(jié)束點(diǎn)
path.quadraticBezierTo(secondConttorPoint.dx, secondConttorPoint.dy,
secondendPoint.dx, secondendPoint.dy);
其他的點(diǎn)和上面通普通貝塞爾曲線相同最后我們返回path 即可實(shí)現(xiàn)我們的波浪形貝塞爾曲線的繪制了
到此我們最基礎(chǔ)的貝塞爾曲線的繪制就講完了
最后總結(jié):
有時(shí)候我們?cè)诠ぷ髦行枰玫揭恍┣€背景的時(shí)候 我們就可以用到貝塞爾曲線繪制加上對(duì)應(yīng)顏色背景即可 這時(shí)候有同學(xué)就跳出來講 直接一張圖片就搞定了 但是我們加了圖片就會(huì)增加資源文件 也相對(duì)應(yīng)增加flutter項(xiàng)目打包成安裝包的體積,flutter里面提供好用的api供我們調(diào)用 我們只需要找到對(duì)應(yīng)節(jié)點(diǎn)然后返回路徑去繪制即可。以上的簡(jiǎn)單例子只是分享給同學(xué)們 ,同學(xué)們可以自己研究繪制出更多炫酷的曲線效果,我這邊就不展開講了。 最后希望我的文章能幫助到各位解決問題 ,以后我還會(huì)貢獻(xiàn)更多有用的代碼分享給大家。各位同學(xué)如果覺得文章還不錯(cuò) ,麻煩給關(guān)注和star,小弟在這里謝過啦