FlutterUnit & TolyUI | 布局游乐场
FlutterUnit 基于 TolyUI 大大简化了界面构建的代码复杂程度,因此之前想要实现的一些小功能,就可以轻松支持。
布局游乐场是通过交互的方式来 直观体验 组件的布局特性,从而更易学和掌握。
目前 FlutterUnit 已在 知识集录模块新增了 布局宝库, 大家可以更新代码查看 ~
1. 什么是布局游乐场对于新手朋友,对有些较复杂的布局组件很难把握其特性。为此 FlutterUnit 设立了 布局宝库 模块,来帮助开发者更容易理解 Flutter 中的布局特性以及核心的布局组件。
其中的 Playground 指的是可交互操作的组件展示面板,如下的 Flex Playground 将淋漓尽致地展示 Flex 组件布局特性。
Playground 实现过程中,依赖了很多 TolyUI 中的组件:
对于枚举类型的参数,通过 TolySelect 组件处理选择事件。操作的图标按钮使用 TolyAction 组件。布局宝库的侧栏导航,使用 TolyRailMenuTree 组件。目前已经完成了 Flex、Wrap、Stack 三个多字布局的 Playground 。可以在操作面板中增加/删除,指定宽高的色块。来更好的体验组件的布局效果。
2. Flex Playground 功能实现 - 数据层下面以 Flex Playground 来介绍一下功能实现。一个 Playground 主要包括两个区域:左侧的组件 效果展示区 和右侧的 操作面板区。其中右侧的交互操作会影响左侧的效果展示:
image.png我们知道 Flutter 中,数据决定界面的表现,首先应该确定 Flex Playground 中依赖了哪些数据。
当前功能是通过交互修改 Flex 组件的属性,所以 Flex 组件的属性内容是一份需要维护的状态。通过下面的 FlexAttr 类承载各个属性数据:
classFlexAttr{
finalAxisdirection;
finalMainAxisAlignmentmainAxisAlignment;
finalCrossAxisAlignmentcrossAxisAlignment;
finalMainAxisSizemainAxisSize;
finalTextDirectiontextDirection;
finalVerticalDirectionverticalDirection;
finalTextBaselinetextBaseline;
另外,需要若干个色块,它们有各自的宽度和高度,通过 DisplayItem 类承载相关数据:
classDisplayItem{
finaldoublewidth;
finaldoubleheight;
finalColorcolor;
这样 Flex Playground 中的状态数据就呼之欲出了:
[1] . DisplayItem 列表数据,记录色块信息。[2]. _selectIndex 选中的色块索引,用于删除色块。[3]. FlexAttr 数据,决定 Flex 组件的展示效果。class_FlexPlaygroundStateextendsStateFlexPlayground{
ListDisplayItem_data=
lateFlexAttr_attr;
int_selectIndex=-1;
3. Flex Playground 功能实现 - 视图层左侧的布局效果展示区封装为如下的 FlexDisplay 组件,依赖三个状态数据,通过 Flex 组件来构建展示内容。其中,
Flex 构造函数中的各个属性由 FlexAttr 数据提供;children 组件由 ListDisplayItem 数据映射得到;色块的选中事件,通过 onSelectChanged 回调,交由使用者处理,更新激活索引。image.pngclassFlexDisplayextendsStatelessWidget{
finalListDisplayItemitems;
finalFlexAttrattr;
finalintselectIndex;
finalValueChangedintonSelectChanged;
constFlexDisplay({
super.key,
requiredthis.items,
requiredthis.attr,
requiredthis.selectIndex,
requiredthis.onSelectChanged,
@override
Widgetbuild(BuildContextcontext){
returnFlex(
direction:attr.direction,
mainAxisAlignment:attr.mainAxisAlignment,
crossAxisAlignment:attr.crossAxisAlignment,
mainAxisSize:attr.mainAxisSize,
textDirection:attr.textDirection,
verticalDirection:attr.verticalDirection,
textBaseline:TextBaseline.alphabetic,
children:items.asMap().keys.map((intindex){
boolactive=selectIndex==index;
returnGestureDetector(
onTap:()=onSelectChanged(index),
child:DisplayPlayItem(item:items[index],selected:active),
}).toList(),
}
}
右侧的操作面板需要支持交互操作,通过触发事件来更新状态数据,然后更新界面,即可实现我们期望的功能。
Flex 组件的属性中有很多枚举值,这比较适合使用下拉选择来处理。
Flutter 中自带的选择器在桌面端的体验效果并不是很好,于是 TolyUI 中提供了 TolySelect 组件,便于构建类似的选择功能:
image.png右侧的面板通过 FlexOpTool 组件展示,其中添加、删除、重置的按钮事件,分别通过回调交由使用者处理。
另外属性操作时数据的变化,也会通过 ValueChanged 通知外界进行数据处理。
也就是说 FlexOpTool 本身并不参与状态数据的维护逻辑。只负责基于数据构建界面,以及数据变化时的回调通知:
classFlexOpToolextendsStatefulWidget{
finalValueChangedSizeonAddBox;
finalVoidCallbackonDelete;
finalVoidCallbackonReset;
finalFlexAttrattr;
finalValueChangedFlexAttronAttrChange;
这里着重介绍一下选择器的使用, TolySelect 主要通过 String 列表 data 和激活索引 selectIndex 决定菜单项羽和激活项;通过 cellStyle 可以简单定制菜单项的展示效果。
由于这里选择器的使用场合非常多,所以封装了 ItemSelector 组件统一处理标题、布局等效果:
image.pngtypedefNameCalc=StringFunction(Tdata);
classItemSelectorTextendsStatelessWidget{
finalintselectIndex;
finalListdata;
finalNameCalccalcFun;
finalValueChangedonSelect;
finalStringlabel;
finalStringsubTitle;
constItemSelector({
super.key,
requiredthis.selectIndex,
requiredthis.data,
requiredthis.calcFun,
requiredthis.onSelect,
requiredthis.subTitle,
requiredthis.label,
@override
Widgetbuild(BuildContextcontext){
TextStylelabelStyle=constTextStyle(color:Color(0xff61666d),fontSize:12);
DropMenuCellStylelightStyle=constDropMenuCellStyle(
padding:EdgeInsets.symmetric(horizontal:4,vertical:1),
borderRadius:BorderRadius.all(Radius.circular(6)),
foregroundColor:Color(0xff1f1f1f),
backgroundColor:Colors.transparent,
disableColor:Color(0xffbfbfbf),
hoverBackgroundColor:Color(0xfff5f5f5),
hoverForegroundColor:Color(0xff1f1f1f),
textStyle:TextStyle(fontSize:11)
returnPadding(
padding:constEdgeInsets.symmetric(horizontal:8.0,vertical:6),
child:Row(
children:[
Column(
crossAxisAlignment:CrossAxisAlignment.start,
children:[
Text(label,style:labelStyle),
Text(subTitle,style:labelStyle.copyWith(fontSize:8)),
],
),
constSpacer(),
TolySelect(
fontSize:11,
cellStyle:lightStyle,
data:data.map((e)=calcFun(e)).toList(),
selectIndex:selectIndex,
iconSize:16,
height:25,
width:110,
maxHeight:200,
onSelected:(intindex)=onSelect(data[index]),
)
],
),
}
}
4. Flex Playground 功能实现 - 数据逻辑层FlexOpTool 提供了交互过程中数据变化的时机,使用者需要在对应的时机来维护状态数据的正确性。
image.png如下所示,_onAddBox 方法,会在 DisplayItem 列表中增加一个色块,触发 setState 重新构建;_deleteSelectIndex 方法将移除对应索引的色块,并重新构建更新界面:
void_onAddBox(Sizesize){
intindex=_data.length+1;
Colorcolor=kColors[index%kColors.length];
_data.add(DisplayItem(width:size.width,height:size.height,color:color));
setState(()
}
void_deleteSelectIndex(){
if(_selectIndex0||_selectIndex=_data.length){
$message.warning(message:'请先选择删除的色块!');
return;
}
_data.removeAt(_selectIndex);
_selectIndex=-1;
setState(()
}
当属性数据变化,通过 _onAttrChange 方法更新 _attr 数据即可;重置回调时,将三个状态数据设为初始值:
void_onAttrChange(FlexAttrattr){
setState((){
_attr=attr;
}
void_reset({boolinit=false}){
_attr=FlexAttr(direction:Axis.horizontal);
_data=[
DisplayItem(width:20,height:20,color:kColors[0]),
DisplayItem(width:10,height:80,color:kColors[1]),
DisplayItem(width:40,height:30,color:kColors[2]),
DisplayItem(width:60,height:20,color:kColors[3]),
_selectIndex=-1;
if(init)return;
setState(()
}
这就是 Flex Playground 功能的核心实现过程,紧紧把握 状态数据、组件构建、交互事件 和 数据维护 四个方面,就可以很轻松地完成任何功能需求。
其他的 Playground 实现方式类似,就不一一介绍了,希望大家可以在 布局游乐场 中,通过交互的方式,学习更多知识。
以后,FlutterUnit 将在 TolyUI 的加持下,支持更多的好玩和使用的功能,敬请期待~
阅读原文
网站开发网络凭借多年的网站建设经验,坚持以“帮助中小企业实现网络营销化”为宗旨,累计为4000多家客户提供品质建站服务,得到了客户的一致好评。如果您有网站建设、网站改版、域名注册、主机空间、手机网站建设、网站备案等方面的需求...
请立即点击咨询我们或拨打咨询热线:13245491521 13245491521 ,我们会详细为你一一解答你心中的疑难。 项目经理在线