AnimatedContainer - 如何只展开一个而其余的留在下面?

AnimatedContainer - How do I expand only one and the rest stay below?

所以我正在处理一些事情,我想要这些“胶囊”(圆角矩形容器)的列表。当用户点击其中任何一个时,它会扩展到全屏,而其余的则停留在较低的一层,什么都不做。

我正在使用 AnimatedContainer 和 GestureDetector 来改变它们的状态。当只有一个时,它非常适合我想做的事情。同时,一旦我在 Column 中添加更多内容,因为它是我在 GestureDetector 中使用单个布尔值编码的单个 Widget,它们都会同时打开。而且我知道,即使我单独对它们进行编码,它基本上也只是将周围的那些推开,而不是在它们上方打开。我该如何处理?

我尝试搜索此内容,但找不到任何有用的信息。希望这个问题的答案对未来的项目也有帮助。

bool chatCapsuleTapped = false;
bool hasFullSize = false;

@override
  Widget build(BuildContext context) {
    Widget _chatCapsuleAnimation() {
      return GestureDetector(
        onTap: () {
          setState(() {
            chatCapsuleTapped = !chatCapsuleTapped;
            hasFullSize = true;
          });
        },
        child: AnimatedContainer(
          width: !chatCapsuleTapped ? 350 : MediaQuery.of(context).size.width,
          height: !chatCapsuleTapped ? 75 : MediaQuery.of(context).size.height,
          //color: !chatCapsuleTapped ? Colors.grey.withOpacity(1) : Colors.grey,
          decoration: BoxDecoration(
            color: !chatCapsuleTapped ? Colors.grey.shade500 : Colors.grey.shade300,
            borderRadius: !chatCapsuleTapped ? BorderRadius.circular(40) : BorderRadius.circular(0),
          ),
          child: !chatCapsuleTapped ? Container(child: Container(),) : Container(),
          duration: Duration(milliseconds: 500),
          curve: Curves.fastOutSlowIn,
        ),
      );
    }

    return Scaffold(
      body: Container(
        alignment: Alignment.center,
        child: Column(
          mainAxisAlignment: MainAxisAlignment.center,
          children: [
            _chatCapsuleAnimation(),
          ],
        ),
      ),
    );
  }
} ```

您可以使用 Hero:

将每个小部件放在一个 Hero 小部件中,根据 index.

为其分配一个标签

然后有一个 Full-Screen 页面,其中包含更大版本的小部件,但具有与点击项目相同的标签。

here, you can paste it in DartPad

抓取的样本
class MyWidget extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: const Text('Basic Hero Animation'),
      ),
      body: SingleChildScrollView(
          child: Column(
              children: List<Widget>.generate(5, (index) {
        return InkWell(
            onTap: () {
              Navigator.of(context).push(
                MaterialPageRoute<void>(
                  builder: (BuildContext context) {
                    return Scaffold(
                      appBar: AppBar(
                        title: const Text('Full-Screen Page'),
                      ),
                      body: Container(
                        child: Hero(
                          // TAG should be same as the tapped item's index
                          tag: index.toString(),
                          child: SizedBox(
                            child: Container(
                                color: Colors.grey[(index + 1) * 100]),
                          ),
                        ),
                      ),
                    );
                  },
                ),
              );
            },
            child: Hero(
              // Assigning tag of item as its index in the list
              tag: index.toString(),
              child: Container(
                  height: 200, color: Colors.grey[(index + 1) * 100]),
            ));
      }))),
    );
  }
}

为简单起见,我已将目标页面放在主文件的范围内,但您可以制作一个单独的小部件并接受 index 作为 Bigger Hero 标签的参数