import 'package:cached_network_image/cached_network_image.dart'; import 'package:flutter/cupertino.dart'; import 'package:flutter/material.dart'; import 'package:flutter_screenutil/flutter_screenutil.dart'; import 'package:keyboard/data/bean/option_select_item.dart'; import '../../../data/bean/option_select_config.dart'; import '../../../resource/colors.gen.dart'; /// 切换选中时回调 typedef OnOptionSelectCallback = void Function(OptionSelectConfig config, OptionSelectItem optionItem); /// 选项选择组件 class OptionSelectWidget extends StatelessWidget { /// 选项行的配置 final OptionSelectConfig optionSelect; /// 切换选中时回调 final OnOptionSelectCallback optionSelectCallback; const OptionSelectWidget({ super.key, required this.optionSelect, required this.optionSelectCallback, }); @override Widget build(BuildContext context) { return Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ // 标题 _buildTitle(), SizedBox(height: 8.h), // 选项 _buildOptionList(), ], ); } /// 图标和标题 Widget _buildTitle() { String icon = optionSelect.iconUrl; return Row( children: [ Visibility( visible: icon.isNotEmpty, child: Row( children: [ // 图标 CachedNetworkImage( imageUrl: icon, height: 14.h, width: 14.w, fit: BoxFit.fill, ), SizedBox(width: 2), ], ), ), // 标题 Text( optionSelect.title, style: TextStyle( fontSize: 12.sp, fontWeight: FontWeight.w500, color: ColorName.black80, ), ), ], ); } /// 选项列表 Widget _buildOptionList() { // 固定一行3列,每项的宽度一样 return GridView.builder( // 去掉默认的Padding,默认会有一个默认的顶部padding大小 padding: EdgeInsets.zero, // 包裹内容 shrinkWrap: true, // 禁止滚动 physics: const NeverScrollableScrollPhysics(), gridDelegate: SliverGridDelegateWithFixedCrossAxisCount( // 一行3列 crossAxisCount: 3, // 垂直方向的间距 crossAxisSpacing: 8.0, // 水平方向的间距 mainAxisSpacing: 7.0, // 子项的宽高比 childAspectRatio: 2.6, ), itemCount: optionSelect.options.length, itemBuilder: (context, index) { OptionSelectItem option = optionSelect.options[index]; return _buildOptionItem(optionSelect, option); }, ); // 流式布局,类似安卓的FlowLayout,1列不固定3个,放不下就自动换行 // return Wrap( // direction: Axis.horizontal, // alignment: WrapAlignment.start, // // 主轴间距 // spacing: 8.0, // // 交叉轴间距 // runSpacing: 7.0, // children: [ // for (var option in optionSelect.options) // _buildOptionItem(optionSelect, option), // ], // ); } /// 选项 /// [rowConfig] 选项行的配置 /// [optionItem] 当前构建的那一项 Widget _buildOptionItem( OptionSelectConfig rowConfig, OptionSelectItem optionItem, ) { // 背景圆角 double bgBorderRadius = 31.r; // 背景,选中时为渐变色,未选中时为灰色 BoxDecoration bgDecoration; if (optionItem.selected) { bgDecoration = BoxDecoration( gradient: LinearGradient( colors: [ ColorName.bgOptionSelectSelected1, ColorName.bgOptionSelectSelected2, ], begin: Alignment.centerLeft, end: Alignment.centerRight, ), borderRadius: BorderRadius.circular(bgBorderRadius), ); } else { bgDecoration = BoxDecoration( color: ColorName.bgOptionSelectNormal, borderRadius: BorderRadius.circular(bgBorderRadius), ); } return GestureDetector( onTap: () { optionSelectCallback(rowConfig, optionItem); }, child: Container( // padding: EdgeInsets.symmetric(horizontal: 12.w, vertical: 6.h), decoration: bgDecoration, child: Center( child: Text( optionItem.name, style: TextStyle( fontSize: 13.sp, fontWeight: FontWeight.w400, // 文字颜色,选中时为白色,未选中时为黑色 color: optionItem.selected ? ColorName.white : ColorName.black80, ), ), ), ), ); } }