У меня есть streambuilder, который загружает информацию из пожарного хранилища. Затем я использую listview.builder для отображения информации. Отображаемая информация вызывается функцией firstBuildItem или buildItem.
Функциональность, которую я хочу, заключается в том, что когда пользователь нажимает на контейнер, обернутый детектором жестов, я хочу, чтобы другой виджет был развернут ниже основного виджета. Я не уверен, как этого добиться с помощью flutter, потому что, поскольку каждое сообщение является внутренним элементом listview.builder, логическое значение должно быть локальным внутри функции, поскольку каждая функция имеет свой логический параметр, который проверяет, был ли выбран элемент списка. , Я хотел бы выяснить, как исправить мой код, чтобы каждый элемент реагировал на щелчок внутри просмотра списка путем расширения.
ListView.builder(
padding: EdgeInsets.all(10.0),
itemBuilder: (context, index) =>
index == 0 ? firstBuildItem(index, snapshot.data.documents[index]) : buildItem(index, snapshot.data.documents[index], snapshot.data.documents[index-1]),
itemCount: snapshot.data.documents.length,
reverse: true,
controller: listScrollController,
),
, тогда вот функция builditem:
Widget firstBuildItem(int index, DocumentSnapshot mainDocument) {
///If the box is expanded
bool _isExpanded = false;
///Toggle the box to expand or collapse
void _toggleExpand() {
setState(() {
_isExpanded = !_isExpanded;
});
}
return GestureDetector(
onTap: _toggleExpand,
child: Container(
color: _isExpanded ? Colors.blueGrey : null,
child: Column(
children: <Widget>[
Column(
children: <Widget>[
SizedBox(height: 20.0),
Row(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
ChatDateHeader(timestamp: mainDocument['timestamp']),
],
),
],
),
Column(
children: <Widget>[
Row(
children: <Widget>[
Container(
child: Text(
mainDocument['content'],
style: TextStyle(color: primaryColor),
),
padding: EdgeInsets.fromLTRB(15.0, 10.0, 15.0, 10.0),
),
],
mainAxisAlignment: MainAxisAlignment.end,
),
getTime(mainDocument['timestamp'], true),
ExpandedSection(
expand: _isExpanded,
child: getDate(mainDocument['timestamp'], true),
),
SizedBox(height: 20.0),
],
crossAxisAlignment: CrossAxisAlignment.end,
),
],
),
),
);
}
и затем расширенный виджет:
class ExpandedSection extends StatefulWidget {
final Widget child;
final bool expand;
ExpandedSection({this.expand = false, this.child});
@override
_ExpandedSectionState createState() => _ExpandedSectionState();
}
class _ExpandedSectionState extends State<ExpandedSection> with SingleTickerProviderStateMixin {
AnimationController expandController;
Animation<double> animation;
@override
void initState() {
super.initState();
prepareAnimations();
}
///Setting up the animation
void prepareAnimations() {
expandController = AnimationController(
vsync: this,
duration: Duration(milliseconds: 500)
);
Animation curve = CurvedAnimation(
parent: expandController,
curve: Curves.fastOutSlowIn,
);
animation = Tween(begin: 0.0, end: 1.0).animate(curve)
..addListener(() {
setState(() {
});
}
);
}
@override
void didUpdateWidget(ExpandedSection oldWidget) {
super.didUpdateWidget(oldWidget);
if(widget.expand) {
expandController.forward();
}
else {
expandController.reverse();
}
}
@override
void dispose() {
expandController.dispose();
super.dispose();
}
@override
Widget build(BuildContext context) {
return SizeTransition(
axisAlignment: 1.0,
sizeFactor: animation,
child: widget.child
);
}
}