Flutter圈子Flutter教程网Flutter中文社区

Flutter Ui 实验室(二)头像堆叠

2019-06-04  本文已影响24人  funpig

前几天在QQ群里看到有人问类似这种头像堆叠的效果在Flutter里面怎么实现?


image.png

想了一想,在Flutter里面好像可以用Stack和Positioned来实现。

最后效果如下


image.png

问题1:Stack靠右不好处理,现在是用 Row 嵌套2个 Expanded(黄色背景和红色背景),然后根据显示头像的数量来计算这2个Expanded的 flex。

问题2:动态调整Stack里面头像的数量。第一行,靠左显示可以很好的解决。第二行,靠右显示,因为Stack被Expanded包围,如果用函数返回一个 List<Widget>给Stack的children,Flutter会报错。

image.png

PS: 问题1,2的解决。使用SizedBox


image.png
Container(
                height: 40,
                alignment: Alignment.topRight,
                child: Row(
                  mainAxisAlignment: MainAxisAlignment.end,
                  children: <Widget>[
                    SizedBox(
                      width: _getImageStackWidth(8),
                      height: double.infinity,
                      child: Stack(
                        children: _getStackItems(8),
                      ),
                    ),
                    Icon(Icons.arrow_forward),
                  ],
                )),

最后上代码

import 'package:flutter/material.dart';

class ImageStackPage extends StatelessWidget {
  final double sizeW = 50.0;
  final double offsetW = 20.0;

  int _getSpaceStackFlex(BuildContext context, int imageNumber) {
    int maxNum = (MediaQuery.of(context).size.width - 16).toInt();
    int num = (offsetW * (imageNumber - 1) + sizeW).toInt();
    return maxNum - num + 1;
  }

  int _getImageStackFlex(BuildContext context, int imageNumber) {
    int num = (offsetW * (imageNumber - 1) + sizeW).toInt();
    return num;
  }

  double _getImageStackWidth(int imageNumber) {
    return offsetW * (imageNumber - 1) + sizeW;
  }

  List<Widget> _getStackItems(int count) {
    List<Widget> _list = new List<Widget>();
    for (var i = 0; i < count; i++) {
      double off = 20.0 * i;
      _list.add(Positioned(
        left: off,
        child: CircleAvatar(
          child: Image(
            image: AssetImage("images/head02.png"),
            width: sizeW,
            height: sizeW,
          ),
        ),
      ));
    }
    return _list;
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text('头像堆叠'),
      ),
      body: Container(
        child: Column(
          children: <Widget>[
            Container(
                height: 40,
                alignment: Alignment.topRight,
                child: Row(
                  mainAxisAlignment: MainAxisAlignment.end,
                  children: <Widget>[
                    SizedBox(
                      width: _getImageStackWidth(8),
                      height: double.infinity,
                      child: Stack(
                        children: _getStackItems(8),
                      ),
                    ),
                    Icon(Icons.arrow_forward),
                  ],
                )),
            Container(
                height: 40,
                child: Container(
                  color: Colors.teal,
                  child: Stack(
                    children: _getStackItems(8),
                  ),
                )),
            Container(
                color: Colors.grey,
                child: new Row(
                  children: <Widget>[
                    Expanded(
                      flex: _getSpaceStackFlex(context, 8),
                      child: Container(
                        color: Colors.yellow,
                        height: 40,
                      ),
                    ),
                    Expanded(
                      flex: _getImageStackFlex(context, 8),
                      child: Container(
                        color: Colors.red,
                        child: Stack(
                          alignment: AlignmentDirectional.bottomEnd,
                          children: <Widget>[
                            CircleAvatar(
                              child: Image(
                                image: AssetImage("images/head01.png"),
                                width: sizeW,
                                height: sizeW,
                              ),
                            ),
                            Positioned(
                              right: 20,
                              child: CircleAvatar(
                                child: Image(
                                  image: AssetImage("images/head02.png"),
                                  width: sizeW,
                                  height: sizeW,
                                ),
                              ),
                            ),
                            Positioned(
                              right: 40,
                              child: CircleAvatar(
                                child: Image(
                                  image: AssetImage("images/head01.png"),
                                  width: sizeW,
                                  height: sizeW,
                                ),
                              ),
                            ),
                            Positioned(
                              right: 60,
                              child: CircleAvatar(
                                child: Image(
                                  image: AssetImage("images/head01.png"),
                                  width: sizeW,
                                  height: sizeW,
                                ),
                              ),
                            ),
                            Positioned(
                              right: 80,
                              child: CircleAvatar(
                                child: Image(
                                  image: AssetImage("images/head01.png"),
                                  width: sizeW,
                                  height: sizeW,
                                ),
                              ),
                            ),
                            Positioned(
                              right: 100,
                              child: CircleAvatar(
                                child: Image(
                                  image: AssetImage("images/head01.png"),
                                  width: sizeW,
                                  height: sizeW,
                                ),
                              ),
                            ),
                            Positioned(
                              right: 120,
                              child: CircleAvatar(
                                child: Image(
                                  image: AssetImage("images/head01.png"),
                                  width: sizeW,
                                  height: sizeW,
                                ),
                              ),
                            ),
                            Positioned(
                              right: 140,
                              child: CircleAvatar(
                                child: Image(
                                  image: AssetImage("images/head01.png"),
                                  width: sizeW,
                                  height: sizeW,
                                ),
                              ),
                            )
                          ],
                        ),
                      ),
                    ),
                    Icon(Icons.arrow_forward),
                  ],
                )),
          ],
        ),
      ),
    );
  }
}

上一篇下一篇

猜你喜欢

热点阅读