前幾天在QQ群里看到有人問類似這種頭像堆疊的效果在Flutter里面怎么實(shí)現(xiàn)乏德?
image.png
想了一想忙芒,在Flutter里面好像可以用Stack和Positioned來實(shí)現(xiàn)掉瞳。
最后效果如下
image.png
問題1:Stack靠右不好處理,現(xiàn)在是用 Row 嵌套2個 Expanded(黃色背景和紅色背景)猪腕,然后根據(jù)顯示頭像的數(shù)量來計算這2個Expanded的 flex配阵。
問題2:動態(tài)調(diào)整Stack里面頭像的數(shù)量馏颂。第一行,靠左顯示可以很好的解決棋傍。第二行救拉,靠右顯示,因?yàn)镾tack被Expanded包圍瘫拣,如果用函數(shù)返回一個 List<Widget>給Stack的children亿絮,F(xiàn)lutter會報錯。
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),
],
)),
],
),
),
);
}
}