如何使用 ListView 更改在 flutter 中点击的按钮颜色
how to change button color of that which is tapped in flutter using ListView
我已经使用 ListView.builder
创建了按钮,现在我想如果我点击任何按钮,那么只有那个按钮的颜色应该改变,但是当我点击任何按钮时,所有按钮的颜色都会改变。
这是代码
List<String> litems = ["Counter No 1", "Counter No 2", "Counter No 3", "Counter No 4"];
bool pressAttention=false;
Widget build(BuildContext context) {
return SafeArea(
child: SingleChildScrollView(
SizedBox(
height: MediaQuery.of(context).size.height,
child: ListView.builder(
shrinkWrap: true,
itemCount: litems.length,
itemBuilder: (BuildContext ctxt, int index) {
return Column(
children: [
Container(
height: 55.0,
width: MediaQuery.of(context).size.width*0.9,
child: new RaisedButton(
child: new Text(litems[index]),
textColor: Colors.white,
shape: new RoundedRectangleBorder(
borderRadius: new BorderRadius.circular(30.0),
),
color: pressAttention ? Colors.green : Colors.grey,
onPressed: () => setState(() => pressAttention = !pressAttention),
),
),
SizedBox20(),
],
);
}),
),
);
}
}
如果有人知道如何做到这一点,请提供帮助。
使用 int 类型来标记点击按钮,
List<String> litems = ["Counter No 1", "Counter No 2", "Counter No 3", "Counter No 4"];
late int tapIndex;
@override
void initState() {
super.initState();
tapIndex = litems.length; // make sure no buttons are clicked in the initial state
}
Widget build(BuildContext context) {
return SafeArea(
child: SingleChildScrollView(
SizedBox(
height: MediaQuery.of(context).size.height,
child: ListView.builder(
shrinkWrap: true,
itemCount: litems.length,
itemBuilder: (BuildContext ctxt, int index) {
return Column(
children: [
Container(
height: 55.0,
width: MediaQuery.of(context).size.width*0.9,
child: new RaisedButton(
child: new Text(litems[index]),
textColor: Colors.white,
shape: new RoundedRectangleBorder(
borderRadius: new BorderRadius.circular(30.0),
),
color: tapIndex == index ? Colors.green : Colors.grey,
onPressed: () => setState(() => tapIndex = index),
),
),
SizedBox20(),
],
);
}),
),
);
}
}
最简单的方法是在单独的小部件中提取按钮逻辑。但是,如果您需要顶部小部件中的每个 pressAttentions
值,这将不起作用。
无论如何,这是最简单的方法:
import 'package:flutter/material.dart';
void main() {
runApp(MaterialApp(home: Material(child: MyApp())));
}
class MyApp extends StatelessWidget {
final List<String> litems = ["Counter No 1", "Counter No 2", "Counter No 3", "Counter No 4"];
@override
Widget build(BuildContext context) {
return SafeArea(
child: ListView.builder(
shrinkWrap: true,
itemCount: litems.length,
itemBuilder: (context, index) {
return MyButton(title: litems[index]);
}
),
);
}
}
class MyButton extends StatefulWidget {
final String title;
const MyButton({
Key? key,
required this.title,
}) : super(key: key);
@override
State<MyButton> createState() => _MyButtonState();
}
class _MyButtonState extends State<MyButton> {
// Default to non pressed
bool pressAttention = false;
@override
Widget build(BuildContext context) {
return Padding(
padding: const EdgeInsets.only(bottom: 20.0),
child: Container(
height: 55.0,
width: MediaQuery.of(context).size.width * 0.9,
child: new RaisedButton(
child: new Text(widget.title),
textColor: Colors.white,
shape: new RoundedRectangleBorder(
borderRadius: new BorderRadius.circular(30.0),
),
color: pressAttention ? Colors.green : Colors.grey,
onPressed: () => setState(() => pressAttention = !pressAttention),
),
),
);
}
}
如果您需要 pressAttentions
的列表,请使用以下方法:
import 'package:flutter/material.dart';
void main() {
runApp(MaterialApp(home: Material(child: MyApp())));
}
class MyApp extends StatefulWidget {
@override
State<MyApp> createState() => _MyAppState();
}
class _MyAppState extends State<MyApp> {
final List<String> litems = ["Counter No 1", "Counter No 2", "Counter No 3", "Counter No 4"];
// Initialize with the same length as litems and with only falses
late List<bool> pressedAttentions = litems.map((e) => false).toList();
@override
Widget build(BuildContext context) {
return SafeArea(
child: ListView.builder(
shrinkWrap: true,
itemCount: litems.length,
itemBuilder: (context, index) {
final pressAttention = pressedAttentions[index];
return Padding(
padding: const EdgeInsets.only(bottom: 20.0),
child: Container(
height: 55.0,
width: MediaQuery.of(context).size.width * 0.9,
child: new RaisedButton(
child: new Text(litems[index]),
textColor: Colors.white,
shape: new RoundedRectangleBorder(
borderRadius: new BorderRadius.circular(30.0),
),
color: pressAttention ? Colors.green : Colors.grey,
onPressed: () => setState(() => pressedAttentions[index] = !pressAttention),
),
),
);
}
),
);
}
}
作为奖励,如果您希望一次只选择 1 个按钮:
import 'package:flutter/material.dart';
void main() {
runApp(MaterialApp(home: Material(child: MyApp())));
}
class MyApp extends StatefulWidget {
@override
State<MyApp> createState() => _MyAppState();
}
class _MyAppState extends State<MyApp> {
final List<String> litems = ["Counter No 1", "Counter No 2", "Counter No 3", "Counter No 4"];
// Initialize to -1 so that none are selected
// If you want to select the first by default you could change this to 0
int pressedAttentionIndex = -1;
@override
Widget build(BuildContext context) {
return SafeArea(
child: ListView.builder(
shrinkWrap: true,
itemCount: litems.length,
itemBuilder: (context, index) {
final pressAttention = pressedAttentionIndex == index;
return Padding(
padding: const EdgeInsets.only(bottom: 20.0),
child: Container(
height: 55.0,
width: MediaQuery.of(context).size.width * 0.9,
child: new RaisedButton(
child: new Text(litems[index]),
textColor: Colors.white,
shape: new RoundedRectangleBorder(
borderRadius: new BorderRadius.circular(30.0),
),
color: pressAttention ? Colors.green : Colors.grey,
onPressed: () => setState(() => pressedAttentionIndex = index),
),
),
);
}
),
);
}
}
附带说明:您的命名似乎有问题:
- 你是否使用驼峰式命名属性(差:
litems
,好:lItems
)
- DO start your bool variables be
is
or has
: (BAD: pressAttention
, GOOD: hasPressedAttention
)
尝试下面的代码希望它对你有所帮助,并且使用 ElevatedButton 而不是 RaisedButton 的一件事是因为当前的 flutter 版本 RaisedButton Widget 已被删除。 ElevatedButton
声明 int var 和您的列表:
int? tappedIndex;
List<String> litems = [
"Counter No 1",
"Counter No 2",
"Counter No 3",
"Counter No 4"
];
声明 initState() 方法
@override
void initState() {
super.initState();
tappedIndex = 0;
}
您的小部件:
return Scaffold(
body: Column(
mainAxisAlignment: MainAxisAlignment.center,
crossAxisAlignment: CrossAxisAlignment.center,
children: [
ListView.builder(
shrinkWrap: true,
itemCount: litems.length,
itemBuilder: (context, index) {
return Container(
child: ElevatedButton(
style: ElevatedButton.styleFrom(
shape: RoundedRectangleBorder(
borderRadius: new BorderRadius.circular(30.0),
),
primary: tappedIndex == index
? Colors.blue
: Colors.transparent,
),
child: Center(
child: Text(litems[index]),
),
onPressed: () {
setState(() {
tappedIndex = index;
});
}),
);
}),
],
),
);
完整代码:
import 'package:flutter/material.dart';
void main() {
runApp(
MaterialApp(
home: Material(
child: Search(),
),
),
);
}
class Search extends StatefulWidget {
const Search({Key? key}) : super(key: key);
@override
State<Search> createState() => _SearchState();
}
class _SearchState extends State<Search> {
int? tappedIndex;
List<String> litems = [
"Counter No 1",
"Counter No 2",
"Counter No 3",
"Counter No 4"
];
@override
void initState() {
super.initState();
tappedIndex = 0;
}
@override
Widget build(BuildContext context) {
return Scaffold(
body: Column(
mainAxisAlignment: MainAxisAlignment.center,
crossAxisAlignment: CrossAxisAlignment.center,
children: [
ListView.builder(
shrinkWrap: true,
itemCount: litems.length,
itemBuilder: (context, index) {
return Container(
child: ElevatedButton(
style: ElevatedButton.styleFrom(
shape: RoundedRectangleBorder(
borderRadius: new BorderRadius.circular(30.0),
),
primary: tappedIndex == index
? Colors.blue
: Colors.transparent,
),
child: Center(
child: Text(litems[index]),
),
onPressed: () {
setState(() {
tappedIndex = index;
});
}),
);
}),
],
),
);
}
}
您的结果屏幕->
我已经使用 ListView.builder
创建了按钮,现在我想如果我点击任何按钮,那么只有那个按钮的颜色应该改变,但是当我点击任何按钮时,所有按钮的颜色都会改变。
这是代码
List<String> litems = ["Counter No 1", "Counter No 2", "Counter No 3", "Counter No 4"];
bool pressAttention=false;
Widget build(BuildContext context) {
return SafeArea(
child: SingleChildScrollView(
SizedBox(
height: MediaQuery.of(context).size.height,
child: ListView.builder(
shrinkWrap: true,
itemCount: litems.length,
itemBuilder: (BuildContext ctxt, int index) {
return Column(
children: [
Container(
height: 55.0,
width: MediaQuery.of(context).size.width*0.9,
child: new RaisedButton(
child: new Text(litems[index]),
textColor: Colors.white,
shape: new RoundedRectangleBorder(
borderRadius: new BorderRadius.circular(30.0),
),
color: pressAttention ? Colors.green : Colors.grey,
onPressed: () => setState(() => pressAttention = !pressAttention),
),
),
SizedBox20(),
],
);
}),
),
);
}
}
如果有人知道如何做到这一点,请提供帮助。
使用 int 类型来标记点击按钮,
List<String> litems = ["Counter No 1", "Counter No 2", "Counter No 3", "Counter No 4"];
late int tapIndex;
@override
void initState() {
super.initState();
tapIndex = litems.length; // make sure no buttons are clicked in the initial state
}
Widget build(BuildContext context) {
return SafeArea(
child: SingleChildScrollView(
SizedBox(
height: MediaQuery.of(context).size.height,
child: ListView.builder(
shrinkWrap: true,
itemCount: litems.length,
itemBuilder: (BuildContext ctxt, int index) {
return Column(
children: [
Container(
height: 55.0,
width: MediaQuery.of(context).size.width*0.9,
child: new RaisedButton(
child: new Text(litems[index]),
textColor: Colors.white,
shape: new RoundedRectangleBorder(
borderRadius: new BorderRadius.circular(30.0),
),
color: tapIndex == index ? Colors.green : Colors.grey,
onPressed: () => setState(() => tapIndex = index),
),
),
SizedBox20(),
],
);
}),
),
);
}
}
最简单的方法是在单独的小部件中提取按钮逻辑。但是,如果您需要顶部小部件中的每个 pressAttentions
值,这将不起作用。
无论如何,这是最简单的方法:
import 'package:flutter/material.dart';
void main() {
runApp(MaterialApp(home: Material(child: MyApp())));
}
class MyApp extends StatelessWidget {
final List<String> litems = ["Counter No 1", "Counter No 2", "Counter No 3", "Counter No 4"];
@override
Widget build(BuildContext context) {
return SafeArea(
child: ListView.builder(
shrinkWrap: true,
itemCount: litems.length,
itemBuilder: (context, index) {
return MyButton(title: litems[index]);
}
),
);
}
}
class MyButton extends StatefulWidget {
final String title;
const MyButton({
Key? key,
required this.title,
}) : super(key: key);
@override
State<MyButton> createState() => _MyButtonState();
}
class _MyButtonState extends State<MyButton> {
// Default to non pressed
bool pressAttention = false;
@override
Widget build(BuildContext context) {
return Padding(
padding: const EdgeInsets.only(bottom: 20.0),
child: Container(
height: 55.0,
width: MediaQuery.of(context).size.width * 0.9,
child: new RaisedButton(
child: new Text(widget.title),
textColor: Colors.white,
shape: new RoundedRectangleBorder(
borderRadius: new BorderRadius.circular(30.0),
),
color: pressAttention ? Colors.green : Colors.grey,
onPressed: () => setState(() => pressAttention = !pressAttention),
),
),
);
}
}
如果您需要 pressAttentions
的列表,请使用以下方法:
import 'package:flutter/material.dart';
void main() {
runApp(MaterialApp(home: Material(child: MyApp())));
}
class MyApp extends StatefulWidget {
@override
State<MyApp> createState() => _MyAppState();
}
class _MyAppState extends State<MyApp> {
final List<String> litems = ["Counter No 1", "Counter No 2", "Counter No 3", "Counter No 4"];
// Initialize with the same length as litems and with only falses
late List<bool> pressedAttentions = litems.map((e) => false).toList();
@override
Widget build(BuildContext context) {
return SafeArea(
child: ListView.builder(
shrinkWrap: true,
itemCount: litems.length,
itemBuilder: (context, index) {
final pressAttention = pressedAttentions[index];
return Padding(
padding: const EdgeInsets.only(bottom: 20.0),
child: Container(
height: 55.0,
width: MediaQuery.of(context).size.width * 0.9,
child: new RaisedButton(
child: new Text(litems[index]),
textColor: Colors.white,
shape: new RoundedRectangleBorder(
borderRadius: new BorderRadius.circular(30.0),
),
color: pressAttention ? Colors.green : Colors.grey,
onPressed: () => setState(() => pressedAttentions[index] = !pressAttention),
),
),
);
}
),
);
}
}
作为奖励,如果您希望一次只选择 1 个按钮:
import 'package:flutter/material.dart';
void main() {
runApp(MaterialApp(home: Material(child: MyApp())));
}
class MyApp extends StatefulWidget {
@override
State<MyApp> createState() => _MyAppState();
}
class _MyAppState extends State<MyApp> {
final List<String> litems = ["Counter No 1", "Counter No 2", "Counter No 3", "Counter No 4"];
// Initialize to -1 so that none are selected
// If you want to select the first by default you could change this to 0
int pressedAttentionIndex = -1;
@override
Widget build(BuildContext context) {
return SafeArea(
child: ListView.builder(
shrinkWrap: true,
itemCount: litems.length,
itemBuilder: (context, index) {
final pressAttention = pressedAttentionIndex == index;
return Padding(
padding: const EdgeInsets.only(bottom: 20.0),
child: Container(
height: 55.0,
width: MediaQuery.of(context).size.width * 0.9,
child: new RaisedButton(
child: new Text(litems[index]),
textColor: Colors.white,
shape: new RoundedRectangleBorder(
borderRadius: new BorderRadius.circular(30.0),
),
color: pressAttention ? Colors.green : Colors.grey,
onPressed: () => setState(() => pressedAttentionIndex = index),
),
),
);
}
),
);
}
}
附带说明:您的命名似乎有问题:
- 你是否使用驼峰式命名属性(差:
litems
,好:lItems
) - DO start your bool variables be
is
orhas
: (BAD:pressAttention
, GOOD:hasPressedAttention
)
尝试下面的代码希望它对你有所帮助,并且使用 ElevatedButton 而不是 RaisedButton 的一件事是因为当前的 flutter 版本 RaisedButton Widget 已被删除。 ElevatedButton
声明 int var 和您的列表:
int? tappedIndex;
List<String> litems = [
"Counter No 1",
"Counter No 2",
"Counter No 3",
"Counter No 4"
];
声明 initState() 方法
@override
void initState() {
super.initState();
tappedIndex = 0;
}
您的小部件:
return Scaffold(
body: Column(
mainAxisAlignment: MainAxisAlignment.center,
crossAxisAlignment: CrossAxisAlignment.center,
children: [
ListView.builder(
shrinkWrap: true,
itemCount: litems.length,
itemBuilder: (context, index) {
return Container(
child: ElevatedButton(
style: ElevatedButton.styleFrom(
shape: RoundedRectangleBorder(
borderRadius: new BorderRadius.circular(30.0),
),
primary: tappedIndex == index
? Colors.blue
: Colors.transparent,
),
child: Center(
child: Text(litems[index]),
),
onPressed: () {
setState(() {
tappedIndex = index;
});
}),
);
}),
],
),
);
完整代码:
import 'package:flutter/material.dart';
void main() {
runApp(
MaterialApp(
home: Material(
child: Search(),
),
),
);
}
class Search extends StatefulWidget {
const Search({Key? key}) : super(key: key);
@override
State<Search> createState() => _SearchState();
}
class _SearchState extends State<Search> {
int? tappedIndex;
List<String> litems = [
"Counter No 1",
"Counter No 2",
"Counter No 3",
"Counter No 4"
];
@override
void initState() {
super.initState();
tappedIndex = 0;
}
@override
Widget build(BuildContext context) {
return Scaffold(
body: Column(
mainAxisAlignment: MainAxisAlignment.center,
crossAxisAlignment: CrossAxisAlignment.center,
children: [
ListView.builder(
shrinkWrap: true,
itemCount: litems.length,
itemBuilder: (context, index) {
return Container(
child: ElevatedButton(
style: ElevatedButton.styleFrom(
shape: RoundedRectangleBorder(
borderRadius: new BorderRadius.circular(30.0),
),
primary: tappedIndex == index
? Colors.blue
: Colors.transparent,
),
child: Center(
child: Text(litems[index]),
),
onPressed: () {
setState(() {
tappedIndex = index;
});
}),
);
}),
],
),
);
}
}
您的结果屏幕->