在颤振中使用最佳方法创建自定义复杂布局?

Posted

技术标签:

【中文标题】在颤振中使用最佳方法创建自定义复杂布局?【英文标题】:create custom complex layout with best approach in flutter? 【发布时间】:2021-08-04 14:49:12 【问题描述】:

我构建了一个布局,但我知道这不是创建此布局的好方法。 那么如何获得最好的方法来创建这个布局,中间小部件的动态和对齐应该在中心。

代码:

class StartGroupChatScreen extends StatelessWidget 
  double startPoint = 30;
  @override
  Widget build(BuildContext context) 
    final size = MediaQuery.of(context).size;
    return Scaffold(
      appBar: AppBar(
          automaticallyImplyLeading: false,
          title: Row(
            children: [
              IconButton(
                icon: Icon(
                  Icons.arrow_back_ios,
                  color: MyTheme.secondryColor,
                ),
                onPressed: () ,
              ),
              Text(
                "GROUP CHAT",
                style: TextStyle(
                    fontSize: 17,
                    fontWeight: FontWeight.bold,
                    color: MyTheme.secondryColor),
              ),
            ],
          )),
      body: Container(
        color: MyTheme.grey800,
        child: Stack(
          children: [
            InkWell(
              child: Align(
                alignment: Alignment.center,
                child: Column(
                  mainAxisAlignment: MainAxisAlignment.center,
                  children: [
                    Container(
                      height: size.height * 0.14,
                      alignment: Alignment.center,
                      child: Stack(
                        children: [
                          Positioned(
                            left: startPoint,
                            child: UserAvatar(
                                imageUrl:
                                    "https://wallpaperaccess.com/full/3957694.jpg",
                                avatarRadius: size.height * 0.12),
                          ),
                          Positioned(
                            left: startPoint + 30,
                            child: UserAvatar(
                                imageUrl:
                                    "https://m.media-amazon.com/images/M/MV5BZDA1ODgyODEtOWI3Yy00N2UzLTk5ZGMtZGI1MzU5YzFkZDQ1XkEyXkFqcGdeQXVyMTc4MzI2NQ@@._V1_UY1200_CR285,0,630,1200_AL_.jpg",
                                avatarRadius: size.height * 0.12),
                          ),
                          Positioned(
                            left: startPoint + 60,
                            child: UserAvatar(
                                imageUrl:
                                    "https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcQhS1n9AgNPFrsPjj0fHqwPdIJPJLl9hXUq5Q&usqp=CAU",
                                avatarRadius: size.height * 0.12),
                          ),
                          Positioned(
                            left: startPoint + 90,
                            child: UserAvatar(
                                imageUrl:
                                    "https://img.mensxp.com/media/content/2020/Aug/Michele-Morrone-From-365-Days-Floored-Us-With-His-Fashion-Game-1200x900_5f2a761253b66_1200x900.jpeg",
                                avatarRadius: size.height * 0.12),
                          ),
                          Positioned(
                            left: startPoint + 120,
                            child: UserAvatar(
                                imageUrl:
                                    "https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcS44UpSZW-GZwDVxU3763H9HPOWqdB6ThRAoQ&usqp=CAU",
                                avatarRadius: size.height * 0.12),
                          ),
                          Positioned(
                            left: startPoint + 150,
                            child: UserAvatar(
                                imageUrl:
                                    "https://img1.nickiswift.com/img/gallery/the-untold-truth-of-michele-morrone-from-365-days/intro-1593017194.jpg",
                                avatarRadius: size.height * 0.12),
                          ),
                          Positioned(
                            left: startPoint + 180,
                            child: UserAvatar(
                                imageUrl:
                                    "https://images2.minutemediacdn.com/image/upload/c_fill,w_720,ar_16:9,f_auto,q_auto,g_auto/shape/cover/sport/Bar-Giuseppe-Red-Carpet---14th-Rome-Film-Fest-2019-7de8f118ccdbce430f2d706463c8e09c.jpg",
                                avatarRadius: size.height * 0.12),
                          ),
                          Positioned(
                            left: startPoint + 210,
                            child: UserAvatar(
                                imageUrl:
                                    "https://stat2.bollywoodhungama.in/wp-content/uploads/2021/04/Netflixs-365-Days-breakout-star-Michele-Morrone-looks-sharp-on-the-cover-of-Elle-India-..jpg",
                                avatarRadius: size.height * 0.12),
                          ),
                        ],
                      ),
                    ),
                    SizedBox(
                      height: size.height * 0.02,
                    ),
                    Text(
                      "START CHAT",
                      style: TextStyle(
                          color: MyTheme.white,
                          fontWeight: FontWeight.bold,
                          fontSize: 28.0),
                    ),
                  ],
                ),
              ),
            ),
            Align(
              alignment: Alignment.bottomCenter,
              child: InkWell(
                onTap: () ,
                child: Container(
                  height: size.height * 0.08,
                  alignment: Alignment.center,
                  decoration: BoxDecoration(
                    color: MyTheme.primaryColor,
                  ),
                  child: Text(
                    "CONTINUE",
                    style: const TextStyle(
                        fontWeight: FontWeight.bold, fontSize: 17.0),
                  ),
                ),
              ),
            )
          ],
        ),
      ),
    );
  


用户角色:

class UserAvatar extends StatelessWidget 
  final String imageUrl;
  final double avatarRadius;

  const UserAvatar(Key key,@required this.imageUrl , @required this.avatarRadius) : super(key: key);
  @override
  Widget build(BuildContext context) 
    return Container(
      height: avatarRadius,
      width: avatarRadius,
      decoration: BoxDecoration(
        shape: BoxShape.circle,
        image: DecorationImage(
          image: NetworkImage(imageUrl),
          fit: BoxFit.cover
        )
      ),
    );
  


输出:

dartPad

【问题讨论】:

要使堆栈居中对齐,您可以使用container 将其包裹,然后您可以align 将其居中。并将容器宽度指定为double.infinityMediaQuery.of(context).size.width 请您实施,应该在哪里? 【参考方案1】:

其实挺好的?

但这似乎是重复的,我认为您应该添加另一个字段属性,例如图像的位置和头像半径,因为它具有相同的重复 const 值

UserAvatar(
     imageUrl: "https://wallpaperaccess.com/full/3957694.jpg",
     imageNo : 1,
),
),

所以小部件应该是这样的

class UserAvatar extends StatelessWidget 
  final String imageUrl;
  final double avatarRadius;
  final int imageNo;

  const UserAvatar(Key key,@required this.imageUrl , @required this.avatarRadius) : super(key: key);
  @override
  Widget build(BuildContext context) 

  double startPoint = 30;
  final size = MediaQuery.of(context).size;

    return Positioned( 
left: startPoint + (30 * imageNo),
Container(
      height: size.height * 0.12,
      width: size.height * 0.12,
      decoration: BoxDecoration(
        shape: BoxShape.circle,
        image: DecorationImage(
          image: NetworkImage(imageUrl),
          fit: BoxFit.cover
        )
      ),
    ),
);
  

而且实际上你还可以为表演头像移动身体 从第 37 行到第 100 行,因为它是常数值

【讨论】:

以上是关于在颤振中使用最佳方法创建自定义复杂布局?的主要内容,如果未能解决你的问题,请参考以下文章

如何在颤振中创建自定义范围选择器?

创建自定义布局 ExtJs 4.1

如何使用颤振创建自定义弹出菜单

如何创建自定义颤振 sdk 小部件,重建颤振和使用新的小部件

在自定义tableviewcells中添加约束的最佳位置在哪里?

Android 自定义View