对齐两个圆形头像的最佳方法是啥?

Posted

技术标签:

【中文标题】对齐两个圆形头像的最佳方法是啥?【英文标题】:What is the best way to align the two circleavatars?对齐两个圆形头像的最佳方法是什么? 【发布时间】:2020-03-27 00:21:23 【问题描述】:

我正在 Flutter 的 Stack 中设计这样的屏幕。

问题是我在 Flutter 中实现时考虑了视口高度和宽度等变量,然后在构建它时,它无法正确显示。

我想要的:

我得到了什么:

有什么帮助吗?

更新: 这是我想要 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,
            ),
          ),
        ],
      ),
    ),
   ],
  );
 

【问题讨论】:

发布您的代码。 【参考方案1】:

@Dhruvam,不确定你是如何调用你的 GameCard,但有很多与头像圈无关的东西可能会影响对齐,

确保在 GridView 中调用 GameCard 根据屏幕大小计算卡片数量 用 Expanded 包围 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(),
      ],
    );
  

希望这会有所帮助。祝你好运!

【讨论】:

【参考方案2】:

您可以在一个 Stack 小部件中添加大图像和两个圆形头像,然后添加底部边距或填充或大图像,并使用 Positioned 小部件将两个圆形头像包装在 Row 小部件中,以将它们放置在底部大图。

例子:

Stack(
   children: <Widget>[
      Container(
         margin: EdgeInsets.only(bottom: 40),
         child: BigImage(),
      ),
      Positioned(
         bottom: 20,
         child: Row(
            children: <Widget>[
               CircularAvatar(),
               CircularAvatar(),
            ],
         ),
      ),
   ],
)

这是一个粗略的想法,您可以尝试一下,看看它是否有效。

【讨论】:

这正是我所做的。我已经更新了我的问题。请检查。

以上是关于对齐两个圆形头像的最佳方法是啥?的主要内容,如果未能解决你的问题,请参考以下文章

Flutter圆形头像不支持来自存储的图像

圆形头像CircleImageView和Cardview使用

Android自己定义圆形ImageView(圆形头像 可指定大小)

用户头像的圆形显示

iOS 裁剪圆形图像并显示(类似于微信头像)

如何检查图像资产是不是存在,然后将其用作圆形头像或在圆形头像中写下姓名的第一个字母