Flutter构建自定义Widgets的全过程记录
作者:伟雪无痕
一.组合widget实现
1.android和flutter自定义控件对比
Android中,一般会继承View或已经存在的某个控件,然后覆盖draw方法来实现自定义View。在Flutter中,一个自定义widget通常是通过组合其它widget来实现的,而不是继承。下面看看如何构建持有一个label的CustomButton。这是通过将Text与RaisedButton组合来实现的,而不是继承RaisedButton并重写其绘制方法实现,eg :custombuttontest.dart
import 'package:flutter/material.dart'; class CustomButtonTest extends StatelessWidget{ final String textStr; CustomButtonTest(this.textStr); @override Widget build(BuildContext context) { return RaisedButton( onPressed: (){}, child: Text( textStr, textAlign: TextAlign.center, ) ); } }
上面定义好组件之后,可直接在调用build的方法中现实,eg :
@override Widget build(BuildContext context) { return new Center( child: new CustomButton("Custom Button"), ); } }
二.通过自定义CustomPainter实现widgets
1.CustomPainter主要属性介绍,和Android开发中的自定义View类似,Flutter中的绘制也是依靠Canvas和Paint来实现的
1).Canvas //画布,为开发者提供了点、线、矩形、圆形、嵌套矩形等绘制方法。
2).Paint //画笔,可以设置抗锯齿,画笔颜色,粗细,填充模式等属性,绘制时可以定义多个画笔以满足不同的绘制需求。eg:
Paint _paint = new Paint() ..color = Colors.red // 画笔颜色 ..strokeCap = StrokeCap.round //画笔笔触类型,包括(1.round-画笔笔触呈半圆形轮廓开始和结束;2.butt-笔触开始和结束边缘平坦,没有外延;3.square-笔触开始和结束边缘平坦,向外延伸长度为画笔宽度的一半) ..isAntiAlias = true //是否启动抗锯齿 ..style=PaintingStyle.fill //绘画风格,默认为填充,有fill和stroke两种 ..blendMode=BlendMode.exclusion //颜色混合模式 ..colorFilter=ColorFilter.mode(Colors.blueAccent, BlendMode.exclusion)//颜色渲染模式 ..maskFilter=MaskFilter.blur(BlurStyle.inner, 3.0)//模糊遮罩效果 ..filterQuality=FilterQuality.high//颜色渲染模式的质量 ..strokeWidth = 15.0;//画笔的宽度复制代码
3).Offset //坐标,可以用来表示某个点在画布中的坐标位置。
4).Rect //矩形,在图形的绘制中,一般都是分区域绘制的,这个区域一般都是一个矩形,在绘制中通常使用Rect来存储绘制的位置信息。
5).坐标系 //在Flutter中,坐标系原点(0,0)位于左上角,X轴向右变大,Y轴向下变大。
2.painting.dart中的主要方法,eg:
void drawRect(Rect rect, Paint paint) {...} //画矩形 void drawLine(Offset p1, Offset p2, Paint paint) {...} //画线 void drawPoints(PointMode pointMode, List<Offset> points, Paint paint) {...} //画点 void drawCircle(Offset c, double radius, Paint paint) {...} //画圆 void drawArc(Rect rect, double startAngle, double sweepAngle, bool useCenter, Paint paint) {...} //画圆弧
三.饼状图piechart.dart代码展示
import 'dart:math'; import 'package:flutter/material.dart'; class PieChartTest extends StatelessWidget{ const PieChartTest({Key? key}) : super(key: key); @override Widget build(BuildContext context) { return Scaffold( appBar: AppBar( title: const Text('pie chart'), ), body:Container( alignment: Alignment.center, child: CustomPaint( size: const Size(300, 300), painter: PieChartPainter(), ), ) ); } } class PieChartPainter extends CustomPainter{ Paint getColoredPaint(Color color){ Paint paint=Paint(); paint.color=color; return paint; } @override void paint(Canvas canvas, Size size) { double wheelSize=min(size.width, size.height)/2; double nbElem=8; double radius=(2*pi)/nbElem; Rect boundingRect=Rect.fromCircle(center: Offset(wheelSize,wheelSize), radius: wheelSize); canvas.drawArc(boundingRect, 0, radius, true, getColoredPaint(Colors.orange)); canvas.drawArc(boundingRect, radius, radius, true, getColoredPaint(Colors.black)); canvas.drawArc(boundingRect, radius*2, radius, true, getColoredPaint(Colors.green)); canvas.drawArc(boundingRect, radius*3, radius, true, getColoredPaint(Colors.red)); canvas.drawArc(boundingRect, radius*4, radius, true, getColoredPaint(Colors.blue)); canvas.drawArc(boundingRect, radius*5, radius, true, getColoredPaint(Colors.yellow)); canvas.drawArc(boundingRect, radius*6, radius, true, getColoredPaint(Colors.purple)); canvas.drawArc(boundingRect, radius*7, radius, true, getColoredPaint(Colors.white)); } @override bool shouldRepaint(covariant CustomPainter oldDelegate)=>oldDelegate!=this; }
四.实际效果图,eg:
附:Flutter中父widget调用子widget的方法
一、定义globalKey,注意<>中的是State类。
final _childWidgetKey = GlobalKey();
二、在父页面初始化子widget
ChildPage(key:_receiveKey),
三、
class ChildPage extends StatefulWidget {undefined ChildPage({Key key}) : super(key: key); @override ChildPageState createState() => ChildPageState(); }
四、在父界面调用子widget中的方法
_childWidgetKey.currentState.onRefresh();
总结
到此这篇关于Flutter构建自定义Widgets的文章就介绍到这了,更多相关Flutter构建自定义Widgets内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!