我正在尝试创建类似Flutter的流布局。我只需要在FlexibleGridView上执行类似this的操作,但是要使用拉伸动画。因此,在我的情况下,我基于元素列表构建矩阵,然后更改元素的位置,但是当我对许多元素执行此操作时,我不知道如何使它们不重叠。
这是我的课程
class UserSuggestion extends StatefulWidget {
static final String tag = '/user-suggestion';
UserSuggestion({Key key}) : super(key: key);
@override
_UserSuggestionState createState() => _UserSuggestionState();
}
class _UserSuggestionState extends State<UserSuggestion>
with TickerProviderStateMixin {
double screenHeight;
List<Example01Tile> list;
List<SuggestionCategory> items = [];
Map<int, List<SuggestionCategory>> suggestionMatrix = {
0: [],
1: [],
2: [],
3: []
};
StreamController onTapListener = StreamController();
@override
void initState() {
// TODO: implement initState
super.initState();
final number = 30;
items = List.generate(
number,
(index) => SuggestionCategory(
name: index.toString(),
width: 100,
height: 100,
),
);
int rowCount = (items.length / 4).round();
suggestionMatrix = Map.from(suggestionMatrix.map((key, value) {
final endIndex = (rowCount * (key + 1));
return MapEntry(
key,
items
.getRange(rowCount * key,
endIndex < items.length ? endIndex : items.length)
.toList()
.asMap()
.entries
.map((element) {
final val = element.value;
final i = element.key;
return SuggestionCategory(
name: i.toString(),
width: 100,
height: 100,
x: (i) * 100.0,
y: (key) * 100.0);
}).toList());
}));
onTapListener.stream.listen((event) {
calculeteNewTapsPositions(event);
});
}
@override
Widget build(BuildContext context) {
final isDesktop = isDisplayDesktop(context);
screenHeight = MediaQuery.of(context).size.height;
return Scaffold(body: Center(child: mobile()));
}
mobile() {
return Column(
mainAxisAlignment: MainAxisAlignment.center,
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text(
"Tell me what noo jiu jkwk?",
style: Theme.of(context).textTheme.headline2,
).paddingOnly(
top: PADDING_TOP_BIG_SUGGESTION,
left: PADDING_LR_MEDIUM,
right: PADDING_LR_MEDIUM),
Flexible(
child: grid(),
),
]);
}
grid() {
return SingleChildScrollView(
scrollDirection: Axis.horizontal,
child: Container(
height: 600,
width: 800,
child: Stack(
fit: StackFit.expand,
alignment: Alignment.topLeft,
children: jjjjjj(),
),
));
}
List<Widget> jjjjjj() {
List<Widget> widgets = [];
suggestionMatrix.entries.forEach((columns) {
int iColumn = columns.key;
List<SuggestionCategory> rowsList = columns.value;
rowsList.asMap().entries.forEach((rows) {
int iRow = rows.key;
SuggestionCategory rowsList = rows.value;
rowsList.iColumn = iColumn;
rowsList.iRow = iRow;
widgets.add(AnimatedPositioned(
duration: Duration(milliseconds: 600),
curve: Curves.easeInOut,
left: rows.value.x,
top: rows.value.y,
// bottom: bottom,
// right: right,
height: rows.value.height,
width: rows.value.width,
child: item(rows.value),
));
});
});
return widgets;
}
void calculeteNewTapsPositions(SuggestionCategory suggestionCategory) {
final iRow = suggestionCategory.iRow;
final iColumn = suggestionCategory.iColumn;
bool needExpand = suggestionCategory.currentWeight > 1;
bool isEndExpandIteration = suggestionCategory.currentWeight > 2;
List<SuggestionCategory> rowList = suggestionMatrix[iColumn];
//mark for right rows
rowList.getRange(iRow + 1, rowList.length).forEach((SuggestionCategory e) {
setState(() {
if (needExpand) {
print("right");
e.x = e.x + 100;
} else {
print("back");
e.x = e.x - 200;
}
});
});
//mark for left columns
suggestionMatrix.forEach((key, value) {
if (key > iColumn) {
SuggestionCategory e1 = value.elementAt(iRow);
SuggestionCategory e2 = value.elementAt(iRow + 1);
SuggestionCategory e3 = value.elementAt(iRow + 2);
setState(() {
if (needExpand) {
e1.y = e1.y + 50;
e2.y = e2.y + 50;
} else {
e1.y = e1.y - 100;
e2.y = e2.y - 100;
//e3.y = e3.y - 100;
}
// if (isEndExpandIteration && needExpand) {
// e3.y = e3.y + 100;
// }
});
}
});
}
Widget item(SuggestionCategory e) => AnimatedSize(
vsync: this,
duration: Duration(seconds: 1),
curve: Curves.bounceIn,
child: Example01Tile(
backgroundColor: Colors.blueGrey,
iconData: Icons.hd,
name: e.name,
).addOnTap(
onTap: () {
setState(() {
if (e.currentWeight <= 2) {
e.currentWeight = e.currentWeight + 1;
e.height = e.height + 50;
e.width = e.width + 50;
//x.y.nextposel
} else {
e.currentWeight = 1;
e.height = 100;
e.width = 100;
}
onTapListener.add(e);
});
},
),
);
}
class SuggestionCategory {
String name;
StaggeredTile staggeredTile;
int currentWeight = 1;
double width;
double height;
double x;
double y;
int iRow;
int iColumn;
SuggestionCategory({this.name, this.width, this.height, this.x, this.y});
}