登录流程已全部重构

This commit is contained in:
zhutao
2025-09-23 11:47:29 +08:00
parent a4992a063b
commit 8988b3feea
71 changed files with 2036 additions and 901 deletions

View File

@@ -1,45 +0,0 @@
import 'package:flutter/material.dart';
class AsyncImage extends StatelessWidget {
final String url;
final double? width;
const AsyncImage({
super.key,
required this.url,
this.width,
});
@override
Widget build(BuildContext context) {
return SizedBox(
width: width,
child: Image.network(
url,
fit: BoxFit.cover,
// 加载中的样式
loadingBuilder: (context, child, loadingProgress) {
if (loadingProgress == null) {
return child; // 加载完成,直接返回图片
}
return Container(
color: Colors.grey[200],
alignment: Alignment.center,
child: CircularProgressIndicator(strokeWidth: 2),
);
},
// 加载失败的样式
errorBuilder: (context, error, stackTrace) {
return Container(
color: Colors.grey[200],
child: const Icon(
Icons.broken_image,
size: 30,
color: Colors.grey,
),
);
},
),
);
}
}

View File

@@ -0,0 +1,43 @@
import 'package:cached_network_image/cached_network_image.dart';
import 'package:flutter/material.dart';
class AsyncImage extends StatelessWidget {
final String url;
final double? width;
const AsyncImage({
super.key,
required this.url,
this.width,
});
@override
Widget build(BuildContext context) {
return SizedBox(
width: width,
child: CachedNetworkImage(
width: double.infinity,
height: double.infinity,
fit: BoxFit.cover,
imageUrl: url ?? "",
imageBuilder: (context, imageProvider) => Container(
decoration: BoxDecoration(
image: DecorationImage(
image: imageProvider,
fit: BoxFit.cover,
),
),
),
errorWidget: (context, url, error) => Icon(Icons.error),
placeholder: (context, url) => Container(
alignment: Alignment.center,
child: FractionallySizedBox(
widthFactor: 0.3,
heightFactor: 0.3,
child: CircularProgressIndicator(),
),
),
),
);
}
}

View File

@@ -0,0 +1,75 @@
import 'package:flutter/material.dart';
import '../utils/enums/ui_theme.dart';
import '../utils/enums/ui_variant.dart';
import '../utils/theme/ui_color.dart';
class AppButton extends StatelessWidget {
final Widget child;
final VoidCallback? onPressed;
final UiThemeType type;
final UiVariant variant;
final bool loading;
final bool round;
final bool disabled;
const AppButton({
super.key,
required this.child,
this.onPressed,
this.type = UiThemeType.primary,
this.variant = UiVariant.solid,
this.loading = false,
this.round = true,
this.disabled = false,
});
@override
Widget build(BuildContext context) {
//设置颜色
final scheme = UiColor.getColorScheme(
context,
type: type,
variant: variant,
);
return Opacity(
opacity: disabled ? 0.5 : 1,
child: ElevatedButton(
onPressed: () {
if (!loading && !disabled) {
onPressed?.call();
}
},
style: ElevatedButton.styleFrom(
backgroundColor: scheme.background,
// 应用自定义颜色
shadowColor: Colors.transparent,
foregroundColor: scheme.foreground,
shape: round
? const StadiumBorder()
: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(10),
),
),
child: Row(
mainAxisAlignment: MainAxisAlignment.center,
spacing: 8,
children: [
Visibility(
visible: loading,
child: SizedBox.square(
dimension: 15,
child: CircularProgressIndicator(
color: scheme.foreground,
strokeWidth: 2,
),
),
),
child,
],
),
),
);
}
}

View File

@@ -1,84 +0,0 @@
import 'package:flutter/material.dart';
///自定义按钮
///包括loading功能
class CustomButton extends StatelessWidget {
final Widget child;
final VoidCallback? onPressed;
final bool loading;
final bool round;
final bool disabled;
const CustomButton({
super.key,
required this.child,
this.onPressed,
this.loading = false,
this.round = true,
this.disabled = false,
});
@override
Widget build(BuildContext context) {
///自定义颜色
// switch (size) {
// case ButtonSize.small:
// height = 28;
// loadingSize = 16;
// fontSize = 12;
// padding = const EdgeInsets.symmetric(horizontal: 12);
// break;
// case ButtonSize.large:
// height = 48;
// loadingSize = 24;
// fontSize = 18;
// padding = const EdgeInsets.symmetric(horizontal: 20);
// break;
// case ButtonSize.medium:
// height = 45;
// loadingSize = 15;
// fontSize = 16;
// padding = const EdgeInsets.symmetric(horizontal: 16);
// break;
// }
void handClick() {
if (!loading && !disabled) {
onPressed?.call();
}
}
return Opacity(
opacity: disabled ? 0.5 : 1,
child: ElevatedButton(
onPressed: handClick,
style: ElevatedButton.styleFrom(
shape: round
? const StadiumBorder()
: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(10),
),
),
child: Row(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Visibility(
visible: loading,
child: Container(
margin: EdgeInsets.only(right: 8),
child: SizedBox.square(
dimension: 15,
child: CircularProgressIndicator(
color: Colors.white,
strokeWidth: 2,
),
),
),
),
child,
],
),
),
);
}
}

View File

@@ -0,0 +1,7 @@
// 主题风格
enum UiThemeType {
primary,
success,
warning,
danger,
}

View File

@@ -0,0 +1,5 @@
//定义Variant
enum UiVariant {
solid,
plain,
}

View File

@@ -0,0 +1,46 @@
import 'package:flutter/material.dart';
import 'package:food_health/config/theme/base/app_theme_ext.dart';
import '../enums/ui_theme.dart';
import '../enums/ui_variant.dart';
class UiColorScheme {
final Color background;
final Color foreground;
UiColorScheme({
required this.background,
required this.foreground,
});
}
class UiColor {
static UiColorScheme getColorScheme(
BuildContext context, {
UiThemeType type = UiThemeType.primary,
UiVariant variant = UiVariant.solid,
}) {
final colorScheme = Theme.of(context).colorScheme;
final themeExt = Theme.of(context).extension<AppThemeExtension>()!;
//主题色映射
final baseColor = switch (type) {
UiThemeType.primary => colorScheme.primary,
UiThemeType.success => themeExt.success,
UiThemeType.warning => themeExt.warning,
UiThemeType.danger => themeExt.danger,
};
// 风格区分
return switch (variant) {
UiVariant.solid => UiColorScheme(
background: baseColor,
foreground: Colors.white,
),
UiVariant.plain => UiColorScheme(
background: baseColor.withValues(alpha: 0.3),
foreground: baseColor,
),
};
}
}