使用 flutter 在 ListView 中实现单选按钮

Implementing Radio Buttons inside a ListView with flutter

我有 3 个列表,每个列表中有多个 numbers/tiles。我希望能够点击它们,但每个列表一次只能点击一个。 (换句话说,我想实现单选按钮)。我试过在 ListView itemBuilder 中添加 RadioListTile(而不是 Container),但没有成功。任何帮助将不胜感激!

这是我的代码:

import 'package:flutter/material.dart';
import 'dart:math';
import 'package:flutter/gestures.dart';

void main() {
  runApp(MyApp());
}

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Flutter Demo',
      home: MyHomePage(),
    );
  }
}

class MyHomePage extends StatefulWidget {
  @override
  State<MyHomePage> createState() => _MyHomePageState();
}

class _MyHomePageState extends State<MyHomePage> {
  // const MyHomePage({Key? key}) : super(key: key);
  final List<String> one = [
    '1',
    '2',
  ];
  final List<String> two = ['1', '2', '3'];
  final List<String> three = [
    '1',
    '2',
    '3',
    '4',
    '5',
    '6',
    '7',
    '8',
    '9',
    '10',
    '11',
    '12',
  ];

  @override
  Widget build(BuildContext context) {
    return SafeArea(
      child: Scaffold(
        backgroundColor: Colors.black,
        body: Padding(
          padding: const EdgeInsets.symmetric(horizontal: 10.0),
          child: Row(
            children: <Widget>[
              Expanded(
                child: ListView.separated(
                  itemCount: one.length,
                  controller: ScrollController(),
                  separatorBuilder: (_, __) => const SizedBox(height: 10),
                  itemBuilder: ((context, index) => Container(
                        height: 50,
                        color: Colors.white,
                        child: Text('${one[index]}'),
                      )),
                ),
              ),
              const SizedBox(width: 10),
              Expanded(
                child: ListView.separated(
                  controller: ScrollController(),
                  itemCount: two.length,
                  separatorBuilder: (_, __) => const SizedBox(height: 10),
                  itemBuilder: ((context, index) => Container(
                        height: 50,
                        color: Colors.white,
                        child: Text('${two[index]}'),
                      )),
                ),
              ),
              const SizedBox(width: 10),
              Expanded(
                child: ListView.separated(
                  controller: ScrollController(),
                  itemCount: three.length,
                  separatorBuilder: (_, __) => const SizedBox(height: 10),
                  itemBuilder: ((context, index) => Container(
                        height: 50,
                        color: Colors.white,
                        child: Text('${three[index]}'),
                      )),
                ),
              ),
            ],
          ),
        ),
      ),
    );
  }
}

您使用 RadioListTile 的想法是正确的。您必须设置一个变量来保存该值,在下面的代码示例中,它是 _oneValue_twoValue_threeValue - 这是存储所选值的位置。然后列表直到将其值设置为该值,在我的示例中,它首先设置为空,一旦您单击单选按钮,它将更改该值并更新状态(以便将选择反馈给 UI).

class _MyHomePageState extends State<MyHomePage> {
    // const MyHomePage({Key? key}) : super(key: key);
    final List<String> one = [
      '1',
      '2',
    ];
    final List<String> two = ['1', '2', '3'];
    final List<String> three = [
      '1',
      '2',
      '3',
      '4',
      '5',
      '6',
      '7',
      '8',
      '9',
      '10',
      '11',
      '12',
    ];

    var _oneValue = '';

    var _twoValue = '';

    var _threeValue = '';

    @override
    Widget build(BuildContext context) {
      return SafeArea(
        child: Scaffold(
          backgroundColor: Colors.black,
          body: Padding(
            padding: const EdgeInsets.symmetric(horizontal: 10.0),
            child: Row(
              children: <Widget>[
                Expanded(
                  child: ListView.separated(
                    itemCount: one.length,
                    controller: ScrollController(),
                    separatorBuilder: (_, __) => const SizedBox(height: 10),
                    itemBuilder: (context, index) => Container(
                      height: 50,
                      color: Colors.white,
                      child: RadioListTile(title: Text(one[index]),
                        value: one[index],
                        groupValue: _oneValue,
                        onChanged: (value) {
                          setState(() {
                            _oneValue = value.toString();
                          });
                        },
                      ),
                    ),
                  ),
                ),
                const SizedBox(width: 10),
                Expanded(
                  child: ListView.separated(
                    controller: ScrollController(),
                    itemCount: two.length,
                    separatorBuilder: (_, __) => const SizedBox(height: 10),
                    itemBuilder: (context, index) => Container(
                      height: 50,
                      color: Colors.white,
                      child: RadioListTile(title: Text(two[index]),
                        value: two[index],
                        groupValue: _twoValue,
                        onChanged: (value) {
                          setState(() {
                            _twoValue = value.toString();
                          });
                        },
                      ),
                    ),
                  ),
                ),
                const SizedBox(width: 10),
                Expanded(
                  child: ListView.separated(
                    controller: ScrollController(),
                    itemCount: three.length,
                    separatorBuilder: (_, __) => const SizedBox(height: 10),
                    itemBuilder: (context, index) => Container(
                      height: 50,
                      color: Colors.white,
                      child: RadioListTile(title: Text(three[index]),
                        value: three[index],
                        groupValue: _threeValue,
                        onChanged: (value) {
                          setState(() {
                            _threeValue = value.toString();
                          });
                        },
                      ),
                    ),
                  ),
                ),
              ],
            ),
          ),
        ),
      );
    }
  }