import 'package:flutter/material.dart'; import '../tools/tools.dart'; /// 自定义组件 class ListItemFactory { /// 类型1:横向spaceBetween布局两个文本加按钮 static Widget createRowSpaceBetweenItem({ required String leftText, required String rightText, double verticalPadding = 10, double horizontalPadding = 0, Color textColor = Colors.black, bool isRight = false, }) { return Padding( padding: EdgeInsets.symmetric( vertical: verticalPadding, horizontal: horizontalPadding, ), child: Row( mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [ Text( leftText, style: TextStyle( fontSize: 15, fontWeight: FontWeight.bold, color: textColor, ), ), if (isRight) Row( mainAxisAlignment: MainAxisAlignment.center, children: [ Text( rightText, style: TextStyle(fontSize: 15, color: Colors.grey), ), SizedBox(width: 2,), Icon(Icons.arrow_forward_ios_rounded, color: Colors.black45, size: 15), ], ) else Text(rightText, style: TextStyle(fontSize: 15, color: Colors.grey)), ], ), ); } ///类型2:上下布局两个文本(自适应高度) static Widget createColumnTextItem({ required String topText, required String bottomText, double verticalPadding = 15, double horizontalPadding = 0, }) { return Padding( padding: EdgeInsets.symmetric( vertical: verticalPadding, horizontal: horizontalPadding, ), child: Column( crossAxisAlignment: CrossAxisAlignment.start, mainAxisSize: MainAxisSize.min, children: [ Text( topText, style: TextStyle( fontSize: 15, fontWeight: FontWeight.bold, color: Colors.black, ), ), const SizedBox(height: 5), Text( bottomText, style: TextStyle(fontSize: 15, color: Colors.grey), softWrap: true, maxLines: null, // 允许无限行数 ), ], ), ); } /// 类型3:文本和图片上下布局 static Widget createTextImageItem({ required String text, required List imageUrls, double imageHeight = 90, double verticalPadding = 10, double horizontalPadding = 0, // 点击图片时回调,index 为被点击图片的下标 void Function(int index)? onImageTapped, }) { return Padding( padding: EdgeInsets.symmetric( vertical: verticalPadding, horizontal: horizontalPadding, ), child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ Text( text, style: const TextStyle( fontSize: 15, fontWeight: FontWeight.bold, color: Colors.black, ), ), const SizedBox(height: 10), Wrap( spacing: 8, // 水平间距 runSpacing: 8, // 垂直间距 children: List.generate(imageUrls.length, (i) { final url = imageUrls[i]; Widget img; if (url.startsWith('http')) { img = Image.network( url, height: imageHeight, width: imageHeight * 3 / 2, fit: BoxFit.cover, ); } else { img = Image.asset( url, height: imageHeight, width: imageHeight * 3 / 2, fit: BoxFit.cover, ); } return GestureDetector( onTap: () { if (onImageTapped != null) onImageTapped(i); }, child: ClipRRect( borderRadius: BorderRadius.circular(4), child: img, ), ); }), ), ], ), ); } /// 类型6:文本和视频上下布局 static Widget createTextVideoItem({ required String text, required String videoUrl, double videoHeight = 90, double verticalPadding = 10, double horizontalPadding = 0, VoidCallback? onVideoTapped, }) { return Padding( padding: EdgeInsets.symmetric( vertical: verticalPadding, horizontal: horizontalPadding, ), child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ Text( text, style: const TextStyle( fontSize: 15, fontWeight: FontWeight.bold, color: Colors.black, ), ), const SizedBox(height: 10), GestureDetector( onTap: onVideoTapped, child: Container( height: videoHeight, width: videoHeight * 3 / 2, decoration: BoxDecoration( color: Colors.grey[300], borderRadius: BorderRadius.circular(4), ), child: const Center( child: Icon( Icons.play_circle_outline, size: 40, color: Colors.white, ), ), ), ), ], ), ); } ///类型4:一个文本(自适应高度) static Widget createAloneTextItem({ required String text, double verticalPadding = 10, double horizontalPadding = 0, }) { return Padding( padding: EdgeInsets.symmetric( vertical: verticalPadding, horizontal: horizontalPadding, ), child: Column( crossAxisAlignment: CrossAxisAlignment.start, mainAxisSize: MainAxisSize.min, children: [ Text( text, style: TextStyle(fontSize: 15, color: Colors.grey), softWrap: true, maxLines: null, // 允许无限行数 ), ], ), ); } /// 分类头部 static Widget createYesNoSection({ required String title, required String yesLabel, required String noLabel, required bool groupValue, required ValueChanged onChanged, double verticalPadding = 15, double horizontalPadding = 10, }) { return Padding( padding: EdgeInsets.only(top: 0, right: horizontalPadding, left: horizontalPadding, bottom: verticalPadding), child: Container( padding: EdgeInsets.symmetric(horizontal: 10), decoration: BoxDecoration( color: Colors.white, borderRadius: BorderRadius.circular(5), ), child: Row( children: [ Expanded( child: Text( title, style: TextStyle( fontSize: 15, fontWeight: FontWeight.bold, color: Colors.black, ), ), ), Row( children: [ Row( children: [ Radio( activeColor: Colors.blue, value: true, groupValue: groupValue, onChanged: (val) => onChanged(val!), ), Text(yesLabel), ], ), const SizedBox(width: 16), Row( children: [ Radio( activeColor: Colors.blue, value: false, groupValue: groupValue, onChanged: (val) => onChanged(val!), ), Text(noLabel), ], ), ], ), ], ), ), ); } /// 列表标题头(蓝色标识+文字) static Widget createBuildSimpleSection(String title) { return Container( decoration: BoxDecoration( color: Colors.white, borderRadius: BorderRadius.circular(8), ), child: Padding( padding: const EdgeInsets.symmetric(horizontal: 10, vertical: 10), child: Row( children: [ Container(width: 3, height: 15, color: Colors.blue), const SizedBox(width: 8), Text( title, style: const TextStyle(fontSize: 16, fontWeight: FontWeight.bold), ), ], ), ), ); } /// 扩展项(根据需求自定义) static Widget createCustomItem({ required Widget child, double verticalPadding = 15, double horizontalPadding = 0, }) { return Padding( padding: EdgeInsets.symmetric( vertical: verticalPadding, horizontal: horizontalPadding, ), child: child, ); } /// 标题加输入框上下排列 static Widget createBuildMultilineInput( String label, String hint, TextEditingController controller, ) { return Container( height: 130, padding: const EdgeInsets.only(top: 8), child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ HhTextStyleUtils.mainTitle(label, fontSize: 15), const SizedBox(height: 8), Expanded( child: TextField( controller: controller, keyboardType: TextInputType.multiline, maxLines: null, expands: true, style: const TextStyle(fontSize: 15), decoration: InputDecoration( hintText: hint, border: InputBorder.none, ), ), ), ], ), ); } }