Flutter构建自定义Widgets的全过程记录
作者:伟雪无痕 发布时间:2022-01-27 16:37:39
一.组合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();
来源:https://blog.csdn.net/j086924/article/details/122406209


猜你喜欢
- 微信小程序 navigator 跳转url传递参数使用方法说明(1)传值:在navigator的属性url后拼接?id(参数名字
- 首先来个效果图 布局文件代码在布局文件中,CoordinatorLayout作为布局文件根节点,AppBarLayo
- 前言大家都知道Android Studio目前已经更新到2.0 Preview 6了,作为Google大力推崇的开发工具,相对于Eclips
- 背景众所周知,所有被打开的系统资源,比如流、文件或者Socket连接等,都需要被开发者手动关闭,否则随着程序的不断运行,资源泄露将会累积成重
- 异常捕获机制 C#1.示意图2.异常捕获机制,代码:3.异常捕获机制,结果:4.求几周,剩余几天?代码:5.结果:6.求几月几周零几天 设一
- 1 泰勒级数介绍近期工作中需要使用matlab建模,期间做案例的时候有个方程:sin(x)=0,要求不使用现有api进行求解,然后有点懵,不
- 一、SpringBoot可以识别4种配置文件1.application.yml2.application.properties3.boots
- 前言5个xml文件实现 按钮的圆角、阴影效果以及按下变化效果实现drawable/shape.xml<?xml version=&qu
- 转载请标明出处:http://blog.csdn.net/lmj623565791/article/details/24252901很多的A
- 本文实例为大家分享了Java实现学生管理系统的具体代码,供大家参考,具体内容如下1.学生管理系统(控制台界面实现)//学生类,继承Seria
- 本人使用Android开发有一段时间了,但是本身没有系统学,而且多年专注服务端开发,总觉得因为项目需要接触Android移动端开发只是暂时的
- 前言:项目中我们经常会遇到有时候需要等待其他线程完成任务后,主线程才能执行其他任务,那么我们将如何实现呢?Join 解决方案join 的工作
- 本文实例讲述了C#正则过滤HTML标签并保留指定标签的方法。分享给大家供大家参考,具体如下:这边主要看到一个过滤的功能:public sta
- 想做一个APP,设计中有侧边栏这个功能,所以现在开始学习下侧边栏的实现。在官方的UI空间中已经给出了DrawerLayout这个侧滑的菜单空
- 在Android原生的TextView的基础上,可收缩/扩展的TextView:PhilExpandableTextView。实现原理:核心
- 本文实例讲述了C#实现Zip压缩目录中所有文件的方法。分享给大家供大家参考。具体实现方法如下:using System;using Syst
- 先来看两段代码: Thread t = new Thread(() => { AddIt AddDelegate = new
- 引言当我们通过@ConfigurationProperties注解实现配置 bean的时候,如果默认的配置属性转换无法满足我们的需求的时候,
- 本文以实例形式展示了基于C#实现Windows服务状态启动和停止服务的方法。非常实用。分享给大家供大家参考之用。具体方法如下:首先先引用:S
- 前言Mybatis是web工程开发中非常常用的数据持久化的框架,通过该框架,我们非常容易的进行数据库的增删改查。数据库连接进行事务提交的时候