Flutter开发技巧RadialGradient中radius计算详解
作者:SoaringHeart 发布时间:2023-10-05 17:42:22
标签:Flutter,RadialGradient,radius,计算
一、问题来源
项目中遇到 json 模型映射成 RadialGradient 组件的需求,其他参数正常传递即可;
唯独 radius 参数效果有出入,总结记录一下;
二、四种情况
通过 RadialGradient 参数 center 可以分为四种情况,这四种情况分别对应四种 radius 的值:
1、情况一
Alignment.center,
贪婪模式下组件的宽高中最大值的一半/最小值的一半为 radius;否则radius是0.5;
【贪婪模式】
p>【非贪婪模式】
2、情况二
Alignment.centerLeft,
Alignment.centerRight,
【贪婪模式】
【非贪婪模式】
3、情况三
Alignment.topCenter,
Alignment.bottomCenter,
【贪婪模式】
【非贪婪模式】
4、情况四
Alignment.topLeft,
Alignment.topRight,
Alignment.bottomLeft,
Alignment.bottomRight,
【贪婪模式】
【非贪婪模式】
【使用对角线半径】(注意左下角的一点点留白,基本实现全覆盖)
三、实现源码
GradientOfRadialDemo
import 'package:flutter/material.dart';
import 'package:flutter_templet_project/basicWidget/SectionHeader.dart';
import 'package:flutter_templet_project/extension/alignment_ext.dart';
import 'package:tuple/tuple.dart';
class GradientOfRadialDemo extends StatefulWidget {
GradientOfRadialDemo({ Key? key, this.title}) : super(key: key);
final String? title;
@override
_GradientOfRadialDemoState createState() => _GradientOfRadialDemoState();
}
class _GradientOfRadialDemoState extends State<GradientOfRadialDemo> {
var maxWidth = double.infinity;
var maxHeight = double.infinity;
/// 是否是贪婪模式
var isGreed = true;
/// 是否使用对角线做半径
bool isDiagonal = true;
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text(widget.title ?? "$widget"),
bottom: buildAppBottom(),
),
body: Container(
// height: 300,
child: buildRadial(),
),
// body: ListView(
// children: [
// SectionHeader.h4(title: 'RadialGradient',),
// buildRadial(),
// ],
// )
);
}
buildAppBottom() {
return PreferredSize(
preferredSize: Size(double.infinity, 50),
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
children: [
_buildDropdownButton(),
_buildButton(
text: "isGreed: ${isGreed.toString()}",
onPressed: () {
this.isGreed = !this.isGreed;
setState(() {});
},
),
_buildButton(
text: "isDiagonal: ${isDiagonal.toString()}",
onPressed: () {
this.isDiagonal = !this.isDiagonal;
setState(() {});
},
),
],
)
);
}
var _dropValue = AlignmentExt.allCases[0];
var _radius = 0.5;
_buildDropdownButton() {
return DropdownButton<Alignment>(
value: _dropValue,
items: AlignmentExt.allCases.map((e) => DropdownMenuItem(
child: Text(e.toString().split('.')[1]),
value: e,
),
).toList(),
onChanged: (Alignment? value) {
if (value == null) return;
_dropValue = value;
setState(() {});
},
);
}
_buildButton({
required String text,
required VoidCallback onPressed
}) {
return TextButton(
onPressed: onPressed,
child: Center(
child: Text(text,
style: TextStyle(color: Colors.white),
)
),
);
}
Widget _buildBox({
required String text,
required Decoration decoration,
double height: 100,
double? width,
}) {
return LayoutBuilder(
builder: (context, constraints) {
this.maxWidth = constraints.maxWidth;
this.maxHeight = constraints.maxHeight;
return Container(
// width: width,
// height: height,
margin: const EdgeInsets.all(8.0),
decoration: decoration,
alignment: Alignment.center,
child: Text(text, style: TextStyle(color: Colors.white, fontSize: 16.0)),
);
}
);
}
buildRadial() {
var tuples = <Tuple2<Color, double>>[ Tuple2(Colors.red, 0.1), Tuple2(Colors.blue, 0.3), Tuple2(Colors.yellow, 0.5), Tuple2(Colors.green, 1), ];
_radius = _dropValue.radiusOfRadialGradient(
width: this.maxWidth,
height: this.maxHeight,
isGreed: this.isGreed,
isDiagonal: this.isDiagonal
) ?? 0.5;
print("_dropValue:${_dropValue} _radius:${_radius} maxWidth:${maxWidth} maxHeight:${maxHeight}");
print("_radius: $_radius");
return _buildBox(
height: 100,
text: 'RadialGradient',
decoration: BoxDecoration(
border: Border.all(),
gradient: RadialGradient(
// tileMode: this.tileMode,
// tileMode: TileMode.mirror,
radius: _radius,
tileMode: TileMode.decal,
center: _dropValue,
// focal: Alignment.bottomCenter,
colors: tuples.map((e) => e.item1).toList(),
stops: tuples.map((e) => e.item2).toList(),
),
),
);
}
}
四、radiusOfRadialGradient 方法实现
// AlignmentExtension.dart
// flutter_templet_project
//
// Created by shang on 2023/1/12 20:57.
// Copyright © 2023/1/12 shang. All rights reserved.
//
import 'dart:math' as math;
import 'package:flutter/cupertino.dart';
extension AlignmentExt on Alignment{
/// 获取雷达渐进色 radius
/// isGreed 是否贪婪模式(贪婪模式用大半径,否则小半径)
/// isDiagonal 四角是否使用对角线(为 true 则 isGreed 参数无效)
double? radiusOfRadialGradient({
required double? width,
required double? height,
bool isGreed = true,
bool isDiagonal = true,
}) {
if(width == null || height == null
|| width <= 0 || height <= 0) {
return null;
}
final max = math.max(width, height);
final min = math.min(width, height);
double result = 0.5;
if([
Alignment.center,
].contains(this)){
result = isGreed == true ? max/min * 0.5 : 0.5;
} else if ([
Alignment.topCenter,
Alignment.bottomCenter,
].contains(this)) {
result = isGreed == true ? max/min : 0.5;
} else if ([
Alignment.topLeft,
Alignment.topRight,
Alignment.bottomLeft,
Alignment.bottomRight
].contains(this)) {
if (isDiagonal) {
final tmp = math.sqrt(math.pow(max, 2) + math.pow(min, 2)).ceil();
// result = isGreed == true ? tmp/min : max/min;
result = tmp/min;
} else {
result = isGreed == true ? max/min : 1;
}
} else if ([
Alignment.centerLeft,
Alignment.centerRight,
].contains(this)) {
result = isGreed == true ? 1 : max/min * 0.5;
}
return result;
}
}
最后
项目中为了方便查看差异使用了 TileMode.decal 模式,正常使用默认模式即可;
github
来源:https://juejin.cn/post/7188426039587143738
![](https://www.aspxhome.com/images/zang.png)
![](https://www.aspxhome.com/images/jiucuo.png)
猜你喜欢
- #region 监视文件夹的变化
- 一、前言尽管Unity有一个像样的脚本编辑器(Mono),但很多人喜欢使用另一个编辑器。这篇短文解释了如何更改脚本编辑器,并介绍了Mono的
- 本文实例讲述了C#读取或设置ScrollLock状态的方法。分享给大家供大家参考。具体如下:C#读取或者设置ScrollLock状态,允许滚
- 这篇文章主要介绍了spring boot如何指定启动端口,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的
- 如果不熟悉Java8新特性的小伙伴,初次看到函数式接口写出的代码可能会是一种懵逼的状态,我是谁,我在哪,我可能学了假的Java,(・∀・(・
- 前言大家都知道网络操作的响应时间是不定的,所有的网络操作都应该放在一个异步操作中处理,而且为了模块解耦,我们希望网络操作由专门的类来处理。所
- 正文将 Java 对象序列化为二进制文件的 Java 序列化技术是 Java 系列技术中一个较为重要的技术点,在大部分情况下,开发人员只需要
- 本文实例为大家分享了java实现学生成绩档案管理系统的具体代码,供大家参考,具体内容如下实验要求• 学生信息录入,信息包括学号、姓名、专业、
- 目录前言1、创建一个控制台应用程序2、编写测试代码并分析3、总结前言对于C#里面的Foreach学过 语言的人都知道怎么用,但是其原理相信很
- 在Android studio实现简易计算器App并实现加减乘除功能,供大家参考,具体内容如下结果activity_main.xml<
- 运用到的MongoDB支持的C#驱动,当前版本为1.6.0下载地址:https://github.com/mongodb/mongo-csh
- 以在搜索框搜索时,自动补全为例:其中还涉及到一个词,Tokenizer:分词器,分解器。上效果图:MainActivity.java:pac
- 简介FTP是TCP/IP协议组中的协议之一,包括两个组成部分,一是FTP服务端,二是FTP客户端,其中FTP服务器用来存储文件,用户可以使用
- package 斐波那契数;import java.util.Scanner;class 斐波那契数 { public static voi
- Android植物大战僵尸小游戏全部内容如下:相关下载:Android植物大战僵尸小游戏具体代码如下所示:package com.examp
- 前言Spring 框架作为一个管理 Bean 的 IoC 容器,那么 Bean 自然是 Spring 中的重要资源了,那 Bean 的作用域
- 本文实例为大家分享了Android短信验证服务的具体代码,供大家参考,具体内容如下package com.skiers.demo_learn
- 在C#中,当引用类型需要转换的时候,经常会用到关键字is、as以及显式强转。本篇来体验这三者的用法。先来梳理.NET引用类型转换的"
- 指针的概念:指针是一个特殊的变量,它里面存储的数值被解释成为内存里的一个地址。要搞清一个指针需要搞清指针的四方面的内容:指针的类型,指针所指
- 本文实例讲述了C#编程读取文档Doc、Docx及Pdf内容的方法。分享给大家供大家参考。具体分析如下:Doc文档:Microsoft Wor