2 changed files with 271 additions and 7 deletions
@ -0,0 +1,236 @@ |
|||
import 'package:flutter/material.dart'; |
|||
import 'package:flutter_screenutil/flutter_screenutil.dart'; |
|||
import 'package:get/get.dart'; |
|||
|
|||
class RowKeypressWidget extends StatefulWidget { |
|||
final Map templateData; |
|||
|
|||
const RowKeypressWidget(this.templateData, {super.key}); |
|||
|
|||
@override |
|||
State<RowKeypressWidget> createState() => _RowKeypressWidgetState(); |
|||
} |
|||
|
|||
class _RowKeypressWidgetState extends State<RowKeypressWidget> { |
|||
Map get _templateData => widget.templateData; |
|||
|
|||
String _getLabel(int value) { |
|||
return _templateData['options'].firstWhere((item) => item['value'] == value, |
|||
orElse: () => {'label': ''})['label']; |
|||
} |
|||
|
|||
@override |
|||
Widget build(BuildContext context) { |
|||
final isDarkMode = Theme.of(context).brightness == Brightness.dark; |
|||
|
|||
return Column( |
|||
children: [ |
|||
Padding( |
|||
padding: EdgeInsets.symmetric(vertical: 10.w), |
|||
child: Row( |
|||
children: [ |
|||
const Spacer(), |
|||
Expanded( |
|||
child: Text( |
|||
'左', |
|||
textAlign: TextAlign.center, |
|||
style: TextStyle( |
|||
fontSize: 14.sp, |
|||
color: isDarkMode ? Colors.white : Colors.black, |
|||
), |
|||
), |
|||
), |
|||
Expanded( |
|||
child: Text( |
|||
'右', |
|||
textAlign: TextAlign.center, |
|||
style: TextStyle( |
|||
fontSize: 14.sp, |
|||
color: isDarkMode ? Colors.white : Colors.black, |
|||
), |
|||
), |
|||
), |
|||
], |
|||
), |
|||
), |
|||
..._templateData['data'] |
|||
.map((item) => _rowItem(isDarkMode, item)) |
|||
.toList(), |
|||
], |
|||
); |
|||
} |
|||
|
|||
Widget _rowItem(bool isDarkMode, Map item) { |
|||
return Padding( |
|||
padding: EdgeInsets.symmetric(vertical: 10.w), |
|||
child: Row( |
|||
children: [ |
|||
Expanded( |
|||
child: Text( |
|||
item['label'], |
|||
textAlign: TextAlign.center, |
|||
style: TextStyle( |
|||
fontSize: 14.sp, |
|||
color: isDarkMode ? Colors.white : Colors.black, |
|||
), |
|||
), |
|||
), |
|||
Expanded( |
|||
child: GestureDetector( |
|||
onTap: () => _radioDialog(isDarkMode, item, 'left'), |
|||
behavior: HitTestBehavior.translucent, |
|||
child: Text( |
|||
_getLabel(item['left']), |
|||
textAlign: TextAlign.center, |
|||
style: TextStyle( |
|||
fontSize: 12.sp, |
|||
color: isDarkMode ? Colors.white : Colors.grey, |
|||
), |
|||
), |
|||
), |
|||
), |
|||
Expanded( |
|||
child: GestureDetector( |
|||
onTap: () => _radioDialog(isDarkMode, item, 'right'), |
|||
behavior: HitTestBehavior.translucent, |
|||
child: Text( |
|||
_getLabel(item['right']), |
|||
textAlign: TextAlign.center, |
|||
style: TextStyle( |
|||
fontSize: 12.sp, |
|||
color: isDarkMode ? Colors.white : Colors.grey, |
|||
), |
|||
), |
|||
), |
|||
), |
|||
], |
|||
), |
|||
); |
|||
} |
|||
|
|||
void _radioDialog(bool isDarkMode, Map item, String key) { |
|||
Get.dialog( |
|||
Dialog( |
|||
backgroundColor: isDarkMode ? Colors.grey[900] : Colors.white, |
|||
shape: RoundedRectangleBorder( |
|||
borderRadius: BorderRadius.circular(16.r), |
|||
), |
|||
child: Padding( |
|||
padding: EdgeInsets.all(12.w), |
|||
child: Column( |
|||
mainAxisSize: MainAxisSize.min, |
|||
crossAxisAlignment: CrossAxisAlignment.start, |
|||
children: [ |
|||
Text( |
|||
'${item['label']}-${key == 'left' ? '左' : '右'}', |
|||
style: TextStyle( |
|||
fontSize: 18.sp, |
|||
fontWeight: FontWeight.w600, |
|||
color: isDarkMode ? Colors.white : Colors.black87, |
|||
), |
|||
), |
|||
SizedBox(height: 16.h), |
|||
Container( |
|||
constraints: BoxConstraints(maxHeight: 0.5.sh), |
|||
child: SingleChildScrollView( |
|||
child: Column( |
|||
mainAxisSize: MainAxisSize.min, |
|||
children: _templateData['options'] |
|||
.map<Widget>((option) => |
|||
_radioItem(isDarkMode, option, item, key)) |
|||
.toList(), |
|||
), |
|||
), |
|||
), |
|||
SizedBox(height: 16.h), |
|||
Row( |
|||
mainAxisAlignment: MainAxisAlignment.end, |
|||
children: [ |
|||
TextButton( |
|||
onPressed: () => Get.back(), |
|||
child: Text( |
|||
'cancel'.tr, // 取消 |
|||
style: TextStyle( |
|||
color: isDarkMode ? Colors.white70 : Colors.black54, |
|||
), |
|||
), |
|||
), |
|||
], |
|||
), |
|||
], |
|||
), |
|||
), |
|||
), |
|||
); |
|||
} |
|||
|
|||
Widget _radioItem(bool isDarkMode, Map option, Map item, String key) { |
|||
return GestureDetector( |
|||
onTap: () { |
|||
setState(() { |
|||
item[key] = option['value']; |
|||
}); |
|||
Map data = { |
|||
'key': item['key'], |
|||
key: option['value'], |
|||
}; |
|||
_templateData['onCallback'](data); |
|||
Get.back(); |
|||
}, |
|||
child: Container( |
|||
margin: EdgeInsets.only(bottom: 10.h), |
|||
padding: EdgeInsets.all(10.w), |
|||
decoration: BoxDecoration( |
|||
color: item[key] == option['value'] |
|||
? (isDarkMode |
|||
? Colors.teal[900]!.withValues(alpha: 0.3) |
|||
: Colors.teal[50]!) |
|||
: (isDarkMode |
|||
? Colors.white.withValues(alpha: 0.05) |
|||
: Colors.grey[100]!), |
|||
borderRadius: BorderRadius.circular(12.r), |
|||
border: Border.all( |
|||
color: item[key] == option['value'] |
|||
? (isDarkMode ? Colors.teal[300]! : Colors.teal[600]!) |
|||
: Colors.transparent, |
|||
width: 1, |
|||
), |
|||
), |
|||
child: Row( |
|||
children: [ |
|||
Expanded( |
|||
child: Text( |
|||
option['label'], |
|||
style: TextStyle( |
|||
fontSize: 16.sp, |
|||
fontWeight: FontWeight.w500, |
|||
color: isDarkMode ? Colors.white : Colors.black87, |
|||
), |
|||
overflow: TextOverflow.ellipsis, |
|||
), |
|||
), |
|||
Container( |
|||
width: 24.w, |
|||
height: 24.w, |
|||
decoration: BoxDecoration( |
|||
color: item[key] == option['value'] |
|||
? (isDarkMode ? Colors.teal[300] : Colors.teal[600]) |
|||
: (isDarkMode |
|||
? Colors.white.withValues(alpha: 0.1) |
|||
: Colors.grey[300]), |
|||
shape: BoxShape.circle, |
|||
), |
|||
child: item[key] == option['value'] |
|||
? Icon( |
|||
Icons.check, |
|||
size: 16.w, |
|||
color: Colors.white, |
|||
) |
|||
: null, |
|||
), |
|||
], |
|||
), |
|||
), |
|||
); |
|||
} |
|||
} |
|||
Loading…
Reference in new issue