我正在尝试在一个卡片小工具中实现呼叫按钮,
我希望当我按下呼叫按钮时,整个卡片的背景颜色变为蓝色(如选中),并且当我按下任何其他卡片时,背景颜色被更改回正常状态,如使呼叫按钮开关用于卡片选择,尝试使用setState功能,但它不起作用,因为它只在我点击整个卡片时改变颜色,而不是其中的一个特定按钮。如何在我按下呼叫按钮时选择整个卡,并在我按下任何其他卡时释放(在我从拨号器应用程序返回后)
下面是我的代码:
_launchCaller() async {
const url = "tel:+972545522973";
if (await canLaunch(url)) {
await launch(url);
} else {
throw 'Could not launch $url';
}
}
return Padding(
padding: const EdgeInsets.only(top: 8.0),
child: Card(
margin: EdgeInsets.fromLTRB(20.0, 6.0, 20.0, 0.0),
color: Colors.brown[30],
child: ListTile(
isThreeLine: true,
title: Row(
children: <Widget> [
Container(
child:Text(widget.helpRequest.category.description) ,
alignment: Alignment.topLeft,
),
Spacer(),
Container(
child:Text(formatter.format(now)),
alignment: Alignment.topRight,
),
]
)
,
subtitle: Container(
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[
GetUserName(widget.helpRequest.sender_id, DataBaseService().userInNeedCollection),
Text(widget.helpRequest.description),
]
)
),
trailing: Row(
mainAxisSize: MainAxisSize.min,
children: <Widget>[
GestureDetector(
onTap: (){
_launchCaller();
** Here i think I should add the code **
},
onLongPress: () => print("Long Press: Call"),
child: Padding(
padding: EdgeInsets.all(16.0),
child: Icon(Icons.call,
size: 20.0,
color: Colors.green,
)
),
),
],
),
),
),
);我尝试使用的这个setState函数在我的例子中不能很好地工作(我正在改变onTap函数的状态):
void initState() {
super.initState();
color = Colors.transparent;
}发布于 2020-12-09 17:28:42
最终输出:

您可以设置特定卡片的颜色,但要实现这一点,您需要有某种方法来引用所选卡片被单击的位置,通过此引用,我们可以确定卡片是否被选中,如果是,则根据我们的喜好更改颜色。
在下面的示例中,我或多或少使用了您在问题中提到的相同的卡片小部件模板,然后我使用ListView.builder呈现了五张卡片,每一张卡片都具有相同的功能。
每当呼叫按钮被按下时,该特定卡的相应index被分配给状态selectedIndex,由此,我们可以将颜色分配给所选卡。
下面是完整的示例:
import 'package:flutter/material.dart';
void main() => runApp(MyApp());
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter Demo',
debugShowCheckedModeBanner: false,
theme: ThemeData(
primarySwatch: Colors.blue,
),
home: MyHomePage(title: 'Flutter Demo Home Page'),
);
}
}
class MyHomePage extends StatefulWidget {
MyHomePage({Key key, this.title}) : super(key: key);
final String title;
@override
_MyHomePageState createState() => _MyHomePageState();
}
class _MyHomePageState extends State<MyHomePage> {
int selectedIndex;
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text(widget.title),
),
body: Padding(
padding: const EdgeInsets.only(top: 8.0),
child: ListView.builder(
itemCount: 5,
itemBuilder: (context, index) {
return Padding(
padding: const EdgeInsets.only(top: 8.0),
child: Card(
margin: EdgeInsets.fromLTRB(20.0, 6.0, 20.0, 0.0),
color: index == selectedIndex
? Colors.amberAccent
: Colors.brown[30],
child: ListTile(
isThreeLine: true,
title: Row(children: <Widget>[
Container(
child: Text("Some Text"),
alignment: Alignment.topLeft,
),
Spacer(),
Container(
child: Text("Some Text"),
alignment: Alignment.topRight,
),
]),
subtitle: Container(
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[
Text("Some Text"),
])),
trailing: Row(
mainAxisSize: MainAxisSize.min,
children: <Widget>[
GestureDetector(
onTap: () {
setState(() {
selectedIndex = index;
});
},
onLongPress: () => print("Long Press: Call"),
child: Padding(
padding: EdgeInsets.all(16.0),
child: Icon(
Icons.call,
size: 20.0,
color: Colors.green,
),
),
),
],
),
),
),
);
},
),
),
);
}
}发布于 2020-12-09 17:26:46
跟踪单击的项并传递列表的索引
int clickedItemPosition = -1;
bool isChecked(currentPosition) => clickedItemPosition == currentPosition;然后在你的卡片里
//..
Card(
margin: EdgeInsets.fromLTRB(20.0, 6.0, 20.0, 0.0),
color: isChecked(index) ? Colors.blue : Colors.transparent,
//..在手势检测器中更新clickedItemPosition
//...
GestureDetector(
onTap: () => setState(() => clickedItemPosition = index),
//..https://stackoverflow.com/questions/65213467
复制相似问题