如何显示像弹出窗口一样的小部件

时间:2020-09-22 08:16:30

标签: flutter

目前,我有一个网格视图。当我点击它时,我使用英雄小部件导航到另一个页面。

在该页面上,我只有一个容器,用于显示有关该网格图块的信息。

我想要的是让该容器位于网格视图的顶部,而不是另一个页面。

我该如何弹出呢?如果可能的话,我宁愿保留英雄动画。 the grid

the container

3 个答案:

答案 0 :(得分:1)

您应该使用showDialog方法,如下所示:

InkWell(
 child: GridItem(),
 onTap: () {
  showDialog(
   context: context,
     builder: (context) => AlertDialog(
      content: Hero(child: Card(child: YourWidget()))
     ); // you can use SimpleDialog, specify barrier dismissible etc
 },
)

这是关于对话框类的链接 https://api.flutter.dev/flutter/material/Dialog-class.html

关于英雄,我不确定,因为我从头开始就写了,但是应该可以解决问题(ofc附加相同的标签,如果您的小部件已经有一个,则不需要Card父级-Hero需要材质小部件)

答案 1 :(得分:1)

我正在发布我最终所做的事情,因为它可以工作。

@Nonstapp和@Parth所建议的工作方式是英雄转换,但它仅适用于PageRoutes。

因此,我找到了另一种显示PageRoute弹出窗口的方法。

我正在显示的信息小部件:

return Padding(
  padding: EdgeInsets.fromLTRB(
      MediaQuery.of(context).size.width / 8,
      MediaQuery.of(context).size.height / 4,
      MediaQuery.of(context).size.width / 8,
      0),
  child: Material(
    color: Colors.transparent,
    child: ...

填充显然是用于定位的,而Material小部件则是为其提供Material样式和诸如IconButton之类的已启用小部件。为“材质”小部件赋予透明颜色。

这就是我所说的:

void seeDetails(BuildContext context, Book book) {
    Navigator.push(
      context,
      PageRouteBuilder(
        fullscreenDialog: true,
        opaque: false,
        pageBuilder: (_, __, ___) => ChangeNotifierProvider.value(
          value: book,
          child: DetailCard(),
        ),
      ),
    );
  }

我使用PageRouter来显示全屏对话框,但是由于我在那里进行了设置,因此只有信息卡可见。

缺点是我无法启用barrierDismissible,因为我位于另一条路线的atm。

这是我的结果:

result

但是,真正的解决方案是上面@pskink建议的解决方案。它需要更多的设置和调整,并且我与提供者有问题。 Here is how you can implement it

答案 2 :(得分:0)

您可以使用自定义对话框:-

onPressed: () {
        showDialog(
            context: context,
            builder: (_) => Center(
          child: RaisedButton(
            child: Text("Show dialog"),
            onPressed: () {
              showDialog(
                context: context,
                builder: (context) {
                  return Dialog(
                    shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(40)),
                    elevation: 16,
                    child: Container(
                      height: 400.0,
                      width: 360.0,
                      child: ListView(
                        children: <Widget>[
                          SizedBox(height: 20),
                          Center(
                            child: Text(
                              "Leaderboard",
                              style: TextStyle(fontSize: 24, color: Colors.blue, fontWeight: FontWeight.bold),
                            ),
                          ),
                          SizedBox(height: 20),
                          _buildName(imageAsset: 'assets/chocolate.jpg', name: "Name 1", score: 1000),
                          _buildName(imageAsset: 'assets/chocolate.jpg', name: "Name 2", score: 2000),
                          _buildName(imageAsset: 'assets/chocolate.jpg', name: "Name 3", score: 3000),
                          _buildName(imageAsset: 'assets/chocolate.jpg', name: "Name 4", score: 4000),
                          _buildName(imageAsset: 'assets/chocolate.jpg', name: "Name 5", score: 5000),
                          _buildName(imageAsset: 'assets/chocolate.jpg', name: "Name 6", score: 6000),
                        ],
                      ),
                    ),
                  );
                },
              );
            },
          ),
        ),
        );
    }
    
    
    Widget _buildName({String imageAsset, String name, double score}) {
      return Padding(
        padding: const EdgeInsets.symmetric(horizontal: 20.0),
        child: Column(
          children: <Widget>[
            SizedBox(height: 12),
            Container(height: 2, color: Colors.redAccent),
            SizedBox(height: 12),
            Row(
              children: <Widget>[
                CircleAvatar(
                  backgroundImage: AssetImage(imageAsset),
                  radius: 30,
                ),
                SizedBox(width: 12),
                Text(name),
                Spacer(),
                Container(
                  padding: EdgeInsets.symmetric(vertical: 8, horizontal: 20),
                  child: Text("${score}"),
                  decoration: BoxDecoration(
                    color: Colors.yellow[900],
                    borderRadius: BorderRadius.circular(20),
                  ),
                ),
              ],
            ),
          ],
        ),
      );
    }