如何在Flutter中实现如图所示的自定义RadioButton?
你可以通过组合基础组件并配合状态管理,实现如图所示的自定义RadioButton,下面是完整的可复用实现方案:
自定义RadioButton组件代码
import 'package:flutter/material.dart'; class CustomRadio<T> extends StatefulWidget { final T value; final T groupValue; final ValueChanged<T?> onChanged; final Color activeColor; final Color inactiveBorderColor; final double size; const CustomRadio({ Key? key, required this.value, required this.groupValue, required this.onChanged, this.activeColor = Colors.blue, this.inactiveBorderColor = Colors.grey, this.size = 24.0, }) : super(key: key); @override State<CustomRadio<T>> createState() => _CustomRadioState<T>(); } class _CustomRadioState<T> extends State<CustomRadio<T>> { bool get _isSelected => widget.value == widget.groupValue; @override Widget build(BuildContext context) { return InkWell( onTap: () => widget.onChanged(widget.value), borderRadius: BorderRadius.circular(widget.size / 2), child: Container( width: widget.size, height: widget.size, decoration: BoxDecoration( shape: BoxShape.circle, border: Border.all( color: _isSelected ? widget.activeColor : widget.inactiveBorderColor, width: 2.0, ), color: _isSelected ? widget.activeColor.withOpacity(0.2) : Colors.transparent, ), child: _isSelected ? Center( child: Container( width: widget.size * 0.5, height: widget.size * 0.5, decoration: BoxDecoration( shape: BoxShape.circle, color: widget.activeColor, ), ), ) : null, ), ); } }
使用示例
class RadioDemoPage extends StatefulWidget { const RadioDemoPage({Key? key}) : super(key: key); @override State<RadioDemoPage> createState() => _RadioDemoPageState(); } class _RadioDemoPageState extends State<RadioDemoPage> { String? _selectedOption; @override Widget build(BuildContext context) { return Scaffold( appBar: AppBar(title: const Text("自定义RadioButton示例")), body: Padding( padding: const EdgeInsets.all(16.0), child: Column( children: [ Row( children: [ CustomRadio<String>( value: "option1", groupValue: _selectedOption, onChanged: (value) => setState(() => _selectedOption = value), ), const SizedBox(width: 8), const Text("选项1"), ], ), const SizedBox(height: 16), Row( children: [ CustomRadio<String>( value: "option2", groupValue: _selectedOption, onChanged: (value) => setState(() => _selectedOption = value), activeColor: Colors.green, ), const SizedBox(width: 8), const Text("选项2(自定义选中颜色)"), ], ), ], ), ), ); } }
关键特性说明
- 泛型设计:支持任意类型的选项值(字符串、整数等)
- 状态同步:通过
groupValue和value的对比判断选中状态 - 可定制化:支持修改选中颜色、未选中边框颜色、组件大小
- 交互反馈:使用
InkWell实现点击水波纹效果,符合Material Design规范
内容的提问来源于stack exchange,提问作者Wassef Hassine
相关产品推荐
相关产品推荐

