Skip to content

Instantly share code, notes, and snippets.

@Arathi
Last active May 22, 2023 09:58
Show Gist options
  • Save Arathi/5c6acb45a915b2eea9cadf25b280d74a to your computer and use it in GitHub Desktop.
Save Arathi/5c6acb45a915b2eea9cadf25b280d74a to your computer and use it in GitHub Desktop.
Flutter栅格系统
import 'package:flutter/widgets.dart' hide Row;
import 'package:get/get.dart';
import '../utils/reactive_units.dart';
enum JustifyContent {
start,
center,
end,
}
enum AlignItems {
start,
center,
end,
}
class Row extends StatelessWidget {
static const spanAmount = 24;
// 列间隔
double gutter;
// 水平对齐(交叉轴)
JustifyContent justify;
// 垂直对齐(主轴)
AlignItems align;
double marginBottom;
List<Col> cols = [];
Row(
{super.key,
this.gutter = 0,
this.justify = JustifyContent.start,
this.align = AlignItems.start,
this.marginBottom = 0,
required this.cols});
MainAxisAlignment get mainAxisAlignment {
switch (align) {
case AlignItems.start:
return MainAxisAlignment.start;
case AlignItems.end:
return MainAxisAlignment.end;
case AlignItems.center:
return MainAxisAlignment.center;
}
}
CrossAxisAlignment get crossAxisAlignment {
switch (justify) {
case JustifyContent.start:
return CrossAxisAlignment.start;
case JustifyContent.end:
return CrossAxisAlignment.end;
case JustifyContent.center:
return CrossAxisAlignment.center;
}
}
List<Widget> buildChildren(BuildContext context) {
List<Widget> children = <Widget>[];
var useSpan = false;
var spanSum = 0;
var flexSum = 0;
for (int index = 0; index < cols.length; index++) {
var col = cols[index];
if (col.span != null) {
useSpan = true;
spanSum += col.span!;
}
else if (col.flex != null) {
flexSum += col.flex!;
}
}
// print("span和:$spanSum");
// print("flex和:$flexSum");
double scale = 10;
if (useSpan) {
var spanLeft = spanAmount - spanSum;
// print("剩余span数:$spanLeft");
for (int index = 0; index < cols.length; index++) {
var col = cols[index];
if (col.span != null) {
col.flex = (col.span! * scale).toInt();
}
else if (col.flex != null) {
double flexRate = col.flex! * 1.0 / flexSum;
double spanRate = spanLeft * flexRate / spanAmount;
col.flex = (spanRate * spanAmount * scale).toInt();
}
// print("col[$index].flex = ${col.flex}");
}
}
for (int index = 0; index < cols.length; index++) {
var col = cols[index];
Widget child = col;
if (gutter > 0 && index != cols.length - 1) {
child = child.marginOnly(right: gutter.rpx);
}
if (col.flex != null) {
child = Expanded(
flex: col.flex!,
child: child,
);
}
children.add(child);
}
return children;
}
@override
Widget build(BuildContext context) {
Widget row = Flex(
direction: Axis.horizontal,
mainAxisAlignment: mainAxisAlignment,
crossAxisAlignment: crossAxisAlignment,
children: buildChildren(context),
);
if (marginBottom > 0) {
row = row.marginOnly(bottom: marginBottom.rpx);
}
return row;
}
}
class Col extends StatelessWidget {
int? span;
int? offset;
int? flex;
double? widthRpx;
Color? backgroundColor;
Widget child;
double get widthDp {
return 0;
}
Col(
{super.key,
this.span,
this.offset = 0,
this.flex,
double? width,
this.backgroundColor,
required this.child}) {
widthRpx = width;
}
@override
Widget build(BuildContext context) {
Widget col = Container(
color: backgroundColor,
child: child,
);
if (widthRpx != null) {
col = SizedBox(
width: widthRpx!.rpx,
child: col,
);
}
return col;
}
}
import 'package:get/get.dart';
extension ReactiveUnits on num {
double get rpx => this * Get.width / 750.0;
double get vw => this * Get.width / 100.0;
double get vh => this * Get.height / 100.0;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment