0

我正在尝试创建一个AnimatedList使用bloc模式,但遇到了一些问题。

当我将 initialItemsCount 设置为AnimatedListstate.itemList.length,它不会构建。虽然当我在 's listener 中打印出state.itemList(来自ListBloc)时,BlocConsumer它会打印出itemList.

那么,问题是为什么这不起作用?

我尝试做同样的事情ListView.builder并且效果很好。我是否遗漏了某些东西,或者AnimatedList甚至不应该使用 bloc 工作?

这是一些示例代码,对于这种情况来说非常简单:

MyApp 类:

class _MyAppState extends State<MyApp> {
  final key = GlobalKey<AnimatedListState>();

  @override
  Widget build(BuildContext context) {
    return BlocProvider(
      create: (context) => ListBloc()..add(LoadList()),
      child: MaterialApp(
        home: SafeArea(
          child: BlocConsumer<ListBloc, ListState>(
            listener: (_, state) {
              print(state.itemList);
            },
            builder: (context, state) => Scaffold(
              body: Column(
                children: [
                  Expanded(
                    child: AnimatedList(
                      key: key,
                      initialItemCount: state.itemList.length,
                      itemBuilder: (context, index, animation) {
                        return Item(
                            animation: animation,
                            index: index,
                            text: state.itemList[index],
                            onTap: () => removeItem(index, state.itemList));
                      },
                    ),
                  ),
                ],
              ),
            ),
          ),
        ),
      ),
    );
  }

  void removeItem(int index, List<String> items) {
    final item = items.removeAt(index);

    key.currentState?.removeItem(
        index,
        (context, animation) => Item(
            animation: animation,
            index: index,
            text: items[index],
            onTap: () => removeItem(index, items)));
  }
}

物品类别:

class Item extends StatelessWidget {
  final Animation<double> animation;
  final int index;
  final String text;
  final VoidCallback onTap;

  const Item(
      {required this.animation,
      required this.index,
      required this.text,
      required this.onTap,
      Key? key})
      : super(key: key);

  @override
  Widget build(BuildContext context) {
    return ScaleTransition(
      scale: animation,
      child: Padding(
        padding: const EdgeInsets.all(8.0),
        child: InkWell(
            onTap: onTap,
            child: Container(
              color: Colors.blue,
              child: Padding(
                padding: const EdgeInsets.all(8.0),
                child: Text(text),
              ),
            )),
      ),
    );
  }
}

集团:

class ListEvent extends Equatable {
  const ListEvent();

  @override
  List<Object> get props => [];
}

class LoadList extends ListEvent {}

class ListState extends Equatable {
  final List<String> itemList;

  const ListState({required this.itemList});

  @override
  List<Object> get props => [itemList];
}

class ListBloc extends Bloc<ListEvent, ListState> {
  ListBloc() : super(ListState(itemList: []));

  @override
  Stream<ListState> mapEventToState(ListEvent event) async* {
    if (event is LoadList) {
      var items = ['1', '2', '3', '4', '5', '6'];
      yield ListState(itemList: items);
    }
  }
}

谢谢!

4

1 回答 1

0

我在如何调用 itemBuilder 和重新构建列表时遇到过关于 AnimatedList 的类似情况。

如果您在 AnimatedList 小部件(即您的父 Expanded 小部件)上方和 itemBuilder 调用中设置了一个断点,您可能会注意到 itemBuilder 在某些情况下正在执行,而没有遇到第一个断点。

这看起来是因为 AnimatedList 的动画特性导致 itemBuilder 被直接调用为框架页面刷新的一部分(在包含的小部件之外,例如您的 BlocConsumer,因此您的状态尚未按预期设置)。

于 2021-09-01T22:24:56.633 回答