671 lines
22 KiB
Dart
671 lines
22 KiB
Dart
/*
|
|
* @Author: wangyang 1147192855@qq.com
|
|
* @Date: 2022-07-15 09:20:43
|
|
* @LastEditors: wangyang 1147192855@qq.com
|
|
* @LastEditTime: 2022-07-29 10:17:22
|
|
* @FilePath: \marking_app\lib\pages\marking\review.dart
|
|
* @Description: 回评页面
|
|
*/
|
|
|
|
import 'dart:async';
|
|
|
|
import 'package:flutter/material.dart';
|
|
import 'package:flutter/services.dart';
|
|
import 'package:flutter_easyrefresh/easy_refresh.dart';
|
|
import 'package:flutter_keyboard_visibility/flutter_keyboard_visibility.dart';
|
|
import 'package:flutter_screenutil/flutter_screenutil.dart';
|
|
import 'package:marking_app/common/model/review/additional_conditions_for_review.dart';
|
|
import 'package:marking_app/utils/drawer_util/auto_drawer.dart';
|
|
import 'package:marking_app/utils/easy_refresh/MyEmptyWidget.dart';
|
|
import 'package:marking_app/utils/my_text.dart';
|
|
import 'package:marking_app/utils/request/rest_client.dart';
|
|
import 'package:marking_app/common/mixin/common.dart';
|
|
import 'package:marking_app/common/model/common/base_page_data.dart';
|
|
import 'package:marking_app/common/model/common/base_structure_result.dart';
|
|
import 'package:marking_app/common/model/review/review_item.dart';
|
|
import 'package:marking_app/common/model/review/review_page_params.dart';
|
|
import 'package:marking_app/common/model/review/review_tab.dart';
|
|
import 'package:marking_app/components/review_item_view.dart';
|
|
import 'package:marking_app/routes/RouterManager.dart';
|
|
import 'package:marking_app/utils/easy_refresh/mixin/refresh_data_handle.dart';
|
|
import 'package:marking_app/utils/index.dart';
|
|
|
|
class Review extends StatefulWidget {
|
|
final int examSubjectId;
|
|
final int markingUserId;
|
|
final String examName;
|
|
const Review(this.markingUserId, this.examSubjectId, this.examName, {Key? key}) : super(key: key);
|
|
|
|
@override
|
|
State<Review> createState() => _ReviewState();
|
|
}
|
|
|
|
class _ReviewState extends State<Review> with CommonMixin, SingleTickerProviderStateMixin {
|
|
final GlobalKey<_TheBodyBoxState> _key = GlobalKey<_TheBodyBoxState>();
|
|
late final AdditionalConditionsForReview otherConditions = AdditionalConditionsForReview(); // 赛选条件
|
|
late final int markingUserId;
|
|
late final String examName;
|
|
|
|
late Future<List<ReviewTab>> _future;
|
|
late final TabController? _tabController;
|
|
|
|
/* 请求获取回评tab */
|
|
Future<List<ReviewTab>> getTabs() async {
|
|
RestClient client = await getClient();
|
|
BaseStructureResult<List<ReviewTab>> result = await client.getReviewTab(markingUserId.toString(), markingUserId);
|
|
if (result.code == 200 && result.data != null) {
|
|
int allNUmber = result.data!.isEmpty
|
|
? 0
|
|
: result.data!.map((e) => e.questionCount).reduce((value, element) => value + element);
|
|
List<ReviewTab> data = [ReviewTab(allNUmber, '全部'), ...result.data!];
|
|
return data;
|
|
}
|
|
return [];
|
|
}
|
|
|
|
@override
|
|
void initState() {
|
|
markingUserId = widget.markingUserId;
|
|
examName = widget.examName;
|
|
|
|
_future = getTabs()..then((value) => _tabController = TabController(length: value.length, vsync: this));
|
|
super.initState();
|
|
}
|
|
|
|
@override
|
|
void dispose() {
|
|
super.dispose();
|
|
_tabController?.dispose();
|
|
}
|
|
|
|
// 抽屉关闭回调
|
|
void autoDrawerSwitch(bool val) {}
|
|
|
|
// 筛选条件回调
|
|
Future<void> conditionsDrawerCall({required bool reset, CollationItem? item, String? testId}) async {
|
|
if (reset || (item == null && testId == null)) {
|
|
// 筛选条件重置
|
|
otherConditions.cleanCollation().whenComplete(() => _key.currentState?.setingOtherParams());
|
|
return;
|
|
}
|
|
|
|
// 同步数据
|
|
otherConditions.synchronizationInstance(item, testId);
|
|
_key.currentState?.setingOtherParams(otherParam: otherConditions);
|
|
}
|
|
|
|
@override
|
|
Widget build(BuildContext context) {
|
|
return AnnotatedRegion(
|
|
value: const SystemUiOverlayStyle(
|
|
statusBarColor: Colors.transparent,
|
|
systemNavigationBarIconBrightness: Brightness.light,
|
|
statusBarIconBrightness: Brightness.light,
|
|
statusBarBrightness: Brightness.dark,
|
|
),
|
|
child: Container(
|
|
width: ScreenUtil().scaleWidth,
|
|
height: ScreenUtil().scaleHeight,
|
|
color: Colors.white,
|
|
child: Stack(
|
|
children: [
|
|
const ReviewHeadBox(),
|
|
Scaffold(
|
|
backgroundColor: Colors.transparent,
|
|
appBar: PreferredSize(
|
|
preferredSize: Size.fromHeight(40.h),
|
|
child: AppBar(
|
|
title: quickText(
|
|
'回评',
|
|
size: 18.sp,
|
|
color: Colors.white,
|
|
),
|
|
elevation: 0,
|
|
actions: [
|
|
Container(
|
|
height: double.infinity,
|
|
padding: EdgeInsets.only(right: 6.w),
|
|
alignment: Alignment.center,
|
|
child: InkWell(
|
|
onTap: () {
|
|
_key.currentState!.seeAbnormal();
|
|
},
|
|
child: Text(
|
|
'查看异常',
|
|
style: TextStyle(fontSize: 14.sp, color: Colors.white),
|
|
),
|
|
),
|
|
)
|
|
],
|
|
backgroundColor: Colors.transparent,
|
|
),
|
|
),
|
|
body: MyFutureBuilder.buildFutureBuilder<ReviewTab>(
|
|
context,
|
|
_future,
|
|
(List<ReviewTab> data) {
|
|
return TheBodyBox(
|
|
data,
|
|
_tabController!,
|
|
markingUserId,
|
|
widget.examSubjectId,
|
|
key: _key,
|
|
);
|
|
},
|
|
),
|
|
floatingActionButton: Builder(builder: (context) {
|
|
return FloatingActionButton(
|
|
tooltip: '筛选条件',
|
|
backgroundColor: Theme.of(context).primaryColor,
|
|
foregroundColor: Colors.white,
|
|
onPressed: () {
|
|
Scaffold.of(context).openEndDrawer(); //打开右边抽屉
|
|
},
|
|
child: Icon(Icons.filter_alt_outlined, size: 24.sp),
|
|
);
|
|
}),
|
|
drawerEdgeDragWidth: 0.0,
|
|
// 右侧抽屉
|
|
endDrawer: AutoDrawer(
|
|
callback: autoDrawerSwitch,
|
|
widthPercent: 0.72,
|
|
child: ConditionsDrawer(
|
|
condition: otherConditions,
|
|
callback: conditionsDrawerCall,
|
|
),
|
|
),
|
|
),
|
|
],
|
|
),
|
|
),
|
|
);
|
|
}
|
|
}
|
|
|
|
class TheBodyBox extends StatefulWidget {
|
|
final List<ReviewTab> data;
|
|
final TabController tabController;
|
|
final int examSubjectId;
|
|
final int markingUserId;
|
|
final Function? call;
|
|
const TheBodyBox(this.data, this.tabController, this.markingUserId, this.examSubjectId, {this.call, Key? key})
|
|
: super(key: key);
|
|
|
|
@override
|
|
State<TheBodyBox> createState() => _TheBodyBoxState();
|
|
}
|
|
|
|
class _TheBodyBoxState extends State<TheBodyBox> with CommonMixin, RefreshDataHandle<ReviewItem, ReviewPageParams> {
|
|
late final int markingUserId;
|
|
late final TabController tabController;
|
|
int _tabIndex = 0;
|
|
late final List<ReviewTab> reviewTabs;
|
|
late final List<Tab> tabs = [];
|
|
late final List<EasyRefreshController> refreshCotlrs = [];
|
|
late final List<ReviewPageParams> refreshParams = [];
|
|
late final List<List<ReviewItem>> refreshDatas = [];
|
|
late final List<bool> tabRefresh = [];
|
|
|
|
@override
|
|
void initState() {
|
|
reviewTabs = widget.data;
|
|
tabController = widget.tabController;
|
|
markingUserId = widget.markingUserId;
|
|
|
|
disRefreshCotlrs();
|
|
for (ReviewTab e in reviewTabs) {
|
|
String questionNum = e.questionNum;
|
|
tabs.add(Tab(text: '$questionNum(${e.questionCount})'));
|
|
refreshCotlrs.add(EasyRefreshController());
|
|
refreshParams.add(ReviewPageParams(
|
|
qNum: questionNum == '全部' ? null : questionNum,
|
|
isException: false,
|
|
page: 1,
|
|
limit: 10,
|
|
));
|
|
refreshDatas.add([]);
|
|
tabRefresh.add(false);
|
|
}
|
|
if (tabRefresh.isNotEmpty) {
|
|
tabRefresh[0] = true;
|
|
}
|
|
|
|
super.initState();
|
|
}
|
|
|
|
/* 发起请求 */
|
|
Future<List<ReviewItem>?> toGetPageData(EasyRefreshController controller, ReviewPageParams params,
|
|
{bool isReFresh = false}) async {
|
|
RestClient client = await getClient();
|
|
// ignore: use_build_context_synchronously
|
|
BasePageData<ReviewItem>? results = await toRefreshDataWithPath(
|
|
controller,
|
|
api: client.getReviewPage,
|
|
params: params,
|
|
isReFresh: isReFresh,
|
|
pahtVal: markingUserId.toString(),
|
|
context: context,
|
|
);
|
|
if (results != null) return results.items;
|
|
}
|
|
|
|
// 查看异常
|
|
void seeAbnormal() {
|
|
ReviewTab tab = reviewTabs[_tabIndex];
|
|
String thePath =
|
|
'${RouterManager.markingReviewAbnormalPath}?markingId=$markingUserId&examSubjectId=${widget.examSubjectId}&name=${Uri.encodeComponent(tab.questionNum)}&questionNum=${Uri.encodeComponent(tab.questionNum == '全部' ? '' : tab.questionNum)}';
|
|
|
|
RouterManager.router.navigateTo(
|
|
context,
|
|
thePath,
|
|
transition: getTransition(),
|
|
);
|
|
}
|
|
|
|
// 设置其他赛选参数
|
|
void setingOtherParams({AdditionalConditionsForReview? otherParam}) {
|
|
// 同步参数、初始化上拉下拉插件
|
|
if (otherParam == null) {
|
|
for (var param in refreshParams) {
|
|
param.markingUserDetailId = null;
|
|
param.markingTimeOrderType = null;
|
|
param.markingUserDetailId = null;
|
|
}
|
|
refreshCotlrs[_tabIndex].callRefresh();
|
|
return;
|
|
}
|
|
|
|
int? markingTimeOrderType = otherParam.markingTimeOrderType;
|
|
int? scoreOrderType = otherParam.scoreOrderType;
|
|
|
|
String? questionIdStr = otherParam.questionId;
|
|
int? questionId = questionIdStr == null ? null : (questionIdStr == '' ? null : int.parse(questionIdStr));
|
|
|
|
refreshParams.asMap().keys.forEach((index) {
|
|
ReviewPageParams param = refreshParams[index];
|
|
|
|
param.markingUserDetailId = questionId;
|
|
if (markingTimeOrderType != null) {
|
|
param.markingTimeOrderType = markingTimeOrderType;
|
|
param.scoreOrderType = null;
|
|
}
|
|
|
|
if (scoreOrderType != null) {
|
|
param.scoreOrderType = scoreOrderType;
|
|
param.markingTimeOrderType = null;
|
|
}
|
|
tabRefresh[index] = false;
|
|
});
|
|
refreshCotlrs[_tabIndex].callRefresh();
|
|
}
|
|
|
|
@override
|
|
void dispose() {
|
|
super.dispose();
|
|
disRefreshCotlrs();
|
|
}
|
|
|
|
// 清空上拉加载下拉刷新工具
|
|
void disRefreshCotlrs() {
|
|
tabs.clear();
|
|
if (refreshCotlrs.isEmpty) return;
|
|
for (var e in refreshCotlrs) {
|
|
e.dispose();
|
|
}
|
|
refreshCotlrs.clear();
|
|
}
|
|
|
|
@override
|
|
Widget build(BuildContext context) {
|
|
return Column(
|
|
children: <Widget>[
|
|
Padding(
|
|
padding: EdgeInsets.only(top: 10.h),
|
|
child: Align(
|
|
alignment: Alignment.centerLeft,
|
|
child: TabBar(
|
|
isScrollable: true,
|
|
controller: tabController,
|
|
indicatorColor: Colors.white,
|
|
unselectedLabelStyle: TextStyle(fontSize: 14.sp, color: const Color.fromRGBO(173, 191, 255, 1)),
|
|
labelStyle: TextStyle(fontSize: 16.sp, color: const Color.fromRGBO(148, 163, 182, 1)),
|
|
labelColor: Colors.white,
|
|
indicatorSize: TabBarIndicatorSize.label,
|
|
onTap: (index) {
|
|
bool flagTbRsh = tabRefresh[index];
|
|
setState(() {
|
|
_tabIndex = index;
|
|
if (!flagTbRsh) {
|
|
refreshCotlrs[index].callRefresh();
|
|
tabRefresh[index] = true;
|
|
}
|
|
});
|
|
},
|
|
tabs: tabs,
|
|
),
|
|
),
|
|
),
|
|
Expanded(
|
|
child: IndexedStack(
|
|
index: _tabIndex,
|
|
children: <Widget>[
|
|
...tabs.asMap().keys.map((theIdx) {
|
|
EasyRefreshController controller = refreshCotlrs[theIdx];
|
|
ReviewPageParams param = refreshParams[theIdx];
|
|
List<ReviewItem> reviewItems = refreshDatas[theIdx];
|
|
return EasyRefresh(
|
|
firstRefresh: theIdx == 0,
|
|
taskIndependence: true,
|
|
enableControlFinishLoad: true,
|
|
enableControlFinishRefresh: true,
|
|
header: MaterialHeader(),
|
|
footer: TaurusFooter(),
|
|
emptyWidget: reviewItems.isEmpty ? const MyEmptyWidget() : null,
|
|
controller: controller,
|
|
child: ListView.builder(
|
|
padding: EdgeInsets.only(left: 16.w, right: 16.w, bottom: 16.h),
|
|
itemBuilder: (context, index) =>
|
|
ReviewItemView(markingUserId, reviewItems[index], widget.examSubjectId),
|
|
itemCount: reviewItems.length,
|
|
),
|
|
onRefresh: () async {
|
|
param.page = 1;
|
|
List<ReviewItem>? data = await toGetPageData(controller, param, isReFresh: true);
|
|
if (data != null) {
|
|
reviewItems.clear();
|
|
setState(() => reviewItems.addAll(data));
|
|
}
|
|
},
|
|
onLoad: () async {
|
|
param.page += 1;
|
|
List<ReviewItem>? data = await toGetPageData(controller, param);
|
|
if (data != null && data.isNotEmpty) {
|
|
setState(() => reviewItems.addAll(data));
|
|
return;
|
|
}
|
|
param.page -= 1;
|
|
},
|
|
);
|
|
}).toList()
|
|
],
|
|
),
|
|
),
|
|
],
|
|
);
|
|
}
|
|
}
|
|
|
|
// 赛选条件抽屉
|
|
class ConditionsDrawer extends StatefulWidget {
|
|
final AdditionalConditionsForReview condition;
|
|
final CollationCallback callback;
|
|
const ConditionsDrawer({required this.callback, required this.condition, Key? key}) : super(key: key);
|
|
@override
|
|
State<ConditionsDrawer> createState() => _ConditionsDrawerState();
|
|
}
|
|
|
|
class _ConditionsDrawerState extends State<ConditionsDrawer> {
|
|
late StreamSubscription<bool> keyboardSubscription;
|
|
late TextEditingController _inputController;
|
|
late FocusNode _inputFocusNode;
|
|
|
|
int collationIndex = -1; // 排序方式选中下标
|
|
|
|
@override
|
|
void initState() {
|
|
super.initState();
|
|
AdditionalConditionsForReview condition = widget.condition;
|
|
|
|
CollationItem? orderItem = condition.orderItem;
|
|
if (orderItem != null) {
|
|
toUpState(
|
|
setState, () => collationIndex = AdditionalConditionsForReview.collationArr.indexOf(orderItem), mounted);
|
|
}
|
|
|
|
_inputController = TextEditingController(text: condition.questionId);
|
|
_inputFocusNode = FocusNode()..addListener(_theSetState);
|
|
|
|
// 软键盘监听
|
|
keyboardSubscription = KeyboardVisibilityController().onChange.listen((bool visible) {
|
|
debugPrint('Keyboard visibility update. Is visible: $visible');
|
|
if (!visible) _inputFocusNode.unfocus();
|
|
});
|
|
}
|
|
|
|
@override
|
|
void dispose() {
|
|
super.dispose();
|
|
keyboardSubscription.cancel();
|
|
_inputController.dispose();
|
|
_inputFocusNode
|
|
..removeListener(_theSetState)
|
|
..dispose();
|
|
}
|
|
|
|
void _theSetState({VoidCallback? call}) {
|
|
toUpState(setState, () {
|
|
if (call != null) call();
|
|
}, mounted);
|
|
}
|
|
|
|
// 设置排序规则
|
|
void choiceOrderField(CollationItem item, int index) {
|
|
if (_inputFocusNode.hasFocus) {
|
|
_inputFocusNode.unfocus();
|
|
}
|
|
_theSetState(call: () => collationIndex = index);
|
|
}
|
|
|
|
@override
|
|
Widget build(BuildContext context) {
|
|
return Container(
|
|
width: 270.w,
|
|
color: Colors.white,
|
|
child: Column(
|
|
children: [
|
|
Expanded(
|
|
child: Container(
|
|
width: double.infinity,
|
|
height: double.infinity,
|
|
padding: EdgeInsets.only(
|
|
left: 20.w,
|
|
right: 30.h,
|
|
bottom: 30.h,
|
|
top: MediaQuery.of(context).padding.top + 20.h,
|
|
),
|
|
child: Column(
|
|
crossAxisAlignment: CrossAxisAlignment.start,
|
|
children: [
|
|
getPaperIDInput(),
|
|
getCollation(),
|
|
],
|
|
),
|
|
),
|
|
),
|
|
Padding(
|
|
padding: EdgeInsets.symmetric(
|
|
horizontal: 10.w,
|
|
vertical: 20.h,
|
|
),
|
|
child: getBtn(),
|
|
),
|
|
],
|
|
),
|
|
);
|
|
}
|
|
|
|
// 确认、重置按钮
|
|
Widget getBtn() {
|
|
return Row(
|
|
children: [
|
|
Expanded(
|
|
child: MaterialButton(
|
|
height: 40.h,
|
|
splashColor: Colors.pink,
|
|
// color: Colors.blueGrey,
|
|
color: Colors.grey[100],
|
|
textColor: const Color.fromRGBO(102, 102, 102, 1),
|
|
minWidth: MediaQuery.of(context).size.width / 2,
|
|
shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(10)),
|
|
child: const Text(
|
|
'重置',
|
|
),
|
|
onPressed: () {
|
|
if (_inputFocusNode.hasFocus) {
|
|
_inputFocusNode.unfocus();
|
|
}
|
|
widget.callback(reset: false).then((_) => Navigator.pop(context));
|
|
},
|
|
),
|
|
),
|
|
SizedBox(width: 15.w),
|
|
Expanded(
|
|
flex: 2,
|
|
child: MaterialButton(
|
|
height: 40.h,
|
|
splashColor: Colors.pink,
|
|
color: Theme.of(context).primaryColor,
|
|
textColor: Colors.white,
|
|
shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(10)),
|
|
child: const Text(
|
|
'确定',
|
|
),
|
|
onPressed: () {
|
|
if (_inputFocusNode.hasFocus) {
|
|
_inputFocusNode.unfocus();
|
|
}
|
|
widget
|
|
.callback(
|
|
reset: false,
|
|
item: collationIndex > -1 ? AdditionalConditionsForReview.collationArr[collationIndex] : null,
|
|
testId: _inputController.text)
|
|
.then((_) => Navigator.pop(context));
|
|
}),
|
|
),
|
|
],
|
|
);
|
|
}
|
|
|
|
// 试题ID输入框
|
|
Widget getPaperIDInput() {
|
|
return Container(
|
|
child: Column(
|
|
mainAxisSize: MainAxisSize.min,
|
|
crossAxisAlignment: CrossAxisAlignment.start,
|
|
children: [
|
|
quickText('试题ID', size: 18.sp),
|
|
SizedBox(height: 10.h),
|
|
TextField(
|
|
controller: _inputController,
|
|
focusNode: _inputFocusNode,
|
|
keyboardType: const TextInputType.numberWithOptions(decimal: true),
|
|
inputFormatters: [FilteringTextInputFormatter.digitsOnly], //数字,只能是整数
|
|
style: TextStyle(color: Colors.black45, fontSize: 14.sp),
|
|
decoration: InputDecoration(
|
|
enabledBorder: UnderlineInputBorder(
|
|
borderSide: BorderSide(color: Colors.grey[300]!),
|
|
),
|
|
hintText: '请输入答卷ID',
|
|
hintStyle: TextStyle(color: Colors.grey[300], fontSize: 14.sp),
|
|
suffixIcon: !_inputFocusNode.hasFocus
|
|
? null
|
|
: IconButton(
|
|
icon: Icon(Icons.highlight_off, size: 14.sp, color: Colors.grey),
|
|
onPressed: () {
|
|
_inputController.clear();
|
|
},
|
|
),
|
|
),
|
|
)
|
|
],
|
|
),
|
|
);
|
|
}
|
|
|
|
// 排序规则
|
|
Widget getCollation() {
|
|
return Container(
|
|
margin: EdgeInsets.only(top: 50.h),
|
|
child: Column(
|
|
crossAxisAlignment: CrossAxisAlignment.start,
|
|
mainAxisSize: MainAxisSize.min,
|
|
children: [
|
|
quickText('试题ID', size: 18.sp),
|
|
SizedBox(height: 20.h),
|
|
...AdditionalConditionsForReview.collationArr.asMap().keys.map((iIndex) {
|
|
CollationItem item = AdditionalConditionsForReview.collationArr[iIndex];
|
|
bool flag = iIndex == collationIndex;
|
|
|
|
return Container(
|
|
margin: EdgeInsets.symmetric(vertical: 6.h),
|
|
width: double.infinity,
|
|
height: 34.h,
|
|
alignment: Alignment.center,
|
|
decoration: BoxDecoration(
|
|
color: flag ? Colors.blue[50] : Colors.grey[100],
|
|
borderRadius: BorderRadius.all(Radius.circular(4.sp)),
|
|
),
|
|
child: Row(
|
|
children: [
|
|
Expanded(
|
|
child: TextButton(
|
|
onPressed: () => choiceOrderField(item, iIndex),
|
|
child: quickText(
|
|
item.title,
|
|
size: 14.sp,
|
|
color: flag ? Theme.of(context).primaryColor : Colors.black54,
|
|
),
|
|
),
|
|
)
|
|
],
|
|
),
|
|
);
|
|
|
|
// return Container(
|
|
// margin: EdgeInsets.symmetric(vertical: 6.h),
|
|
// width: double.infinity,
|
|
// height: 34.h,
|
|
// alignment: Alignment.center,
|
|
// decoration: BoxDecoration(
|
|
// color: flag ? Colors.blue[50] : Colors.grey[200],
|
|
// borderRadius: BorderRadius.all(Radius.circular(4.sp))
|
|
// ),
|
|
// child: quickText(item.title,
|
|
// size: 15.sp, color: flag ? Theme.of(context).primaryColor : Colors.black54),
|
|
// );
|
|
}).toList()
|
|
],
|
|
),
|
|
);
|
|
}
|
|
}
|
|
|
|
// 底层头部区域
|
|
class ReviewHeadBox extends StatelessWidget {
|
|
const ReviewHeadBox({Key? key}) : super(key: key);
|
|
|
|
@override
|
|
Widget build(BuildContext context) {
|
|
return SizedBox(
|
|
height: double.infinity,
|
|
child: Column(
|
|
children: [
|
|
Container(
|
|
height: 200.h,
|
|
decoration: const BoxDecoration(
|
|
image: DecorationImage(
|
|
image: AssetImage('assets/images/personal_bgi.png'),
|
|
fit: BoxFit.cover,
|
|
),
|
|
),
|
|
),
|
|
Expanded(
|
|
child: Container(
|
|
color: const Color.fromRGBO(248, 248, 248, 1),
|
|
))
|
|
],
|
|
),
|
|
);
|
|
}
|
|
}
|