主页框架

master
张萌 2 years ago
parent fb60f29c88
commit af5d2b53f1

@ -43,6 +43,7 @@ linter:
prefer_function_declarations_over_variables: true prefer_function_declarations_over_variables: true
prefer_interpolation_to_compose_strings: true prefer_interpolation_to_compose_strings: true
prefer_null_aware_operators: true prefer_null_aware_operators: true
avoid_slow_async_io : true
# avoid_print: false # Uncomment to disable the `avoid_print` rule # avoid_print: false # Uncomment to disable the `avoid_print` rule
# prefer_single_quotes: true # Uncomment to enable the `prefer_single_quotes` rule # prefer_single_quotes: true # Uncomment to enable the `prefer_single_quotes` rule

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 15 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 28 KiB

@ -164,16 +164,33 @@ class MyAppStyle extends ThemeExtension<MyAppStyle> {
final BoxDecoration? bottomButtonDecoration; final BoxDecoration? bottomButtonDecoration;
final TextStyle? bottomButtonText; final TextStyle? bottomButtonText;
///
final TextStyle? hintText;
/// (线
final Color? lightDark;
///
final TextStyle? titleText;
@override @override
MyAppStyle copyWith( MyAppStyle copyWith({
{Color? mainColor, Color? mainColor,
TextStyle? bottomButtonText, TextStyle? bottomButtonText,
BoxDecoration? bottomButtonDecoration}) { BoxDecoration? bottomButtonDecoration,
TextStyle? hintText,
Color? lightDark,
TextStyle? titleText,
}) {
return MyAppStyle( return MyAppStyle(
mainColor: mainColor ?? this.mainColor, mainColor: mainColor ?? this.mainColor,
bottomButtonDecoration: bottomButtonDecoration:
bottomButtonDecoration ?? this.bottomButtonDecoration, bottomButtonDecoration ?? this.bottomButtonDecoration,
bottomButtonText: bottomButtonText ?? this.bottomButtonText); bottomButtonText: bottomButtonText ?? this.bottomButtonText,
hintText: hintText ?? this.hintText,
lightDark: lightDark ?? this.lightDark,
titleText: titleText ?? this.titleText,
);
} }
@override @override
@ -187,6 +204,9 @@ class MyAppStyle extends ThemeExtension<MyAppStyle> {
bottomButtonDecoration, other.bottomButtonDecoration, t), bottomButtonDecoration, other.bottomButtonDecoration, t),
bottomButtonText: bottomButtonText:
TextStyle.lerp(bottomButtonText, other.bottomButtonText, t), TextStyle.lerp(bottomButtonText, other.bottomButtonText, t),
hintText: TextStyle.lerp(hintText, other.hintText, t),
lightDark: Color.lerp(lightDark, other.lightDark, t),
titleText: TextStyle.lerp(titleText, other.titleText, t),
); );
} }
@ -194,19 +214,27 @@ class MyAppStyle extends ThemeExtension<MyAppStyle> {
this.bottomButtonText, this.bottomButtonText,
this.mainColor, this.mainColor,
this.bottomButtonDecoration, this.bottomButtonDecoration,
this.hintText,
this.lightDark,
this.titleText,
}); });
MyAppStyle.def() MyAppStyle.def()
: mainColor = Colors.blue, : mainColor = Colors.blue,
bottomButtonDecoration = bottomButtonDecoration = BoxDecoration(
BoxDecoration(
gradient: const LinearGradient( gradient: const LinearGradient(
begin: Alignment.centerLeft, begin: Alignment.centerLeft,
end: Alignment.centerRight, end: Alignment.centerRight,
colors: [Color(0xFF0593FF), Color(0xFF027AFF)]), colors: [Color(0xFF0593FF), Color(0xFF027AFF)]),
borderRadius: BorderRadius.circular(8.w)), borderRadius: BorderRadius.circular(4.w)),
bottomButtonText = TextStyle( bottomButtonText = TextStyle(
fontSize: 30.sp, fontSize: 14.sp,
color: const Color(0xFF333333), color: const Color(0xFFFFFFFF),
); ),
hintText = TextStyle(fontSize: 18.sp, color: const Color(0xFFCCCCCC)),
lightDark = const Color(0xFFCCCCCC),
titleText = TextStyle(
fontSize: 16.sp,
fontWeight: FontWeight.bold,
color: const Color(0xFF111111));
} }

@ -0,0 +1,38 @@
extension ListExt<T> on List<T> {
List<T> sep(T sep) => _sepIterable(sep).toList();
Iterable<T> _sepIterable(T separate) sync* {
final it = iterator;
if (!it.moveNext()) return;
yield it.current;
while (it.moveNext()) {
yield separate;
yield it.current;
}
}
}
extension OddListExt<T> on List<T> {
List<T> oddList() {
List<T> newList = [];
for (var element in this) {
if (indexOf(element).isEven) {
newList.add(element);
}
}
return newList;
}
}
extension EvenListExt<T> on List<T> {
List<T> evenList() {
List<T> newList = [];
forEach((element) {
if (indexOf(element).isOdd) {
newList.add(element);
}
});
return newList;
}
}

@ -0,0 +1,8 @@
import 'package:flutter/material.dart';
import 'package:flutter_screenutil/flutter_screenutil.dart';
extension NumExt on num {
Widget get wb => SizedBox(width: w);
Widget get hb => SizedBox(height: w);
}

@ -0,0 +1,95 @@
/// GENERATED CODE - DO NOT MODIFY BY HAND
/// *****************************************************
/// FlutterGen
/// *****************************************************
// ignore_for_file: directives_ordering,unnecessary_import
import 'package:flutter/widgets.dart';
class $AssetsIconsGen {
const $AssetsIconsGen();
/// File path: assets/icons/personal_select.png
AssetGenImage get personalSelect =>
const AssetGenImage('assets/icons/personal_select.png');
/// File path: assets/icons/personal_unselect.png
AssetGenImage get personalUnselect =>
const AssetGenImage('assets/icons/personal_unselect.png');
/// File path: assets/icons/work_stage_select.png
AssetGenImage get workStageSelect =>
const AssetGenImage('assets/icons/work_stage_select.png');
/// File path: assets/icons/work_stage_unselect.png
AssetGenImage get workStageUnselect =>
const AssetGenImage('assets/icons/work_stage_unselect.png');
}
class $AssetsImagesGen {
const $AssetsImagesGen();
/// File path: assets/images/app_title.png
AssetGenImage get appTitle =>
const AssetGenImage('assets/images/app_title.png');
/// File path: assets/images/home_bg.png
AssetGenImage get homeBg => const AssetGenImage('assets/images/home_bg.png');
}
class Assets {
Assets._();
static const $AssetsIconsGen icons = $AssetsIconsGen();
static const $AssetsImagesGen images = $AssetsImagesGen();
}
class AssetGenImage extends AssetImage {
const AssetGenImage(String assetName) : super(assetName);
Image image({
Key? key,
ImageFrameBuilder? frameBuilder,
ImageLoadingBuilder? loadingBuilder,
ImageErrorWidgetBuilder? errorBuilder,
String? semanticLabel,
bool excludeFromSemantics = false,
double? width,
double? height,
Color? color,
BlendMode? colorBlendMode,
BoxFit? fit,
AlignmentGeometry alignment = Alignment.center,
ImageRepeat repeat = ImageRepeat.noRepeat,
Rect? centerSlice,
bool matchTextDirection = false,
bool gaplessPlayback = false,
bool isAntiAlias = false,
FilterQuality filterQuality = FilterQuality.low,
}) {
return Image(
key: key,
image: this,
frameBuilder: frameBuilder,
loadingBuilder: loadingBuilder,
errorBuilder: errorBuilder,
semanticLabel: semanticLabel,
excludeFromSemantics: excludeFromSemantics,
width: width,
height: height,
color: color,
colorBlendMode: colorBlendMode,
fit: fit,
alignment: alignment,
repeat: repeat,
centerSlice: centerSlice,
matchTextDirection: matchTextDirection,
gaplessPlayback: gaplessPlayback,
isAntiAlias: isAntiAlias,
filterQuality: filterQuality,
);
}
String get path => assetName;
}

@ -50,7 +50,7 @@ class MyApp extends StatelessWidget {
ChangeNotifierProvider(create: (context) => UserProvider()), ChangeNotifierProvider(create: (context) => UserProvider()),
], ],
child: ScreenUtilInit( child: ScreenUtilInit(
designSize: const Size(750, 1334), designSize: const Size(375, 812),
builder: (context) => GestureDetector( builder: (context) => GestureDetector(
onTap: () { onTap: () {
// //

@ -0,0 +1,47 @@
import 'package:cloud_car_internal/gen/assets.gen.dart';
import 'package:cloud_car_internal/utils/user_tool.dart';
import 'package:flutter/material.dart';
import 'package:flutter_screenutil/flutter_screenutil.dart';
class HomePage extends StatefulWidget {
const HomePage({super.key});
@override
_HomePageState createState() => _HomePageState();
}
class _HomePageState extends State<HomePage> {
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
backgroundColor: Colors.transparent,
title: Row(
children: [
Text(
'HI,张三',
style: UserTool.myAppStyle.titleText,
)
],
),
centerTitle: false,
),
extendBody: true,
extendBodyBehindAppBar: true,
body: Stack(
children: [
Assets.images.homeBg
.image(fit: BoxFit.fill, width: double.infinity, height: 200.w),
CustomScrollView(
slivers: [
SliverGrid.count(
crossAxisCount: 4,
children: [],
),
],
),
],
),
);
}
}

@ -1,4 +1,12 @@
import 'package:cloud_car_internal/extensions/num_ext.dart';
import 'package:cloud_car_internal/gen/assets.gen.dart';
import 'package:cloud_car_internal/ui/tab_navigator.dart';
import 'package:cloud_car_internal/widget/buttons/cloud_bottom_button.dart';
import 'package:cloud_car_internal/widget/scaffold/cloud_scaffold.dart';
import 'package:cloud_car_internal/widget/text_filed/account_input_text_field.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:flutter_screenutil/flutter_screenutil.dart';
import 'package:get/get.dart';
class LoginPage extends StatefulWidget { class LoginPage extends StatefulWidget {
const LoginPage({super.key}); const LoginPage({super.key});
@ -10,6 +18,41 @@ class LoginPage extends StatefulWidget {
class _LoginPageState extends State<LoginPage> { class _LoginPageState extends State<LoginPage> {
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
return Container(); return CloudScaffold(
appbar: AppBar(
title: const Text(''),
backgroundColor: const Color(0xFFF9F9F9),
),
body: SafeArea(
child: Column(
children: [
40.hb,
Assets.images.appTitle.image(width: 150.w, height: 30.w),
70.hb,
Padding(
padding: EdgeInsets.symmetric(horizontal: 32.w),
child: AccountInputTextField(
hintText: '请输入账号',
onChange: (text) {},
),
),
Padding(
padding: EdgeInsets.symmetric(horizontal: 32.w),
child: AccountInputTextField(
hintText: '请输入密码',
onChange: (text) {},
),
),
48.hb,
CloudBottomButton(
onTap: () {
Get.offAll(const TabNavigator());
},
text: '登录',
),
],
),
),
);
} }
} }

@ -0,0 +1,16 @@
import 'package:cloud_car_internal/widget/scaffold/cloud_scaffold.dart';
import 'package:flutter/material.dart';
class PersonalPage extends StatefulWidget {
const PersonalPage({super.key});
@override
_PersonalPageState createState() => _PersonalPageState();
}
class _PersonalPageState extends State<PersonalPage> {
@override
Widget build(BuildContext context) {
return CloudScaffold();
}
}

@ -1,15 +1,112 @@
import 'package:bot_toast/bot_toast.dart';
import 'package:cloud_car_internal/gen/assets.gen.dart';
import 'package:cloud_car_internal/ui/personal/personal_page.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:flutter_screenutil/flutter_screenutil.dart';
import '../utils/user_tool.dart';
import 'home/home_page.dart';
class TabNavigator extends StatefulWidget { class TabNavigator extends StatefulWidget {
const TabNavigator({super.key}); final int? index;
const TabNavigator({
super.key,
this.index,
});
@override @override
_TabNavigatorState createState() => _TabNavigatorState(); _TabNavigatorState createState() => _TabNavigatorState();
} }
class _TabNavigatorState extends State<TabNavigator> { class _TabNavigatorState extends State<TabNavigator>
with SingleTickerProviderStateMixin {
TabController? _tabController;
int _currentIndex = 0;
DateTime? _lastPressed;
//
List<Widget> get _pages => [
const HomePage(),
const PersonalPage(),
];
@override
void initState() {
super.initState();
_tabController = TabController(
length: _pages.length, vsync: this, initialIndex: widget.index ?? 0);
}
_buildBottomBar(
String title,
String unselected,
String selected,
) {
return BottomNavigationBarItem(
icon: Image.asset(
unselected,
height: 44.w,
width: 44.w,
//color: Colors.black38,
),
activeIcon: Image.asset(
selected,
height: 44.w,
width: 44.w,
),
label: title,
);
}
late bool isOpen = UserTool.userProvider.userInfo.level < 0;
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
return Container(); //
List<BottomNavigationBarItem> bottomNav = <BottomNavigationBarItem>[
_buildBottomBar(
'工作台',
Assets.icons.workStageUnselect.path,
Assets.icons.workStageSelect.path,
),
_buildBottomBar(
'我的',
Assets.icons.personalUnselect.path,
Assets.icons.personalSelect.path,
),
];
return Scaffold(
body: WillPopScope(
onWillPop: () async {
if (_lastPressed == null ||
DateTime.now().difference(_lastPressed!) >
const Duration(seconds: 1)) {
//1
_lastPressed = DateTime.now();
BotToast.showText(text: '再点击一次返回退出');
return false;
}
//app
return true;
},
child: TabBarView(
controller: _tabController,
physics: const NeverScrollableScrollPhysics(),
children: _pages,
),
),
bottomNavigationBar: BottomNavigationBar(
items: bottomNav,
backgroundColor: Colors.white,
currentIndex: _currentIndex,
selectedFontSize: 12.sp,
unselectedFontSize: 12.sp,
onTap: (index) {
_tabController!.animateTo(index, curve: Curves.easeInOutCubic);
setState(() => _currentIndex = index);
}),
);
} }
} }

@ -25,8 +25,8 @@ class _CloudBottomButtonState extends State<CloudBottomButton> {
color:Colors.transparent, color:Colors.transparent,
child: Container( child: Container(
alignment: Alignment.center, alignment: Alignment.center,
padding: EdgeInsets.symmetric(vertical: 15.w), padding: EdgeInsets.symmetric(vertical: 10.w),
margin: EdgeInsets.symmetric(horizontal: 32.w), margin: EdgeInsets.symmetric(horizontal:16.w),
decoration:widget.decoration?? UserTool.myAppStyle.bottomButtonDecoration!, decoration:widget.decoration?? UserTool.myAppStyle.bottomButtonDecoration!,
child: Text( child: Text(
widget.text, widget.text,

@ -49,7 +49,7 @@ class CloudScaffold extends StatelessWidget {
extendBody: extendBody, extendBody: extendBody,
body: body, body: body,
appBar: PreferredSize( appBar: PreferredSize(
preferredSize: Size.fromHeight(176.w), preferredSize: Size.fromHeight(88.w),
child: title == null child: title == null
? appbar! ? appbar!
: AppBar( : AppBar(
@ -62,7 +62,7 @@ class CloudScaffold extends StatelessWidget {
style: TextStyle( style: TextStyle(
color: Colors.black, color: Colors.black,
fontWeight: FontWeight.bold, fontWeight: FontWeight.bold,
fontSize: 32.sp), fontSize: 16.sp),
), ),
actions: actions, actions: actions,
), ),

@ -0,0 +1,22 @@
import 'package:cloud_car_internal/utils/user_tool.dart';
import 'package:flutter/material.dart';
class AccountInputTextField extends StatelessWidget {
final String hintText;
final Function(String) onChange;
const AccountInputTextField(
{super.key, required this.hintText, required this.onChange});
@override
Widget build(BuildContext context) {
return TextField(
onChanged: onChange,
decoration: InputDecoration(
border: UnderlineInputBorder(
borderSide: BorderSide(color: UserTool.myAppStyle.lightDark!)),
hintText: hintText,
hintStyle: UserTool.myAppStyle.hintText),
);
}
}

@ -83,4 +83,8 @@ dev_dependencies:
flutter: flutter:
uses-material-design: true uses-material-design: true
generate: true
assets:
- assets/
- assets/icons/
- assets/images/

Loading…
Cancel
Save