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

@@ -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),
curve: Curves.easeOut,
bottom: bottomSheetController.isVisible.value ? 0 : -maxHeight,
left: 0,
right: 0,
child: GestureDetector(
onVerticalDragUpdate: (DragUpdateDetails details) {
bottomSheetController.updateHeight(details.primaryDelta);
},
child: Container(
height: data.value,
decoration: BoxDecoration(
color: backgroundColor,
borderRadius: BorderRadius.vertical(top: Radius.circular(50)),
),
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)],
),
),
const SizedBox(height: 10),
child ?? SizedBox.shrink(),
],
return Obx(() {
if (!controller.isVisible.value) return SizedBox.shrink();
return Stack(
children: [
// پس‌زمینه تیره
Positioned.fill(
child: GestureDetector(
onTap: controller.toggle,
child: Container(color: Colors.black54),
),
),
),
),
bottomSheetController.currentHeight,
// محتوای BottomSheet
AnimatedPositioned(
duration: Duration(milliseconds: 300),
curve: Curves.easeOut,
left: 0,
right: 0,
bottom: 0,
child: GestureDetector(
onVerticalDragUpdate: (details) =>
controller.updateHeight(details.primaryDelta),
child: Container(
height: controller.currentHeight.value,
decoration: BoxDecoration(
color: backgroundColor,
borderRadius: BorderRadius.vertical(
top: Radius.circular(20),
),
boxShadow: [
BoxShadow(
color: Colors.black.withValues(alpha: 0.1),
blurRadius: 10,
),
],
),
child: Column(
children: [
GestureDetector(
onTap: controller.toggle,
child: Container(
padding: EdgeInsets.all(10),
child: Icon(Icons.drag_handle),
),
),
Expanded(child: child ?? SizedBox.shrink()),
],
),
),
),
),
],
);
}
);
}
}
}

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';