feat : BottomSheet manger and some changed in draggable bottom sheet

This commit is contained in:
2025-05-05 09:06:35 +03:30
parent 2ba786b556
commit 6ef1ab06c9
10 changed files with 804 additions and 755 deletions

View File

@@ -1,12 +1,10 @@
import 'dart:async';
import 'package:flutter/animation.dart';
import 'package:flutter/material.dart';
import 'package:inspection/data/utils/marker_generator.dart';
import 'package:inspection/presentation/filter/view.dart';
import 'package:rasadyar_core/core.dart';
enum BottomSheetStep { filter, markerSelected, markerDetails }
class InspectorFilterLogic extends GetxController
with GetTickerProviderStateMixin {
Rx<LatLng> currentLocation = LatLng(35.824891, 50.948025).obs;
@@ -19,22 +17,22 @@ class InspectorFilterLogic extends GetxController
RxInt showIndex = 0.obs;
bool showSlideHint = true;
Rx<BottomSheetStep> bottomSheetStep = BottomSheetStep.filter.obs;
late Rx<SlidableController> slidController;
Rx<MapController> mapController = MapController().obs;
late final AnimatedMapController animatedMapController;
late Rx<DraggableBottomSheetController> sheetController;
late DraggableBottomSheetController filterBottomSheetController;
late DraggableBottomSheetController selectedLocationBottomSheetController;
late DraggableBottomSheetController detailsLocationBottomSheetController;
late final BottomSheetManager bottomSheetManager;
Future<void> determineCurrentPosition() async {
final position = await Geolocator.getCurrentPosition(
locationSettings: AndroidSettings(accuracy: LocationAccuracy.best),
);
final latLng = LatLng(position.latitude, position.longitude);
currentLocation.value = latLng;
markers.add(latLng);
animatedMapController.animateTo(
@@ -77,7 +75,6 @@ class InspectorFilterLogic extends GetxController
allMarkers.value = generatedMarkers;
}
@override
void onInit() {
super.onInit();
@@ -87,53 +84,43 @@ class InspectorFilterLogic extends GetxController
curve: Curves.easeInOut,
cancelPreviousAnimations: true,
);
sheetController =
DraggableBottomSheetController(
initialVisibility: false,
initialHeight: 300,
minHeight: 70,
maxHeight: 600,
).obs;
filterBottomSheetController = DraggableBottomSheetController(
initialHeight: 350,
minHeight: 200,
maxHeight: Get.height * 0.5,
);
selectedLocationBottomSheetController = DraggableBottomSheetController(
initialHeight: 200,
minHeight: 100,
maxHeight: 200,
);
detailsLocationBottomSheetController = DraggableBottomSheetController(
initialHeight: Get.height * 0.5,
minHeight: Get.height * 0.37,
maxHeight: Get.height * 0.5,
);
slidController = SlidableController(this).obs;
/*bottomSheetStep.listen((data) {
tLog('1 bottomSheetStep -> ${data.nme}');
if (data == BottomSheetStep.filter) {
sheetController.value = DraggableBottomSheetController(
initialVisibility: true,
initialHeight: 300,
minHeight: 70,
maxHeight: 600,
);
} else if (data == BottomSheetStep.markerSelected) {
sheetController.value =
DraggableBottomSheetController(
initialVisibility: true,
initialHeight: 250,
minHeight: 50,
maxHeight: 300,
);
}else if(data == BottomSheetStep.markerDetails){
sheetController.value =
DraggableBottomSheetController(
initialVisibility: true,
initialHeight: 500,
minHeight: 50,
maxHeight: 700,
);
}
sheetController.refresh();
sheetController.value.toggle();
});*/
bottomSheetManager = BottomSheetManager({
filterBottomSheetController:
() => filterWidget(filterIndex: filterIndex, showIndex: showIndex),
selectedLocationBottomSheetController:
() => selectedLocationWidget(
showHint: selectedLocationBottomSheetController.isVisible.value,
sliderController: slidController.value,
trigger: triggerSlidableAnimation,
toggle: selectedLocationBottomSheetController.toggle,
),
detailsLocationBottomSheetController: () => markerDetailsWidget(),
});
}
@override
void onReady() {
super.onReady();
// determineCurrentPosition();
determineCurrentPosition();
generatedMarkers();
}
@@ -147,6 +134,7 @@ class InspectorFilterLogic extends GetxController
@override
void onClose() {
slidController.close();
super.onClose();
}
}

View File

@@ -1,6 +1,7 @@
import 'package:flutter/material.dart';
import 'package:inspection/presentation/routes/app_routes.dart';
import 'package:rasadyar_core/core.dart';
import 'package:rasadyar_core/data/utils.dart';
import 'package:rasadyar_core/presentation/widget/buttons/fab.dart';
import 'logic.dart';
@@ -10,103 +11,88 @@ class SupervisionFilterPage extends GetView<InspectorFilterLogic> {
@override
Widget build(BuildContext context) {
return PopScope(
canPop: controller.sheetController.value.handleBack,
return Scaffold(
body: PopScope(
canPop: !controller.bottomSheetManager.isAnyVisible,
onPopInvokedWithResult: (didPop, result) {
if (!didPop &&
controller.sheetController.value.bottomSheets.isNotEmpty) {
controller.sheetController.value.removeLastBottomSheet();
}
controller.bottomSheetManager.closeFirstVisible();
},
child: Stack(
children: [
ObxValue((currentLocation) {
_buildMap(),
_buildGpsButton(),
_buildFilterButton(),
Obx(() => controller.bottomSheetManager.buildVisibleSheet())],
),
),
);
}
Widget _buildMap() {
return ObxValue((currentLocation) {
return FlutterMap(
mapController: controller.animatedMapController.mapController,
options: MapOptions(
initialCenter: currentLocation.value,
initialZoom: 18,
onPositionChanged: (camera, hasGesture) {
controller.debouncedUpdateVisibleMarkers(
center: camera.center,
);
controller.debouncedUpdateVisibleMarkers(center: camera.center);
},
),
children: [
TileLayer(
urlTemplate: 'https://tile.openstreetmap.org/{z}/{x}/{y}.png',
),
ObxValue((markers) {
return MarkerLayer(
markers:
markers.map((marker) => markerWidget(marker)).toList(),
);
return MarkerLayer(markers: markers.map((e)=>markerWidget(marker: e, onTap: () {
controller.selectedLocationBottomSheetController.isVisible.value = true;
})).toList());
}, controller.markers),
],
);
}, controller.currentLocation),
Positioned(
}, controller.currentLocation);
}
Widget _buildGpsButton() {
return Positioned(
right: 10,
bottom: 150,
bottom:83,
child: ObxValue((data) {
return RFab.small(
backgroundColor: AppColor.greenNormal,
isLoading: data.value,
icon: vecWidget(Assets.vecGpsSvg),
onPressed: () {
onPressed: () async {
controller.isLoading.value = true;
controller.determineCurrentPosition().then(
(value) =>
controller.isLoading.value =
!controller.isLoading.value,
);
await controller.determineCurrentPosition();
controller.isLoading.value = false;
},
);
}, controller.isLoading),
),
Positioned(
right: 10,
bottom: 100,
child: RFab.small(
backgroundColor: AppColor.blueNormal,
icon: vecWidget(Assets.vecFilterSvg, width: 24, height: 24),
onPressed: () {
controller.sheetController.value.addBottomSheet(
child: filterWidget(),
initHeight: 400,
maxHeight: 470,
minHeight: 350,
);
},
),
),
Obx(
() => Stack(
children:
controller.sheetController.value.bottomSheets
.map((sheet) => sheet)
.toList(),
),
),
],
),
);
}
Marker markerWidget(LatLng marker) {
Widget _buildFilterButton() {
return Positioned(
right: 10,
bottom: 30,
child: RFab.small(
backgroundColor: AppColor.blueNormal,
icon: vecWidget(Assets.vecFilterSvg, width: 24, height: 24),
onPressed: () => controller.filterBottomSheetController.toggle(),
),
);
}
}
Marker markerWidget({required LatLng marker, required VoidCallback onTap}) {
return Marker(
point: marker,
child: GestureDetector(
onTap: () {
controller.sheetController.value.addBottomSheet(
child: selectedLocationWidget(),
minHeight: 0,
maxHeight: 250,
initHeight: 250,
);
},
onTap: onTap,
behavior: HitTestBehavior.opaque,
child: SizedBox(
width: 36,
@@ -117,114 +103,7 @@ class SupervisionFilterPage extends GetView<InspectorFilterLogic> {
);
}
Widget selectedLocationWidget() {
if (controller.showSlideHint) {
controller.triggerSlidableAnimation();
}
return Padding(
padding: const EdgeInsets.symmetric(horizontal: 30, vertical: 20),
child: Slidable(
key: Key('selectedLocationWidget'),
controller: controller.slidController.value,
endActionPane: ActionPane(
motion: StretchMotion(),
children: [
CustomSlidableAction(
onPressed: (context) {
Get.toNamed(InspectionRoutes.inspectionLocationDetails);
},
backgroundColor: AppColor.blueNormal,
foregroundColor: Colors.white,
padding: EdgeInsets.all(16),
borderRadius: BorderRadius.only(
bottomRight: Radius.circular(8),
topRight: Radius.circular(8),
),
child: vecWidget(Assets.vecMapSvg, width: 24, height: 24),
),
CustomSlidableAction(
onPressed: (context) {
Get.toNamed(InspectionRoutes.inspectionAddSupervision);
},
backgroundColor: AppColor.greenNormal,
padding: EdgeInsets.all(16),
child: vecWidget(Assets.vecMessageAddSvg),
),
CustomSlidableAction(
onPressed: (context) {},
backgroundColor: AppColor.warning,
padding: EdgeInsets.all(16),
borderRadius: BorderRadius.only(
bottomLeft: Radius.circular(8),
topLeft: Radius.circular(8),
),
child: vecWidget(Assets.vecSecurityTimeSvg),
),
],
),
child: GestureDetector(
onTap: () {
controller.sheetController.value.addBottomSheet(
child: markerDetailsWidget(),
minHeight: 0,
maxHeight: Get.height * 0.65,
initHeight: Get.height * 0.6,
);
},
child: Container(
height: 58,
padding: EdgeInsets.symmetric(horizontal: 20, vertical: 15),
decoration: BoxDecoration(
color: Colors.white,
borderRadius: BorderRadius.circular(8),
border: Border.all(width: 1, color: AppColor.blackLightHover),
),
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Column(
children: [
Text(
'داود خرم مهری پور',
style: AppFonts.yekan10.copyWith(
color: AppColor.blueNormal,
),
),
Text(
'گوشت و مرغ',
style: AppFonts.yekan12.copyWith(
color: AppColor.darkGreyDarkHover,
),
),
],
),
Column(
children: [
Text(
'باقی مانده',
style: AppFonts.yekan10.copyWith(
color: AppColor.blueNormal,
),
),
Text(
'0 کیلوگرم',
style: AppFonts.yekan12.copyWith(
color: AppColor.darkGreyDarkHover,
),
),
],
),
vecWidget(Assets.vecScanBarcodeSvg),
],
),
),
),
),
);
}
Padding filterWidget() {
Padding filterWidget({required RxInt filterIndex, required RxInt showIndex}) {
return Padding(
padding: const EdgeInsets.all(20.0),
child: Column(
@@ -309,7 +188,7 @@ class SupervisionFilterPage extends GetView<InspectorFilterLogic> {
customChip(
isSelected: data.value == 0,
onTap: (data) {
controller.filterIndex.value = data;
filterIndex.value = data;
},
index: 0,
title: 'دامداران',
@@ -318,7 +197,7 @@ class SupervisionFilterPage extends GetView<InspectorFilterLogic> {
isSelected: data.value == 1,
title: 'مرغداران',
onTap: (data) {
controller.filterIndex.value = data;
filterIndex.value = data;
},
index: 1,
),
@@ -326,13 +205,13 @@ class SupervisionFilterPage extends GetView<InspectorFilterLogic> {
isSelected: data.value == 2,
title: 'اصناف',
onTap: (data) {
controller.filterIndex.value = data;
filterIndex.value = data;
},
index: 2,
),
],
);
}, controller.filterIndex),
}, filterIndex),
],
),
@@ -357,7 +236,7 @@ class SupervisionFilterPage extends GetView<InspectorFilterLogic> {
isSelected: data.value == 0,
title: 'نمایش همه',
onTap: (data) {
controller.showIndex.value = data;
showIndex.value = data;
},
index: 0,
),
@@ -365,7 +244,7 @@ class SupervisionFilterPage extends GetView<InspectorFilterLogic> {
isSelected: data.value == 1,
title: 'دارای تراکنش',
onTap: (data) {
controller.showIndex.value = data;
showIndex.value = data;
},
index: 1,
),
@@ -373,7 +252,7 @@ class SupervisionFilterPage extends GetView<InspectorFilterLogic> {
isSelected: data.value == 2,
title: 'بازرسی شده ها',
onTap: (data) {
controller.showIndex.value = data;
showIndex.value = data;
},
index: 2,
),
@@ -381,7 +260,7 @@ class SupervisionFilterPage extends GetView<InspectorFilterLogic> {
isSelected: data.value == 3,
title: 'بازرسی نشده ها',
onTap: (data) {
controller.showIndex.value = data;
showIndex.value = data;
},
index: 3,
),
@@ -389,14 +268,14 @@ class SupervisionFilterPage extends GetView<InspectorFilterLogic> {
isSelected: data.value == 4,
title: 'متخلفین',
onTap: (data) {
controller.showIndex.value = data;
showIndex.value = data;
},
index: 4,
),
],
),
);
}, controller.showIndex),
}, showIndex),
],
),
],
@@ -612,4 +491,107 @@ class SupervisionFilterPage extends GetView<InspectorFilterLogic> {
),
);
}
Widget selectedLocationWidget({
required bool showHint,
required SlidableController sliderController,
required VoidCallback trigger,
required VoidCallback toggle,
}) {
if (showHint) {
trigger.call();
}
return Padding(
padding: const EdgeInsets.symmetric(horizontal: 30, vertical: 20),
child: Slidable(
key: Key('selectedLocationWidget'),
controller: sliderController,
endActionPane: ActionPane(
motion: StretchMotion(),
children: [
CustomSlidableAction(
onPressed: (context) {
Get.toNamed(InspectionRoutes.inspectionLocationDetails);
},
backgroundColor: AppColor.blueNormal,
foregroundColor: Colors.white,
padding: EdgeInsets.all(16),
borderRadius: BorderRadius.only(
bottomRight: Radius.circular(8),
topRight: Radius.circular(8),
),
child: vecWidget(Assets.vecMapSvg, width: 24, height: 24),
),
CustomSlidableAction(
onPressed: (context) {
Get.toNamed(InspectionRoutes.inspectionAddSupervision);
},
backgroundColor: AppColor.greenNormal,
padding: EdgeInsets.all(16),
child: vecWidget(Assets.vecMessageAddSvg),
),
CustomSlidableAction(
onPressed: (context) {},
backgroundColor: AppColor.warning,
padding: EdgeInsets.all(16),
borderRadius: BorderRadius.only(
bottomLeft: Radius.circular(8),
topLeft: Radius.circular(8),
),
child: vecWidget(Assets.vecSecurityTimeSvg),
),
],
),
child: GestureDetector(
onTap: toggle,
child: Container(
height: 58,
padding: EdgeInsets.symmetric(horizontal: 20, vertical: 15),
decoration: BoxDecoration(
color: Colors.white,
borderRadius: BorderRadius.circular(8),
border: Border.all(width: 1, color: AppColor.blackLightHover),
),
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Column(
children: [
Text(
'داود خرم مهری پور',
style: AppFonts.yekan10.copyWith(
color: AppColor.blueNormal,
),
),
Text(
'گوشت و مرغ',
style: AppFonts.yekan12.copyWith(
color: AppColor.darkGreyDarkHover,
),
),
],
),
Column(
children: [
Text(
'باقی مانده',
style: AppFonts.yekan10.copyWith(
color: AppColor.blueNormal,
),
),
Text(
'0 کیلوگرم',
style: AppFonts.yekan12.copyWith(
color: AppColor.darkGreyDarkHover,
),
),
],
),
vecWidget(Assets.vecScanBarcodeSvg),
],
),
),
),
),
);
}

View File

@@ -113,9 +113,9 @@ class RootPage extends GetView<RootLogic> {
controller.currentIndex,
),
Align(
alignment: Alignment.bottomCenter,
child: WaveBottomNavigation(
],
),
bottomNavigationBar: WaveBottomNavigation(
items: [
WaveBottomNavigationItem(title: 'خانه', icon: Assets.vecMapSvg),
WaveBottomNavigationItem(
@@ -147,9 +147,6 @@ class RootPage extends GetView<RootLogic> {
controller.changePage(index);
},
),
),
],
),
);
}
}

View File

@@ -100,7 +100,7 @@ packages:
source: sdk
version: "0.0.0"
flutter_map:
dependency: "direct main"
dependency: transitive
description:
name: flutter_map
sha256: f7d0379477274f323c3f3bc12d369a2b42eb86d1e7bd2970ae1ea3cff782449a
@@ -108,7 +108,7 @@ packages:
source: hosted
version: "8.1.1"
flutter_map_animations:
dependency: "direct main"
dependency: transitive
description:
name: flutter_map_animations
sha256: bf583863561861aaaf4854ae7ed8940d79bea7d32918bf7a85d309b25235a09e
@@ -161,7 +161,7 @@ packages:
source: hosted
version: "3.0.0"
geolocator:
dependency: "direct main"
dependency: transitive
description:
name: geolocator
sha256: e7ebfa04ce451daf39b5499108c973189a71a919aa53c1204effda1c5b93b822
@@ -228,18 +228,18 @@ packages:
dependency: transitive
description:
name: hive_ce
sha256: ac66daee46ad46486a1ed12cf91e9d7479c875fb46889be8d2c96b557406647f
sha256: fdc19336f03ecd01dbc1d1afe69d87ed9336bdf996c5374a25f9c21ef5f2989e
url: "https://pub.dev"
source: hosted
version: "2.10.1"
version: "2.11.1"
hive_ce_flutter:
dependency: transitive
description:
name: hive_ce_flutter
sha256: "74c1d5f10d803446b4e7913bb272137e2724ba8a56465444f9e7713aeb60a877"
sha256: "5eaf57a5af980eda63ddaa8c34d618dc446f76fe79410f2a283522744291c05c"
url: "https://pub.dev"
source: hosted
version: "2.2.0"
version: "2.3.0"
http:
dependency: transitive
description:
@@ -264,6 +264,14 @@ packages:
url: "https://pub.dev"
source: hosted
version: "0.19.0"
isolate_channel:
dependency: transitive
description:
name: isolate_channel
sha256: bafedfbcc1e9796ada179b5dac7043b33eb85d35204b089ca37d480d9c0068df
url: "https://pub.dev"
source: hosted
version: "0.2.2"
json_annotation:
dependency: transitive
description:
@@ -273,7 +281,7 @@ packages:
source: hosted
version: "4.9.0"
latlong2:
dependency: "direct main"
dependency: transitive
description:
name: latlong2
sha256: "98227922caf49e6056f91b6c56945ea1c7b166f28ffcd5fb8e72fc0b453cc8fe"
@@ -288,30 +296,6 @@ packages:
url: "https://pub.dev"
source: hosted
version: "1.0.1"
location:
dependency: "direct main"
description:
name: location
sha256: c2c4304071ec860525d5c50d142410072f8620c1d9f74874811af2e804e1a9c8
url: "https://pub.dev"
source: hosted
version: "8.0.0"
location_platform_interface:
dependency: transitive
description:
name: location_platform_interface
sha256: a3404ea6d74e89b121630be62ed8edcc7b39fd108bd19805d0ae55c397135dd7
url: "https://pub.dev"
source: hosted
version: "6.0.0"
location_web:
dependency: transitive
description:
name: location_web
sha256: "744bdff53dc455a2dc9a34474c49cde364d4fbef2aee009f8b0b4b68570c27a1"
url: "https://pub.dev"
source: hosted
version: "6.0.0"
logger:
dependency: transitive
description:
@@ -523,10 +507,10 @@ packages:
dependency: transitive
description:
name: shamsi_date
sha256: "4614789ed11bfffe5ba0aa157a20f2857ab6328528401766e0d924e453c866bd"
sha256: b6c79ff34ddfb1e9e4761347f18e30afdd7d16cc3db77defd5a40e2d93894c51
url: "https://pub.dev"
source: hosted
version: "1.0.4"
version: "1.1.0"
sky_engine:
dependency: transitive
description: flutter

View File

@@ -0,0 +1,42 @@
import 'package:flutter/material.dart';
import 'draggable_bottom_sheet.dart';
import 'draggable_bottom_sheet_controller.dart';
class BottomSheetManager {
final Map<DraggableBottomSheetController, Widget Function()> _sheetBuilders;
BottomSheetManager(this._sheetBuilders);
bool get isAnyVisible =>
_sheetBuilders.keys.any((controller) => controller.isVisible.value);
void closeFirstVisible() {
for (final controller in _sheetBuilders.keys) {
if (controller.isVisible.value) {
controller.toggle();
break;
}
}
}
Widget buildVisibleSheet() {
for (final entry in _sheetBuilders.entries) {
if (entry.key.isVisible.value) {
return _buildDraggableSheet(entry.key, entry.value());
}
}
return const SizedBox.shrink();
}
Widget _buildDraggableSheet(
DraggableBottomSheetController controller,
Widget child,
) {
return DraggableBottomSheet(
controller: controller,
backgroundColor: Colors.white,
child: child,
);
}
}

View File

@@ -4,86 +4,87 @@ import 'package:get/get.dart';
import 'package:rasadyar_core/data/utils.dart';
import 'package:rasadyar_core/presentation/common/app_color.dart';
import 'package:rasadyar_core/presentation/widget/draggable_bottom_sheet/draggable_bottom_sheet_controller.dart';
import 'package:flutter/material.dart';
import 'package:get/get.dart';
class DraggableBottomSheet extends StatelessWidget {
final DraggableBottomSheetController? controller;
final bool isVisible;
final double initialHeight;
final double minHeight;
final double maxHeight;
final DraggableBottomSheetController controller;
final Widget? child;
final Color? backgroundColor;
const DraggableBottomSheet({
super.key,
this.controller,
this.isVisible = false,
this.backgroundColor = AppColor.lightGreyNormal,
this.initialHeight = 200,
this.minHeight = 0,
this.maxHeight = 700,
required this.controller,
this.child,
this.backgroundColor = Colors.white,
});
@override
Widget build(BuildContext context) {
final DraggableBottomSheetController bottomSheetController =
controller ??
Get.put(
DraggableBottomSheetController(
initialVisibility: false,
initialHeight: initialHeight,
minHeight: minHeight,
maxHeight: maxHeight,
),
tag: 'local_$hashCode',
);
// Optionally show after first frame if isVisible is true
WidgetsBinding.instance.addPostFrameCallback((_) {
if (isVisible && !bottomSheetController.isVisible.value) {
bottomSheetController.show();
if (controller.isVisible.value && !controller.isVisible.value) {
controller.show();
}
});
return ObxValue(
(data) => AnimatedPositioned(
duration: const Duration(milliseconds: 300),
return Obx(() {
if (!controller.isVisible.value) return SizedBox.shrink();
return Stack(
children: [
// پس‌زمینه تیره
Positioned.fill(
child: GestureDetector(
onTap: controller.toggle,
child: Container(color: Colors.black54),
),
),
// محتوای BottomSheet
AnimatedPositioned(
duration: Duration(milliseconds: 300),
curve: Curves.easeOut,
bottom: bottomSheetController.isVisible.value ? 0 : -maxHeight,
left: 0,
right: 0,
bottom: 0,
child: GestureDetector(
onVerticalDragUpdate: (DragUpdateDetails details) {
bottomSheetController.updateHeight(details.primaryDelta);
},
onVerticalDragUpdate: (details) =>
controller.updateHeight(details.primaryDelta),
child: Container(
height: data.value,
height: controller.currentHeight.value,
decoration: BoxDecoration(
color: backgroundColor,
borderRadius: BorderRadius.vertical(top: Radius.circular(50)),
borderRadius: BorderRadius.vertical(
top: Radius.circular(20),
),
boxShadow: [
BoxShadow(
color: Colors.black.withValues(alpha: 0.1),
blurRadius: 10,
),
],
),
child: Column(
children: [
const SizedBox(height: 10),
GestureDetector(
onTap: () {
bottomSheetController.toggle();
},
behavior: HitTestBehavior.opaque,
child: Row(
mainAxisAlignment: MainAxisAlignment.center,
children: [const Icon(CupertinoIcons.chevron_down)],
onTap: controller.toggle,
child: Container(
padding: EdgeInsets.all(10),
child: Icon(Icons.drag_handle),
),
),
const SizedBox(height: 10),
child ?? SizedBox.shrink(),
Expanded(child: child ?? SizedBox.shrink()),
],
),
),
),
),
bottomSheetController.currentHeight,
],
);
}
);
}
}

View File

@@ -3,7 +3,7 @@ import 'package:get/get.dart';
import 'package:rasadyar_core/core.dart';
import 'draggable_bottom_sheet.dart';
class DraggableBottomSheetController extends GetxController {
/*class DraggableBottomSheetController extends GetxController {
final RxList<DraggableBottomSheet> bottomSheets =
<DraggableBottomSheet>[].obs;
@@ -124,5 +124,43 @@ class DraggableBottomSheetController extends GetxController {
return false;
}
}*/
class DraggableBottomSheetController extends GetxController {
final RxBool isVisible = false.obs;
final RxDouble currentHeight = 200.0.obs;
late double initialHeight;
late double minHeight;
late double maxHeight;
DraggableBottomSheetController({
this.initialHeight = 200,
this.minHeight = 100,
this.maxHeight = 700,
}) {
currentHeight.value = initialHeight;
}
void show() => isVisible.value = true;
void hide() => isVisible.value = false;
void toggle() => isVisible.value = !isVisible.value;
void updateHeight(double? delta) {
if (delta == null) return;
final newHeight = (currentHeight.value - delta).clamp(minHeight, maxHeight);
if (newHeight <= minHeight) {
hide();
} else {
currentHeight.value = newHeight;
}
}
@override
void onInit() {
super.onInit();
}
}

View File

@@ -8,6 +8,7 @@ export 'buttons/text_button.dart';
export 'captcha/captcha_widget.dart';
export 'draggable_bottom_sheet/draggable_bottom_sheet.dart';
export 'draggable_bottom_sheet/draggable_bottom_sheet_controller.dart';
export 'draggable_bottom_sheet/bottom_sheet_manger.dart';
export 'inputs/r_input.dart';
export 'pagination/pagination_from_until.dart';
export 'pagination/show_more.dart';

View File

@@ -417,26 +417,26 @@ packages:
dependency: "direct main"
description:
name: hive_ce
sha256: ac66daee46ad46486a1ed12cf91e9d7479c875fb46889be8d2c96b557406647f
sha256: fdc19336f03ecd01dbc1d1afe69d87ed9336bdf996c5374a25f9c21ef5f2989e
url: "https://pub.dev"
source: hosted
version: "2.10.1"
version: "2.11.1"
hive_ce_flutter:
dependency: "direct main"
description:
name: hive_ce_flutter
sha256: "74c1d5f10d803446b4e7913bb272137e2724ba8a56465444f9e7713aeb60a877"
sha256: "5eaf57a5af980eda63ddaa8c34d618dc446f76fe79410f2a283522744291c05c"
url: "https://pub.dev"
source: hosted
version: "2.2.0"
version: "2.3.0"
hive_ce_generator:
dependency: "direct dev"
description:
name: hive_ce_generator
sha256: "0b1c750e2d10c55a14cde16d479ada42704be6cef43c54b728ed0e4e02f7d808"
sha256: "84940c2fd3cb1d1eb318892cdb666bc0b8023f365f28aefe09b9e5a7222bc740"
url: "https://pub.dev"
source: hosted
version: "1.8.2"
version: "1.9.1"
http:
dependency: transitive
description:
@@ -477,6 +477,14 @@ packages:
url: "https://pub.dev"
source: hosted
version: "1.0.5"
isolate_channel:
dependency: transitive
description:
name: isolate_channel
sha256: bafedfbcc1e9796ada179b5dac7043b33eb85d35204b089ca37d480d9c0068df
url: "https://pub.dev"
source: hosted
version: "0.2.2"
js:
dependency: transitive
description:
@@ -825,10 +833,10 @@ packages:
dependency: transitive
description:
name: shamsi_date
sha256: "4614789ed11bfffe5ba0aa157a20f2857ab6328528401766e0d924e453c866bd"
sha256: b6c79ff34ddfb1e9e4761347f18e30afdd7d16cc3db77defd5a40e2d93894c51
url: "https://pub.dev"
source: hosted
version: "1.0.4"
version: "1.1.0"
shelf:
dependency: transitive
description:

View File

@@ -257,18 +257,18 @@ packages:
dependency: transitive
description:
name: hive_ce
sha256: ac66daee46ad46486a1ed12cf91e9d7479c875fb46889be8d2c96b557406647f
sha256: fdc19336f03ecd01dbc1d1afe69d87ed9336bdf996c5374a25f9c21ef5f2989e
url: "https://pub.dev"
source: hosted
version: "2.10.1"
version: "2.11.1"
hive_ce_flutter:
dependency: transitive
description:
name: hive_ce_flutter
sha256: "74c1d5f10d803446b4e7913bb272137e2724ba8a56465444f9e7713aeb60a877"
sha256: "5eaf57a5af980eda63ddaa8c34d618dc446f76fe79410f2a283522744291c05c"
url: "https://pub.dev"
source: hosted
version: "2.2.0"
version: "2.3.0"
http:
dependency: transitive
description:
@@ -300,6 +300,14 @@ packages:
url: "https://pub.dev"
source: hosted
version: "0.19.0"
isolate_channel:
dependency: transitive
description:
name: isolate_channel
sha256: bafedfbcc1e9796ada179b5dac7043b33eb85d35204b089ca37d480d9c0068df
url: "https://pub.dev"
source: hosted
version: "0.2.2"
json_annotation:
dependency: transitive
description:
@@ -575,10 +583,10 @@ packages:
dependency: transitive
description:
name: shamsi_date
sha256: "4614789ed11bfffe5ba0aa157a20f2857ab6328528401766e0d924e453c866bd"
sha256: b6c79ff34ddfb1e9e4761347f18e30afdd7d16cc3db77defd5a40e2d93894c51
url: "https://pub.dev"
source: hosted
version: "1.0.4"
version: "1.1.0"
sky_engine:
dependency: transitive
description: flutter