一个顶N个!Flutter界面开发提速大杀器Getwidget 🚀(五)
站长
· 阅读数 4
前言
Flutter 是 Google 开源的应用开发框架,仅通过一套代码就能构建支持Android、iOS、Windows、Linux等多平台的应用。Flutter的性能非常高,拥有120fps的刷新率,也是目前非常流行的跨平台UI开发框架。
本专栏为大家收集了Github上近70个优秀开源库,后续也将持续更新。希望可以帮助大家提升搬砖效率,同时祝愿Flutter的生态越来越完善🎉🎉。
Getwidget 索引
👉 第五篇:闪光组件 GFShimmer、动画 GFAnimation、边框 GFBorder、底部抽屉 GFBottomSheet、复选框 GFCheckbox
正文
一、🚀 轮子介绍
二、⚙️ 安装及使用
dependencies:
getwidget: ^2.0.5
import 'package:getwidget/getwidget.dart';
三、🗂 组件示例
21. 闪光组件 GFShimmer
属性及含义描述
属性 | 描述 |
---|---|
child | 用以显示微光效果的子组件 |
direction | 动画方向,默认GFShimmerDirection.leftToRight |
duration | 动画时长,默认1.5s |
showGradient | 是否显示渐变色 |
gradient | 渐变色,showGradient 为true 时生效 |
shimmerEffectCount | 动画执行次数,默认0(无限循环) |
showShimmerEffect | 控制动画效果的活跃状态 |
mainColor | 主要颜色 |
secondaryColor | 次要颜色 |
GFShimmer(
child: Container(
width: 100,
height: 100,
// 这里的颜色不会在GFShimmer中显示,但不能为transparent
color: Colors.green,
))
2.这里包裹的是一个行列样式,也可以包裹GFListTile
等封装好的组件来快速实现(SizedBox
和透明的Container
不会被GFShimmer
显示):
GFShimmer(child: shimmerTest())
Widget shimmerTest() {
return Padding(
padding: const EdgeInsets.symmetric(horizontal: 16),
child: Row(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Container(
width: 80,
height: 80,
color: Colors.white,
),
const SizedBox(width: 12),
Expanded(
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[
Container(
width: double.infinity,
height: 15,
color: Colors.white,
),
const SizedBox(height: 6),
Container(
width: MediaQuery.of(context).size.width * 0.5,
height: 15,
color: Colors.white,
),
const SizedBox(height: 6),
Container(
width: MediaQuery.of(context).size.width * 0.25,
height: 15,
color: Colors.white,
),
],
),
)
],
),);
}}
GFShimmer(
child: const Text(
'GF Shimmer',
style: TextStyle(fontSize: 48, fontWeight: FontWeight.w700),
),
showGradient: true,
gradient: LinearGradient(colors: [Colors.red, Colors.blue]),
),
22.动画 GFAnimation
属性及含义描述
属性 | 描述 |
---|---|
duration | 动画执行的持续时间 |
reverseDuration | 反向动画执行的持续时间 |
alignment | 定义动画组件在动画期间的对齐方式 |
activeAlignment | 定义动画组件在动画期间的对齐方式(在 onTap 之后) |
child | 显示动画效果的子组件 |
curve | 动画曲线, 默认为 Curves.linear |
type | GFAnimation 的类型,即 align 、size 、container 、rotateTransition 、scaleTransition 、slideTransition 和 textStyle |
width | 定义 AnimatedContainer 初始宽度 |
changedWidth | 定义 AnimatedContainer 的宽度,它可以在动画期间展开 |
height | 定义 AnimatedContainer 初始高度 |
changedHeight | 定义 AnimatedContainer 的高度,它可以在动画期间展开 |
activeColor | 定义onTap触发时 AnimatedContainer 的颜色 |
color | 定义 AnimatedContainer 的颜色 |
padding | 定义 child 或 AnimatedContainer 的填充 |
margin | 定义 child 或 AnimatedContainer 的边距 |
onTap | 用户点击 child 时的调用 |
turnsAnimation | 对于 GFAnimationType.rotateTransition ,可以在 RotationTransition 小部件中添加自定义的转弯动画 |
scaleAnimation | 对于 GFAnimationType.scaleTransition ,可以在 ScaleTransition 小部件中添加自定义缩放动画 |
controller | 动画的控制器。 |
textDirection | 定义 AnimatedDefaultTextStyle 的文本方向,即 [ltr,rtl] |
slidePosition | 对于 GFAnimationType.slideTransition ,它为组件的位置设置动画 |
style | 文本风格 |
textAlign | 文本对齐方式 |
textOverflow | 文本溢出处理 |
maxLines | 最大行数 |
textWidthBasis | 文本基础宽度 |
fontSize | 字号 |
fontWeight | 字重 |
1.旋转动画示例⬇️:
class GFAnimationPage extends StatefulWidget {
const GFAnimationPage({Key? key}) : super(key: key);
@override
State<GFAnimationPage> createState() => _GFAnimationPagePageState();
}
class _GFAnimationPagePageState extends State<GFAnimationPage> with TickerProviderStateMixin {
late AnimationController controller;
late Animation<double> animation;
bool isWorking = false;
@override
void initState() {
controller = AnimationController(duration: const Duration(seconds: 5), vsync: this);
animation = CurvedAnimation(parent: controller, curve: Curves.linear);
super.initState();
}
@override
void dispose() {
controller.dispose();
super.dispose();
}
...
GFAnimation(
turnsAnimation: animation,
controller: controller,
type: GFAnimationType.rotateTransition,
alignment: Alignment.center,
child: Image.asset(
'images/mypicture.png',
width: 80,
height: 80,
),
),
GFButton(
text: isWorking ? '停止' : ' 播放',
color: isWorking ? Colors.green : Colors.blue,
onPressed: () {
isWorking ? controller.stop() : controller.repeat();
setState(() {
isWorking = !isWorking;
});
}),
}
2.缩放动画:
...
GFAnimation(
turnsAnimation: animation,
controller: controller,
type: GFAnimationType.scaleTransition,
alignment: Alignment.center,
child: Image.asset(
'images/mypicture.png',
width: 80,
height: 80,
),
),
3.对齐动画:
...
GFAnimation(
turnsAnimation: animation,
controller: controller,
type: GFAnimationType.align,
alignment:
isWorking ? Alignment.bottomLeft : Alignment.bottomRight,
child: Image.asset(
'images/mypicture.png',
width: 80,
height: 80,
),
)
4.过渡动画:
...
offsetAnimation = Tween<Offset>(
begin: Offset(0, 0),
end: Offset(1, 0),
).animate(CurvedAnimation(
parent: controller,
curve: Curves.linear,
));
...
Container(
color: Colors.white,
width: MediaQuery.of(context).size.width,
child: GFAnimation(
controller: controller,
slidePosition: offsetAnimation,
type: GFAnimationType.slideTransition,
child: Image.asset(
'images/mypicture.png',
width: 80,
height: 80,
),
),
)
5.一个可以在给定的时间内自动转换尺寸的动态组件:
bool selected = false;
late AnimationController controller;
late Animation<double> animation;
@override
void initState() {
super.initState();
controller = AnimationController(duration: const Duration(seconds: 2), vsync: this);
animation = CurvedAnimation(parent: controller, curve: Curves.linear);
controller.repeat();
}
@override
void dispose() {
controller.dispose();
super.dispose();
}
Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Text('data'),
GFAnimation(
onTap: () {
if (mounted) {
setState(() {
selected = !selected;
});
}
},
width: selected ? 100 : 50,
height: selected ? 100 : 50,
type: GFAnimationType.size,
controller: controller,
child: Image.asset(
'images/mypicture.png',
width: 80,
height: 80,
),
),
Row(
children: [
Expanded(child: SizedBox()),
GFButton(onPressed: () {})
],
)
],
)
6.动画容器:
late AnimationController controller;
late Animation<double> animation;
double fontSize = 30;
@override
void initState() {
super.initState();
controller = AnimationController(duration: const Duration(seconds: 3), vsync: this);
animation = CurvedAnimation(parent: controller, curve: Curves.linear);
controller.repeat();
}
@override
void dispose() {
controller.dispose();
super.dispose();
}
Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Text('这是一段文字'),
GFAnimation(
width: 50,
changedWidth: 100,
height: 50,
changedHeight: 100,
activeColor: Colors.transparent,
color: Colors.transparent,
fontSize: fontSize,
type: GFAnimationType.container,
child: Image.asset(
'images/mypicture.png',
width: 80,
height: 80,
),
),
Row(
children: [
Expanded(child: SizedBox()),
GFButton(text: '这是个按钮', onPressed: () {})
],
)
],
)
23.边框 GFBorder
属性及含义描述
属性 | 描述 |
---|---|
child | Widget 类型的子元素,可以是任何组件或文本等 |
padding | child 的填充 |
strokeWidth | double 类型,用于定义边框的粗细 |
color | 用于更改边框类型的颜色 |
dashedLine | 用于实现边框实线和虚线的数组,例如dashedLine: [14, 4] , 这里的14代表单个实线长度,4代表虚线长度 |
type | GFBorderType 的类型,用于定义不同类型的边框,即圆形、矩形 和椭圆形 |
radius | 边框的圆角属性 |
1.基础样式⬇️:
GFBorder(
color: Color(0xFF19CA4B),
type: GFBorderType.rect,
child: Image.asset(
'images/picture.png',
width: 200,
fit: BoxFit.fitWidth,
),
)
2.虚线边框:
GFBorder(
color: Color(0xFF19CA4B),
// 这里的14代表单个实线长度,4代表虚线长度
dashedLine: [14, 4],
type: GFBorderType.rect,
child: Image.asset(
'images/picture.png',
width: 200,
fit: BoxFit.fitWidth,
),
)
3. 点边框:
GFBorder(
color: Color(0xFF19CA4B),
dashedLine: [1, 2],
type: GFBorderType.rect,
child: Image.asset(
'images/picture.png',
width: 200,
fit: BoxFit.fitWidth,
),
)
4.圆角边框:
GFBorder(
radius: Radius.circular(20),
color: Color(0xFF19CA4B),
dashedLine: [2, 0],
type: GFBorderType.rRect,
child: Container(
height: 100,
color: Color(0xFFE9FFEF),
),
)
5.椭圆形边框:
GFBorder(
type: GFBorderType.oval,
dashedLine: [2, 0],
color: Color(0xFF19CA4B),
strokeWidth: 2,
child: Center(child: Text('Oval Border')),
)
6.圆形边框(虚线、点等同理):
SizedBox(
width: 100,
height: 100,
child: GFBorder(
type: GFBorderType.circle,
dashedLine: [1, 0],
color: Color(0xFF19CA4B),
strokeWidth: 2,
child: Center(
child: Text(
'Circular Border',
textAlign: TextAlign.center,
)),
),
),
24.底部抽屉 GFBottomSheet
属性及含义描述
属性 | 描述 |
---|---|
minContentHeight | 内容的最小高度。当 enableExpandableContent 为 false 时生效,必须大于或等于0,默认值为 0 |
maxContentHeight | 内容的最大高度。必须大于等于0。默认值为300 |
stickyHeader | GFBottomSheet 的表头。可以通过滑动或点击 stickyHeader 进行交互 |
contentBody | GFBottomSheet 的主体。可以通过滑动或点击 contentBody 进行交互 |
stickyFooter | GFBottomSheet 的底部。可以通过滑动或点击 stickyFooter 进行交互 |
stickyFooterHeight | 定义 GFBottomSheet 的底部高度 |
stickyHeaderHeight | 定义 GFBottomSheet 的表头高度 |
elevation | 可以理解为垂直高度,控制 GFBottomSheet 下方的阴影。必须大于等于 0,默认值为 0。 |
enableExpandableContent | 是否允许 contentBody 展开。默认值为 false。 |
controller | GFBottomSheet 控制器 |
animationDuration | 展开 / 收起动画持续时长 |
示例代码⬇️:
import 'package:flutter/material.dart';
import 'package:getwidget/getwidget.dart';
class GFBottomSheetPage extends StatefulWidget {
const GFBottomSheetPage({Key? key}) : super(key: key);
@override
State<GFBottomSheetPage> createState() => _GFBottomSheetPagePageState();
}
class _GFBottomSheetPagePageState extends State<GFBottomSheetPage> {
final GFBottomSheetController controller = GFBottomSheetController();
@override
Widget build(BuildContext context) {
return Scaffold(
backgroundColor: Colors.blueGrey,
bottomSheet: GFBottomSheet(
animationDuration: 500,
controller: controller,
maxContentHeight: 150,
stickyHeaderHeight: 100,
stickyHeader: Container(
decoration: BoxDecoration(
color: Colors.white,
boxShadow: [BoxShadow(color: Colors.black45, blurRadius: 0)]),
child: const GFListTile(
avatar: GFAvatar(
backgroundImage: AssetImage('images/mypicture.png'),
),
titleText: '晚夜',
subTitleText: 'Flutter工程师',
),
),
contentBody: Container(
height: 250,
margin: EdgeInsets.symmetric(horizontal: 15, vertical: 10),
child: ListView(
shrinkWrap: true,
physics: const ScrollPhysics(),
children: const [
Center(
child: Text(
'Flutter 是 Google 开源的应用开发框架,拥有120fps的刷新率,也是目前非常流行的跨平台UI开发框架。\n本专栏为大家收集了Github上近70个优秀开源库,后续也将持续更新。希望可以帮助大家提升搬砖效率,同时祝愿Flutter的生态越来越完善🎉🎉。',
style: TextStyle(
fontSize: 15, wordSpacing: 0.3, letterSpacing: 0.2),
))
],
),
),
stickyFooter: Container(
color: GFColors.SUCCESS,
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
children: [
Text(
'Flutter轮子推荐',
style: TextStyle(
fontSize: 18,
fontWeight: FontWeight.bold,
color: Colors.white),
),
Text(
'Getwidget',
style: TextStyle(fontSize: 15, color: Colors.white),
),
],
),
),
stickyFooterHeight: 50,
),
floatingActionButton: FloatingActionButton(
backgroundColor: GFColors.SUCCESS,
child: controller.isBottomSheetOpened
? Icon(Icons.keyboard_arrow_down)
: Icon(Icons.keyboard_arrow_up),
onPressed: () {
controller.isBottomSheetOpened
? controller.hideBottomSheet()
: controller.showBottomSheet();
}),
);
}
}
25.复选框 GFCheckbox
属性及含义描述
属性 | 描述 |
---|---|
type | 复选框类型 |
size | 复选框尺寸 |
activeBgColor | 选中背景色 |
inactiveBgColor | 未选中背景色 |
activeBorderColor | 选中边框颜色 |
inactiveBorderColor | 未选中边框颜色 |
onChanged | 状态改变回调 |
value | 是否选中 |
activeIcon | 选中图标样式 |
inactiveIcon | 未选中图标样式 |
customBgColor | 自定义样式背景色 |
autofocus | 在真实状态下,当当前范围内没有其他节点处于焦点时,此复选框将被选为初始焦点 |
focusNode | 一个可选的焦点节点,用作此复选框的焦点节点。 |
1.基础样式(带圆角)⬇️:
GFCheckbox(
size: GFSize.SMALL,
activeBgColor: GFColors.SUCCESS,
onChanged: (value) {
setState(() {
isChecked = value;
});
},
value: isChecked,
)
2.正方形样式:
type: GFCheckboxType.square,
3.圆形样式:
type: GFCheckboxType.circle,
4.自定义样式:
GFCheckbox(
type: GFCheckboxType.square,
activeBgColor: GFColors.SECONDARY,
activeIcon: Icon(Icons.sentiment_satisfied),
onChanged: (value) {
setState(() {
isChecked = value;
});
},
value: isChecked,
inactiveIcon: Icon(Icons.sentiment_dissatisfied),
)
5.示例:
bool isSmileChecked = false;
bool isMiddleChecked = false;
bool isLargeChecked = false;
GFCard(
content: Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: <Widget>[
GFCheckbox(
size: GFSize.SMALL,
activeBgColor: GFColors.DANGER,
onChanged: (value) {
setState(() {
isSmileChecked = value;
});
},
value: isSmileChecked,
inactiveIcon: null,
),
GFCheckbox(
activeBgColor: GFColors.SECONDARY,
onChanged: (value) {
setState(() {
isMiddleChecked = value;
});
},
value: isMiddleChecked,
inactiveIcon: null,
),
GFCheckbox(
size: GFSize.LARGE,
activeBgColor: GFColors.SUCCESS,
onChanged: (value) {
setState(() {
isLargeChecked = value;
});
},
value: isLargeChecked,
inactiveIcon: null,
),
],
),
)