You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在Flutter中实现如图所示的自定义RadioButton?

在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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.24 10:48:16