Flutter Using ListView.Builder:如何在我选择的所有项目上仅更改一项的背景颜色
Posted
技术标签:
【中文标题】Flutter Using ListView.Builder:如何在我选择的所有项目上仅更改一项的背景颜色【英文标题】:Flutter Using ListView.Builder: how can i change background color of only one item on all items with i selected it 【发布时间】:2021-01-01 11:33:37 【问题描述】: 我使用 ListViewBuilder 来渲染一个时间槽列表,我需要的是能够只选择其中一项,当我选择它时,我需要只更改此项的背景,然后出现预订细节,但实际上所做的是所有项目的背景都变成了另一种颜色
[![This is image that before select a one time slot][1]][1][![And this when i try to select one item all items are selected and then the reservation details appear when i preesed the time slot][1]][1]
[![And this when i try to select one item all items are selected and then the reservation details appear when i preesed the time slot][1]][1]
class _ReservationSlotsWidgetState extends State<ReservationSlotsWidget>
var _isExpanded = false;
var slots = [
'09:00AM',
'10:00AM',
'11:00AM',
'12:00PM',
'01:00PM',
'02:00PM',
'03:00PM',
'04:00PM',
];
@override
Widget build(BuildContext context)
final deviceSize = MediaQuery.of(context).size;
return Scaffold(
extendBodyBehindAppBar: true,
....
Expanded(
child: ListView.builder(
itemCount: slots.length,
scrollDirection: Axis.horizontal,
itemBuilder: (ctx, index)
var slot = slots[index];
return GestureDetector(
onTap: ()
setState(()
_isExpanded = !_isExpanded;
);
,
child: Container(
padding: EdgeInsets.all(4),
margin: EdgeInsets.all(4),
decoration: BoxDecoration(
color: _isExpanded
? Theme.of(context).primaryColor
: parseColor('#2A2E43'),
borderRadius:
BorderRadius.all(Radius.circular(10))),
child: SlotsWidget())
);
)),
],
),
),
SizedBox(
height: deviceSize.height * 0.00025,
),
if (_isExpanded)
Container(
padding: EdgeInsets.all(16),
margin: EdgeInsets.all(16),
height: deviceSize.height * 0.2,
decoration: BoxDecoration(
color: Theme.of(context).primaryColorDark,
borderRadius: BorderRadius.all(Radius.circular(10))),
child: Column(
mainAxisAlignment: MainAxisAlignment.spaceAround,
children: <Widget>[
Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: <Widget>[
Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[
Row(
children: <Widget>[
Icon(
Icons.person_add,
color: Colors.white,
),
SizedBox(
width: 5,
),
Text('Number of persons',
style: TextStyle(
color: Colors.white,
)),
SizedBox(
height: 5,
),
],
),
Row(
children: <Widget>[
Icon(
Icons.person_add,
color: Colors.transparent,
),
SizedBox(
width: 5,
),
Text('(max 7 persons)',
style: TextStyle(
color: Colors.white,
)),
....
【问题讨论】:
【参考方案1】:所以问题的关键是 ListView Builder 的索引。 您当前执行此操作的方式是将单个布尔值设置为 true 或 false,这适用于列表的 每个元素。 您需要做的是保存展开的小部件的索引。
改变
onTap: ()
setState(()
_isExpanded = !_isExpanded;
);
,
到
int _expandedIndex;
...
onTap: ()
setState(()
_expandedIndex = index
);
,
然后改变
color: _isExpanded
? Theme.of(context).primaryColor
: parseColor('#2A2E43'),
到
color: _expandedIndex == index
? Theme.of(context).primaryColor
: parseColor('#2A2E43'),
【讨论】:
【参考方案2】:创建单独的类
class Slot
String time;
bool isSelected;
Slot(this.time, this.isSelected);
创建上述类的槽列表
var slots = [
Slot('09:00AM', false),
Slot('10:00AM', false),
Slot('11:00AM', false),
Slot('12:00PM', false),
//... Rest of the items
];
从列表中获取槽对象(这应该在Listview.Builder
里面)
var slot = slots[index];
var time = slot.time; // Get the time from slot object
点击列表项时将isSelected
标记为true
slot.isSelected = true;
或
slot.isSelected = !slot.isSelected; // Vice versa
【讨论】:
以上是关于Flutter Using ListView.Builder:如何在我选择的所有项目上仅更改一项的背景颜色的主要内容,如果未能解决你的问题,请参考以下文章
Flutter 项目 Your app isn't using AndroidX错误
Flutter + Firebase Throwing Unhandled Exception: This widget has been unmounted Error Using Navigato
flutter解决 dart:html 只支持 flutter_web 其他平台编译报错 Avoid using web-only libraries outside Flutter web(代码片段
Flutter Using ListView.Builder:如何在我选择的所有项目上仅更改一项的背景颜色
Android Gradle plugin requires Java 11 to run. You are currently using Java 1.8.