Initial commit

This commit is contained in:
admin1
2026-07-14 11:11:36 +08:00
commit 656499cf94
604 changed files with 119518 additions and 0 deletions
+97
View File
@@ -0,0 +1,97 @@
import 'package:flutter/material.dart';
import '../layout/adaptive_card_grid.dart';
import '../theme/app_theme.dart';
class AppSkeleton extends StatefulWidget {
final double? width;
final double? height;
final double radius;
const AppSkeleton({super.key, this.width, this.height, this.radius = 8});
@override
State<AppSkeleton> createState() => _AppSkeletonState();
}
class _AppSkeletonState extends State<AppSkeleton>
with SingleTickerProviderStateMixin {
late final AnimationController _c = AnimationController(
vsync: this,
duration: const Duration(milliseconds: 1100),
)..repeat(reverse: true);
@override
void dispose() {
_c.dispose();
super.dispose();
}
@override
Widget build(BuildContext context) {
final base = Theme.of(context).colorScheme.onSurface;
return AnimatedBuilder(
animation: _c,
builder: (context, _) {
final alpha = 0.04 + 0.05 * _c.value;
return Container(
width: widget.width,
height: widget.height,
decoration: BoxDecoration(
color: base.withValues(alpha: alpha),
borderRadius: BorderRadius.circular(widget.radius),
),
);
},
);
}
}
class SkeletonGrid extends StatelessWidget {
final int itemCount;
final double itemHeight;
final double minCardWidth;
final EdgeInsetsGeometry padding;
const SkeletonGrid({
super.key,
this.itemCount = 6,
this.itemHeight = 84,
this.minCardWidth = kRichCardMinWidth,
this.padding = const EdgeInsets.symmetric(horizontal: 24),
});
@override
Widget build(BuildContext context) {
final tokens = context.appTokens;
return Padding(
padding: padding,
child: LayoutBuilder(
builder: (_, constraints) {
final columns = cardColumnsFor(
constraints.maxWidth,
minCardWidth: minCardWidth,
);
final width =
(constraints.maxWidth - kCardGap * (columns - 1)) / columns;
return Wrap(
spacing: kCardGap,
runSpacing: kCardGap,
children: [
for (var i = 0; i < itemCount; i++)
SizedBox(
width: width,
child: AppSkeleton(
height: itemHeight,
radius: tokens.radiusCard,
),
),
],
);
},
),
);
}
}