fix:修复 锁分组修改名字后没有侧滑按钮

This commit is contained in:
anfe 2024-06-24 16:37:33 +08:00
parent d6c7115418
commit 103570a97b
8 changed files with 230 additions and 182 deletions

View File

@ -46,7 +46,7 @@ class _CardDetailPageState extends State<CardDetailPage> with RouteAware {
rightTitle: state.typeNumber.value, rightTitle: state.typeNumber.value,
isHaveDirection: false, isHaveDirection: false,
isHaveLine: true)), isHaveLine: true)),
Obx(() => lockDataListItem(TranslationLoader.lanKeys!.name!.tr,state.typeName.value, () { Obx(() => lockDataListItem(TranslationLoader.lanKeys!.name!.tr,state.typeName.value, () {
ShowTipView().showTFViewAlertDialog( ShowTipView().showTFViewAlertDialog(
state.changeNameController, state.changeNameController,
'${TranslationLoader.lanKeys!.amend!.tr}${TranslationLoader.lanKeys!.name!.tr}', '${TranslationLoader.lanKeys!.amend!.tr}${TranslationLoader.lanKeys!.name!.tr}',
@ -62,6 +62,7 @@ class _CardDetailPageState extends State<CardDetailPage> with RouteAware {
FilteringTextInputFormatter.deny('\n'), FilteringTextInputFormatter.deny('\n'),
LengthLimitingTextInputFormatter(50), LengthLimitingTextInputFormatter(50),
]); ]);
})), })),
Obx(() => Visibility( Obx(() => Visibility(
visible: state.keyType.value == 4 || visible: state.keyType.value == 4 ||

View File

@ -1,11 +1,10 @@
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:flutter_easyloading/flutter_easyloading.dart'; import 'package:flutter_easyloading/flutter_easyloading.dart';
import 'package:flutter_screenutil/flutter_screenutil.dart'; import 'package:flutter_screenutil/flutter_screenutil.dart';
import 'package:get/get.dart'; import 'package:get/get.dart';
import 'package:star_lock/main/lockDetail/fingerprint/fingerprintList/fingerprintListData_entity.dart'; import 'package:star_lock/main/lockDetail/fingerprint/fingerprintList/fingerprintListData_entity.dart';
import 'package:star_lock/tools/keySearchWidget.dart'; import 'package:star_lock/tools/keySearchWidget.dart';
import 'package:star_lock/tools/left_slide_actions.dart'; import 'package:star_lock/tools/left_slide/left_slide_actions.dart';
import 'package:star_lock/tools/showTipView.dart'; import 'package:star_lock/tools/showTipView.dart';
import '../../../../appRouters.dart'; import '../../../../appRouters.dart';
@ -26,15 +25,15 @@ class FaceListPage extends StatefulWidget {
State<FaceListPage> createState() => _FaceListPageState(); State<FaceListPage> createState() => _FaceListPageState();
} }
class _FaceListPageState extends State<FaceListPage> with RouteAware { class _FaceListPageState extends State<FaceListPage> with RouteAware {
final logic = Get.put(FaceListLogic()); final logic = Get.put(FaceListLogic());
final state = Get.find<FaceListLogic>().state; final state = Get.find<FaceListLogic>().state;
Future<void> getHttpData() async { Future<void> getHttpData() async {
var isDemoMode = await Storage.getBool(ifIsDemoModeOrNot); var isDemoMode = await Storage.getBool(ifIsDemoModeOrNot);
if (isDemoMode == false) { if (isDemoMode == false) {
logic.getFaceListData().then((FingerprintListDataEntity value){ logic.getFaceListData().then((FingerprintListDataEntity value) {
if(mounted) setState(() {}); if (mounted) setState(() {});
}); });
} }
} }
@ -46,7 +45,6 @@ class _FaceListPageState extends State<FaceListPage> with RouteAware {
getHttpData(); getHttpData();
} }
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
return Scaffold( return Scaffold(
@ -66,7 +64,8 @@ class _FaceListPageState extends State<FaceListPage> with RouteAware {
var isDemoMode = await Storage.getBool(ifIsDemoModeOrNot); var isDemoMode = await Storage.getBool(ifIsDemoModeOrNot);
if (isDemoMode == false) { if (isDemoMode == false) {
// showDeletAlertDialog(context); // showDeletAlertDialog(context);
ShowTipView().showIosTipWithContentDialog("重置后,该锁的人脸都将被删除哦,确认要重置吗?", () async { ShowTipView().showIosTipWithContentDialog(
"重置后,该锁的人脸都将被删除哦,确认要重置吗?", () async {
state.isDeletAll = true; state.isDeletAll = true;
state.deletKeyID = "1"; state.deletKeyID = "1";
state.deletFaceNo = 0; state.deletFaceNo = 0;
@ -82,11 +81,11 @@ class _FaceListPageState extends State<FaceListPage> with RouteAware {
], ],
), ),
body: EasyRefreshTool( body: EasyRefreshTool(
onRefresh: (){ onRefresh: () {
logic.pageNo = 1; logic.pageNo = 1;
getHttpData(); getHttpData();
}, },
onLoad: (){ onLoad: () {
getHttpData(); getHttpData();
}, },
child: Column( child: Column(
@ -130,10 +129,12 @@ class _FaceListPageState extends State<FaceListPage> with RouteAware {
? ListView.separated( ? ListView.separated(
itemCount: state.faceItemListData.value.length, itemCount: state.faceItemListData.value.length,
itemBuilder: (c, index) { itemBuilder: (c, index) {
FingerprintItemData getFaceItemData = state.faceItemListData.value[index]; FingerprintItemData getFaceItemData =
state.faceItemListData.value[index];
// //
if (index < state.faceItemListData.value.length) { if (index < state.faceItemListData.value.length) {
return LeftSlideActions( return LeftSlideActions(
tag: getFaceItemData.faceName!,
key: Key(getFaceItemData.faceName!), key: Key(getFaceItemData.faceName!),
actionsWidth: 60, actionsWidth: 60,
actions: [ actions: [
@ -146,9 +147,9 @@ class _FaceListPageState extends State<FaceListPage> with RouteAware {
'images/icon_face.png', 'images/icon_face.png',
getFaceItemData.faceName!, getFaceItemData.faceName!,
logic.getKeyType(getFaceItemData), logic.getKeyType(getFaceItemData),
logic.getKeyDateType(getFaceItemData), logic.getKeyDateType(getFaceItemData), () async {
() async { var data =
var data = await Get.toNamed(Routers.faceDetailPage, arguments: { await Get.toNamed(Routers.faceDetailPage, arguments: {
"faceItemData": getFaceItemData, "faceItemData": getFaceItemData,
}); });
if (data != null) { if (data != null) {
@ -252,14 +253,13 @@ class _FaceListPageState extends State<FaceListPage> with RouteAware {
child: Row( child: Row(
children: [ children: [
Flexible( Flexible(
child: Text( child: Text(lockTypeTitle,
lockTypeTitle,
maxLines: 1, maxLines: 1,
overflow: TextOverflow.ellipsis, overflow: TextOverflow.ellipsis,
style: TextStyle(fontSize: 24.sp, color: AppColors.blackColor) style: TextStyle(
), fontSize: 24.sp,
color: AppColors.blackColor)),
), ),
], ],
), ),
), ),

View File

@ -5,7 +5,7 @@ import 'package:get/get.dart';
import 'package:star_lock/main/lockDetail/fingerprint/fingerprintList/fingerprintListData_entity.dart'; import 'package:star_lock/main/lockDetail/fingerprint/fingerprintList/fingerprintListData_entity.dart';
import 'package:star_lock/main/lockDetail/iris/irisList/irisList_logic.dart'; import 'package:star_lock/main/lockDetail/iris/irisList/irisList_logic.dart';
import 'package:star_lock/tools/keySearchWidget.dart'; import 'package:star_lock/tools/keySearchWidget.dart';
import 'package:star_lock/tools/left_slide_actions.dart'; import 'package:star_lock/tools/left_slide/left_slide_actions.dart';
import '../../../../appRouters.dart'; import '../../../../appRouters.dart';
import '../../../../app_settings/app_colors.dart'; import '../../../../app_settings/app_colors.dart';
@ -42,7 +42,7 @@ class _IrisListPageState extends State<IrisListPage> {
style: TextStyle(color: Colors.white, fontSize: 24.sp), style: TextStyle(color: Colors.white, fontSize: 24.sp),
), ),
onPressed: () async { onPressed: () async {
var isDemoMode = await Storage.getBool(ifIsDemoModeOrNot); final isDemoMode = await Storage.getBool(ifIsDemoModeOrNot);
if (isDemoMode == false) { if (isDemoMode == false) {
showDeletAlertDialog(context); showDeletAlertDialog(context);
} else { } else {
@ -73,7 +73,7 @@ class _IrisListPageState extends State<IrisListPage> {
// "lockId": state.lockId.value, // "lockId": state.lockId.value,
// "fromType": 1 // 1 2 // "fromType": 1 // 1 2
// }); // });
var data = final data =
await Get.toNamed(Routers.addIrisTypeManagePage, arguments: { await Get.toNamed(Routers.addIrisTypeManagePage, arguments: {
"lockId": state.lockId.value, "lockId": state.lockId.value,
"fromType": 1 // 1 2 "fromType": 1 // 1 2
@ -95,11 +95,12 @@ class _IrisListPageState extends State<IrisListPage> {
? ListView.separated( ? ListView.separated(
itemCount: state.faceItemListData.value.length, itemCount: state.faceItemListData.value.length,
itemBuilder: (c, index) { itemBuilder: (c, index) {
FingerprintItemData getFaceItemData = final FingerprintItemData getFaceItemData =
state.faceItemListData.value[index]; state.faceItemListData.value[index];
// //
if (index < state.faceItemListData.value.length) { if (index < state.faceItemListData.value.length) {
return LeftSlideActions( return LeftSlideActions(
tag: getFaceItemData.faceName!,
key: Key(getFaceItemData.faceName!), key: Key(getFaceItemData.faceName!),
actionsWidth: 60, actionsWidth: 60,
actions: [ actions: [
@ -122,7 +123,7 @@ class _IrisListPageState extends State<IrisListPage> {
// ? "永久" // ? "永久"
// : "${DateTool().dateToYMDHNString(fingerprintItemData.startDate.toString())} - ${DateTool().dateToYMDHNString(fingerprintItemData.endDate.toString())}", // : "${DateTool().dateToYMDHNString(fingerprintItemData.startDate.toString())} - ${DateTool().dateToYMDHNString(fingerprintItemData.endDate.toString())}",
() async { () async {
var data = final data =
await Get.toNamed(Routers.faceDetailPage, arguments: { await Get.toNamed(Routers.faceDetailPage, arguments: {
"faceItemData": getFaceItemData, "faceItemData": getFaceItemData,
}); });

View File

@ -5,7 +5,7 @@ import 'package:get/get.dart';
import 'package:star_lock/main/lockDetail/fingerprint/fingerprintList/fingerprintListData_entity.dart'; import 'package:star_lock/main/lockDetail/fingerprint/fingerprintList/fingerprintListData_entity.dart';
import 'package:star_lock/main/lockDetail/palm/palmList/palmList_logic.dart'; import 'package:star_lock/main/lockDetail/palm/palmList/palmList_logic.dart';
import 'package:star_lock/tools/keySearchWidget.dart'; import 'package:star_lock/tools/keySearchWidget.dart';
import 'package:star_lock/tools/left_slide_actions.dart'; import 'package:star_lock/tools/left_slide/left_slide_actions.dart';
import '../../../../appRouters.dart'; import '../../../../appRouters.dart';
import '../../../../app_settings/app_colors.dart'; import '../../../../app_settings/app_colors.dart';
@ -100,6 +100,7 @@ class _PalmListPageState extends State<PalmListPage> {
// //
if (index < state.faceItemListData.value.length) { if (index < state.faceItemListData.value.length) {
return LeftSlideActions( return LeftSlideActions(
tag:getFaceItemData.faceName!,
key: Key(getFaceItemData.faceName!), key: Key(getFaceItemData.faceName!),
actionsWidth: 60, actionsWidth: 60,
actions: [ actions: [

View File

@ -4,6 +4,7 @@ import 'package:flutter_screenutil/flutter_screenutil.dart';
import 'package:get/get.dart'; import 'package:get/get.dart';
import 'package:star_lock/main/lockDetail/electronicKey/massSendElectronicKey/massSendLockGroupList/massSendLockGroupListEntity.dart'; import 'package:star_lock/main/lockDetail/electronicKey/massSendElectronicKey/massSendLockGroupList/massSendLockGroupListEntity.dart';
import 'package:star_lock/mine/mineSet/lockGroup/lockGroupList/lockGroupList_state.dart'; import 'package:star_lock/mine/mineSet/lockGroup/lockGroupList/lockGroupList_state.dart';
import 'package:star_lock/tools/left_slide/left_slide_logic.dart';
import 'package:star_lock/tools/showTipView.dart'; import 'package:star_lock/tools/showTipView.dart';
import '../../../../../../appRouters.dart'; import '../../../../../../appRouters.dart';
@ -11,7 +12,7 @@ import '../../../../../../app_settings/app_colors.dart';
import '../../../../../../tools/commonItem.dart'; import '../../../../../../tools/commonItem.dart';
import '../../../../../../tools/titleAppBar.dart'; import '../../../../../../tools/titleAppBar.dart';
import '../../../../../../translations/trans_lib.dart'; import '../../../../../../translations/trans_lib.dart';
import '../../../../tools/left_slide_actions.dart'; import '../../../../tools/left_slide/left_slide_actions.dart';
import '../../../../tools/noData.dart'; import '../../../../tools/noData.dart';
import 'lockGroupList_logic.dart'; import 'lockGroupList_logic.dart';
@ -56,9 +57,11 @@ class _LockGroupListPageState extends State<LockGroupListPage> {
logic.showToast( logic.showToast(
TranslationLoader.lanKeys!.pleaseEnterAGroupName!.tr); TranslationLoader.lanKeys!.pleaseEnterAGroupName!.tr);
} }
}, isShowSuffixIcon:true, inputFormatters: <TextInputFormatter>[ },
LengthLimitingTextInputFormatter(50), isShowSuffixIcon: true,
]); inputFormatters: <TextInputFormatter>[
LengthLimitingTextInputFormatter(50),
]);
}, },
), ),
], ],
@ -66,23 +69,22 @@ class _LockGroupListPageState extends State<LockGroupListPage> {
body: Column( body: Column(
children: <Widget>[ children: <Widget>[
Expanded( Expanded(
child: Obx(() => state.itemDataList.value.isEmpty child: Obx(() =>
? NoData() state.itemDataList.isEmpty ? NoData() : _buildMainUI())),
: _buildMainUI())),
], ],
), ),
); );
} }
Widget _buildMainUI() { Widget _buildMainUI() {
for (int i = 0; i < state.itemDataList.value.length; i++) { for (int i = 0; i < state.itemDataList.length; i++) {
final GroupListItem itemData = state.itemDataList.value[i]; final GroupListItem itemData = state.itemDataList[i];
state.lockNum += itemData.lockList!.length; state.lockNum += itemData.lockList!.length;
} }
return ListView.separated( return ListView.separated(
itemCount: state.itemDataList.value.length + 1, itemCount: state.itemDataList.length + 1,
itemBuilder: (BuildContext c, int index) { itemBuilder: (BuildContext c, int index) {
if (index == state.itemDataList.value.length) { if (index == state.itemDataList.length) {
return Center( return Center(
child: Column( child: Column(
children: <Widget>[ children: <Widget>[
@ -101,12 +103,13 @@ class _LockGroupListPageState extends State<LockGroupListPage> {
), ),
); );
} else { } else {
final GroupListItem itemData = state.itemDataList.value[index]; final GroupListItem itemData = state.itemDataList[index];
if (itemData.groupType == 0) { if (itemData.groupType == 0) {
state.ungrouped = itemData; state.ungrouped = itemData;
} }
if (index < state.itemDataList.value.length) { if (index < state.itemDataList.length) {
return LeftSlideActions( return LeftSlideActions(
tag: itemData.keyGroupId!.toString(),
key: Key(itemData.keyGroupId!.toString()), key: Key(itemData.keyGroupId!.toString()),
actionsWidth: itemData.groupType != 0 ? 200.w : 0, actionsWidth: itemData.groupType != 0 ? 200.w : 0,
actions: itemData.groupType != 0 actions: itemData.groupType != 0
@ -118,12 +121,15 @@ class _LockGroupListPageState extends State<LockGroupListPage> {
decoration: const BoxDecoration( decoration: const BoxDecoration(
borderRadius: BorderRadius.all(Radius.circular(1)), borderRadius: BorderRadius.all(Radius.circular(1)),
), ),
child: lockDataListItem('${itemData.keyGroupName}(${itemData.lockList?.length})', () { child: lockDataListItem(
Get.toNamed(Routers.lockItemListPage, arguments: <String, GroupListItem>{ '${itemData.keyGroupName}(${itemData.lockList?.length})',
() {
Get.toNamed(Routers.lockItemListPage,
arguments: <String, GroupListItem>{
'groupListItem': itemData, 'groupListItem': itemData,
'ungrouped': state.ungrouped 'ungrouped': state.ungrouped
}); });
}), }),
); );
} }
return const SizedBox.shrink(); return const SizedBox.shrink();
@ -170,13 +176,15 @@ class _LockGroupListPageState extends State<LockGroupListPage> {
state.changeNameController.text = groupListItem.keyGroupName!; state.changeNameController.text = groupListItem.keyGroupName!;
// showCupertinoAlertDialog(context, false, groupListItem.keyGroupId!); // showCupertinoAlertDialog(context, false, groupListItem.keyGroupId!);
ShowTipView().showTFViewAlertDialog( ShowTipView().showTFViewAlertDialog(state.changeNameController,
state.changeNameController, '修改名称'.tr, TranslationLoader.lanKeys!.pleaseEnter!.tr, () {
'修改名称'.tr,
TranslationLoader.lanKeys!.pleaseEnter!.tr, () {
if (state.changeNameController.text.isNotEmpty) { if (state.changeNameController.text.isNotEmpty) {
Get.back(); Get.back();
logic.editLockGroupRequest(groupListItem.keyGroupId!); logic.editLockGroupRequest(groupListItem.keyGroupId!);
final String keyGroupId = groupListItem.keyGroupId!.toString();
if (Get.isRegistered<LeftSlideLogic>(tag: keyGroupId)) {
Get.find<LeftSlideLogic>(tag: keyGroupId).hide();
}
} else { } else {
logic.showToast( logic.showToast(
TranslationLoader.lanKeys!.pleaseEnterAGroupName!.tr); TranslationLoader.lanKeys!.pleaseEnterAGroupName!.tr);
@ -200,26 +208,24 @@ class _LockGroupListPageState extends State<LockGroupListPage> {
); );
} }
Widget lockDataListItem(String title, Function()? action){ Widget lockDataListItem(String title, Function()? action) {
return GestureDetector( return GestureDetector(
onTap: action, onTap: action,
child: Container( child: Container(
// height: 70.h, // height: 70.h,
padding: EdgeInsets.only(left: 20.w, right: 10.w, top: 15.h, bottom: 15.h), padding:
EdgeInsets.only(left: 20.w, right: 10.w, top: 15.h, bottom: 15.h),
decoration: BoxDecoration( decoration: BoxDecoration(
color: Colors.white, color: Colors.white,
border: Border( border: Border(
bottom: BorderSide( bottom: BorderSide(
color: AppColors.greyLineColor, // color: AppColors.greyLineColor, //
width: 2.0.h, // width: 2.0.h, //
), ),
) )),
),
child: Row( child: Row(
children: <Widget>[ children: <Widget>[
Expanded(child: Expanded(child: Text(title, style: TextStyle(fontSize: 22.sp))),
Text(title, style: TextStyle(fontSize: 22.sp))
),
// Text(title, style: TextStyle(fontSize: 22.sp)), // Text(title, style: TextStyle(fontSize: 22.sp)),
], ],
), ),

View File

@ -0,0 +1,101 @@
import 'package:flutter/material.dart';
import 'package:get/get.dart';
import 'package:star_lock/tools/left_slide/left_slide_logic.dart';
typedef BaseFunction<T> = void Function(T o);
/// : https://blog.csdn.net/zhuowalun8427/article/details/121285947
class LeftSlideActions extends StatefulWidget {
const LeftSlideActions({
required this.tag,
required this.actionsWidth,
required this.actions,
required this.child,
Key? key,
this.decoration,
this.actionsWillShow,
this.exportHideActions,
}) : super(key: key);
final String tag;
final double actionsWidth;
final List<Widget> actions;
final Widget child;
final Decoration? decoration;
final VoidCallback? actionsWillShow;
final BaseFunction<VoidCallback>? exportHideActions;
@override
_LeftSlideActionsState createState() => _LeftSlideActionsState();
}
class _LeftSlideActionsState extends State<LeftSlideActions>
with TickerProviderStateMixin {
late AnimationController _controller;
late LeftSlideLogic logic;
@override
void dispose() {
_controller.dispose();
super.dispose();
}
@override
void initState() {
super.initState();
_controller = AnimationController(
lowerBound: -widget.actionsWidth,
upperBound: 0,
vsync: this,
duration: const Duration(milliseconds: 300),
)..addListener(() {
logic.translateX = _controller.value;
setState(() {});
});
if (widget.exportHideActions != null) {
widget.exportHideActions!(logic.hide);
}
logic = LeftSlideLogic(
controller: _controller,
actionsWidth: widget.actionsWidth,
actions: widget.actions,
decoration: widget.decoration,
actionsWillShow: widget.actionsWillShow,
exportHideActions: widget.exportHideActions,
);
Get.put(logic, tag: widget.tag);
}
@override
Widget build(BuildContext context) {
return GetBuilder<LeftSlideLogic>(
tag: widget.tag,
builder: (LeftSlideLogic logic) {
return Container(
decoration: widget.decoration,
clipBehavior: Clip.hardEdge,
child: Stack(
children: <Widget>[
Positioned.fill(
child: Row(
mainAxisAlignment: MainAxisAlignment.end,
children: widget.actions,
),
),
GestureDetector(
onHorizontalDragUpdate: logic.onHorizontalDragUpdate,
onHorizontalDragEnd: logic.onHorizontalDragEnd,
child: Transform.translate(
offset: Offset(logic.translateX, 0),
child: Row(
children: <Widget>[
Expanded(flex: 1, child: widget.child),
],
),
),
),
],
),
);
});
}
}

View File

@ -0,0 +1,62 @@
import 'package:flutter/cupertino.dart';
import 'package:get/get.dart';
import 'package:star_lock/tools/left_slide/left_slide_actions.dart';
class LeftSlideLogic extends GetxController {
LeftSlideLogic({
required this.controller,
required this.actionsWidth,
required this.actions,
required this.decoration,
required this.actionsWillShow,
required this.exportHideActions,
});
late AnimationController controller;
final double actionsWidth;
final List<Widget> actions;
final Decoration? decoration;
final VoidCallback? actionsWillShow;
final BaseFunction<VoidCallback>? exportHideActions;
double translateX = 0;
@override
void onInit() {
super.onInit();
}
void onHorizontalDragUpdate(DragUpdateDetails details) {
translateX = (translateX + details.delta.dx).clamp(-actionsWidth, 0.0);
update();
}
void onHorizontalDragEnd(DragEndDetails details) {
controller.value = translateX;
if (details.velocity.pixelsPerSecond.dx > 200) {
hide();
} else if (details.velocity.pixelsPerSecond.dx < -200) {
show();
} else {
if (translateX.abs() > actionsWidth / 2) {
show();
} else {
hide();
}
}
}
void show() {
if (actionsWillShow != null) {
actionsWillShow!();
}
if (translateX != -actionsWidth) {
controller.animateTo(-actionsWidth);
}
}
void hide() {
if (translateX != 0) {
controller.animateTo(0);
}
}
}

View File

@ -1,124 +0,0 @@
import 'package:flutter/material.dart';
typedef _BaseFunction<T> = void Function(T o);
/// : https://blog.csdn.net/zhuowalun8427/article/details/121285947
class LeftSlideActions extends StatefulWidget {
final double actionsWidth;
final List<Widget> actions;
final Widget child;
final Decoration? decoration;
final VoidCallback? actionsWillShow;
final _BaseFunction<VoidCallback>? exportHideActions;
const LeftSlideActions({
Key? key,
required this.actionsWidth,
required this.actions,
required this.child,
this.decoration,
this.actionsWillShow,
this.exportHideActions,
}) : super(key: key);
@override
_LeftSlideActionsState createState() => _LeftSlideActionsState();
}
class _LeftSlideActionsState extends State<LeftSlideActions>
with TickerProviderStateMixin {
double _translateX = 0;
late AnimationController _controller;
@override
void dispose() {
_controller.dispose();
super.dispose();
}
@override
void initState() {
super.initState();
_controller = AnimationController(
lowerBound: -widget.actionsWidth,
upperBound: 0,
vsync: this,
duration: const Duration(milliseconds: 300),
)..addListener(() {
_translateX = _controller.value;
setState(() {});
});
if (widget.exportHideActions != null) {
widget.exportHideActions!(_hide);
}
}
@override
Widget build(BuildContext context) {
return Container(
decoration: widget.decoration,
clipBehavior: Clip.hardEdge,
child: Stack(
children: [
Positioned.fill(
child: Row(
mainAxisAlignment: MainAxisAlignment.end,
children: widget.actions,
),
),
GestureDetector(
onHorizontalDragUpdate: (v) {
_onHorizontalDragUpdate(v);
},
onHorizontalDragEnd: (v) {
_onHorizontalDragEnd(v);
},
child: Transform.translate(
offset: Offset(_translateX, 0),
child: Row(
children: [
Expanded(flex: 1, child: widget.child),
],
),
),
),
],
),
);
}
void _onHorizontalDragUpdate(DragUpdateDetails details) {
_translateX = (_translateX + details.delta.dx).clamp(-widget.actionsWidth, 0.0);
setState(() {});
}
void _onHorizontalDragEnd(DragEndDetails details) {
_controller.value = _translateX;
if (details.velocity.pixelsPerSecond.dx > 200) {
_hide();
} else if (details.velocity.pixelsPerSecond.dx < -200) {
_show();
} else {
if (_translateX.abs() > widget.actionsWidth / 2) {
_show();
} else {
_hide();
}
}
}
void _show() {
if (widget.actionsWillShow != null) {
widget.actionsWillShow!();
}
if (_translateX != -widget.actionsWidth) {
_controller.animateTo(-widget.actionsWidth);
}
}
void _hide() {
if (_translateX != 0) {
_controller.animateTo(0);
}
}
}