Flutter开发技巧RadialGradient中radius计算详解
作者:SoaringHeart 时间:2023-10-05 17:42:22
一、问题来源
项目中遇到 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
标签:Flutter,RadialGradient,radius,计算
0
投稿
猜你喜欢
Linux系统下安装和卸载JDK8的方式
2023-08-01 15:29:45
关于C# 类的封装详情
2023-11-29 05:38:20
Java使用Iterator迭代器遍历集合数据的方法小结
2021-10-28 00:22:40
Idea自动生成Entity实现过程详解
2022-06-03 12:18:24
java GUI编程之paint绘制操作示例
2023-11-24 17:58:39
Android 屏幕切换监听的实例代码
2023-07-03 13:00:19
Android 自定义gradle property详解及实例代码
2022-05-08 15:17:49
Spring 与 JDK 线程池的简单使用示例详解
2023-08-20 04:02:59
android xml实现按钮的圆角、阴影效果及按下变化效果的实现代码
2022-07-30 23:23:12
Android 自定义一套 Dialog通用提示框 (代码库)
2022-10-08 06:20:31
Android实现微信支付功能
2023-08-04 19:09:03
Android 自定义Button控件实现按钮点击变色
2022-12-04 18:18:46
Unity实现VR中在黑板上写字效果
2021-08-04 20:11:11
mybatis防止SQL注入的方法实例详解
2022-08-14 03:06:57
mybatis多表查询的实现(xml方式)
2021-07-11 01:21:38
RocketMQ消息存储文件的加载与恢复机制源码分析
2021-12-29 20:23:19
Android调用相机并将照片存储到sd卡上实现方法
2023-11-06 00:41:41
hibernate 命名查询如何实现
2023-11-04 02:35:41
Android项目实战手把手教你画圆形水波纹loadingview
2023-03-15 10:13:47
IDEA中创建maven项目引入相关依赖无法下载jar问题及解决方案
2021-06-09 12:51:53