User interface 对齐两个圆圈的最佳方式是什么?

User interface 对齐两个圆圈的最佳方式是什么?,user-interface,flutter,stack,widget,User Interface,Flutter,Stack,Widget,我正在设计一个像这样的屏幕在一堆的颤振 问题是,在颤振中实现时,我考虑了视口高度和宽度等变量,但在构建它时,它没有正确显示 我想要的是: 我得到的是: 有什么帮助吗? 更新: 这是我想要的UI卡的代码 class GameCard extends StatelessWidget { final bool isNew = false; @override Widget build(BuildContext context) { return Stack( chi

我正在设计一个像这样的屏幕在一堆的颤振

问题是,在颤振中实现时,我考虑了视口高度和宽度等变量,但在构建它时,它没有正确显示

我想要的是:

我得到的是:

有什么帮助吗?

更新: 这是我想要的UI卡的代码

class GameCard extends StatelessWidget {

final bool isNew = false;

  @override
  Widget build(BuildContext context) {
    return Stack(
      children: <Widget>[
        Card(
          clipBehavior: Clip.antiAliasWithSaveLayer,
          child: Column(
            mainAxisAlignment: MainAxisAlignment.spaceBetween,
            children: <Widget>[
              CachedNetworkImage(
                imageUrl: CommonUrls.beginnersContestDefaultImage,
                fit: BoxFit.fill,
                height: MediaQuery.of(context).size.height / 7,
              ),
              Container(
                padding: EdgeInsets.all(20.0),
                child: Column(
                  mainAxisAlignment: MainAxisAlignment.center,
                  children: <Widget>[
                    Text('Game Name', style: CommonTextStyles.getSubTitleTextStyleDark(context).copyWith(
                      fontWeight: FontWeight.bold
                    ),),
                    Text('4543', style: CommonTextStyles.getTitleTextStyleGray(context).copyWith(
                      fontSize: 12,
                      color: Colors.grey
                    ),),
                  ],
                ),
              ),
            ],
          ),
        ),
    isNew? Positioned(
      right: 4,
      top: 4,
      child: Container(
        padding: EdgeInsets.only(top: 8.0, right: 18.0, left: 18.0, bottom: 8.0),
        decoration: BoxDecoration(
            color: Colors.white,
            borderRadius: BorderRadius.only(topRight: Radius.circular(5.0), bottomLeft: Radius.circular(5.0),)
        ),
        child: Text('NEW', style: CommonTextStyles.getTitleTextStyleLight(context).copyWith(
          fontWeight: FontWeight.bold,
          fontSize: 14,
        ),),
      ),
    )
    : Container(),
    isNew? Positioned(
      right: 0,
      child: Container(
        padding: EdgeInsets.only(top: 8.0, right: 18.0, left: 18.0, bottom: 8.0),
        decoration: BoxDecoration(
          color: Colors.red,
          borderRadius: BorderRadius.only(topRight: Radius.circular(5.0), bottomLeft: Radius.circular(5.0),)
        ),
        child: Text('NEW', style: CommonTextStyles.getTitleTextStyleLight(context).copyWith(
          fontWeight: FontWeight.bold,
          fontSize: 14,
        ),),
      ),
    )
     : Container(),

    Positioned(
      bottom: MediaQuery.of(context).size.height / 13,
      left: MediaQuery.of(context).size.width/7.5,
      child: Row(
        children: <Widget>[
          Padding(
            padding: const EdgeInsets.only(left: 8.0, right: 8.0),
            child: CircleAvatar(
              backgroundColor: getColor(0xff8951d9),
              radius: 13,
                ),
          ),
          Padding(
            padding: const EdgeInsets.only(left: 8.0, right: 8.0),
            child: CircleAvatar(
              backgroundColor: getColor(0xff3e51b5),
              radius: 13,
            ),
          ),
        ],
      ),
    ),
   ],
  );
 }
}
class游戏卡扩展了无状态小部件{
最终bool isNew=false;
@凌驾
小部件构建(构建上下文){
返回堆栈(
儿童:[
卡片(
clipBehavior:Clip.antiAliasWithSaveLayer,
子:列(
mainAxisAlignment:mainAxisAlignment.spaceBetween,
儿童:[
CachedNetworkImage(
imageUrl:CommonUrls.OrientsContestDefaultImage,
fit:BoxFit.fill,
高度:MediaQuery.of(context).size.height/7,
),
容器(
填充:所有边缘设置(20.0),
子:列(
mainAxisAlignment:mainAxisAlignment.center,
儿童:[
Text('Game Name',style:CommonTextStyles.getSubTitleTextStyleDark(上下文)。copyWith(
fontWeight:fontWeight.bold
),),
文本('4543',样式:CommonTextStyles.getTitleTextStyleGray(上下文).copyWith(
尺寸:12,
颜色:颜色。灰色
),),
],
),
),
],
),
),
是新的吗(
右:4,,
排名:4,
子:容器(
填充:仅限边设置(顶部:8.0,右侧:18.0,左侧:18.0,底部:8.0),
装饰:盒子装饰(
颜色:颜色,白色,
borderRadius:borderRadius.only(右上角:半径.圆形(5.0),左下角:半径.圆形(5.0),)
),
子项:Text('NEW',样式:CommonTextStyles.getTitleTextStyleLight(上下文).copyWith(
fontWeight:fontWeight.bold,
尺寸:14,
),),
),
)
:Container(),
是新的吗(
右:0,,
子:容器(
填充:仅限边设置(顶部:8.0,右侧:18.0,左侧:18.0,底部:8.0),
装饰:盒子装饰(
颜色:颜色,红色,
borderRadius:borderRadius.only(右上角:半径.圆形(5.0),左下角:半径.圆形(5.0),)
),
子项:Text('NEW',样式:CommonTextStyles.getTitleTextStyleLight(上下文).copyWith(
fontWeight:fontWeight.bold,
尺寸:14,
),),
),
)
:Container(),
定位(
底部:MediaQuery.of(context).size.height/13,
左:MediaQuery.of(context).size.width/7.5,
孩子:排(
儿童:[
填充物(
填充:仅限常量边集(左:8.0,右:8.0),
孩子:圆环星(
背景颜色:getColor(0xff8951d9),
半径:13,
),
),
填充物(
填充:仅限常量边集(左:8.0,右:8.0),
孩子:圆环星(
背景色:getColor(0xff3e51b5),
半径:13,
),
),
],
),
),
],
);
}
}

您可以在一个堆栈小部件中添加大图像和两个圆形化身,然后添加底部边距或填充或大图像,并使用定位小部件将两个圆形化身包装在一个行小部件中,以将它们放置在大图像的底部

例如:

Stack(
   children: <Widget>[
      Container(
         margin: EdgeInsets.only(bottom: 40),
         child: BigImage(),
      ),
      Positioned(
         bottom: 20,
         child: Row(
            children: <Widget>[
               CircularAvatar(),
               CircularAvatar(),
            ],
         ),
      ),
   ],
)
堆栈(
儿童:[
容器(
页边距:仅限边集(底部:40),
子项:BigImage(),
),
定位(
底数:20,
孩子:排(
儿童:[
CircularAvatar(),
CircularAvatar(),
],
),
),
],
)

这是一个粗略的想法,你可以尝试一下,看看它是否工作。

@Dhruvam,不确定你是如何调用你的游戏卡的,但有很多事情与化身圈无关,可能会影响对齐

  • 确保您正在GridView中调用GameCard
  • 根据屏幕大小计算卡的数量
  • 将CachedNeworkImage与扩展的图像一起封装,以正确填充您的卡
  • 设置游戏标题/数字容器的高度,以便您可以相应地将头像放置在底部
  • 最后,根据一行中的牌数向左定位你的化身
下面基于您的代码的示例应该会给您一个想法。你可能想在左侧位置玩一玩,以支持不同的屏幕大小

class HomePage extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    double width = MediaQuery.of(context).size.width;
    double cardWidth = 150.0;
    int countRow = width ~/ cardWidth;// Calculate no. of cards in a row
    return MaterialApp(
        home: Scaffold(
            body: SafeArea(
                child: GridView.count(
      primary: false,
      padding: EdgeInsets.zero,
      crossAxisSpacing: 10,
      mainAxisSpacing: 10,
      crossAxisCount: countRow,
      children: <Widget>[
        getGameCard(
            context,
            'https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcScDI-oN5NuYMe-Jxnou1U8ZyzBP_6dXTxx_DdB7Gcu_y9ksP-0aQ&s',
            true,
            countRow),
        getGameCard(
            context,
            'https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcScDI-oN5NuYMe-Jxnou1U8ZyzBP_6dXTxx_DdB7Gcu_y9ksP-0aQ&s',
            false,
            countRow),
        getGameCard(
            context,
            'https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcScDI-oN5NuYMe-Jxnou1U8ZyzBP_6dXTxx_DdB7Gcu_y9ksP-0aQ&s',
            false,
            countRow),
        getGameCard(
            context,
            'https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcScDI-oN5NuYMe-Jxnou1U8ZyzBP_6dXTxx_DdB7Gcu_y9ksP-0aQ&s',
            false,
            countRow),
        getGameCard(
            context,
            'https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcScDI-oN5NuYMe-Jxnou1U8ZyzBP_6dXTxx_DdB7Gcu_y9ksP-0aQ&s',
            false,
            countRow),
        getGameCard(
            context,
            'https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcScDI-oN5NuYMe-Jxnou1U8ZyzBP_6dXTxx_DdB7Gcu_y9ksP-0aQ&s',
            false,
            countRow),
      ],
    ))));
  }

  getGameCard(BuildContext context, String url, bool isNew, int rowCount) {
    return Stack(
      children: <Widget>[
        Card(
              clipBehavior: Clip.antiAliasWithSaveLayer,
              child: Column(
                mainAxisAlignment: MainAxisAlignment.spaceBetween,
                children: <Widget>[
                  Expanded(
                      child: CachedNetworkImage(
                    imageUrl: url,
                    fit: BoxFit.fill,
                  )),
                  Container(
                    height: 55.0,
                    padding: EdgeInsets.all(10.0),
                    child: Column(
                      children: <Widget>[
                        Text(
                          'Game Name',
                          style: TextStyle(fontWeight: FontWeight.bold),
                        ),
                        Text(
                          '4543',
                          style: TextStyle(fontSize: 12, color: Colors.grey),
                        ),
                      ],
                    ),
                  ),
                ],
              ),
            ),
        Positioned(
            left: MediaQuery.of(context).size.width / (7 + rowCount),
            bottom: 48.0,
            child: Row(
              children: <Widget>[
                Padding(
                  padding: const EdgeInsets.only(left: 8.0, right: 8.0),
                  child: CircleAvatar(
                    backgroundColor: Color(0xff8951d9),
                    radius: 13,
                  ),
                ),
                Padding(
                  padding: const EdgeInsets.only(left: 8.0, right: 8.0),
                  child: CircleAvatar(
                    backgroundColor: Color(0xff3e51b5),
                    radius: 13,
                  ),
                ),
              ],
            )),
        isNew
            ? Positioned(
                right: 4,
                top: 4,
                child: Container(
                  padding: EdgeInsets.only(
                      top: 8.0, right: 18.0, left: 18.0, bottom: 8.0),
                  decoration: BoxDecoration(
                      color: Colors.white,
                      borderRadius: BorderRadius.only(
                        topRight: Radius.circular(5.0),
                        bottomLeft: Radius.circular(5.0),
                      )),
                  child: Text(
                    'NEW',
                    style: TextStyle(
                      fontWeight: FontWeight.bold,
                      fontSize: 14,
                    ),
                  ),
                ),
              )
            : Container(),
        isNew
            ? Positioned(
                right: 0,
                child: Container(
                  padding: EdgeInsets.only(
                      top: 8.0, right: 18.0, left: 18.0, bottom: 8.0),
                  decoration: BoxDecoration(
                      color: Colors.red,
                      borderRadius: BorderRadius.only(
                        topRight: Radius.circular(5.0),
                        bottomLeft: Radius.circular(5.0),
                      )),
                  child: Text(
                    'NEW',
                    style: TextStyle(
                      fontWeight: FontWeight.bold,
                      fontSize: 14,
                    ),
                  ),
                ),
              )
            : Container(),
      ],
    );
  }
}
类主页扩展了无状态小部件{
@凌驾
小部件构建(构建上下文){
double width=MediaQuery.of(context).size.width;
双卡宽度=150.0;
int countRow=width~/cardWidth;//计算一行中的卡数
返回材料PP(
家:脚手架(
正文:安全区(
子项:GridView.count(
主要:错误,
填充:EdgeInsets.zero,
横轴间距:10,
平均间距:10,
crossAxisCount:countRow,
儿童:[
游戏卡(
上下文
'https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcScDI-在5NUYME-Jxnou1U8ZyzBP_6DXTX_DdB7Gcu_y9ksP-0aQ&s'上,
是的,
countRow),
游戏卡(
上下文
'https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcScDI-在5NUYME-Jxnou1U8ZyzBP_6DXTX_DdB7Gcu_y9ksP-0aQ&s'上,
假,,
countRow),
游戏卡(
上下文
'https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcScDI-在5NUYME-Jxnou1U8ZyzBP_6DXTX_DdB7Gcu_y9ksP-0aQ&s'上,
假,,
countRow),
游戏卡(