feat: single search more

This commit is contained in:
louis 2024-04-02 12:24:08 +08:00
parent bb93b1ad63
commit 1a3f57ce0e
10 changed files with 843 additions and 289 deletions

View File

@ -47,6 +47,9 @@ final theme = ThemeData(
foregroundColor: foregroundColor:
MaterialStateProperty.all<Color>(AppTheme.primaryColor), // MaterialStateProperty.all<Color>(AppTheme.primaryColor), //
)), )),
floatingActionButtonTheme: FloatingActionButtonThemeData(
backgroundColor: AppTheme.primaryColorLight,
),
datePickerTheme: DatePickerThemeData( datePickerTheme: DatePickerThemeData(
confirmButtonStyle: ButtonStyle( confirmButtonStyle: ButtonStyle(
textStyle: MaterialStateProperty.resolveWith<TextStyle?>( textStyle: MaterialStateProperty.resolveWith<TextStyle?>(

View File

@ -0,0 +1,34 @@
import 'package:flutter/material.dart';
import 'package:get/get_rx/src/rx_types/rx_types.dart';
import 'package:pull_to_refresh/pull_to_refresh.dart';
mixin BaseSearchMore<T> {
RxList<T> list = RxList([]);
RxString searchKey = ''.obs;
final searchBarTextConroller = TextEditingController();
RefreshController refreshController = RefreshController(initialRefresh: true);
int page = 1;
int limit = 15;
int total = 0;
getData({bool isRefresh = false}) {}
Future<void> onRefresh() async {
await getData(isRefresh: true).then((_) {
refreshController.refreshCompleted(resetFooterState: true);
}).catchError((_) {
refreshController.refreshFailed();
});
}
Future<void> onLoading() async {
await getData().then((_) {
if (_.isEmpty) {
refreshController.loadNoData();
} else {
refreshController.loadComplete();
}
}).catchError((_) {
refreshController.loadFailed();
});
}
}

View File

@ -32,11 +32,14 @@ class InventoryInoutViewItem extends StatelessWidget {
class Grid extends StatelessWidget { class Grid extends StatelessWidget {
final int columnNum; final int columnNum;
final int ind; int ind;
final controller = Get.find<InventoryInoutController>(); final controller = Get.find<InventoryInoutController>();
Grid({super.key, required this.columnNum, required this.ind}); Grid({super.key, required this.columnNum, required this.ind});
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
if (controller.currentIndex.value != ind) {
ind = controller.currentIndex.value;
}
return Obx( return Obx(
() => controller.loading.value () => controller.loading.value
? const LoadingIndicator(common: true) ? const LoadingIndicator(common: true)

View File

@ -347,27 +347,16 @@ class NewInventoryInout extends StatelessWidget {
floatingLabelBehavior: FloatingLabelBehavior.always), floatingLabelBehavior: FloatingLabelBehavior.always),
readOnly: true, readOnly: true,
onTap: () { onTap: () {
if (inOrOut == InventoryInOrOutEnum.In) { ModalUtil.showGeneralDialog(
ModalUtil.showGeneralDialog(content: AgentSearch( content: AgentSearch(
onSelected: (UserInfoModel userInfo) { onSelected: (UserInfoModel userInfo) {
Get.back(); Get.back();
controller.payload['agent'] = userInfo.nickname; controller.payload['agent'] = userInfo.nickname;
controller.agentTextController.text = userInfo.nickname!; controller.agentTextController.text = userInfo.nickname!;
}, },
)); ),
} else { width: Get.width - ScreenAdaper.width(50))
ModalUtil.showGeneralDialog( .then((value) => Get.delete<AgentSearchController>());
content: AgentSearch(
onSelected: (UserInfoModel userInfo) {
Get.back();
controller.payload['agent'] = userInfo.nickname;
controller.agentTextController.text =
userInfo.nickname!;
},
),
width: Get.width - ScreenAdaper.width(50))
.then((value) => Get.delete<AgentSearchController>());
}
}); });
} }

View File

@ -0,0 +1,210 @@
import 'dart:async';
import 'package:flutter/material.dart';
import 'package:get/get.dart';
import 'package:pull_to_refresh/pull_to_refresh.dart';
import 'package:sk_base_mobile/apis/index.dart';
import 'package:sk_base_mobile/app_theme.dart';
import 'package:sk_base_mobile/constants/bg_color.dart';
import 'package:sk_base_mobile/models/sale_quotation.model.dart';
import 'package:sk_base_mobile/models/user_info.model.dart';
import 'package:sk_base_mobile/util/debouncer.dart';
import 'package:sk_base_mobile/util/screen_adaper_util.dart';
import 'package:sk_base_mobile/widgets/empty.dart';
import 'package:sk_base_mobile/widgets/fade_in_cache_image.dart';
class SaleQuotationGroupSearch extends StatelessWidget {
final Function(SaleQuotationModel)? onSelected;
final Function(SaleQuotationModel)? beforeSelectedCheck;
SaleQuotationGroupSearch(
{super.key, this.onSelected, this.beforeSelectedCheck});
final controller = Get.put(GroupSearchController());
final listTitleTextStyle =
TextStyle(fontSize: ScreenAdaper.height(20), fontWeight: FontWeight.w600);
@override
Widget build(BuildContext context) {
return Container(
padding: EdgeInsets.symmetric(
horizontal: ScreenAdaper.width(20),
vertical: ScreenAdaper.height(20)),
child: Column(
children: [
buildSearchBar(),
SizedBox(
height: ScreenAdaper.height(defaultPadding) / 2,
),
Expanded(child: buildList())
],
),
);
}
Widget buildSearchBar() {
final doSearch = debouncer((String value) {
controller.searchKey.value = value;
controller.onRefresh();
}, delayTime: 500);
return Row(
children: [
Expanded(
flex: 5,
child: TextField(
controller: controller.searchBarTextConroller,
onChanged: (value) => doSearch(value),
decoration: InputDecoration(
contentPadding: EdgeInsets.symmetric(
vertical: ScreenAdaper.height(10),
horizontal: ScreenAdaper.width(10)),
hintText: '名称',
floatingLabelBehavior: FloatingLabelBehavior.always,
prefixIcon: const Icon(Icons.search),
// searchBarController有值时不显示
suffixIcon: Obx(() => controller.searchKey.value.isEmpty
? const SizedBox()
: IconButton(
icon: const Icon(Icons.clear),
onPressed: () {
controller.searchKey.value = '';
controller.searchBarTextConroller.clear();
doSearch('');
},
)),
border: OutlineInputBorder(
borderRadius: BorderRadius.circular(10),
),
))),
],
);
}
Widget buildList() {
return Obx(() => SmartRefresher(
enablePullDown: true,
enablePullUp: true,
controller: controller.refreshController,
onLoading: controller.onLoading,
onRefresh: controller.onRefresh,
child: controller.refreshController.isLoading
? const SizedBox()
: controller.list.isEmpty
? const Center(
child: Empty(text: '暂无数据'),
)
: ListView.separated(
separatorBuilder: (context, index) => const Divider(
color: AppTheme.dividerColor,
),
itemCount: controller.list.length,
itemBuilder: (_, index) => buildItem(index))));
}
Widget buildItem(int index) {
return InkWell(
onTap: () => {
if (beforeSelectedCheck != null)
{
if (beforeSelectedCheck!(controller.list[index]))
{onSelected!(controller.list[index])}
}
else
{onSelected!(controller.list[index])}
},
child: Container(
padding: EdgeInsets.symmetric(
horizontal: ScreenAdaper.width(5),
vertical: ScreenAdaper.height(10)),
child: Row(
children: [
// ClipRRect(
// borderRadius: BorderRadius.circular(ScreenAdaper.sp(15)),
// child: FadeInCacheImage(
// url: controller.list[index].avatar ?? '',
// width: ScreenAdaper.width(60),
// height: ScreenAdaper.width(60),
// ),
// ),
// SizedBox(
// width: ScreenAdaper.width(20),
// ),
Text(
'${controller.list[index].name}',
style: TextStyle(fontSize: ScreenAdaper.height(25)),
),
// if (controller.list[index].dept != null) ...[
// SizedBox(
// width: ScreenAdaper.width(20),
// ),
// Container(
// padding: EdgeInsets.symmetric(
// horizontal: ScreenAdaper.width(10),
// vertical: ScreenAdaper.height(5)),
// decoration: BoxDecoration(
// color: Colors.grey[300],
// borderRadius: BorderRadius.circular(ScreenAdaper.sp(10))),
// child: Text('${controller.list[index].dept?.name}'),
// )
],
),
),
);
}
}
class GroupSearchController extends GetxController {
RxList<SaleQuotationModel> list = RxList([]);
RxString searchKey = ''.obs;
final searchBarTextConroller = TextEditingController();
RefreshController refreshController = RefreshController(initialRefresh: true);
int page = 1;
int limit = 15;
int total = 0;
Future<List<SaleQuotationModel>> getData({bool isRefresh = false}) async {
// if (isRefresh == true) {
// page = 1;
// } else {
// page++;
// }
// final res = await Api.getUsers({
// 'page': page,
// 'pageSize': 15,
// 'keyword': searchKey.value,
// });
// List<UserInfoModel> newList =
// res.data!.items.map((e) => UserInfoModel.fromJson(e)).toList();
// isRefresh == true ? list.assignAll(newList) : list.addAll(newList);
List<SaleQuotationModel> newList = [
SaleQuotationModel(name: '中间过渡架电控部分', items: []),
SaleQuotationModel(name: '端头架电控部分', items: []),
SaleQuotationModel(name: '主阀部分', items: []),
SaleQuotationModel(name: '自动反冲洗过滤器部分', items: []),
SaleQuotationModel(name: '位移测量部分', items: []),
SaleQuotationModel(name: '压力检测部分', items: []),
SaleQuotationModel(name: '煤机定位部分', items: []),
SaleQuotationModel(name: '姿态检测部分', items: []),
];
list.assignAll(newList);
return newList;
}
Future<void> onRefresh() async {
await getData(isRefresh: true).then((_) {
refreshController.refreshCompleted(resetFooterState: true);
}).catchError((_) {
refreshController.refreshFailed();
});
}
Future<void> onLoading() async {
await getData().then((_) {
if (_.isEmpty) {
refreshController.loadNoData();
} else {
refreshController.loadComplete();
}
}).catchError((_) {
refreshController.loadFailed();
});
}
}

View File

@ -1,5 +1,12 @@
import 'package:flutter/material.dart';
import 'package:get/get.dart'; import 'package:get/get.dart';
import 'package:pull_to_refresh/pull_to_refresh.dart';
import 'package:sk_base_mobile/models/base_search_more.dart';
import 'package:sk_base_mobile/models/sale_quotation.model.dart'; import 'package:sk_base_mobile/models/sale_quotation.model.dart';
import 'package:sk_base_mobile/screens/sale_quotation/components/sale_quotation_group_search.dart';
import 'package:sk_base_mobile/widgets/core/sk_single_search_more.dart';
import 'package:sk_base_mobile/util/modal.util.dart';
import 'package:sk_base_mobile/util/screen_adaper_util.dart';
class SaleQuotationController extends GetxController { class SaleQuotationController extends GetxController {
static SaleQuotationController get to => Get.find(); static SaleQuotationController get to => Get.find();
@ -27,19 +34,149 @@ class SaleQuotationController extends GetxController {
SaleQuotationItemModel(name: '各类安装附件'), SaleQuotationItemModel(name: '各类安装附件'),
]); ]);
RxList<SaleQuotationModel> groups = RxList<SaleQuotationModel>([]); RxList<SaleQuotationModel> groups = RxList<SaleQuotationModel>([]);
@override @override
void onReady() { void onReady() {
groups.assignAll([ // groups.assignAll();
SaleQuotationModel(name: '中间过渡架电控部分', items: products), // SaleQuotationModel(name: '中间过渡架电控部分', items: products),
SaleQuotationModel(name: '端头架电控部分', items: products), // SaleQuotationModel(name: '端头架电控部分', items: products),
SaleQuotationModel(name: '主阀部分', items: products), // SaleQuotationModel(name: '主阀部分', items: products),
SaleQuotationModel(name: '自动反冲洗过滤器部分', items: products), // SaleQuotationModel(name: '自动反冲洗过滤器部分', items: products),
SaleQuotationModel(name: '位移测量部分', items: products), // SaleQuotationModel(name: '位移测量部分', items: products),
SaleQuotationModel(name: '压力检测部分', items: products), // SaleQuotationModel(name: '压力检测部分', items: products),
SaleQuotationModel(name: '煤机定位部分', items: products), // SaleQuotationModel(name: '煤机定位部分', items: products),
SaleQuotationModel(name: '姿态检测部分', items: products), // SaleQuotationModel(name: '姿态检测部分', items: products),
]);
super.onReady(); super.onReady();
} }
Future<void> addGroup() async {
final controller = Get.put(GroupSearchMoreController());
//
ModalUtil.showGeneralDialog(
content: SkSingleSearchMore<SaleQuotationModel>(
controller: controller,
enablePullUp: false,
enablePullDown: true,
itemBuilder: (_, index) {
return InkWell(
onTap: () {
Get.back();
groups.add(controller.list[index]);
},
child: Container(
padding: EdgeInsets.symmetric(
horizontal: ScreenAdaper.width(5),
vertical: ScreenAdaper.height(10)),
child: Row(
children: [
Text(
controller.list[index].name,
style: TextStyle(fontSize: ScreenAdaper.height(25)),
),
],
),
));
},
),
width: Get.width - ScreenAdaper.width(50))
.then((value) => Get.delete<GroupSearchController>());
}
Future<void> removeGroup(int index) async {
groups.removeAt(index);
}
Future<void> addItems() async {
final controller = Get.put(ItemSearchMoreController());
//
ModalUtil.showGeneralDialog(
content: SkSingleSearchMore<SaleQuotationItemModel>(
controller: controller,
enablePullUp: false,
enablePullDown: true,
isDialog: true,
itemBuilder: (_, index) {
return InkWell(
onTap: () {
Get.back();
// if (beforeSelectedCheck != null)
// {
// if (beforeSelectedCheck!(controller.list[index]))
// {onSelected!(controller.list[index])}
// }
// else
// {onSelected!(controller.list[index])}
},
child: Container(
padding: EdgeInsets.symmetric(
horizontal: ScreenAdaper.width(5),
vertical: ScreenAdaper.height(10)),
child: Row(
children: [
Text(
controller.list[index].name,
style: TextStyle(fontSize: ScreenAdaper.height(25)),
),
],
),
));
},
// onSelected: (SaleQuotationItemModel info) {
// Get.back();
// // groups.add(info);
// },
),
width: Get.width - ScreenAdaper.width(50))
.then((value) => Get.delete<ItemSearchMoreController>());
}
}
class GroupSearchMoreController extends GetxController
with BaseSearchMore<SaleQuotationModel> {
@override
Future<List<SaleQuotationModel>> getData({bool isRefresh = false}) async {
List<SaleQuotationModel> newList = [
SaleQuotationModel(name: '中间过渡架电控部分', items: []),
SaleQuotationModel(name: '端头架电控部分', items: []),
SaleQuotationModel(name: '主阀部分', items: []),
SaleQuotationModel(name: '自动反冲洗过滤器部分', items: []),
SaleQuotationModel(name: '位移测量部分', items: []),
SaleQuotationModel(name: '压力检测部分', items: []),
SaleQuotationModel(name: '煤机定位部分', items: []),
SaleQuotationModel(name: '姿态检测部分', items: []),
];
list.assignAll(newList);
return newList;
}
}
class ItemSearchMoreController extends GetxController
with BaseSearchMore<SaleQuotationItemModel> {
@override
Future<List<SaleQuotationItemModel>> getData({bool isRefresh = false}) async {
List<SaleQuotationItemModel> newList = [
SaleQuotationItemModel(name: '矿用本安型支架控制器', unit: '', spec: 'ZDYZ-Z'),
SaleQuotationItemModel(name: '矿用本安型电磁阀驱动器'),
SaleQuotationItemModel(name: '矿用隔爆兼本安型电源'),
SaleQuotationItemModel(name: '矿用本安型隔离耦合器'),
SaleQuotationItemModel(name: '钢丝编织橡胶护套连接器'),
SaleQuotationItemModel(name: '钢丝编织橡胶护套连接器', remark: '控制器-控制器'),
SaleQuotationItemModel(name: '钢丝编织橡胶护套连接器', remark: '控制器-驱动器'),
SaleQuotationItemModel(name: '钢丝编织橡胶护套连接器', remark: '控制器-隔离耦合器'),
SaleQuotationItemModel(name: '矿用本安型支架无线遥控器'),
SaleQuotationItemModel(name: '矿用隔爆兼本安型电源'),
SaleQuotationItemModel(name: '电液换向阀(10功能10接口)', remark: '中间过渡架主阀组'),
SaleQuotationItemModel(name: '电液换向阀(20功能20接口)', remark: '端头架主阀组'),
SaleQuotationItemModel(name: '自动反冲洗过滤装置', remark: '流量:900L/min,过滤精度25μm'),
SaleQuotationItemModel(name: '全自动反冲洗过滤器电缆', remark: '控制器-自动反冲洗'),
SaleQuotationItemModel(name: '矿用本安型位移传感器'),
SaleQuotationItemModel(name: '矿用本安型压力传感器'),
SaleQuotationItemModel(name: '矿用本安型红外发射器'),
SaleQuotationItemModel(name: '矿用本安型LED信号灯'),
SaleQuotationItemModel(name: '倾角传感器'),
SaleQuotationItemModel(name: '各类安装附件'),
];
list.assignAll(newList);
return newList;
}
} }

View File

@ -10,6 +10,7 @@ import 'package:sk_base_mobile/util/modal.util.dart';
import 'package:sk_base_mobile/util/screen_adaper_util.dart'; import 'package:sk_base_mobile/util/screen_adaper_util.dart';
import 'package:sk_base_mobile/widgets/core/sk_number_input.dart'; import 'package:sk_base_mobile/widgets/core/sk_number_input.dart';
import 'package:sk_base_mobile/widgets/core/sk_text_input.dart'; import 'package:sk_base_mobile/widgets/core/sk_text_input.dart';
import 'package:sk_base_mobile/widgets/empty.dart';
import 'package:sk_base_mobile/widgets/sk_appbar.dart'; import 'package:sk_base_mobile/widgets/sk_appbar.dart';
import 'package:flutter_sticky_header/flutter_sticky_header.dart'; import 'package:flutter_sticky_header/flutter_sticky_header.dart';
@ -28,16 +29,28 @@ class SaleQuotationPage extends StatelessWidget {
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
return Scaffold( return Scaffold(
floatingActionButtonLocation: FloatingActionButtonLocation.endFloat,
floatingActionButton: FloatingActionButton(
onPressed: () {
controller.addGroup();
},
child: const Icon(Icons.add),
),
appBar: SkAppbar( appBar: SkAppbar(
title: '报价计算', title: '报价计算',
action: [ action: [
TextButton( TextButton(
onPressed: () {}, onPressed: () {
controller.addGroup();
},
child: Row( child: Row(
children: [ children: [
Icon(Icons.add, color: AppTheme.white), Icon(Icons.save, color: AppTheme.white),
SizedBox(
width: ScreenAdaper.width(10),
),
Text( Text(
'添加组', '保存',
style: TextStyle( style: TextStyle(
color: AppTheme.white, color: AppTheme.white,
fontSize: ScreenAdaper.height(25), fontSize: ScreenAdaper.height(25),
@ -51,63 +64,70 @@ class SaleQuotationPage extends StatelessWidget {
bottom: ScreenAdaper.isLandspace() ? false : true, bottom: ScreenAdaper.isLandspace() ? false : true,
child: Column( child: Column(
children: [ children: [
Container( builderHeader(),
decoration: BoxDecoration(
color: headerBgcolor,
border: Border(
bottom: BorderSide(
color: AppTheme.nearlyBlack.withOpacity(0.5)))),
padding: EdgeInsets.only(
left: ScreenAdaper.width(20),
top: ScreenAdaper.height(10),
bottom: ScreenAdaper.height(10)),
child: Row(
children: [
Text(
'名称',
style: headerTitleStyle,
),
const Spacer(),
Container(
alignment: Alignment.center,
width: quantityWidth,
// constraints: BoxConstraints(minWidth: quantityWidth),
child: Text(
'数量',
style: headerTitleStyle,
),
),
Container(
alignment: Alignment.center,
width: unitPriceWidth,
// constraints: BoxConstraints(minWidth: unitPriceWidth),
child: Text(
'单价',
style: headerTitleStyle,
),
),
Container(
alignment: Alignment.center,
width: amountWidth,
child: Text(
'总价',
style: headerTitleStyle,
),
),
],
)),
Expanded( Expanded(
child: Obx(() => CustomScrollView( child: Obx(() => controller.groups.isEmpty
slivers: controller.groups ? Empty(text: '请先添加分组')
.mapIndexed<Widget>((index, e) => buildBody(e, index)) : CustomScrollView(
.toList(), slivers: controller.groups
))), .mapIndexed<Widget>(
(index, e) => buildBody(e, index))
.toList(),
))),
], ],
), ),
), ),
); );
} }
Widget builderHeader() {
return Container(
decoration: BoxDecoration(
color: headerBgcolor,
border: Border(
bottom:
BorderSide(color: AppTheme.nearlyBlack.withOpacity(0.5)))),
padding: EdgeInsets.only(
left: ScreenAdaper.width(20),
top: ScreenAdaper.height(10),
bottom: ScreenAdaper.height(10)),
child: Row(
children: [
Text(
'名称',
style: headerTitleStyle,
),
const Spacer(),
Container(
alignment: Alignment.center,
width: quantityWidth,
// constraints: BoxConstraints(minWidth: quantityWidth),
child: Text(
'数量',
style: headerTitleStyle,
),
),
Container(
alignment: Alignment.center,
width: unitPriceWidth,
// constraints: BoxConstraints(minWidth: unitPriceWidth),
child: Text(
'单价',
style: headerTitleStyle,
),
),
Container(
alignment: Alignment.center,
width: amountWidth,
child: Text(
'总价',
style: headerTitleStyle,
),
),
],
));
}
Widget buildBody(SaleQuotationModel group, int index) { Widget buildBody(SaleQuotationModel group, int index) {
final titleStyle = TextStyle( final titleStyle = TextStyle(
fontSize: ScreenAdaper.height(30), fontSize: ScreenAdaper.height(30),
@ -156,14 +176,20 @@ class SaleQuotationPage extends StatelessWidget {
const Spacer(), const Spacer(),
IconButton( IconButton(
onPressed: () { onPressed: () {
ModalUtil.confirm(title: '确定要删除此组吗?', onConfirm: () {}); ModalUtil.confirm(
title: '确定要删除此组吗?',
onConfirm: () {
controller.removeGroup(index);
});
}, },
icon: const Icon( icon: const Icon(
Icons.remove_circle_outline_outlined, Icons.remove_circle_outline_outlined,
color: AppTheme.nearlyBlack, color: AppTheme.nearlyBlack,
)), )),
IconButton( IconButton(
onPressed: () {}, onPressed: () {
controller.addItems();
},
icon: const Icon( icon: const Icon(
Icons.add_circle_outline, Icons.add_circle_outline,
color: AppTheme.nearlyBlack, color: AppTheme.nearlyBlack,

View File

@ -0,0 +1,182 @@
import 'package:flutter/material.dart';
import 'package:get/get.dart';
import 'package:pull_to_refresh/pull_to_refresh.dart';
import 'package:sk_base_mobile/app_theme.dart';
import 'package:sk_base_mobile/constants/bg_color.dart';
import 'package:sk_base_mobile/models/base_search_more.dart';
import 'package:sk_base_mobile/util/debouncer.dart';
import 'package:sk_base_mobile/util/screen_adaper_util.dart';
import 'package:sk_base_mobile/widgets/empty.dart';
class SkSingleSearchMore<T> extends StatelessWidget {
final Function(T)? onSelected;
final Function(T)? beforeSelectedCheck;
// ignore: prefer_typing_uninitialized_variables
final BaseSearchMore controller;
final bool enablePullUp;
final bool enablePullDown;
final bool isDialog;
final Function(BuildContext, int)? itemBuilder;
SkSingleSearchMore(
{super.key,
required this.controller,
this.onSelected,
this.isDialog = true,
this.beforeSelectedCheck,
this.itemBuilder,
this.enablePullDown = true,
this.enablePullUp = true});
final listTitleTextStyle =
TextStyle(fontSize: ScreenAdaper.height(20), fontWeight: FontWeight.w600);
@override
Widget build(BuildContext context) {
return Container(
padding: EdgeInsets.symmetric(
horizontal: ScreenAdaper.width(20),
vertical: ScreenAdaper.height(20)),
child: Column(
children: [
Container(
height: ScreenAdaper.height(60),
padding: EdgeInsets.only(bottom: ScreenAdaper.height(15)),
child: Stack(
children: [
Center(
child: Text(
'请选择',
style: TextStyle(
fontSize: ScreenAdaper.height(30),
fontWeight: FontWeight.w600),
),
),
Positioned(
right: 0,
child:
GestureDetector(onTap: () {}, child: Icon(Icons.close)))
],
),
),
buildSearchBar(),
SizedBox(
height: ScreenAdaper.height(defaultPadding) / 2,
),
Expanded(child: buildList())
],
),
);
}
Widget buildSearchBar() {
final doSearch = debouncer((String value) {
controller.searchKey.value = value;
controller.onRefresh();
}, delayTime: 500);
return Row(
children: [
Expanded(
flex: 5,
child: TextField(
controller: controller.searchBarTextConroller,
onChanged: (value) => doSearch(value),
decoration: InputDecoration(
contentPadding: EdgeInsets.symmetric(
vertical: ScreenAdaper.height(10),
horizontal: ScreenAdaper.width(10)),
hintText: '名称',
floatingLabelBehavior: FloatingLabelBehavior.always,
prefixIcon: const Icon(Icons.search),
// searchBarController有值时不显示
suffixIcon: Obx(() => controller.searchKey.value.isEmpty
? const SizedBox()
: IconButton(
icon: const Icon(Icons.clear),
onPressed: () {
controller.searchKey.value = '';
controller.searchBarTextConroller.clear();
doSearch('');
},
)),
border: OutlineInputBorder(
borderRadius: BorderRadius.circular(10),
),
))),
],
);
}
Widget buildList() {
return Obx(() => SmartRefresher(
enablePullDown: enablePullDown,
enablePullUp: enablePullUp,
controller: controller.refreshController,
onLoading: controller.onLoading,
onRefresh: controller.onRefresh,
child: controller.refreshController.isLoading
? const SizedBox()
: controller.list.isEmpty
? const Center(
child: Empty(text: '暂无数据'),
)
: ListView.separated(
separatorBuilder: (context, index) => const Divider(
color: AppTheme.dividerColor,
),
itemCount: controller.list.length,
itemBuilder: (_, index) => itemBuilder != null
? itemBuilder!(_, index)
: buildItem(index))));
}
Widget buildItem(int index) {
return InkWell(
onTap: () => {
// if (beforeSelectedCheck != null)
// {
// if (beforeSelectedCheck!(controller.list[index]))
// {onSelected!(controller.list[index])}
// }
// else
// {onSelected!(controller.list[index])}
},
child: Container(
padding: EdgeInsets.symmetric(
horizontal: ScreenAdaper.width(5),
vertical: ScreenAdaper.height(10)),
child: Row(
children: [
// ClipRRect(
// borderRadius: BorderRadius.circular(ScreenAdaper.sp(15)),
// child: FadeInCacheImage(
// url: controller.list[index].avatar ?? '',
// width: ScreenAdaper.width(60),
// height: ScreenAdaper.width(60),
// ),
// ),
// SizedBox(
// width: ScreenAdaper.width(20),
// ),
Text(
'${controller.list[index].name}',
style: TextStyle(fontSize: ScreenAdaper.height(25)),
),
// if (controller.list[index].dept != null) ...[
// SizedBox(
// width: ScreenAdaper.width(20),
// ),
// Container(
// padding: EdgeInsets.symmetric(
// horizontal: ScreenAdaper.width(10),
// vertical: ScreenAdaper.height(5)),
// decoration: BoxDecoration(
// color: Colors.grey[300],
// borderRadius: BorderRadius.circular(ScreenAdaper.sp(10))),
// child: Text('${controller.list[index].dept?.name}'),
// )
],
),
),
);
}
}

View File

@ -9,15 +9,17 @@ class Empty extends StatelessWidget {
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
return Center( return Center(
child: Column(mainAxisAlignment: MainAxisAlignment.center, children: [ child: Row(mainAxisAlignment: MainAxisAlignment.center, children: [
// Center( Center(
// child: Image( child: Icon(Icons.error_outline,
// height: ScreenAdaper.height(130), size: ScreenAdaper.height(40), color: Colors.red)),
// image: const AssetImage('assets/images/empty_icon.png'))), SizedBox(
width: ScreenAdaper.width(10),
),
Text( Text(
text ?? '', text ?? '',
textAlign: TextAlign.center, textAlign: TextAlign.center,
style: TextStyle(fontSize: ScreenAdaper.height(30)), style: TextStyle(fontSize: ScreenAdaper.height(35)),
), ),
]), ]),
); );

File diff suppressed because it is too large Load Diff