如何停止动画列表小部件同时刷新所有小部件



下面的list widget在每个list item的中间都有一个text。我希望每个文本都是唯一的,所以当我构建每个项目然后添加到列表中时,我会输入文本,但当我添加新的list Item或通过单击它来选择一个项目以删除一个项目时,所有列表项目都会被刷新,以前的list item's中间文本也会更新为我输入的新文本。如何防止所有文本框更新为我输入的最后一个文本,我希望它保留它的文本?

import 'package:app3/widgets/Profile-Card/tool-set-button.dart';
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:app3/GlobalVariables/GlobalVariables.dart';
class AnimatedListWidget extends StatefulWidget {
final String? presetText;
const AnimatedListWidget({
Key? key,
this.presetText,
}) : super(key: key);
@override
State<AnimatedListWidget> createState() => _AnimatedListWidgetState();
}
class _AnimatedListWidgetState extends State<AnimatedListWidget> {
final GlobalKey<AnimatedListState> _listKey = GlobalKey<AnimatedListState>();
late ListModel<int> _list;
int? _selectedItem;
late int _nextItem;
@override
void initState() {
super.initState();
_list = ListModel<int>(
listKey: _listKey,
initialItems: <int>[0, 1, 2],
removedItemBuilder: _buildRemovedItem,
);
_nextItem = 3;
}
String messageText = '';
@override
Widget build(BuildContext context) {
return Scaffold(
body: Column(
crossAxisAlignment: CrossAxisAlignment.center,
children: <Widget>[
Align(
alignment: Alignment.topCenter, //list alignment
child: Container(
width: 200,
child: FittedBox(
fit: BoxFit.contain,
child: SizedBox(
width: 100,
child: Padding(
padding: const EdgeInsets.all(4.0),
child: SingleChildScrollView(
child: Container(
height: 300,
child: AnimatedList(
shrinkWrap: true,
key: _listKey,
initialItemCount: _list.length,
itemBuilder: _buildItem,
),
//),
),
),
),
)))),
Container(
width: 300,
height: 100,
color: Colors.black,
child: Row(
mainAxisAlignment: MainAxisAlignment.start,
children: [
Container(
child: Padding(
padding: EdgeInsets.only(
top: 8,
left: 5,
),
child: Align(
alignment: Alignment.topLeft,
child: Container(
width: 100,
child: FittedBox(
fit: BoxFit.contain,
child: SizedBox(
width: 219,
child: ToolSetButton(
svgPicPathChecked: '',
svgPicPathUnchecked: '',
buttonType: myButtonTypeList.TextButton,
text: 'Add',
width: 200,
height: 60,
functionReceiverforButtonandSVG: () {
addPresetToList();
}),
),
),
),
),
),
),
Container(
child: Padding(
padding: EdgeInsets.only(
top: 8,
left: 5,
),
child: Align(
alignment: Alignment.topLeft,
child: Container(
width: 100,
child: FittedBox(
fit: BoxFit.contain,
child: SizedBox(
width: 219,
child: ToolSetButton(
svgPicPathChecked: '',
svgPicPathUnchecked: '',
buttonType: myButtonTypeList.TextButton,
text: 'Remove',
width: 200,
height: 60,
functionReceiverforButtonandSVG: () {
removePresetFromList();
}),
),
),
),
),
),
),
],
),
)
]));
}
Widget _buildItem(
BuildContext context, int index, Animation<double> animation) {
return PresetObject(
animation: animation,
item: _list[index],
selected: _selectedItem == _list[index],
presetText: widget.presetText,
onTap: () {
_selectedItem = _selectedItem == _list[index] ? null : _list[index];
},
);
}
Widget _buildRemovedItem(
int item, BuildContext context, Animation<double> animation) {
return PresetObject(
animation: animation,
item: item,
);
}
void addPresetToList() {
final int index = 0;
//_selectedItem == null ? _list.length : _list.indexOf(_selectedItem!);
_list.insert(index, _nextItem++);
}
// Remove the selected item from the list model.
void removePresetFromList() {
if (_selectedItem != null) {
_list.removeAt(_list.indexOf(_selectedItem!));
setState(() {
_selectedItem = null;
});
}
}
}
typedef RemovedItemBuilder<T> = Widget Function(
T item, BuildContext context, Animation<double> animation);
class ListModel<E> {
ListModel({
required this.listKey,
required this.removedItemBuilder,
Iterable<E>? initialItems,
}) : _items = List<E>.from(initialItems ?? <E>[]);
final GlobalKey<AnimatedListState> listKey;
final RemovedItemBuilder<E> removedItemBuilder;
final List<E> _items;
AnimatedListState? get _animatedList => listKey.currentState;
void insert(int index, E item) {
_items.insert(index, item);
_animatedList!.insertItem(index);
}
E removeAt(int index) {
final E removedItem = _items.removeAt(index);
if (removedItem != null) {
_animatedList!.removeItem(
index,
(BuildContext context, Animation<double> animation) {
return removedItemBuilder(removedItem, context, animation);
},
);
}
return removedItem;
}
int get length => _items.length;
E operator [](int index) => _items[index];
int indexOf(E item) => _items.indexOf(item);
}
class PresetObject extends StatelessWidget {
final String? presetText;
const PresetObject(
{Key? key,
this.onTap,
this.selected = false,
required this.animation,
required this.item,
this.presetText})
: assert(item >= 0),
super(key: key);
final Animation<double> animation;
final VoidCallback? onTap;
final int item;
final bool selected;
@override
Widget build(BuildContext context) {
TextStyle textStyle = defualtParahTextStyle;
if (selected) {
//if selected change colour of text etc
textStyle = textStyle.copyWith(color: Colors.lightGreenAccent[400]);
}
return Column(children: [
Padding(
padding: const EdgeInsets.only(bottom: 2),
child: SizeTransition(
sizeFactor: animation,
child: GestureDetector(
behavior: HitTestBehavior.opaque,
onTap: onTap,
child: Container(
width: postInner0CardWidth,
height: 100,
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(20.0),
border: Border.all(
color: Colors
.primaries[item % Colors.primaries.length],
width: 1)),
child: Padding(
padding: EdgeInsets.all(5),
child: RichText(
textAlign: TextAlign.left,
text:
TextSpan(style: textStyle, children: <TextSpan>[
TextSpan(text: variableAddNewPreSetTextMessage)
])))),
)))
]);
}
}

如果您使用的是statefull窗口小部件,则必须使用密钥或ovveride重建方法。其他方面,请使用Object密钥并在其中传递您的tile对象。在您的模型类中,您必须覆盖哈希代码或用相等的扩展

因此,通过在flutter重建窗口小部件时传递密钥,如果以前的密钥数据保持不变,则它将不会再次重建该瓦片

或访问flutter文档中的密钥

最新更新