使用 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();
});
},
),
),
),
),
],
),
),
),
);
}
}
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();
});
},
),
),
),
),
],
),
),
),
);
}
}